Fix register clobbering during argument passing

This commit is contained in:
Dmitry Stogov 2022-12-26 18:27:53 +03:00
parent 9f0bf4849f
commit d26b162ffa
11 changed files with 215 additions and 204 deletions

View File

@ -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]);
}
}
}

View File

@ -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]);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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