Fix register clobbering during argument passing and spill load

This commit is contained in:
Dmitry Stogov 2022-12-26 20:25:11 +03:00
parent d26b162ffa
commit 67da9e93ea
4 changed files with 22 additions and 14 deletions

View File

@ -3592,11 +3592,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
}
} else {
/* Pass register arguments to stack (REG->MEM moves) */
if (!IR_IS_CONST_REF(arg) && src_reg != IR_REG_NONE) {
if (src_reg & IR_REG_SPILL_LOAD) {
src_reg &= ~IR_REG_SPILL_LOAD;
ir_emit_load(ctx, type, src_reg, arg);
}
if (!IR_IS_CONST_REF(arg) && src_reg != IR_REG_NONE && !(src_reg & IR_REG_SPILL_LOAD)) {
if (IR_IS_TYPE_INT(type)) {
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
} else {
@ -3686,6 +3682,10 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
IR_ASSERT(tmp_reg != IR_REG_NONE);
ir_emit_load(ctx, type, tmp_reg, arg);
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, tmp_reg);
} else if (src_reg & IR_REG_SPILL_LOAD) {
src_reg &= ~IR_REG_SPILL_LOAD;
ir_emit_load(ctx, type, src_reg, arg);
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
}
} else {
if (IR_IS_CONST_REF(arg)) {
@ -3695,6 +3695,10 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
IR_ASSERT(tmp_fp_reg != IR_REG_NONE);
ir_emit_load(ctx, type, tmp_fp_reg, arg);
ir_emit_store_mem_fp(ctx, IR_DOUBLE, IR_REG_STACK_POINTER, stack_offset, tmp_fp_reg);
} else if (src_reg & IR_REG_SPILL_LOAD) {
src_reg &= ~IR_REG_SPILL_LOAD;
ir_emit_load(ctx, type, src_reg, arg);
ir_emit_store_mem_fp(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
}
}
stack_offset += IR_MAX(sizeof(void*), ir_type_size[type]);

View File

@ -5772,11 +5772,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
}
} else {
/* Pass register arguments to stack (REG->MEM moves) */
if (!IR_IS_CONST_REF(arg) && src_reg != IR_REG_NONE) {
if (src_reg & IR_REG_SPILL_LOAD) {
src_reg &= ~IR_REG_SPILL_LOAD;
ir_emit_load(ctx, type, src_reg, arg);
}
if (!IR_IS_CONST_REF(arg) && src_reg != IR_REG_NONE && !(src_reg & IR_REG_SPILL_LOAD)) {
if (IR_IS_TYPE_INT(type)) {
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
} else {
@ -5878,6 +5874,10 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
IR_ASSERT(tmp_reg != IR_REG_NONE);
ir_emit_load(ctx, type, tmp_reg, arg);
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, tmp_reg);
} else if (src_reg & IR_REG_SPILL_LOAD) {
src_reg &= ~IR_REG_SPILL_LOAD;
ir_emit_load(ctx, type, src_reg, arg);
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
}
} else {
if (IR_IS_CONST_REF(arg)) {
@ -5902,6 +5902,10 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
IR_ASSERT(tmp_fp_reg != IR_REG_NONE);
ir_emit_load(ctx, type, tmp_fp_reg, arg);
ir_emit_store_mem_fp(ctx, IR_DOUBLE, IR_REG_STACK_POINTER, stack_offset, tmp_fp_reg);
} else if (src_reg & IR_REG_SPILL_LOAD) {
src_reg &= ~IR_REG_SPILL_LOAD;
ir_emit_load(ctx, type, src_reg, arg);
ir_emit_store_mem_fp(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
}
}
stack_offset += IR_MAX(sizeof(void*), ir_type_size[type]);

View File

@ -92,10 +92,10 @@ test:
movsd 0x14(%esp), %xmm0
subsd 0xc(%esp), %xmm0
movsd %xmm0, 0x1c(%esp)
movsd 0x1c(%esp), %xmm0
movsd %xmm0, 4(%esp)
leal .L5, %eax
movl %eax, (%esp)
movsd 0x1c(%esp), %xmm0
movsd %xmm0, 4(%esp)
calll printf
movsd 0x1c(%esp), %xmm1
movsd %xmm1, 0xc(%esp)

View File

@ -93,10 +93,10 @@ test:
movsd 0x14(%esp), %xmm0
subsd 0xc(%esp), %xmm0
movsd %xmm0, 0x1c(%esp)
movsd 0x1c(%esp), %xmm0
movsd %xmm0, 4(%esp)
leal .L5, %eax
movl %eax, (%esp)
movsd 0x1c(%esp), %xmm0
movsd %xmm0, 4(%esp)
calll printf
leal .L5, %eax
movl %eax, (%esp)