Merge branches 'pm-cpufreq', 'pm-cpuidle', 'pm-devfreq', 'pm-opp' and 'pm-tools'
[linux-drm-fsl-dcu.git] / arch / s390 / net / bpf_jit.S
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>
9
10 /*
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 = pointer to temp buffer
26  *   %r5 = length to copy
27  */
28 #define SKBDATA %r8
29
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
34
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
44
45 sk_load_word_slow:
46         lgr     %r9,%r2                 # save %r2
47         lgr     %r3,%r1                 # offset
48         la      %r4,160(%r15)           # pointer to temp buffer
49         lghi    %r5,4                   # 4 bytes
50         brasl   %r14,skb_copy_bits      # get data from skb
51         l       %r5,160(%r15)           # load result from temp buffer
52         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
53         lgr     %r2,%r9                 # restore %r2
54         br      %r8
55
56         /* A = *(u16 *) (skb->data+K+X) */
57 ENTRY(sk_load_half_ind)
58         ar      %r3,%r12                # offset += X
59         bmr     %r8                     # < 0 -> return with cc
60
61         /* A = *(u16 *) (skb->data+K) */
62 ENTRY(sk_load_half)
63         llgfr   %r1,%r3                 # extend offset
64         ahi     %r3,2                   # offset + 2
65         clr     %r11,%r3                # hlen <= offset + 2 ?
66         jl      sk_load_half_slow
67         llgh    %r5,0(%r1,%r10)         # get half from skb
68         xr      %r1,%r1                 # set cc to zero
69         br      %r8
70
71 sk_load_half_slow:
72         lgr     %r9,%r2                 # save %r2
73         lgr     %r3,%r1                 # offset
74         la      %r4,162(%r15)           # pointer to temp buffer
75         lghi    %r5,2                   # 2 bytes
76         brasl   %r14,skb_copy_bits      # get data from skb
77         xc      160(2,%r15),160(%r15)
78         l       %r5,160(%r15)           # load result from temp buffer
79         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
80         lgr     %r2,%r9                 # restore %r2
81         br      %r8
82
83         /* A = *(u8 *) (skb->data+K+X) */
84 ENTRY(sk_load_byte_ind)
85         ar      %r3,%r12                # offset += X
86         bmr     %r8                     # < 0 -> return with cc
87
88         /* A = *(u8 *) (skb->data+K) */
89 ENTRY(sk_load_byte)
90         llgfr   %r1,%r3                 # extend offset
91         clr     %r11,%r3                # hlen < offset ?
92         jle     sk_load_byte_slow
93         lhi     %r5,0
94         ic      %r5,0(%r1,%r10)         # get byte from skb
95         xr      %r1,%r1                 # set cc to zero
96         br      %r8
97
98 sk_load_byte_slow:
99         lgr     %r9,%r2                 # save %r2
100         lgr     %r3,%r1                 # offset
101         la      %r4,163(%r15)           # pointer to temp buffer
102         lghi    %r5,1                   # 1 byte
103         brasl   %r14,skb_copy_bits      # get data from skb
104         xc      160(3,%r15),160(%r15)
105         l       %r5,160(%r15)           # load result from temp buffer
106         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
107         lgr     %r2,%r9                 # restore %r2
108         br      %r8
109
110         /* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */
111 ENTRY(sk_load_byte_msh)
112         llgfr   %r1,%r3                 # extend offset
113         clr     %r11,%r3                # hlen < offset ?
114         jle     sk_load_byte_msh_slow
115         lhi     %r12,0
116         ic      %r12,0(%r1,%r10)        # get byte from skb
117         nill    %r12,0x0f
118         sll     %r12,2
119         xr      %r1,%r1                 # set cc to zero
120         br      %r8
121
122 sk_load_byte_msh_slow:
123         lgr     %r9,%r2                 # save %r2
124         lgr     %r3,%r1                 # offset
125         la      %r4,163(%r15)           # pointer to temp buffer
126         lghi    %r5,1                   # 1 byte
127         brasl   %r14,skb_copy_bits      # get data from skb
128         xc      160(3,%r15),160(%r15)
129         l       %r12,160(%r15)          # load result from temp buffer
130         nill    %r12,0x0f
131         sll     %r12,2
132         ltgr    %r2,%r2                 # set cc to (%r2 != 0)
133         lgr     %r2,%r9                 # restore %r2
134         br      %r8