mirror of
https://github.com/danog/ir.git
synced 2024-11-30 04:39:43 +01:00
Fix spill load code
This commit is contained in:
parent
9aac7e76af
commit
57a9731179
77
ir_x86.dasc
77
ir_x86.dasc
@ -2046,7 +2046,7 @@ int ir_match(ir_ctx *ctx)
|
||||
}
|
||||
|
||||
/* code genertion */
|
||||
IR_ALWAYS_INLINE int32_t ir_ref_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
||||
static int32_t ir_ref_spill_slot(ir_ctx *ctx, ir_ref ref, ir_reg *reg)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
int32_t offset;
|
||||
@ -2216,9 +2216,10 @@ static void ir_emit_fp_mov(ir_ctx *ctx, ir_type type, ir_reg dst, ir_reg src)
|
||||
| ASM_FP_REG_REG_OP movaps, movapd, vmovaps, vmovapd, type, dst, src
|
||||
}
|
||||
|
||||
static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref ref, ir_reg reg)
|
||||
static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref ref, ir_reg *preg)
|
||||
{
|
||||
ir_insn *addr_insn = &ctx->ir_base[ref];
|
||||
ir_reg reg;
|
||||
|
||||
if (addr_insn->op == IR_C_ADDR
|
||||
&& (sizeof(void*) == 4 || IR_IS_SIGNED_32BIT(addr_insn->val.i64))) {
|
||||
@ -2227,9 +2228,11 @@ static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref ref, ir_reg reg)
|
||||
return 0;
|
||||
} else if (addr_insn->op == IR_ADD) {
|
||||
IR_ASSERT(!IR_IS_CONST_REF(addr_insn->op1) && IR_IS_CONST_REF(addr_insn->op2));
|
||||
reg = *preg;
|
||||
IR_ASSERT(reg != IR_REG_NONE);
|
||||
if (reg & IR_REG_SPILL_LOAD) {
|
||||
reg &= ~IR_REG_SPILL_LOAD; // TODO: reg is passed by value
|
||||
reg &= ~IR_REG_SPILL_LOAD;
|
||||
*preg = reg;
|
||||
ir_emit_load(ctx, IR_ADDR, reg, addr_insn->op1);
|
||||
}
|
||||
return ctx->ir_base[addr_insn->op2].val.i32;
|
||||
@ -2239,12 +2242,12 @@ static int32_t ir_fuse_addr(ir_ctx *ctx, ir_ref ref, ir_reg reg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t ir_fuse_load(ir_ctx *ctx, ir_ref ref, ir_reg reg)
|
||||
static int32_t ir_fuse_load(ir_ctx *ctx, ir_ref ref, ir_reg *preg)
|
||||
{
|
||||
ir_insn *load_insn = &ctx->ir_base[ref];
|
||||
|
||||
IR_ASSERT(load_insn->op == IR_LOAD);
|
||||
return ir_fuse_addr(ctx, load_insn->op2, reg);
|
||||
return ir_fuse_addr(ctx, load_insn->op2, preg);
|
||||
}
|
||||
|
||||
static void ir_emit_prologue(ir_ctx *ctx)
|
||||
@ -2417,7 +2420,7 @@ static void ir_emit_binop_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -2495,7 +2498,7 @@ static void ir_emit_imul3(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op1, &op1_reg);
|
||||
}
|
||||
@ -2653,7 +2656,7 @@ static void ir_emit_mem_binop_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
}
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
@ -2844,7 +2847,7 @@ static void ir_emit_mem_mul_div_mod_pwr2(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
}
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
@ -2947,7 +2950,7 @@ static void ir_emit_mem_shift(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
}
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
@ -3053,7 +3056,7 @@ static void ir_emit_mem_shift_const(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
}
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
@ -3152,7 +3155,7 @@ static void ir_emit_mem_op_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, ®);
|
||||
}
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
@ -3275,7 +3278,7 @@ static void ir_emit_mul_div_mod(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
} else {
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -3299,7 +3302,7 @@ static void ir_emit_mul_div_mod(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
} else {
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -3316,7 +3319,7 @@ static void ir_emit_mul_div_mod(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
} else {
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -3550,7 +3553,7 @@ static void ir_emit_binop_sse2(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -3663,7 +3666,7 @@ static void ir_emit_binop_avx(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -3716,7 +3719,7 @@ static void ir_emit_cmp_int_common(ir_ctx *ctx, ir_type type, ir_insn *insn, ir_
|
||||
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -3728,7 +3731,7 @@ static void ir_emit_cmp_int_common(ir_ctx *ctx, ir_type type, ir_insn *insn, ir_
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -3901,7 +3904,7 @@ static void ir_emit_test_int_common(ir_ctx *ctx, ir_ref ref, ir_op op)
|
||||
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -3913,7 +3916,7 @@ static void ir_emit_test_int_common(ir_ctx *ctx, ir_ref ref, ir_op op)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ctx->rules[op1] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_load(ctx, op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op1, &op1_reg);
|
||||
}
|
||||
@ -4016,7 +4019,7 @@ static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref cmp_ref, ir_insn *cmp_ins
|
||||
|
||||
if (ctx->rules[op2] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, op2, &op2_reg);
|
||||
}
|
||||
@ -4298,7 +4301,7 @@ static void ir_emit_if_int(ir_ctx *ctx, int b, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_load(ctx, insn->op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
@ -4446,7 +4449,7 @@ static void ir_emit_sext(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -4543,7 +4546,7 @@ static void ir_emit_zext(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -4679,7 +4682,7 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -4729,7 +4732,7 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -4761,7 +4764,7 @@ static void ir_emit_int2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
}
|
||||
if (op1_reg != IR_REG_NONE && ctx->rules[insn->op1] != IR_SKIP_MEM) {
|
||||
if ((op1_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op1)) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
op1_reg &= ~IR_REG_SPILL_LOAD;
|
||||
ir_emit_load(ctx, src_type, op1_reg, insn->op1);
|
||||
}
|
||||
if (!src64) {
|
||||
@ -4803,7 +4806,7 @@ static void ir_emit_int2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -4948,7 +4951,7 @@ static void ir_emit_fp2int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -5052,7 +5055,7 @@ static void ir_emit_fp2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
||||
if (ctx->rules[insn->op1] == IR_SKIP_MEM) {
|
||||
IR_ASSERT(op1_reg != IR_REG_NONE);
|
||||
offset = ir_fuse_load(ctx, insn->op1, op1_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op1, &op1_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op1, &op1_reg);
|
||||
}
|
||||
@ -5240,7 +5243,7 @@ static void ir_emit_load_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, op2_reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
|
||||
ir_emit_load_mem_int(ctx, type, def_reg, op2_reg, offset);
|
||||
@ -5280,7 +5283,7 @@ static void ir_emit_load_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, op2_reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
|
||||
ir_emit_load_mem_fp(ctx, type, def_reg, op2_reg, offset);
|
||||
@ -5325,7 +5328,7 @@ static void ir_emit_store_int(ir_ctx *ctx, ir_reg ref, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, op2_reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
|
||||
if (IR_IS_CONST_REF(insn->op3) && IR_IS_32BIT(type, val_insn->val)) {
|
||||
@ -5371,7 +5374,7 @@ static void ir_emit_store_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_addr(ctx, insn->op2, op2_reg);
|
||||
offset = ir_fuse_addr(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
|
||||
ir_emit_store_mem_fp(ctx, type, op2_reg, offset, op3_reg);
|
||||
@ -6208,7 +6211,7 @@ static void ir_emit_ijmp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
} else if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
int32_t offset;
|
||||
|
||||
offset = ir_fuse_load(ctx, insn->op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
| jmp aword [offset]
|
||||
} else {
|
||||
@ -6277,7 +6280,7 @@ static void ir_emit_guard(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
int32_t offset = 0;
|
||||
|
||||
if (ctx->rules[insn->op2] == IR_SKIP_MEM) {
|
||||
offset = ir_fuse_load(ctx, insn->op2, op2_reg);
|
||||
offset = ir_fuse_load(ctx, insn->op2, &op2_reg);
|
||||
} else {
|
||||
offset = ir_ref_spill_slot(ctx, insn->op2, &op2_reg);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user