@@ -397,15 +397,22 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co
397
397
n++;
398
398
}
399
399
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;
400
409
case IR_MUL_PWR2:
401
410
case IR_DIV_PWR2:
402
411
case IR_MOD_PWR2:
403
412
case IR_SHIFT:
404
413
case IR_SHIFT_CONST:
405
414
case IR_OP_INT:
406
415
case IR_OP_FP:
407
- case IR_INT2FP:
408
- case IR_FP2INT:
409
416
case IR_FP2FP:
410
417
insn = &ctx->ir_base[ref];
411
418
n = 0;
@@ -1398,7 +1405,7 @@ static void ir_load_local_addr(ir_ctx *ctx, ir_reg reg, ir_ref src)
1398
1405
| add Rx(reg), Rx(base), #offset
1399
1406
} else {
1400
1407
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)
1402
1409
}
1403
1410
}
1404
1411
@@ -1587,19 +1594,31 @@ static void ir_emit_prologue(ir_ctx *ctx)
1587
1594
offset = -(ctx->stack_frame_size+16);
1588
1595
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1589
1596
| stp x29, x30, [sp, #offset]!
1590
- } else {
1597
+ } else if (aarch64_may_encode_imm12(ctx->stack_frame_size+16)) {
1591
1598
| sub sp, sp, #(ctx->stack_frame_size+16)
1592
1599
| 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]
1593
1604
}
1594
1605
| mov x29, sp
1595
1606
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
+ }
1597
1613
}
1598
1614
} else if (ctx->stack_frame_size + ctx->call_stack_size) {
1599
1615
if (ctx->fixed_stack_red_zone) {
1600
1616
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)
1601
1619
} 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)
1603
1622
}
1604
1623
}
1605
1624
if (ctx->used_preserved_regs) {
@@ -1623,26 +1642,41 @@ static void ir_emit_prologue(ir_ctx *ctx)
1623
1642
offset -= sizeof(void*) * 2;
1624
1643
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1625
1644
| 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)) {
1628
1646
| str Rx(prev), [Rx(fp), #offset]
1629
1647
| 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)]
1630
1653
}
1631
1654
prev = IR_REG_NONE;
1632
1655
} else {
1633
1656
if (prev < IR_REG_FP_FIRST) {
1634
1657
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
+ }
1638
1668
} else {
1639
1669
offset -= sizeof(void*) * 2;
1640
1670
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1641
1671
| 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)) {
1644
1673
| str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset]
1645
1674
| 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)]
1646
1680
}
1647
1681
}
1648
1682
prev = IR_REG_NONE;
@@ -1652,10 +1686,20 @@ static void ir_emit_prologue(ir_ctx *ctx)
1652
1686
if (prev != IR_REG_NONE) {
1653
1687
if (prev < IR_REG_FP_FIRST) {
1654
1688
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
+ }
1656
1695
} else {
1657
1696
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
+ }
1659
1703
}
1660
1704
}
1661
1705
}
@@ -1685,10 +1729,14 @@ static void ir_emit_prologue(ir_ctx *ctx)
1685
1729
if (prev != IR_REG_NONE) {
1686
1730
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1687
1731
| 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)) {
1690
1733
| str Rx(prev), [Rx(fp), #offset]
1691
1734
| 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)]
1692
1740
}
1693
1741
prev = IR_REG_NONE;
1694
1742
offset += sizeof(void*) * 2;
@@ -1697,7 +1745,12 @@ static void ir_emit_prologue(ir_ctx *ctx)
1697
1745
}
1698
1746
}
1699
1747
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
+ }
1701
1754
offset += sizeof(void*);
1702
1755
}
1703
1756
}
@@ -1782,15 +1835,22 @@ static void ir_emit_epilogue(ir_ctx *ctx)
1782
1835
}
1783
1836
if (aarch64_may_encode_imm7_addr_offset(ctx->stack_frame_size+16, 8)) {
1784
1837
| ldp x29, x30, [sp], #(ctx->stack_frame_size+16)
1785
- } else {
1838
+ } else if (aarch64_may_encode_imm12(ctx->stack_frame_size+16)) {
1786
1839
| ldp x29, x30, [sp]
1787
1840
| 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)
1788
1845
}
1789
1846
} else if (ctx->stack_frame_size + ctx->call_stack_size) {
1790
1847
if (ctx->fixed_stack_red_zone) {
1791
1848
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)) {
1793
1850
| 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)
1794
1854
}
1795
1855
}
1796
1856
}
@@ -4808,7 +4868,9 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
4808
4868
fp_param++;
4809
4869
}
4810
4870
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)))) {
4812
4874
/* delay CONST->REG and MEM->REG moves to third pass */
4813
4875
do_pass3 = 1;
4814
4876
} else {
@@ -4874,7 +4936,9 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
4874
4936
fp_param++;
4875
4937
}
4876
4938
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)))) {
4878
4942
if (IR_IS_CONST_REF(arg) && IR_IS_TYPE_INT(type)) {
4879
4943
if (ir_type_size[type] == 1) {
4880
4944
type = IR_ADDR;
@@ -5473,7 +5537,8 @@ static void ir_emit_load_params(ir_ctx *ctx)
5473
5537
int32_t stack_offset = 0;
5474
5538
5475
5539
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;
5477
5542
} else {
5478
5543
stack_offset = ctx->stack_frame_size + ctx->call_stack_size;
5479
5544
}
0 commit comments