blob: ba44c9f5534633a2da3133714f6b018ba6a69545 [file] [log] [blame]
Martin Schwidefskyc10302e2012-07-31 16:23:59 +02001/*
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
Michael Holzheudb9aa8f2015-01-15 10:20:28 +010025 * %r4 = pointer to temp buffer
26 * %r5 = length to copy
Martin Schwidefskyc10302e2012-07-31 16:23:59 +020027 */
28#define SKBDATA %r8
29
30 /* A = *(u32 *) (skb->data+K+X) */
31ENTRY(sk_load_word_ind)
32 ar %r3,%r12 # offset += X
33 bmr %r8 # < 0 -> return with cc
34
35 /* A = *(u32 *) (skb->data+K) */
36ENTRY(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
45sk_load_word_slow:
46 lgr %r9,%r2 # save %r2
Michael Holzheud86eb742015-01-15 10:21:20 +010047 lgr %r3,%r1 # offset
Michael Holzheudb9aa8f2015-01-15 10:20:28 +010048 la %r4,160(%r15) # pointer to temp buffer
Michael Holzheufe82bba2015-01-15 10:23:46 +010049 lghi %r5,4 # 4 bytes
Martin Schwidefskyc10302e2012-07-31 16:23:59 +020050 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) */
57ENTRY(sk_load_half_ind)
58 ar %r3,%r12 # offset += X
59 bmr %r8 # < 0 -> return with cc
60
61 /* A = *(u16 *) (skb->data+K) */
62ENTRY(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
71sk_load_half_slow:
72 lgr %r9,%r2 # save %r2
Michael Holzheud86eb742015-01-15 10:21:20 +010073 lgr %r3,%r1 # offset
Michael Holzheudb9aa8f2015-01-15 10:20:28 +010074 la %r4,162(%r15) # pointer to temp buffer
Michael Holzheufe82bba2015-01-15 10:23:46 +010075 lghi %r5,2 # 2 bytes
Martin Schwidefskyc10302e2012-07-31 16:23:59 +020076 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) */
84ENTRY(sk_load_byte_ind)
85 ar %r3,%r12 # offset += X
86 bmr %r8 # < 0 -> return with cc
87
88 /* A = *(u8 *) (skb->data+K) */
89ENTRY(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
98sk_load_byte_slow:
99 lgr %r9,%r2 # save %r2
Michael Holzheufe82bba2015-01-15 10:23:46 +0100100 lgr %r3,%r1 # offset
Michael Holzheudb9aa8f2015-01-15 10:20:28 +0100101 la %r4,163(%r15) # pointer to temp buffer
Michael Holzheufe82bba2015-01-15 10:23:46 +0100102 lghi %r5,1 # 1 byte
Martin Schwidefskyc10302e2012-07-31 16:23:59 +0200103 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
Michael Holzheu1a92b2d2015-01-15 10:21:58 +0100110 /* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */
Martin Schwidefskyc10302e2012-07-31 16:23:59 +0200111ENTRY(sk_load_byte_msh)
112 llgfr %r1,%r3 # extend offset
113 clr %r11,%r3 # hlen < offset ?
Michael Holzheu1a92b2d2015-01-15 10:21:58 +0100114 jle sk_load_byte_msh_slow
Martin Schwidefskyc10302e2012-07-31 16:23:59 +0200115 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
122sk_load_byte_msh_slow:
123 lgr %r9,%r2 # save %r2
Michael Holzheufe82bba2015-01-15 10:23:46 +0100124 lgr %r3,%r1 # offset
Michael Holzheu1a92b2d2015-01-15 10:21:58 +0100125 la %r4,163(%r15) # pointer to temp buffer
Michael Holzheufe82bba2015-01-15 10:23:46 +0100126 lghi %r5,1 # 1 byte
Martin Schwidefskyc10302e2012-07-31 16:23:59 +0200127 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