mirror of
https://github.com/danog/ir.git
synced 2024-12-02 09:38:29 +01:00
Implemented code generation for COND (not optimized)
This commit is contained in:
parent
2984f34fe7
commit
613fca0327
2
TODO
2
TODO
@ -27,7 +27,7 @@
|
|||||||
- Try to avoid live-interval construction, see "Efficient Global Register Allocation" Ian Rogers
|
- Try to avoid live-interval construction, see "Efficient Global Register Allocation" Ian Rogers
|
||||||
|
|
||||||
? code generation
|
? code generation
|
||||||
- COND
|
- COND optimization
|
||||||
- TAILCALL with stack arguments (tests/x86/tailcall_001.itr)
|
- TAILCALL with stack arguments (tests/x86/tailcall_001.itr)
|
||||||
- 32-bit x86 back-end 64-bit integers support
|
- 32-bit x86 back-end 64-bit integers support
|
||||||
(add_009.irt, conv_001.irt, conv_002.irt, conv_004.irt, conv_010.irt, sub_009.irt)
|
(add_009.irt, conv_001.irt, conv_002.irt, conv_004.irt, conv_010.irt, sub_009.irt)
|
||||||
|
@ -137,6 +137,15 @@ static bool aarch64_may_encode_addr_offset(int64_t offset, uint32_t type_size)
|
|||||||
|| }
|
|| }
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
||||||
|
|.macro ASM_FP_REG_IMM_OP, op, type, reg, val
|
||||||
|
|| if (type == IR_DOUBLE) {
|
||||||
|
| op Rd(reg-IR_REG_FP_FIRST), #val
|
||||||
|
|| } else {
|
||||||
|
|| IR_ASSERT(type == IR_FLOAT);
|
||||||
|
| op Rs(reg-IR_REG_FP_FIRST), #val
|
||||||
|
|| }
|
||||||
|
|.endmacro
|
||||||
|
|
||||||
|.macro ASM_FP_REG_REG_REG_OP, op, type, dst, src1, src2
|
|.macro ASM_FP_REG_REG_REG_OP, op, type, dst, src1, src2
|
||||||
|| if (type == IR_DOUBLE) {
|
|| if (type == IR_DOUBLE) {
|
||||||
| op Rd(dst-IR_REG_FP_FIRST), Rd(src1-IR_REG_FP_FIRST), Rd(src2-IR_REG_FP_FIRST)
|
| op Rd(dst-IR_REG_FP_FIRST), Rd(src1-IR_REG_FP_FIRST), Rd(src2-IR_REG_FP_FIRST)
|
||||||
@ -2366,6 +2375,69 @@ static void ir_emit_if_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|
|||||||
ir_emit_jcc(ctx, IR_NE, b, def, insn, 1);
|
ir_emit_jcc(ctx, IR_NE, b, def, insn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||||
|
{
|
||||||
|
ir_backend_data *data = ctx->data;
|
||||||
|
dasm_State **Dst = &data->dasm_state;
|
||||||
|
ir_type type = insn->type;
|
||||||
|
ir_ref op1 = insn->op1;
|
||||||
|
ir_ref op2 = insn->op2;
|
||||||
|
ir_ref op3 = insn->op3;
|
||||||
|
ir_type op1_type = ctx->ir_base[op1].type;
|
||||||
|
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||||
|
ir_reg op1_reg = ctx->regs[def][1];
|
||||||
|
ir_reg op2_reg = ctx->regs[def][2];
|
||||||
|
ir_reg op3_reg = ctx->regs[def][3];
|
||||||
|
|
||||||
|
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||||
|
|
||||||
|
if (IR_REG_SPILLED(op2_reg) || IR_IS_CONST_REF(op2)) {
|
||||||
|
op2_reg = IR_REG_NUM(op2_reg);
|
||||||
|
ir_emit_load(ctx, type, op2_reg, op2);
|
||||||
|
if (op1 == op2) {
|
||||||
|
op1_reg = op2_reg;
|
||||||
|
}
|
||||||
|
if (op3 == op2) {
|
||||||
|
op3_reg = op2_reg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (op3 != op2 && (IR_REG_SPILLED(op3_reg) || IR_IS_CONST_REF(op3))) {
|
||||||
|
op3_reg = IR_REG_NUM(op3_reg);
|
||||||
|
ir_emit_load(ctx, type, op3_reg, op3);
|
||||||
|
if (op1 == op2) {
|
||||||
|
op1_reg = op3_reg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (op1 != op2 && op1 != op3 && (IR_REG_SPILLED(op1_reg) || IR_IS_CONST_REF(op1))) {
|
||||||
|
op1_reg = IR_REG_NUM(op1_reg);
|
||||||
|
ir_emit_load(ctx, op1_type, op1_reg, op1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IR_IS_TYPE_INT(op1_type)) {
|
||||||
|
| ASM_REG_IMM_OP cmp, op1_type, op1_reg, 0
|
||||||
|
} else{
|
||||||
|
| ASM_FP_REG_IMM_OP fcmp, op1_type, op1_reg, 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IR_IS_TYPE_INT(type)) {
|
||||||
|
if (ir_type_size[type] == 8) {
|
||||||
|
| csel Rx(def_reg), Rx(op2_reg), Rx(op3_reg), eq
|
||||||
|
} else {
|
||||||
|
| csel Rw(def_reg), Rw(op2_reg), Rw(op3_reg), eq
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
if (type == IR_DOUBLE) {
|
||||||
|
| fcsel Rd(def_reg-IR_REG_FP_FIRST), Rd(op2_reg-IR_REG_FP_FIRST), Rd(op3_reg-IR_REG_FP_FIRST), eq
|
||||||
|
} else {
|
||||||
|
| fcsel Rs(def_reg-IR_REG_FP_FIRST), Rs(op2_reg-IR_REG_FP_FIRST), Rs(op3_reg-IR_REG_FP_FIRST), eq
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
||||||
|
ir_emit_store(ctx, type, def, def_reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ir_emit_return_void(ir_ctx *ctx)
|
static void ir_emit_return_void(ir_ctx *ctx)
|
||||||
{
|
{
|
||||||
ir_backend_data *data = ctx->data;
|
ir_backend_data *data = ctx->data;
|
||||||
@ -4952,6 +5024,9 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
|||||||
case IR_IF_INT:
|
case IR_IF_INT:
|
||||||
ir_emit_if_int(ctx, b, i, insn);
|
ir_emit_if_int(ctx, b, i, insn);
|
||||||
break;
|
break;
|
||||||
|
case IR_COND:
|
||||||
|
ir_emit_cond(ctx, i, insn);
|
||||||
|
break;
|
||||||
case IR_SWITCH:
|
case IR_SWITCH:
|
||||||
ir_emit_switch(ctx, b, i, insn);
|
ir_emit_switch(ctx, b, i, insn);
|
||||||
break;
|
break;
|
||||||
|
115
ir_x86.dasc
115
ir_x86.dasc
@ -369,6 +369,7 @@ typedef struct _ir_backend_data {
|
|||||||
bool float_neg_const;
|
bool float_neg_const;
|
||||||
bool double_abs_const;
|
bool double_abs_const;
|
||||||
bool float_abs_const;
|
bool float_abs_const;
|
||||||
|
bool double_zero_const;
|
||||||
} ir_backend_data;
|
} ir_backend_data;
|
||||||
|
|
||||||
#define IR_GP_REG_NAME(code, name64, name32, name16, name8, name8h) \
|
#define IR_GP_REG_NAME(code, name64, name32, name16, name8, name8h) \
|
||||||
@ -4399,6 +4400,116 @@ static void ir_emit_if_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|
|||||||
ir_emit_jcc(ctx, IR_NE, b, def, insn, 1);
|
ir_emit_jcc(ctx, IR_NE, b, def, insn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||||
|
{
|
||||||
|
ir_backend_data *data = ctx->data;
|
||||||
|
dasm_State **Dst = &data->dasm_state;
|
||||||
|
ir_type type = insn->type;
|
||||||
|
ir_ref op1 = insn->op1;
|
||||||
|
ir_ref op2 = insn->op2;
|
||||||
|
ir_ref op3 = insn->op3;
|
||||||
|
ir_type op1_type = ctx->ir_base[op1].type;
|
||||||
|
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||||
|
ir_reg op1_reg = ctx->regs[def][1];
|
||||||
|
ir_reg op2_reg = ctx->regs[def][2];
|
||||||
|
ir_reg op3_reg = ctx->regs[def][3];
|
||||||
|
|
||||||
|
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||||
|
|
||||||
|
if (op2_reg != IR_REG_NONE && (IR_REG_SPILLED(op2_reg) || IR_IS_CONST_REF(op2))) {
|
||||||
|
op2_reg = IR_REG_NUM(op2_reg);
|
||||||
|
ir_emit_load(ctx, type, op2_reg, op2);
|
||||||
|
if (op1 == op2) {
|
||||||
|
op1_reg = op2_reg;
|
||||||
|
}
|
||||||
|
if (op3 == op2) {
|
||||||
|
op3_reg = op2_reg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (op3_reg != IR_REG_NONE && op3 != op2 && (IR_REG_SPILLED(op3_reg) || IR_IS_CONST_REF(op3))) {
|
||||||
|
op3_reg = IR_REG_NUM(op3_reg);
|
||||||
|
ir_emit_load(ctx, type, op3_reg, op3);
|
||||||
|
if (op1 == op2) {
|
||||||
|
op1_reg = op3_reg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (op1_reg != IR_REG_NONE && op1 != op2 && op1 != op3 && (IR_REG_SPILLED(op1_reg) || IR_IS_CONST_REF(op1))) {
|
||||||
|
op1_reg = IR_REG_NUM(op1_reg);
|
||||||
|
ir_emit_load(ctx, op1_type, op1_reg, op1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IR_IS_TYPE_INT(op1_type)) {
|
||||||
|
if (op1_reg != IR_REG_NONE) {
|
||||||
|
| ASM_REG_REG_OP test, op1_type, op1_reg, op1_reg
|
||||||
|
} else {
|
||||||
|
ir_reg fp;
|
||||||
|
int32_t offset = ir_ref_spill_slot(ctx, op1, &fp);
|
||||||
|
|
||||||
|
| ASM_MEM_IMM_OP cmp, op1_type, [Ra(fp)+offset], 0
|
||||||
|
}
|
||||||
|
| je >2
|
||||||
|
} else {
|
||||||
|
if (!data->double_zero_const) {
|
||||||
|
data->double_zero_const = 1;
|
||||||
|
ir_rodata(ctx);
|
||||||
|
|.align 16
|
||||||
|
|->double_zero_const:
|
||||||
|
|.dword 0, 0
|
||||||
|
|.code
|
||||||
|
}
|
||||||
|
| ASM_FP_REG_MEM_OP ucomiss, ucomisd, vucomiss, vucomisd, op1_type, op1_reg, [->double_zero_const]
|
||||||
|
| jp >1
|
||||||
|
| je >2
|
||||||
|
|1:
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op2_reg != IR_REG_NONE) {
|
||||||
|
if (def_reg != op2_reg) {
|
||||||
|
if (IR_IS_TYPE_INT(type)) {
|
||||||
|
ir_emit_mov(ctx, type, def_reg, op2_reg);
|
||||||
|
} else {
|
||||||
|
ir_emit_fp_mov(ctx, type, def_reg, op2_reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (IR_IS_CONST_REF(op2) || !(ir_rule(ctx, op2) & IR_FUSED)) {
|
||||||
|
ir_emit_load(ctx, type, def_reg, op2);
|
||||||
|
} else {
|
||||||
|
int32_t offset = ir_fuse_load(ctx, op2, &op2_reg);
|
||||||
|
|
||||||
|
if (IR_IS_TYPE_INT(type)) {
|
||||||
|
ir_emit_load_mem_int(ctx, type, def_reg, op2_reg, offset);
|
||||||
|
} else {
|
||||||
|
ir_emit_load_mem_fp(ctx, type, def_reg, op2_reg, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| jmp >3
|
||||||
|
|2:
|
||||||
|
if (op3_reg != IR_REG_NONE) {
|
||||||
|
if (def_reg != op3_reg) {
|
||||||
|
if (IR_IS_TYPE_INT(type)) {
|
||||||
|
ir_emit_mov(ctx, type, def_reg, op3_reg);
|
||||||
|
} else {
|
||||||
|
ir_emit_fp_mov(ctx, type, def_reg, op3_reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (IR_IS_CONST_REF(op3) || !(ir_rule(ctx, op3) & IR_FUSED)) {
|
||||||
|
ir_emit_load(ctx, type, def_reg, op3);
|
||||||
|
} else {
|
||||||
|
int32_t offset = ir_fuse_load(ctx, op3, &op3_reg);
|
||||||
|
|
||||||
|
if (IR_IS_TYPE_INT(type)) {
|
||||||
|
ir_emit_load_mem_int(ctx, type, def_reg, op3_reg, offset);
|
||||||
|
} else {
|
||||||
|
ir_emit_load_mem_fp(ctx, type, def_reg, op3_reg, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|3:
|
||||||
|
|
||||||
|
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
||||||
|
ir_emit_store(ctx, type, def, def_reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ir_emit_return_void(ir_ctx *ctx)
|
static void ir_emit_return_void(ir_ctx *ctx)
|
||||||
{
|
{
|
||||||
ir_backend_data *data = ctx->data;
|
ir_backend_data *data = ctx->data;
|
||||||
@ -8041,6 +8152,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
|||||||
data.float_neg_const = 0;
|
data.float_neg_const = 0;
|
||||||
data.double_abs_const = 0;
|
data.double_abs_const = 0;
|
||||||
data.float_abs_const = 0;
|
data.float_abs_const = 0;
|
||||||
|
data.double_zero_const = 0;
|
||||||
ctx->data = &data;
|
ctx->data = &data;
|
||||||
|
|
||||||
if (!ctx->live_intervals) {
|
if (!ctx->live_intervals) {
|
||||||
@ -8514,6 +8626,9 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
|||||||
case IR_IF_INT:
|
case IR_IF_INT:
|
||||||
ir_emit_if_int(ctx, b, i, insn);
|
ir_emit_if_int(ctx, b, i, insn);
|
||||||
break;
|
break;
|
||||||
|
case IR_COND:
|
||||||
|
ir_emit_cond(ctx, i, insn);
|
||||||
|
break;
|
||||||
case IR_SWITCH:
|
case IR_SWITCH:
|
||||||
ir_emit_switch(ctx, b, i, insn);
|
ir_emit_switch(ctx, b, i, insn);
|
||||||
break;
|
break;
|
||||||
|
25
tests/Windows-x86_64/cond_001.irt
Normal file
25
tests/Windows-x86_64/cond_001.irt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
001: COND(I,I,I)
|
||||||
|
--TARGET--
|
||||||
|
Windows-x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
testl %edi, %edi
|
||||||
|
je .L1
|
||||||
|
movl %esi, %eax
|
||||||
|
jmp .L2
|
||||||
|
.L1:
|
||||||
|
movl %edx, %eax
|
||||||
|
.L2:
|
||||||
|
retq
|
31
tests/Windows-x86_64/cond_002.irt
Normal file
31
tests/Windows-x86_64/cond_002.irt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
--TEST--
|
||||||
|
002: COND(D,I,I)
|
||||||
|
--TARGET--
|
||||||
|
Windows-x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
ucomisd .L4(%rip), %xmm0
|
||||||
|
jp .L1
|
||||||
|
je .L2
|
||||||
|
.L1:
|
||||||
|
movl %edi, %eax
|
||||||
|
jmp .L3
|
||||||
|
.L2:
|
||||||
|
movl %esi, %eax
|
||||||
|
.L3:
|
||||||
|
retq
|
||||||
|
.rodata
|
||||||
|
.db 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||||
|
.L4:
|
||||||
|
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
24
tests/Windows-x86_64/cond_003.irt
Normal file
24
tests/Windows-x86_64/cond_003.irt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
003: COND(I,D,D)
|
||||||
|
--TARGET--
|
||||||
|
Windows-x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
testq %rdi, %rdi
|
||||||
|
je .L1
|
||||||
|
jmp .L2
|
||||||
|
.L1:
|
||||||
|
movapd %xmm1, %xmm0
|
||||||
|
.L2:
|
||||||
|
retq
|
31
tests/Windows-x86_64/cond_004.irt
Normal file
31
tests/Windows-x86_64/cond_004.irt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
--TEST--
|
||||||
|
004: COND(D,D,D)
|
||||||
|
--TARGET--
|
||||||
|
Windows-x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
ucomisd .L4(%rip), %xmm0
|
||||||
|
jp .L1
|
||||||
|
je .L2
|
||||||
|
.L1:
|
||||||
|
movapd %xmm1, %xmm0
|
||||||
|
jmp .L3
|
||||||
|
.L2:
|
||||||
|
movapd %xmm2, %xmm0
|
||||||
|
.L3:
|
||||||
|
retq
|
||||||
|
.rodata
|
||||||
|
.db 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||||
|
.L4:
|
||||||
|
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
20
tests/aarch64/cond_001.irt
Normal file
20
tests/aarch64/cond_001.irt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
--TEST--
|
||||||
|
001: COND(I,I,I)
|
||||||
|
--TARGET--
|
||||||
|
aarch64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
cmp w0, #0
|
||||||
|
csel w0, w1, w2, eq
|
||||||
|
ret
|
20
tests/aarch64/cond_002.irt
Normal file
20
tests/aarch64/cond_002.irt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
--TEST--
|
||||||
|
002: COND(D,I,I)
|
||||||
|
--TARGET--
|
||||||
|
aarch64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
fcmp d0, #0.0
|
||||||
|
csel w0, w0, w1, eq
|
||||||
|
ret
|
20
tests/aarch64/cond_003.irt
Normal file
20
tests/aarch64/cond_003.irt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
--TEST--
|
||||||
|
003: COND(I,D,D)
|
||||||
|
--TARGET--
|
||||||
|
aarch64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
cmp w0, #0
|
||||||
|
fcsel d0, d0, d1, eq
|
||||||
|
ret
|
20
tests/aarch64/cond_004.irt
Normal file
20
tests/aarch64/cond_004.irt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
--TEST--
|
||||||
|
004: COND(D,D,D)
|
||||||
|
--TARGET--
|
||||||
|
aarch64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
fcmp d0, #0.0
|
||||||
|
fcsel d0, d1, d2, eq
|
||||||
|
ret
|
28
tests/x86/cond_001.irt
Normal file
28
tests/x86/cond_001.irt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
--TEST--
|
||||||
|
001: COND(I,I,I)
|
||||||
|
--TARGET--
|
||||||
|
x86
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
movl 4(%esp), %eax
|
||||||
|
movl 8(%esp), %ecx
|
||||||
|
movl 0xc(%esp), %edx
|
||||||
|
testl %eax, %eax
|
||||||
|
je .L1
|
||||||
|
movl %ecx, %eax
|
||||||
|
jmp .L2
|
||||||
|
.L1:
|
||||||
|
movl %edx, %eax
|
||||||
|
.L2:
|
||||||
|
retl
|
33
tests/x86/cond_002.irt
Normal file
33
tests/x86/cond_002.irt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
--TEST--
|
||||||
|
002: COND(D,I,I)
|
||||||
|
--TARGET--
|
||||||
|
x86
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
movsd 4(%esp), %xmm0
|
||||||
|
movl 0xc(%esp), %eax
|
||||||
|
movl 0x10(%esp), %ecx
|
||||||
|
ucomisd .L4, %xmm0
|
||||||
|
jp .L1
|
||||||
|
je .L2
|
||||||
|
.L1:
|
||||||
|
jmp .L3
|
||||||
|
.L2:
|
||||||
|
movl %ecx, %eax
|
||||||
|
.L3:
|
||||||
|
retl
|
||||||
|
.rodata
|
||||||
|
.db 0x90
|
||||||
|
.L4:
|
||||||
|
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
31
tests/x86/cond_003.irt
Normal file
31
tests/x86/cond_003.irt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
--TEST--
|
||||||
|
003: COND(I,D,D)
|
||||||
|
--TARGET--
|
||||||
|
x86
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
subl $8, %esp
|
||||||
|
movl 0xc(%esp), %eax
|
||||||
|
movsd 0x10(%esp), %xmm0
|
||||||
|
movsd 0x18(%esp), %xmm1
|
||||||
|
testl %eax, %eax
|
||||||
|
je .L1
|
||||||
|
jmp .L2
|
||||||
|
.L1:
|
||||||
|
movapd %xmm1, %xmm0
|
||||||
|
.L2:
|
||||||
|
movsd %xmm0, (%esp)
|
||||||
|
fldl (%esp)
|
||||||
|
addl $8, %esp
|
||||||
|
retl
|
38
tests/x86/cond_004.irt
Normal file
38
tests/x86/cond_004.irt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
--TEST--
|
||||||
|
004: COND(D,D,D)
|
||||||
|
--TARGET--
|
||||||
|
x86
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
subl $8, %esp
|
||||||
|
movsd 0xc(%esp), %xmm0
|
||||||
|
movsd 0x14(%esp), %xmm1
|
||||||
|
movsd 0x1c(%esp), %xmm2
|
||||||
|
ucomisd .L4, %xmm0
|
||||||
|
jp .L1
|
||||||
|
je .L2
|
||||||
|
.L1:
|
||||||
|
movapd %xmm1, %xmm0
|
||||||
|
jmp .L3
|
||||||
|
.L2:
|
||||||
|
movapd %xmm2, %xmm0
|
||||||
|
.L3:
|
||||||
|
movsd %xmm0, (%esp)
|
||||||
|
fldl (%esp)
|
||||||
|
addl $8, %esp
|
||||||
|
retl
|
||||||
|
.rodata
|
||||||
|
.db 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||||
|
.L4:
|
||||||
|
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
25
tests/x86_64/cond_001.irt
Normal file
25
tests/x86_64/cond_001.irt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
001: COND(I,I,I)
|
||||||
|
--TARGET--
|
||||||
|
x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
testl %edi, %edi
|
||||||
|
je .L1
|
||||||
|
movl %esi, %eax
|
||||||
|
jmp .L2
|
||||||
|
.L1:
|
||||||
|
movl %edx, %eax
|
||||||
|
.L2:
|
||||||
|
retq
|
31
tests/x86_64/cond_002.irt
Normal file
31
tests/x86_64/cond_002.irt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
--TEST--
|
||||||
|
002: COND(D,I,I)
|
||||||
|
--TARGET--
|
||||||
|
x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
int32_t y = PARAM(l_1, "y", 2);
|
||||||
|
int32_t z = PARAM(l_1, "z", 3);
|
||||||
|
int32_t val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
ucomisd .L4(%rip), %xmm0
|
||||||
|
jp .L1
|
||||||
|
je .L2
|
||||||
|
.L1:
|
||||||
|
movl %edi, %eax
|
||||||
|
jmp .L3
|
||||||
|
.L2:
|
||||||
|
movl %esi, %eax
|
||||||
|
.L3:
|
||||||
|
retq
|
||||||
|
.rodata
|
||||||
|
.db 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||||
|
.L4:
|
||||||
|
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
24
tests/x86_64/cond_003.irt
Normal file
24
tests/x86_64/cond_003.irt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
003: COND(I,D,D)
|
||||||
|
--TARGET--
|
||||||
|
x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
int32_t x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
testl %edi, %edi
|
||||||
|
je .L1
|
||||||
|
jmp .L2
|
||||||
|
.L1:
|
||||||
|
movapd %xmm1, %xmm0
|
||||||
|
.L2:
|
||||||
|
retq
|
31
tests/x86_64/cond_004.irt
Normal file
31
tests/x86_64/cond_004.irt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
--TEST--
|
||||||
|
004: COND(D,D,D)
|
||||||
|
--TARGET--
|
||||||
|
x86_64
|
||||||
|
--ARGS--
|
||||||
|
-S
|
||||||
|
--CODE--
|
||||||
|
{
|
||||||
|
l_1 = START(ret);
|
||||||
|
double x = PARAM(l_1, "x", 1);
|
||||||
|
double y = PARAM(l_1, "y", 2);
|
||||||
|
double z = PARAM(l_1, "z", 3);
|
||||||
|
double val = COND(x, y, z);
|
||||||
|
ret = RETURN(l_1, val);
|
||||||
|
}
|
||||||
|
--EXPECT--
|
||||||
|
test:
|
||||||
|
ucomisd .L4(%rip), %xmm0
|
||||||
|
jp .L1
|
||||||
|
je .L2
|
||||||
|
.L1:
|
||||||
|
movapd %xmm1, %xmm0
|
||||||
|
jmp .L3
|
||||||
|
.L2:
|
||||||
|
movapd %xmm2, %xmm0
|
||||||
|
.L3:
|
||||||
|
retq
|
||||||
|
.rodata
|
||||||
|
.db 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||||
|
.L4:
|
||||||
|
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
Loading…
Reference in New Issue
Block a user