blob: 7e45d13816c183e46962e75c3dc4817d72d5b223 [file] [log] [blame]
/*
* 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