net: filter: Fix some more small issues in sparc JIT.

Fix mixed space and tabs.

Put bpf_jit_load_*[] externs into bpf_jit.h

"while(0)" --> "while (0)"
"COND (X)" --> "COND(X)"
Document branch offset calculations, and bpf_error's return
sequence.

Document the reason we need to emit three nops between the
%y register write and the divide instruction.

Remove erroneous trailing semicolons from emit_read_y() and
emit_write_y().

Based upon feedback from Sam Ravnborg.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2012-04-17 16:38:16 -04:00
parent 7b56f76edf
commit 584c5e2ad3
3 changed files with 84 additions and 44 deletions

View File

@ -38,6 +38,21 @@
#define r_TMP G1 #define r_TMP G1
#define r_TMP2 G2 #define r_TMP2 G2
#define r_OFF G3 #define r_OFF G3
/* assembly code in arch/sparc/net/bpf_jit_asm.S */
extern u32 bpf_jit_load_word[];
extern u32 bpf_jit_load_half[];
extern u32 bpf_jit_load_byte[];
extern u32 bpf_jit_load_byte_msh[];
extern u32 bpf_jit_load_word_positive_offset[];
extern u32 bpf_jit_load_half_positive_offset[];
extern u32 bpf_jit_load_byte_positive_offset[];
extern u32 bpf_jit_load_byte_msh_positive_offset[];
extern u32 bpf_jit_load_word_negative_offset[];
extern u32 bpf_jit_load_half_negative_offset[];
extern u32 bpf_jit_load_byte_negative_offset[];
extern u32 bpf_jit_load_byte_msh_negative_offset[];
#else #else
#define r_SKB %o0 #define r_SKB %o0
#define r_A %o1 #define r_A %o1

View File

@ -195,5 +195,11 @@ bpf_jit_load_byte_msh_negative_offset:
sll r_OFF, 2, r_X sll r_OFF, 2, r_X
bpf_error: bpf_error:
/* Make the JIT program return zero. The JIT epilogue
* stores away the original %o7 into r_saved_O7. The
* normal leaf function return is to use "retl" which
* would evalute to "jmpl %o7 + 8, %g0" but we want to
* use the saved value thus the sequence you see here.
*/
jmpl r_saved_O7 + 8, %g0 jmpl r_saved_O7 + 8, %g0
clr %o0 clr %o0

View File

@ -11,20 +11,6 @@
int bpf_jit_enable __read_mostly; int bpf_jit_enable __read_mostly;
/* assembly code in arch/sparc/net/bpf_jit_asm.S */
extern u32 bpf_jit_load_word[];
extern u32 bpf_jit_load_half[];
extern u32 bpf_jit_load_byte[];
extern u32 bpf_jit_load_byte_msh[];
extern u32 bpf_jit_load_word_positive_offset[];
extern u32 bpf_jit_load_half_positive_offset[];
extern u32 bpf_jit_load_byte_positive_offset[];
extern u32 bpf_jit_load_byte_msh_positive_offset[];
extern u32 bpf_jit_load_word_negative_offset[];
extern u32 bpf_jit_load_half_negative_offset[];
extern u32 bpf_jit_load_byte_negative_offset[];
extern u32 bpf_jit_load_byte_msh_negative_offset[];
static inline bool is_simm13(unsigned int value) static inline bool is_simm13(unsigned int value)
{ {
return value + 0x1000 < 0x2000; return value + 0x1000 < 0x2000;
@ -300,8 +286,8 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \
#define emit_jump(DEST) emit_branch(BA, DEST) #define emit_jump(DEST) emit_branch(BA, DEST)
#define emit_read_y(REG) *prog++ = RD_Y | RD(REG); #define emit_read_y(REG) *prog++ = RD_Y | RD(REG)
#define emit_write_y(REG) *prog++ = WR_Y | IMMED | RS1(REG) | S13(0); #define emit_write_y(REG) *prog++ = WR_Y | IMMED | RS1(REG) | S13(0)
#define emit_cmp(R1, R2) \ #define emit_cmp(R1, R2) \
*prog++ = (SUBCC | RS1(R1) | RS2(R2) | RD(G0)) *prog++ = (SUBCC | RS1(R1) | RS2(R2) | RD(G0))
@ -333,6 +319,35 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \
#define emit_release_stack(SZ) \ #define emit_release_stack(SZ) \
*prog++ = (ADD | IMMED | RS1(SP) | S13(SZ) | RD(SP)) *prog++ = (ADD | IMMED | RS1(SP) | S13(SZ) | RD(SP))
/* A note about branch offset calculations. The addrs[] array,
* indexed by BPF instruction, records the address after all the
* sparc instructions emitted for that BPF instruction.
*
* The most common case is to emit a branch at the end of such
* a code sequence. So this would be two instructions, the
* branch and it's delay slot.
*
* Therefore by default the branch emitters calculate the branch
* offset field as:
*
* destination - (addrs[i] - 8)
*
* This "addrs[i] - 8" is the address of the branch itself or
* what "." would be in assembler notation. The "8" part is
* how we take into consideration the branch and it's delay
* slot mentioned above.
*
* Sometimes we need to emit a branch earlier in the code
* sequence. And in these situations we adjust "destination"
* to accomodate this difference. For example, if we needed
* to emit a branch (and it's delay slot) right before the
* final instruction emitted for a BPF opcode, we'd use
* "destination + 4" instead of just plain "destination" above.
*
* This is why you see all of these funny emit_branch() and
* emit_jump() calls with adjusted offsets.
*/
void bpf_jit_compile(struct sk_filter *fp) void bpf_jit_compile(struct sk_filter *fp)
{ {
unsigned int cleanup_addr, proglen, oldproglen = 0; unsigned int cleanup_addr, proglen, oldproglen = 0;
@ -493,6 +508,10 @@ void bpf_jit_compile(struct sk_filter *fp)
} }
emit_write_y(G0); emit_write_y(G0);
#ifdef CONFIG_SPARC32 #ifdef CONFIG_SPARC32
/* The Sparc v8 architecture requires
* three instructions between a %y
* register write and the first use.
*/
emit_nop(); emit_nop();
emit_nop(); emit_nop();
emit_nop(); emit_nop();