123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- /*
- * BPF Jit compiler for s390, help functions.
- *
- * Copyright IBM Corp. 2012
- *
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
- #include <linux/linkage.h>
- /*
- * Calling convention:
- * registers %r2, %r6-%r8, %r10-%r11, %r13, %r15 are call saved
- * %r2: skb pointer
- * %r3: offset parameter
- * %r5: BPF A accumulator
- * %r8: return address
- * %r9: save register for skb pointer
- * %r10: skb->data
- * %r11: skb->len - skb->data_len (headlen)
- * %r12: BPF X accumulator
- *
- * skb_copy_bits takes 4 parameters:
- * %r2 = skb pointer
- * %r3 = offset into skb data
- * %r4 = length to copy
- * %r5 = pointer to temp buffer
- */
- #define SKBDATA %r8
- /* A = *(u32 *) (skb->data+K+X) */
- ENTRY(sk_load_word_ind)
- ar %r3,%r12 # offset += X
- bmr %r8 # < 0 -> return with cc
- /* A = *(u32 *) (skb->data+K) */
- ENTRY(sk_load_word)
- llgfr %r1,%r3 # extend offset
- ahi %r3,4 # offset + 4
- clr %r11,%r3 # hlen <= offset + 4 ?
- jl sk_load_word_slow
- l %r5,0(%r1,%r10) # get word from skb
- xr %r1,%r1 # set cc to zero
- br %r8
- sk_load_word_slow:
- lgr %r9,%r2 # save %r2
- lhi %r4,4 # 4 bytes
- la %r5,160(%r15) # pointer to temp buffer
- brasl %r14,skb_copy_bits # get data from skb
- l %r5,160(%r15) # load result from temp buffer
- ltgr %r2,%r2 # set cc to (%r2 != 0)
- lgr %r2,%r9 # restore %r2
- br %r8
- /* A = *(u16 *) (skb->data+K+X) */
- ENTRY(sk_load_half_ind)
- ar %r3,%r12 # offset += X
- bmr %r8 # < 0 -> return with cc
- /* A = *(u16 *) (skb->data+K) */
- ENTRY(sk_load_half)
- llgfr %r1,%r3 # extend offset
- ahi %r3,2 # offset + 2
- clr %r11,%r3 # hlen <= offset + 2 ?
- jl sk_load_half_slow
- llgh %r5,0(%r1,%r10) # get half from skb
- xr %r1,%r1 # set cc to zero
- br %r8
- sk_load_half_slow:
- lgr %r9,%r2 # save %r2
- lhi %r4,2 # 2 bytes
- la %r5,162(%r15) # pointer to temp buffer
- brasl %r14,skb_copy_bits # get data from skb
- xc 160(2,%r15),160(%r15)
- l %r5,160(%r15) # load result from temp buffer
- ltgr %r2,%r2 # set cc to (%r2 != 0)
- lgr %r2,%r9 # restore %r2
- br %r8
- /* A = *(u8 *) (skb->data+K+X) */
- ENTRY(sk_load_byte_ind)
- ar %r3,%r12 # offset += X
- bmr %r8 # < 0 -> return with cc
- /* A = *(u8 *) (skb->data+K) */
- ENTRY(sk_load_byte)
- llgfr %r1,%r3 # extend offset
- clr %r11,%r3 # hlen < offset ?
- jle sk_load_byte_slow
- lhi %r5,0
- ic %r5,0(%r1,%r10) # get byte from skb
- xr %r1,%r1 # set cc to zero
- br %r8
- sk_load_byte_slow:
- lgr %r9,%r2 # save %r2
- lhi %r4,1 # 1 bytes
- la %r5,163(%r15) # pointer to temp buffer
- brasl %r14,skb_copy_bits # get data from skb
- xc 160(3,%r15),160(%r15)
- l %r5,160(%r15) # load result from temp buffer
- ltgr %r2,%r2 # set cc to (%r2 != 0)
- lgr %r2,%r9 # restore %r2
- br %r8
- /* A = (*(u8 *)(skb->data+K) & 0xf) << 2 */
- ENTRY(sk_load_byte_msh)
- llgfr %r1,%r3 # extend offset
- clr %r11,%r3 # hlen < offset ?
- jle sk_load_byte_slow
- lhi %r12,0
- ic %r12,0(%r1,%r10) # get byte from skb
- nill %r12,0x0f
- sll %r12,2
- xr %r1,%r1 # set cc to zero
- br %r8
- sk_load_byte_msh_slow:
- lgr %r9,%r2 # save %r2
- lhi %r4,2 # 2 bytes
- la %r5,162(%r15) # pointer to temp buffer
- brasl %r14,skb_copy_bits # get data from skb
- xc 160(3,%r15),160(%r15)
- l %r12,160(%r15) # load result from temp buffer
- nill %r12,0x0f
- sll %r12,2
- ltgr %r2,%r2 # set cc to (%r2 != 0)
- lgr %r2,%r9 # restore %r2
- br %r8
|