mirror of
https://github.com/danog/ir.git
synced 2025-01-22 05:31:32 +01:00
Fix LOAD/STORE with constant addresses
This commit is contained in:
parent
0a93d2e41b
commit
be0ecd0eb8
@ -586,8 +586,6 @@ cmp_fp:
|
||||
}
|
||||
return n;
|
||||
case IR_VSTORE:
|
||||
case IR_STORE_INT:
|
||||
case IR_STORE_FP:
|
||||
insn = &ctx->ir_base[ref];
|
||||
if (IR_IS_CONST_REF(insn->op3)) {
|
||||
insn = &ctx->ir_base[insn->op3];
|
||||
@ -598,6 +596,39 @@ cmp_fp:
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case IR_LOAD_FP:
|
||||
insn = &ctx->ir_base[ref];
|
||||
n = 0;
|
||||
if (IR_IS_CONST_REF(insn->op2)) {
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
tmp_regs[n].num = 2;
|
||||
tmp_regs[n].type = IR_ADDR;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
case IR_STORE_INT:
|
||||
case IR_STORE_FP:
|
||||
insn = &ctx->ir_base[ref];
|
||||
n = 0;
|
||||
if (IR_IS_CONST_REF(insn->op2)) {
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
tmp_regs[n].num = 2;
|
||||
tmp_regs[n].type = IR_ADDR;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
if (IR_IS_CONST_REF(insn->op3)) {
|
||||
insn = &ctx->ir_base[insn->op3];
|
||||
tmp_regs[n].num = 3;
|
||||
tmp_regs[n].type = insn->type;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
case IR_SWITCH:
|
||||
insn = &ctx->ir_base[ref];
|
||||
n = 0;
|
||||
@ -2868,13 +2899,11 @@ static void ir_emit_load_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
if (op2_reg != IR_REG_NONE && (op2_reg & IR_REG_SPILL_LOAD)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
op2_reg = def_reg;
|
||||
}
|
||||
if ((op2_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op2)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
@ -2890,11 +2919,16 @@ static void ir_emit_load_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_reg op2_reg = ctx->regs[def][2];
|
||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||
|
||||
IR_ASSERT(def_reg != IR_REG_NONE && op2_reg != IR_REG_NONE);
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
if (op2_reg != IR_REG_NONE && (op2_reg & IR_REG_SPILL_LOAD)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
ir_emit_load(ctx, type, op2_reg, insn->op2);
|
||||
}
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
op2_reg = def_reg;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
ir_emit_load_mem_fp(ctx, type, def_reg, op2_reg, 0);
|
||||
if (ctx->regs[def][0] & IR_REG_SPILL_STORE) {
|
||||
ir_emit_store(ctx, type, def, def_reg);
|
||||
@ -2909,7 +2943,7 @@ static void ir_emit_store_int(ir_ctx *ctx, ir_reg ref, ir_insn *insn)
|
||||
ir_reg op3_reg = ctx->regs[ref][3];
|
||||
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE && op3_reg != IR_REG_NONE);
|
||||
if (op2_reg & IR_REG_SPILL_LOAD) {
|
||||
if ((op2_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op2)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
@ -2928,7 +2962,7 @@ static void ir_emit_store_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
ir_reg op3_reg = ctx->regs[ref][3];
|
||||
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE && op3_reg != IR_REG_NONE);
|
||||
if (op2_reg & IR_REG_SPILL_LOAD) {
|
||||
if ((op2_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op2)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
|
72
ir_x86.dasc
72
ir_x86.dasc
@ -1024,7 +1024,6 @@ cmp_fp:
|
||||
}
|
||||
break;
|
||||
case IR_VSTORE_INT:
|
||||
case IR_STORE_INT:
|
||||
insn = &ctx->ir_base[ref];
|
||||
if (IR_IS_CONST_REF(insn->op3)) {
|
||||
insn = &ctx->ir_base[insn->op3];
|
||||
@ -1037,8 +1036,29 @@ cmp_fp:
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IR_STORE_INT:
|
||||
insn = &ctx->ir_base[ref];
|
||||
n = 0;
|
||||
if (IR_IS_CONST_REF(insn->op2)) {
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
tmp_regs[n].num = 2;
|
||||
tmp_regs[n].type = IR_ADDR;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
if (IR_IS_CONST_REF(insn->op3)) {
|
||||
insn = &ctx->ir_base[insn->op3];
|
||||
if (ir_type_size[insn->type] == 8 && !IR_IS_32BIT(insn->type, insn->val)) {
|
||||
tmp_regs[n].num = 3;
|
||||
tmp_regs[n].type = insn->type;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
case IR_VSTORE_FP:
|
||||
case IR_STORE_FP:
|
||||
insn = &ctx->ir_base[ref];
|
||||
if (IR_IS_CONST_REF(insn->op3)) {
|
||||
insn = &ctx->ir_base[insn->op3];
|
||||
@ -1049,6 +1069,38 @@ cmp_fp:
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case IR_LOAD_FP:
|
||||
insn = &ctx->ir_base[ref];
|
||||
n = 0;
|
||||
if (IR_IS_CONST_REF(insn->op2)) {
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
tmp_regs[n].num = 2;
|
||||
tmp_regs[n].type = IR_ADDR;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
case IR_STORE_FP:
|
||||
insn = &ctx->ir_base[ref];
|
||||
n = 0;
|
||||
if (IR_IS_CONST_REF(insn->op2)) {
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
tmp_regs[n].num = 2;
|
||||
tmp_regs[n].type = IR_ADDR;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
if (IR_IS_CONST_REF(insn->op3)) {
|
||||
insn = &ctx->ir_base[insn->op3];
|
||||
tmp_regs[n].num = 3;
|
||||
tmp_regs[n].type = insn->type;
|
||||
tmp_regs[n].start = IR_LOAD_SUB_REF;
|
||||
tmp_regs[n].end = IR_DEF_SUB_REF;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
case IR_SWITCH:
|
||||
insn = &ctx->ir_base[ref];
|
||||
n = 0;
|
||||
@ -4257,13 +4309,11 @@ static void ir_emit_load_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
if (op2_reg != IR_REG_NONE && (op2_reg & IR_REG_SPILL_LOAD)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
if (op2_reg == IR_REG_NONE) {
|
||||
op2_reg = def_reg;
|
||||
}
|
||||
if ((op2_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op2)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
}
|
||||
@ -4280,7 +4330,7 @@ static void ir_emit_load_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||
|
||||
IR_ASSERT(def_reg != IR_REG_NONE && op2_reg != IR_REG_NONE);
|
||||
if (op2_reg != IR_REG_NONE && (op2_reg & IR_REG_SPILL_LOAD)) {
|
||||
if ((op2_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op2)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
@ -4301,7 +4351,7 @@ static void ir_emit_store_int(ir_ctx *ctx, ir_reg ref, ir_insn *insn)
|
||||
ir_reg op3_reg = ctx->regs[ref][3];
|
||||
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE);
|
||||
if (op2_reg != IR_REG_NONE && (op2_reg & IR_REG_SPILL_LOAD)) {
|
||||
if ((op2_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op2)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
@ -4324,8 +4374,8 @@ static void ir_emit_store_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
|
||||
ir_reg op2_reg = ctx->regs[ref][2];
|
||||
ir_reg op3_reg = ctx->regs[ref][3];
|
||||
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE && op2_reg != IR_REG_NONE);
|
||||
if (op2_reg & IR_REG_SPILL_LOAD) {
|
||||
IR_ASSERT(op2_reg != IR_REG_NONE && op3_reg != IR_REG_NONE);
|
||||
if ((op2_reg & IR_REG_SPILL_LOAD) || IR_IS_CONST_REF(insn->op2)) {
|
||||
op2_reg &= ~IR_REG_SPILL_LOAD;
|
||||
IR_ASSERT(ctx->ir_base[insn->op2].type == IR_ADDR);
|
||||
ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
|
||||
|
Loading…
x
Reference in New Issue
Block a user