|
@@ -163,6 +163,19 @@ do { \
|
|
|
(ctx)->idx++; \
|
|
|
} while (0)
|
|
|
|
|
|
+/*
|
|
|
+ * Similar to emit_instr but it must be used when we need to emit
|
|
|
+ * 32-bit or 64-bit instructions
|
|
|
+ */
|
|
|
+#define emit_long_instr(ctx, func, ...) \
|
|
|
+do { \
|
|
|
+ if ((ctx)->target != NULL) { \
|
|
|
+ u32 *p = &(ctx)->target[ctx->idx]; \
|
|
|
+ UASM_i_##func(&p, ##__VA_ARGS__); \
|
|
|
+ } \
|
|
|
+ (ctx)->idx++; \
|
|
|
+} while (0)
|
|
|
+
|
|
|
/* Determine if immediate is within the 16-bit signed range */
|
|
|
static inline bool is_range16(s32 imm)
|
|
|
{
|
|
@@ -218,13 +231,6 @@ static inline void emit_ori(unsigned int dst, unsigned src, u32 imm,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static inline void emit_daddu(unsigned int dst, unsigned int src1,
|
|
|
- unsigned int src2, struct jit_ctx *ctx)
|
|
|
-{
|
|
|
- emit_instr(ctx, daddu, dst, src1, src2);
|
|
|
-}
|
|
|
-
|
|
|
static inline void emit_daddiu(unsigned int dst, unsigned int src,
|
|
|
int imm, struct jit_ctx *ctx)
|
|
|
{
|
|
@@ -283,11 +289,7 @@ static inline void emit_xori(ptr dst, ptr src, u32 imm, struct jit_ctx *ctx)
|
|
|
|
|
|
static inline void emit_stack_offset(int offset, struct jit_ctx *ctx)
|
|
|
{
|
|
|
- if (config_enabled(CONFIG_64BIT))
|
|
|
- emit_instr(ctx, daddiu, r_sp, r_sp, offset);
|
|
|
- else
|
|
|
- emit_instr(ctx, addiu, r_sp, r_sp, offset);
|
|
|
-
|
|
|
+ emit_long_instr(ctx, ADDIU, r_sp, r_sp, offset);
|
|
|
}
|
|
|
|
|
|
static inline void emit_subu(unsigned int dst, unsigned int src1,
|
|
@@ -365,10 +367,7 @@ static inline void emit_store_stack_reg(ptr reg, ptr base,
|
|
|
unsigned int offset,
|
|
|
struct jit_ctx *ctx)
|
|
|
{
|
|
|
- if (config_enabled(CONFIG_64BIT))
|
|
|
- emit_instr(ctx, sd, reg, offset, base);
|
|
|
- else
|
|
|
- emit_instr(ctx, sw, reg, offset, base);
|
|
|
+ emit_long_instr(ctx, SW, reg, offset, base);
|
|
|
}
|
|
|
|
|
|
static inline void emit_store(ptr reg, ptr base, unsigned int offset,
|
|
@@ -381,10 +380,7 @@ static inline void emit_load_stack_reg(ptr reg, ptr base,
|
|
|
unsigned int offset,
|
|
|
struct jit_ctx *ctx)
|
|
|
{
|
|
|
- if (config_enabled(CONFIG_64BIT))
|
|
|
- emit_instr(ctx, ld, reg, offset, base);
|
|
|
- else
|
|
|
- emit_instr(ctx, lw, reg, offset, base);
|
|
|
+ emit_long_instr(ctx, LW, reg, offset, base);
|
|
|
}
|
|
|
|
|
|
static inline void emit_load(unsigned int reg, unsigned int base,
|
|
@@ -458,10 +454,7 @@ static inline void emit_load_ptr(unsigned int dst, unsigned int src,
|
|
|
int imm, struct jit_ctx *ctx)
|
|
|
{
|
|
|
/* src contains the base addr of the 32/64-pointer */
|
|
|
- if (config_enabled(CONFIG_64BIT))
|
|
|
- emit_instr(ctx, ld, dst, imm, src);
|
|
|
- else
|
|
|
- emit_instr(ctx, lw, dst, imm, src);
|
|
|
+ emit_long_instr(ctx, LW, dst, imm, src);
|
|
|
}
|
|
|
|
|
|
/* load a function pointer to register */
|
|
@@ -483,10 +476,7 @@ static inline void emit_load_func(unsigned int reg, ptr imm,
|
|
|
/* Move to real MIPS register */
|
|
|
static inline void emit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx)
|
|
|
{
|
|
|
- if (config_enabled(CONFIG_64BIT))
|
|
|
- emit_daddu(dst, src, r_zero, ctx);
|
|
|
- else
|
|
|
- emit_addu(dst, src, r_zero, ctx);
|
|
|
+ emit_long_instr(ctx, ADDU, dst, src, r_zero);
|
|
|
}
|
|
|
|
|
|
/* Move to JIT (32-bit) register */
|
|
@@ -623,10 +613,7 @@ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
|
|
|
if (ctx->flags & SEEN_MEM) {
|
|
|
if (real_off % (RSIZE * 2))
|
|
|
real_off += RSIZE;
|
|
|
- if (config_enabled(CONFIG_64BIT))
|
|
|
- emit_daddiu(r_M, r_sp, real_off, ctx);
|
|
|
- else
|
|
|
- emit_addiu(r_M, r_sp, real_off, ctx);
|
|
|
+ emit_long_instr(ctx, ADDIU, r_M, r_sp, real_off);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1241,7 +1228,7 @@ jmp_cmp:
|
|
|
emit_half_load(r_A, r_skb, off, ctx);
|
|
|
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
|
|
/* This needs little endian fixup */
|
|
|
- if (cpu_has_mips_r2) {
|
|
|
+ if (cpu_has_wsbh) {
|
|
|
/* R2 and later have the wsbh instruction */
|
|
|
emit_wsbh(r_A, r_A, ctx);
|
|
|
} else {
|