/* * The fly in the ointment of code size changing from pass to pass is * avoided by padding the short branch case with a NOP. If code size differs * with different branch reaches we will have the issue of code moving from * one pass to the next and will need a few passes to converge on a stable * state.
*/ #define PPC_BCC(cond, dest) do { \ if (is_offset_in_cond_branch_range((long)(dest) - CTX_NIA(ctx))) { \
PPC_BCC_SHORT(cond, dest); \
EMIT(PPC_RAW_NOP()); \
} else { \ /* Flip the 'T or F' bit to invert comparison */ \
PPC_BCC_SHORT(cond ^ COND_CMP_TRUE, CTX_NIA(ctx) + 2*4); \
PPC_JMP(dest); \
} } while(0)
/* To create a branch condition, select a bit of cr0... */ #define CR0_LT 0 #define CR0_GT 1 #define CR0_EQ 2 /* ...and modify BO[3] */ #define COND_CMP_TRUE 0x100 #define COND_CMP_FALSE 0x000 /* Together, they make all required comparisons: */ #define COND_GT (CR0_GT | COND_CMP_TRUE) #define COND_GE (CR0_LT | COND_CMP_FALSE) #define COND_EQ (CR0_EQ | COND_CMP_TRUE) #define COND_NE (CR0_EQ | COND_CMP_FALSE) #define COND_LT (CR0_LT | COND_CMP_TRUE) #define COND_LE (CR0_GT | COND_CMP_FALSE)
struct codegen_context { /* * This is used to track register usage as well * as calls to external helpers. * - register usage is tracked with corresponding * bits (r3-r31) * - rest of the bits can be used to track other * things -- for now, we use bits 0 to 2 * encoded in SEEN_* macros above
*/ unsignedint seen; unsignedint idx; unsignedint stack_size; int b2p[MAX_BPF_JIT_REG + 2]; unsignedint exentry_idx; unsignedint alt_exit_addr;
};
int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass, struct codegen_context *ctx, int insn_idx, int jmp_off, int dst_reg);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.