The s390x ABI requires to zero extend parameters before functions are called. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
		
			
				
	
	
		
			134 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/*
 | 
						|
 * 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 = pointer to temp buffer
 | 
						|
 *   %r5 = length to copy
 | 
						|
 */
 | 
						|
#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
 | 
						|
	lgr	%r3,%r1			# offset
 | 
						|
	la	%r4,160(%r15)		# pointer to temp buffer
 | 
						|
	lghi	%r5,4			# 4 bytes
 | 
						|
	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
 | 
						|
	lgr	%r3,%r1			# offset
 | 
						|
	la	%r4,162(%r15)		# pointer to temp buffer
 | 
						|
	lghi	%r5,2			# 2 bytes
 | 
						|
	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
 | 
						|
	lgr	%r3,%r1			# offset
 | 
						|
	la	%r4,163(%r15)		# pointer to temp buffer
 | 
						|
	lghi	%r5,1			# 1 byte
 | 
						|
	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
 | 
						|
 | 
						|
	/* X = (*(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_msh_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
 | 
						|
	lgr	%r3,%r1			# offset
 | 
						|
	la	%r4,163(%r15)		# pointer to temp buffer
 | 
						|
	lghi	%r5,1			# 1 byte
 | 
						|
	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
 |