mirror of
https://github.com/danog/ir.git
synced 2024-11-26 20:34:53 +01:00
Fix register clobbering during argument passing
This commit is contained in:
parent
9f0bf4849f
commit
d26b162ffa
150
ir_aarch64.dasc
150
ir_aarch64.dasc
@ -3526,7 +3526,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
const int8_t *fp_reg_params = _ir_fp_reg_params;
|
||||
int32_t used_stack, stack_offset = 0;
|
||||
ir_copy *copies;
|
||||
bool has_mem_const_args = 0;
|
||||
bool do_pass3 = 0;
|
||||
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
|
||||
|
||||
n = ir_input_edges_count(ctx, insn);
|
||||
@ -3547,7 +3547,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
}
|
||||
}
|
||||
|
||||
/* 1. move all arguments that should be passed through stack
|
||||
/* 1. move all register arguments that should be passed through stack
|
||||
* and collect arguments that should be passed through registers */
|
||||
copies = ir_mem_malloc((n - 2) * sizeof(ir_copy));
|
||||
for (j = 3; j <= n; j++) {
|
||||
@ -3572,68 +3572,38 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
}
|
||||
if (dst_reg != IR_REG_NONE && (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE)) {
|
||||
/* delay CONST->REG and MEM->REG moves to third pass */
|
||||
has_mem_const_args = 1;
|
||||
continue;
|
||||
}
|
||||
if (dst_reg != IR_REG_NONE) {
|
||||
IR_ASSERT(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 (src_reg != dst_reg) {
|
||||
/* delay REG->REG moves to second pass */
|
||||
copies[count].type = type;
|
||||
copies[count].from = src_reg;
|
||||
copies[count].to = dst_reg;
|
||||
count++;
|
||||
if (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE) {
|
||||
/* delay CONST->REG and MEM->REG moves to third pass */
|
||||
do_pass3 = 1;
|
||||
} else {
|
||||
IR_ASSERT(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 (src_reg != dst_reg) {
|
||||
/* delay REG->REG moves to second pass */
|
||||
copies[count].type = type;
|
||||
copies[count].from = src_reg;
|
||||
copies[count].to = dst_reg;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Pass argument through stack (REG->MEM, IMM->MEM, MEM->MEM moves) */
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| adr Rx(tmp_reg), =>label
|
||||
| str Rx(tmp_reg), [sp, #stack_offset]
|
||||
} else {
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
ir_emit_load_imm_int(ctx, type, tmp_reg, val_insn->val.i64);
|
||||
| str Rx(tmp_reg), [sp, #stack_offset]
|
||||
}
|
||||
} else if (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);
|
||||
}
|
||||
/* 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_TYPE_INT(type)) {
|
||||
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
|
||||
} else {
|
||||
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);
|
||||
ir_emit_store_mem_fp(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
|
||||
}
|
||||
} else {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
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_NONE) {
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
do_pass3 = 1;
|
||||
}
|
||||
stack_offset += IR_MAX(sizeof(void*), ir_type_size[type]);
|
||||
}
|
||||
@ -3645,8 +3615,9 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
}
|
||||
ir_mem_free(copies);
|
||||
|
||||
/* 3. move the remaining memory and immediate values to registers */
|
||||
if (has_mem_const_args) {
|
||||
/* 3. move the remaining memory and immediate values */
|
||||
if (do_pass3) {
|
||||
stack_offset = 0;
|
||||
int_param = 0;
|
||||
fp_param = 0;
|
||||
for (j = 3; j <= n; j++) {
|
||||
@ -3671,27 +3642,62 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
}
|
||||
if (dst_reg != IR_REG_NONE && (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE)) {
|
||||
if (dst_reg != IR_REG_NONE) {
|
||||
if (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE) {
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
if (type == IR_ADDR) {
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
| adr Rx(dst_reg), =>label
|
||||
continue;
|
||||
}
|
||||
} else if (ir_type_size[type] == 1) {
|
||||
type = IR_ADDR;
|
||||
}
|
||||
}
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
} else {
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
if (type == IR_ADDR) {
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
| adr Rx(dst_reg), =>label
|
||||
continue;
|
||||
}
|
||||
} else if (ir_type_size[type] == 1) {
|
||||
type = IR_ADDR;
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| adr Rx(tmp_reg), =>label
|
||||
| str Rx(tmp_reg), [sp, #stack_offset]
|
||||
} else {
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
ir_emit_load_imm_int(ctx, type, tmp_reg, val_insn->val.i64);
|
||||
| str Rx(tmp_reg), [sp, #stack_offset]
|
||||
}
|
||||
} else if (src_reg == IR_REG_NONE) {
|
||||
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);
|
||||
}
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
} else {
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
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_NONE) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
stack_offset += IR_MAX(sizeof(void*), ir_type_size[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
201
ir_x86.dasc
201
ir_x86.dasc
@ -5698,7 +5698,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
const int8_t *fp_reg_params = _ir_fp_reg_params;
|
||||
int32_t used_stack, stack_offset = 0;
|
||||
ir_copy *copies;
|
||||
bool has_mem_const_args = 0;
|
||||
bool do_pass3 = 0;
|
||||
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
|
||||
|
||||
n = ir_input_edges_count(ctx, insn);
|
||||
@ -5728,7 +5728,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
}
|
||||
}
|
||||
|
||||
/* 1. move all arguments that should be passed through stack
|
||||
/* 1. move all register arguments that should be passed through stack
|
||||
* and collect arguments that should be passed through registers */
|
||||
copies = ir_mem_malloc((n - 2) * sizeof(ir_copy));
|
||||
for (j = 3; j <= n; j++) {
|
||||
@ -5753,95 +5753,37 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
}
|
||||
if (dst_reg != IR_REG_NONE && (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE)) {
|
||||
/* delay CONST->REG and MEM->REG moves to third pass */
|
||||
has_mem_const_args = 1;
|
||||
continue;
|
||||
}
|
||||
if (dst_reg != IR_REG_NONE) {
|
||||
IR_ASSERT(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 (src_reg != dst_reg) {
|
||||
/* delay REG->REG moves to second pass */
|
||||
copies[count].type = type;
|
||||
copies[count].from = src_reg;
|
||||
copies[count].to = dst_reg;
|
||||
count++;
|
||||
if (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE) {
|
||||
/* delay CONST->REG and MEM->REG moves to third pass */
|
||||
do_pass3 = 1;
|
||||
} else {
|
||||
if (src_reg & IR_REG_SPILL_LOAD) {
|
||||
src_reg &= ~IR_REG_SPILL_LOAD;
|
||||
ir_emit_load(ctx, type, src_reg, arg);
|
||||
}
|
||||
if (src_reg != dst_reg) {
|
||||
/* delay REG->REG moves to second pass */
|
||||
copies[count].type = type;
|
||||
copies[count].from = src_reg;
|
||||
copies[count].to = dst_reg;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Pass argument through stack (REG->MEM, IMM->MEM, MEM->MEM moves) */
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| lea Ra(tmp_reg), aword [=>label]
|
||||
| mov [Ra(IR_REG_RSP)+stack_offset], Ra(tmp_reg)
|
||||
} else if (IR_IS_SIGNED_32BIT(val_insn->val.i64)) {
|
||||
if (ir_type_size[type] <= 4) {
|
||||
| mov dword [Ra(IR_REG_RSP)+stack_offset], val_insn->val.i32
|
||||
} else {
|
||||
IR_ASSERT(sizeof(void*) == 8);
|
||||
|.if X64
|
||||
| mov qword [rsp+stack_offset], val_insn->val.i32
|
||||
|.endif
|
||||
}
|
||||
} else {
|
||||
IR_ASSERT(sizeof(void*) == 8);
|
||||
|.if X64
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| mov64 Ra(tmp_reg), val_insn->val.i64
|
||||
| mov [rsp+stack_offset], Ra(tmp_reg)
|
||||
|.endif
|
||||
}
|
||||
} else if (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);
|
||||
}
|
||||
/* 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_TYPE_INT(type)) {
|
||||
ir_emit_store_mem_int(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
|
||||
} else {
|
||||
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);
|
||||
ir_emit_store_mem_fp(ctx, type, IR_REG_STACK_POINTER, stack_offset, src_reg);
|
||||
}
|
||||
} else {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
ir_val *val = &ctx->ir_base[arg].val;
|
||||
if (ir_type_size[type] == 4) {
|
||||
| mov dword [Ra(IR_REG_RSP)+stack_offset], val->i32
|
||||
} else if (sizeof(void*) == 8) {
|
||||
|.if X64
|
||||
if (val->i64 == 0) {
|
||||
| mov qword [rsp+stack_offset], val->i32
|
||||
} else {
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| mov64 Rq(tmp_reg), val->i64
|
||||
| mov qword [rsp+stack_offset], Ra(tmp_reg)
|
||||
}
|
||||
|.endif
|
||||
} else {
|
||||
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_NONE) {
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
do_pass3 = 1;
|
||||
}
|
||||
stack_offset += IR_MAX(sizeof(void*), ir_type_size[type]);
|
||||
}
|
||||
@ -5853,8 +5795,9 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
}
|
||||
ir_mem_free(copies);
|
||||
|
||||
/* 3. move the remaining memory and immediate values to registers */
|
||||
if (has_mem_const_args) {
|
||||
/* 3. move the remaining memory and immediate values */
|
||||
if (do_pass3) {
|
||||
stack_offset = 0;
|
||||
int_param = 0;
|
||||
fp_param = 0;
|
||||
for (j = 3; j <= n; j++) {
|
||||
@ -5879,27 +5822,89 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
} else {
|
||||
IR_ASSERT(0);
|
||||
}
|
||||
if (dst_reg != IR_REG_NONE && (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE)) {
|
||||
if (dst_reg != IR_REG_NONE) {
|
||||
if (IR_IS_CONST_REF(arg) || src_reg == IR_REG_NONE) {
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
if (type == IR_ADDR) {
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
| lea Ra(dst_reg), aword [=>label]
|
||||
continue;
|
||||
}
|
||||
} else if (ir_type_size[type] == 1) {
|
||||
type = IR_ADDR;
|
||||
}
|
||||
}
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
} else {
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
if (type == IR_ADDR) {
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
ir_insn *val_insn = &ctx->ir_base[arg];
|
||||
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
if (val_insn->op == IR_STR) {
|
||||
int label = ctx->cfg_blocks_count - arg;
|
||||
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
| lea Ra(dst_reg), aword [=>label]
|
||||
continue;
|
||||
val_insn->const_flags |= IR_CONST_EMIT;
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| lea Ra(tmp_reg), aword [=>label]
|
||||
| mov [Ra(IR_REG_RSP)+stack_offset], Ra(tmp_reg)
|
||||
} else if (IR_IS_SIGNED_32BIT(val_insn->val.i64)) {
|
||||
if (ir_type_size[type] <= 4) {
|
||||
| mov dword [Ra(IR_REG_RSP)+stack_offset], val_insn->val.i32
|
||||
} else {
|
||||
IR_ASSERT(sizeof(void*) == 8);
|
||||
|.if X64
|
||||
| mov qword [rsp+stack_offset], val_insn->val.i32
|
||||
|.endif
|
||||
}
|
||||
} else if (ir_type_size[type] == 1) {
|
||||
type = IR_ADDR;
|
||||
} else {
|
||||
IR_ASSERT(sizeof(void*) == 8);
|
||||
|.if X64
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| mov64 Ra(tmp_reg), val_insn->val.i64
|
||||
| mov [rsp+stack_offset], Ra(tmp_reg)
|
||||
|.endif
|
||||
}
|
||||
} else if (src_reg == IR_REG_NONE) {
|
||||
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);
|
||||
}
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
} else {
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
if (IR_IS_CONST_REF(arg)) {
|
||||
ir_val *val = &ctx->ir_base[arg].val;
|
||||
if (ir_type_size[type] == 4) {
|
||||
| mov dword [Ra(IR_REG_RSP)+stack_offset], val->i32
|
||||
} else if (sizeof(void*) == 8) {
|
||||
|.if X64
|
||||
if (val->i64 == 0) {
|
||||
| mov qword [rsp+stack_offset], val->i32
|
||||
} else {
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
| mov64 Rq(tmp_reg), val->i64
|
||||
| mov qword [rsp+stack_offset], Ra(tmp_reg)
|
||||
}
|
||||
|.endif
|
||||
} else {
|
||||
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_NONE) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
stack_offset += IR_MAX(sizeof(void*), ir_type_size[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,12 +27,6 @@ test:
|
||||
stp x29, x30, [sp, #-0x10]!
|
||||
mov x29, sp
|
||||
sub sp, sp, #0x20
|
||||
movz w8, #0x8
|
||||
str x8, [sp]
|
||||
movz x8, #0x9
|
||||
str x8, [sp, #8]
|
||||
movz x8, #0x1, lsl #32
|
||||
str x8, [sp, #0x10]
|
||||
adr x0, .L1
|
||||
movz x1, #0x1
|
||||
movz w2, #0x2
|
||||
@ -41,6 +35,12 @@ test:
|
||||
movz x5, #0x1, lsl #32
|
||||
movz x6, #0x6
|
||||
movz w7, #0x7
|
||||
movz w8, #0x8
|
||||
str x8, [sp]
|
||||
movz x8, #0x9
|
||||
str x8, [sp, #8]
|
||||
movz x8, #0x1, lsl #32
|
||||
str x8, [sp, #0x10]
|
||||
bl _IO_printf
|
||||
add sp, sp, #0x20
|
||||
ldp x29, x30, [sp], #0x10
|
||||
|
@ -27,10 +27,6 @@ test:
|
||||
stp x29, x30, [sp, #-0x10]!
|
||||
mov x29, sp
|
||||
sub sp, sp, #0x10
|
||||
ldr d31, .L9
|
||||
str d31, [sp]
|
||||
fmov d31, xzr
|
||||
str d31, [sp, #8]
|
||||
adr x0, .L10
|
||||
ldr d0, .L1
|
||||
ldr d1, .L2
|
||||
@ -40,6 +36,10 @@ test:
|
||||
ldr d5, .L6
|
||||
ldr d6, .L7
|
||||
ldr d7, .L8
|
||||
ldr d31, .L9
|
||||
str d31, [sp]
|
||||
fmov d31, xzr
|
||||
str d31, [sp, #8]
|
||||
bl _IO_printf
|
||||
add sp, sp, #0x10
|
||||
ldp x29, x30, [sp], #0x10
|
||||
|
@ -29,10 +29,6 @@ test:
|
||||
mov w8, w7
|
||||
sub sp, sp, #0x20
|
||||
str w8, [sp]
|
||||
ldr w9, [x29, #0x20]
|
||||
str w9, [sp, #8]
|
||||
ldr w9, [x29, #0x28]
|
||||
str w9, [sp, #0x10]
|
||||
mov w7, w6
|
||||
mov w6, w5
|
||||
mov w5, w4
|
||||
@ -41,6 +37,10 @@ test:
|
||||
mov w2, w1
|
||||
mov w1, w0
|
||||
adr x0, .L1
|
||||
ldr w9, [x29, #0x20]
|
||||
str w9, [sp, #8]
|
||||
ldr w9, [x29, #0x28]
|
||||
str w9, [sp, #0x10]
|
||||
bl _IO_printf
|
||||
add sp, sp, #0x20
|
||||
ldp x29, x30, [sp], #0x10
|
||||
|
@ -92,10 +92,10 @@ test:
|
||||
movsd 0x14(%esp), %xmm0
|
||||
subsd 0xc(%esp), %xmm0
|
||||
movsd %xmm0, 0x1c(%esp)
|
||||
leal .L5, %eax
|
||||
movl %eax, (%esp)
|
||||
movsd 0x1c(%esp), %xmm0
|
||||
movsd %xmm0, 4(%esp)
|
||||
leal .L5, %eax
|
||||
movl %eax, (%esp)
|
||||
calll printf
|
||||
movsd 0x1c(%esp), %xmm1
|
||||
movsd %xmm1, 0xc(%esp)
|
||||
|
@ -93,10 +93,10 @@ test:
|
||||
movsd 0x14(%esp), %xmm0
|
||||
subsd 0xc(%esp), %xmm0
|
||||
movsd %xmm0, 0x1c(%esp)
|
||||
leal .L5, %eax
|
||||
movl %eax, (%esp)
|
||||
movsd 0x1c(%esp), %xmm0
|
||||
movsd %xmm0, 4(%esp)
|
||||
leal .L5, %eax
|
||||
movl %eax, (%esp)
|
||||
calll printf
|
||||
leal .L5, %eax
|
||||
movl %eax, (%esp)
|
||||
|
@ -76,9 +76,9 @@ test:
|
||||
leal (%ebx, %eax), %ebx
|
||||
movl %ebx, %ebp
|
||||
subl %eax, %ebp
|
||||
movl %ebp, 4(%esp)
|
||||
leal .L3, %eax
|
||||
movl %eax, (%esp)
|
||||
movl %ebp, 4(%esp)
|
||||
calll printf
|
||||
movl %ebp, %eax
|
||||
jmp .L1
|
||||
|
@ -25,18 +25,18 @@ x86_64
|
||||
--EXPECT--
|
||||
test:
|
||||
subq $0x28, %rsp
|
||||
movl $6, (%rsp)
|
||||
movl $7, 8(%rsp)
|
||||
movl $8, 0x10(%rsp)
|
||||
movq $9, 0x18(%rsp)
|
||||
movabsq $0x100000000, %rax
|
||||
movq %rax, 0x20(%rsp)
|
||||
leaq .L1(%rip), %rdi
|
||||
movq $1, %rsi
|
||||
movw $2, %dx
|
||||
movl $3, %ecx
|
||||
movq $4, %r8
|
||||
movabsq $0x100000000, %r9
|
||||
movl $6, (%rsp)
|
||||
movl $7, 8(%rsp)
|
||||
movl $8, 0x10(%rsp)
|
||||
movq $9, 0x18(%rsp)
|
||||
movabsq $0x100000000, %rax
|
||||
movq %rax, 0x20(%rsp)
|
||||
movabsq $_IO_printf, %rax
|
||||
callq *%rax
|
||||
addq $0x28, %rsp
|
||||
|
@ -25,9 +25,6 @@ x86_64
|
||||
--EXPECT--
|
||||
test:
|
||||
subq $0x18, %rsp
|
||||
movabsq $0x3feccccccccccccd, %rax
|
||||
movq %rax, (%rsp)
|
||||
movq $0, 8(%rsp)
|
||||
leaq .L9(%rip), %rdi
|
||||
movsd .L1(%rip), %xmm0
|
||||
movsd .L2(%rip), %xmm1
|
||||
@ -37,6 +34,9 @@ test:
|
||||
movsd .L6(%rip), %xmm5
|
||||
movsd .L7(%rip), %xmm6
|
||||
movsd .L8(%rip), %xmm7
|
||||
movabsq $0x3feccccccccccccd, %rax
|
||||
movq %rax, (%rsp)
|
||||
movq $0, 8(%rsp)
|
||||
movabsq $_IO_printf, %rax
|
||||
callq *%rax
|
||||
addq $0x18, %rsp
|
||||
|
@ -27,6 +27,12 @@ test:
|
||||
subq $0x28, %rsp
|
||||
movl %r9d, %eax
|
||||
movl %eax, (%rsp)
|
||||
movl %r8d, %r9d
|
||||
movl %ecx, %r8d
|
||||
movl %edx, %ecx
|
||||
movl %esi, %edx
|
||||
movl %edi, %esi
|
||||
leaq .L1(%rip), %rdi
|
||||
movl 0x30(%rsp), %r10d
|
||||
movl %r10d, 8(%rsp)
|
||||
movl 0x38(%rsp), %r10d
|
||||
@ -35,12 +41,6 @@ test:
|
||||
movl %r10d, 0x18(%rsp)
|
||||
movl 0x48(%rsp), %r10d
|
||||
movl %r10d, 0x20(%rsp)
|
||||
movl %r8d, %r9d
|
||||
movl %ecx, %r8d
|
||||
movl %edx, %ecx
|
||||
movl %esi, %edx
|
||||
movl %edi, %esi
|
||||
leaq .L1(%rip), %rdi
|
||||
movabsq $_IO_printf, %rax
|
||||
callq *%rax
|
||||
addq $0x28, %rsp
|
||||
|
Loading…
Reference in New Issue
Block a user