131 lines
		
	
	
	
		
			3.2 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			131 lines
		
	
	
	
		
			3.2 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 = 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 |