Linux 3.11-rc3
[cris-mirror.git] / arch / s390 / net / bpf_jit.S
blob7e45d13816c183e46962e75c3dc4817d72d5b223
1 /*
2  * BPF Jit compiler for s390, help functions.
3  *
4  * Copyright IBM Corp. 2012
5  *
6  * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7  */
8 #include <linux/linkage.h>
11  * Calling convention:
12  * registers %r2, %r6-%r8, %r10-%r11, %r13, %r15 are call saved
13  *   %r2: skb pointer
14  *   %r3: offset parameter
15  *   %r5: BPF A accumulator
16  *   %r8: return address
17  *   %r9: save register for skb pointer
18  *   %r10: skb->data
19  *   %r11: skb->len - skb->data_len (headlen)
20  *   %r12: BPF X accumulator
21  *
22  * skb_copy_bits takes 4 parameters:
23  *   %r2 = skb pointer
24  *   %r3 = offset into skb data
25  *   %r4 = length to copy
26  *   %r5 = pointer to temp buffer
27  */
28 #define SKBDATA %r8
30         /* A = *(u32 *) (skb->data+K+X) */
31 ENTRY(sk_load_word_ind)
32         ar      %r3,%r12                # offset += X
33         bmr     %r8                     # < 0 -> return with cc
35         /* A = *(u32 *) (skb->data+K) */
36 ENTRY(sk_load_word)
37         llgfr   %r1,%r3                 # extend offset
38         ahi     %r3,4                   # offset + 4
39         clr     %r11,%r3                # hlen <= offset + 4 ?
40         jl      sk_load_word_slow
41         l       %r5,0(%r1,%r10)         # get word from skb
42         xr      %r1,%r1                 # set cc to zero
43         br      %r8
45 sk_load_word_slow:
46         lgr     %r9,%r2                 # save %r2
47         lhi     %r4,4                   # 4 bytes
48         la      %r5,160(%r15)           # pointer to temp buffer
49         brasl   %r14,skb_copy_bits      # get data from skb
50         l       %r5,160(%r15)           # load result from temp buffer
51         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
52         lgr     %r2,%r9                 # restore %r2
53         br      %r8
55         /* A = *(u16 *) (skb->data+K+X) */
56 ENTRY(sk_load_half_ind)
57         ar      %r3,%r12                # offset += X
58         bmr     %r8                     # < 0 -> return with cc
60         /* A = *(u16 *) (skb->data+K) */
61 ENTRY(sk_load_half)
62         llgfr   %r1,%r3                 # extend offset
63         ahi     %r3,2                   # offset + 2
64         clr     %r11,%r3                # hlen <= offset + 2 ?
65         jl      sk_load_half_slow
66         llgh    %r5,0(%r1,%r10)         # get half from skb
67         xr      %r1,%r1                 # set cc to zero
68         br      %r8
70 sk_load_half_slow:
71         lgr     %r9,%r2                 # save %r2
72         lhi     %r4,2                   # 2 bytes
73         la      %r5,162(%r15)           # pointer to temp buffer
74         brasl   %r14,skb_copy_bits      # get data from skb
75         xc      160(2,%r15),160(%r15)
76         l       %r5,160(%r15)           # load result from temp buffer
77         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
78         lgr     %r2,%r9                 # restore %r2
79         br      %r8
81         /* A = *(u8 *) (skb->data+K+X) */
82 ENTRY(sk_load_byte_ind)
83         ar      %r3,%r12                # offset += X
84         bmr     %r8                     # < 0 -> return with cc
86         /* A = *(u8 *) (skb->data+K) */
87 ENTRY(sk_load_byte)
88         llgfr   %r1,%r3                 # extend offset
89         clr     %r11,%r3                # hlen < offset ?
90         jle     sk_load_byte_slow
91         lhi     %r5,0
92         ic      %r5,0(%r1,%r10)         # get byte from skb
93         xr      %r1,%r1                 # set cc to zero
94         br      %r8
96 sk_load_byte_slow:
97         lgr     %r9,%r2                 # save %r2
98         lhi     %r4,1                   # 1 bytes
99         la      %r5,163(%r15)           # pointer to temp buffer
100         brasl   %r14,skb_copy_bits      # get data from skb
101         xc      160(3,%r15),160(%r15)
102         l       %r5,160(%r15)           # load result from temp buffer
103         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
104         lgr     %r2,%r9                 # restore %r2
105         br      %r8
107         /* A = (*(u8 *)(skb->data+K) & 0xf) << 2 */
108 ENTRY(sk_load_byte_msh)
109         llgfr   %r1,%r3                 # extend offset
110         clr     %r11,%r3                # hlen < offset ?
111         jle     sk_load_byte_slow
112         lhi     %r12,0
113         ic      %r12,0(%r1,%r10)        # get byte from skb
114         nill    %r12,0x0f
115         sll     %r12,2
116         xr      %r1,%r1                 # set cc to zero
117         br      %r8
119 sk_load_byte_msh_slow:
120         lgr     %r9,%r2                 # save %r2
121         lhi     %r4,2                   # 2 bytes
122         la      %r5,162(%r15)           # pointer to temp buffer
123         brasl   %r14,skb_copy_bits      # get data from skb
124         xc      160(3,%r15),160(%r15)
125         l       %r12,160(%r15)          # load result from temp buffer
126         nill    %r12,0x0f
127         sll     %r12,2
128         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
129         lgr     %r2,%r9                 # restore %r2
130         br      %r8