@@ -397,15 +397,22 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co
397397 n++;
398398 }
399399 break;
400+ case IR_INT2FP:
401+ case IR_FP2INT:
402+ insn = &ctx->ir_base[ref];
403+ n = 0;
404+ if (IR_IS_CONST_REF(insn->op1)) {
405+ constraints->tmp_regs[n] = IR_TMP_REG(1, ctx->ir_base[insn->op1].type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
406+ n++;
407+ }
408+ break;
400409 case IR_MUL_PWR2:
401410 case IR_DIV_PWR2:
402411 case IR_MOD_PWR2:
403412 case IR_SHIFT:
404413 case IR_SHIFT_CONST:
405414 case IR_OP_INT:
406415 case IR_OP_FP:
407- case IR_INT2FP:
408- case IR_FP2INT:
409416 case IR_FP2FP:
410417 insn = &ctx->ir_base[ref];
411418 n = 0;
@@ -1398,7 +1405,7 @@ static void ir_load_local_addr(ir_ctx *ctx, ir_reg reg, ir_ref src)
13981405 | add Rx(reg), Rx(base), #offset
13991406 } else {
14001407 ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1401- | add sp , sp, Rx(IR_REG_INT_TMP)
1408+ | add Rx(reg) , sp, Rx(IR_REG_INT_TMP)
14021409 }
14031410}
14041411
@@ -1587,19 +1594,31 @@ static void ir_emit_prologue(ir_ctx *ctx)
15871594 offset = -(ctx->stack_frame_size+16);
15881595 if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
15891596 | stp x29, x30, [sp, #offset]!
1590- } else {
1597+ } else if (aarch64_may_encode_imm12(ctx->stack_frame_size+16)) {
15911598 | sub sp, sp, #(ctx->stack_frame_size+16)
15921599 | stp x29, x30, [sp]
1600+ } else {
1601+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size+16);
1602+ | sub sp, sp, Rx(IR_REG_INT_TMP)
1603+ | stp x29, x30, [sp]
15931604 }
15941605 | mov x29, sp
15951606 if (ctx->call_stack_size) {
1596- | sub sp, sp, #(ctx->call_stack_size)
1607+ if (aarch64_may_encode_imm12(ctx->call_stack_size)) {
1608+ | sub sp, sp, #(ctx->call_stack_size)
1609+ } else {
1610+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->call_stack_size);
1611+ | sub sp, sp, Rx(IR_REG_INT_TMP)
1612+ }
15971613 }
15981614 } else if (ctx->stack_frame_size + ctx->call_stack_size) {
15991615 if (ctx->fixed_stack_red_zone) {
16001616 IR_ASSERT(ctx->stack_frame_size + ctx->call_stack_size <= ctx->fixed_stack_red_zone);
1617+ } else if (aarch64_may_encode_imm12(ctx->stack_frame_size + ctx->call_stack_size)) {
1618+ | sub sp, sp, #(ctx->stack_frame_size + ctx->call_stack_size)
16011619 } else {
1602- | sub sp, sp, #(ctx->stack_frame_size + ctx->call_stack_size)
1620+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size + ctx->call_stack_size);
1621+ | sub sp, sp, Rx(IR_REG_INT_TMP)
16031622 }
16041623 }
16051624 if (ctx->used_preserved_regs) {
@@ -1623,26 +1642,41 @@ static void ir_emit_prologue(ir_ctx *ctx)
16231642 offset -= sizeof(void*) * 2;
16241643 if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
16251644 | stp Rx(prev), Rx(i), [Rx(fp), #offset]
1626- } else {
1627- IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1645+ } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) {
16281646 | str Rx(prev), [Rx(fp), #offset]
16291647 | str Rx(i), [Rx(fp), #(offset+8)]
1648+ } else {
1649+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1650+ | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)]
1651+ | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8
1652+ | str Rx(i), [Rx(fp), Rx(IR_REG_INT_TMP)]
16301653 }
16311654 prev = IR_REG_NONE;
16321655 } else {
16331656 if (prev < IR_REG_FP_FIRST) {
16341657 offset -= sizeof(void*);
1635- | str Rx(prev), [Rx(fp), #offset]
1636- offset -= sizeof(void*);
1637- | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
1658+ if (aarch64_may_encode_addr_offset(offset, 8)) {
1659+ | str Rx(prev), [Rx(fp), #offset]
1660+ offset -= sizeof(void*);
1661+ | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
1662+ } else {
1663+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1664+ | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)]
1665+ | sub Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8
1666+ | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)]
1667+ }
16381668 } else {
16391669 offset -= sizeof(void*) * 2;
16401670 if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
16411671 | stp Rd(prev-IR_REG_FP_FIRST), Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
1642- } else {
1643- IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1672+ } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) {
16441673 | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset]
16451674 | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #(offset+8)]
1675+ } else {
1676+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1677+ | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)]
1678+ | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8
1679+ | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)]
16461680 }
16471681 }
16481682 prev = IR_REG_NONE;
@@ -1652,10 +1686,20 @@ static void ir_emit_prologue(ir_ctx *ctx)
16521686 if (prev != IR_REG_NONE) {
16531687 if (prev < IR_REG_FP_FIRST) {
16541688 offset -= sizeof(void*);
1655- | str Rx(prev), [Rx(fp), #offset]
1689+ if (aarch64_may_encode_addr_offset(offset, 8)) {
1690+ | str Rx(prev), [Rx(fp), #offset]
1691+ } else {
1692+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1693+ | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)]
1694+ }
16561695 } else {
16571696 offset -= sizeof(void*);
1658- | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset]
1697+ if (aarch64_may_encode_addr_offset(offset, 8)) {
1698+ | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset]
1699+ } else {
1700+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1701+ | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)]
1702+ }
16591703 }
16601704 }
16611705 }
@@ -1685,10 +1729,14 @@ static void ir_emit_prologue(ir_ctx *ctx)
16851729 if (prev != IR_REG_NONE) {
16861730 if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
16871731 | stp Rx(prev), Rx(int_reg_params[i]), [Rx(fp), #offset]
1688- } else {
1689- IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1732+ } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) {
16901733 | str Rx(prev), [Rx(fp), #offset]
16911734 | str Rx(int_reg_params[i]), [Rx(fp), #(offset+8)]
1735+ } else {
1736+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1737+ | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)]
1738+ | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8
1739+ | str Rx(int_reg_params[i]), [Rx(fp), Rx(IR_REG_INT_TMP)]
16921740 }
16931741 prev = IR_REG_NONE;
16941742 offset += sizeof(void*) * 2;
@@ -1697,7 +1745,12 @@ static void ir_emit_prologue(ir_ctx *ctx)
16971745 }
16981746 }
16991747 if (prev != IR_REG_NONE) {
1700- | str Rx(prev), [Rx(fp), #offset]
1748+ if (aarch64_may_encode_addr_offset(offset + 8, 8)) {
1749+ | str Rx(prev), [Rx(fp), #offset]
1750+ } else {
1751+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset);
1752+ | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)]
1753+ }
17011754 offset += sizeof(void*);
17021755 }
17031756 }
@@ -1782,15 +1835,22 @@ static void ir_emit_epilogue(ir_ctx *ctx)
17821835 }
17831836 if (aarch64_may_encode_imm7_addr_offset(ctx->stack_frame_size+16, 8)) {
17841837 | ldp x29, x30, [sp], #(ctx->stack_frame_size+16)
1785- } else {
1838+ } else if (aarch64_may_encode_imm12(ctx->stack_frame_size+16)) {
17861839 | ldp x29, x30, [sp]
17871840 | add sp, sp, #(ctx->stack_frame_size+16)
1841+ } else {
1842+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size+16);
1843+ | ldp x29, x30, [sp]
1844+ | add sp, sp, Rx(IR_REG_INT_TMP)
17881845 }
17891846 } else if (ctx->stack_frame_size + ctx->call_stack_size) {
17901847 if (ctx->fixed_stack_red_zone) {
17911848 IR_ASSERT(ctx->stack_frame_size + ctx->call_stack_size <= ctx->fixed_stack_red_zone);
1792- } else {
1849+ } else if (aarch64_may_encode_imm12(ctx->stack_frame_size + ctx->call_stack_size)) {
17931850 | add sp, sp, #(ctx->stack_frame_size + ctx->call_stack_size)
1851+ } else {
1852+ ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size + ctx->call_stack_size);
1853+ | add sp, sp, Rx(IR_REG_INT_TMP)
17941854 }
17951855 }
17961856}
@@ -4808,7 +4868,9 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
48084868 fp_param++;
48094869 }
48104870 if (dst_reg != IR_REG_NONE) {
4811- if (src_reg == IR_REG_NONE) {
4871+ if (IR_IS_CONST_REF(arg) ||
4872+ src_reg == IR_REG_NONE ||
4873+ (IR_REG_SPILLED(src_reg) && !IR_REGSET_IN(IR_REGSET_PRESERVED, IR_REG_NUM(src_reg)))) {
48124874 /* delay CONST->REG and MEM->REG moves to third pass */
48134875 do_pass3 = 1;
48144876 } else {
@@ -4874,7 +4936,9 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
48744936 fp_param++;
48754937 }
48764938 if (dst_reg != IR_REG_NONE) {
4877- if (src_reg == IR_REG_NONE) {
4939+ if (IR_IS_CONST_REF(arg) ||
4940+ src_reg == IR_REG_NONE ||
4941+ (IR_REG_SPILLED(src_reg) && !IR_REGSET_IN(IR_REGSET_PRESERVED, IR_REG_NUM(src_reg)))) {
48784942 if (IR_IS_CONST_REF(arg) && IR_IS_TYPE_INT(type)) {
48794943 if (ir_type_size[type] == 1) {
48804944 type = IR_ADDR;
@@ -5473,7 +5537,8 @@ static void ir_emit_load_params(ir_ctx *ctx)
54735537 int32_t stack_offset = 0;
54745538
54755539 if (ctx->flags & IR_USE_FRAME_POINTER) {
5476- stack_offset = sizeof(void*) * 2; /* skip old frame pointer and return address */
5540+ /* skip old frame pointer and return address */
5541+ stack_offset = sizeof(void*) * 2 + ctx->stack_frame_size + ctx->call_stack_size;
54775542 } else {
54785543 stack_offset = ctx->stack_frame_size + ctx->call_stack_size;
54795544 }
0 commit comments