| ... | @@ -118,11 +118,6 @@ const MCValue = union(enum) { | ... | @@ -118,11 +118,6 @@ const MCValue = union(enum) { |
| 118 | /// A pointer-sized integer that fits in a register. | 118 | /// A pointer-sized integer that fits in a register. |
| 119 | /// If the type is a pointer, this is the pointer address in virtual address space. | 119 | /// If the type is a pointer, this is the pointer address in virtual address space. |
| 120 | immediate: u32, | 120 | immediate: u32, |
| 121 | /// The constant was emitted into the code, at this offset. | | |
| 122 | /// If the type is a pointer, it means the pointer address is embedded in the code. | | |
| 123 | embedded_in_code: usize, | | |
| 124 | /// The value is a pointer to a constant which was emitted into the code, at this offset. | | |
| 125 | ptr_embedded_in_code: usize, | | |
| 126 | /// The value is in a target-specific register. | 121 | /// The value is in a target-specific register. |
| 127 | register: Register, | 122 | register: Register, |
| 128 | /// The value is in memory at a hard-coded address. | 123 | /// The value is in memory at a hard-coded address. |
| ... | @@ -144,7 +139,7 @@ const MCValue = union(enum) { | ... | @@ -144,7 +139,7 @@ const MCValue = union(enum) { |
| 144 | | 139 | |
| 145 | fn isMemory(mcv: MCValue) bool { | 140 | fn isMemory(mcv: MCValue) bool { |
| 146 | return switch (mcv) { | 141 | return switch (mcv) { |
| 147 | .embedded_in_code, .memory, .stack_offset, .stack_argument_offset => true, | 142 | .memory, .stack_offset, .stack_argument_offset => true, |
| 148 | else => false, | 143 | else => false, |
| 149 | }; | 144 | }; |
| 150 | } | 145 | } |
| ... | @@ -163,12 +158,10 @@ const MCValue = union(enum) { | ... | @@ -163,12 +158,10 @@ const MCValue = union(enum) { |
| 163 | .dead => unreachable, | 158 | .dead => unreachable, |
| 164 | | 159 | |
| 165 | .immediate, | 160 | .immediate, |
| 166 | .embedded_in_code, | | |
| 167 | .memory, | 161 | .memory, |
| 168 | .compare_flags_unsigned, | 162 | .compare_flags_unsigned, |
| 169 | .compare_flags_signed, | 163 | .compare_flags_signed, |
| 170 | .ptr_stack_offset, | 164 | .ptr_stack_offset, |
| 171 | .ptr_embedded_in_code, | | |
| 172 | .undef, | 165 | .undef, |
| 173 | .stack_argument_offset, | 166 | .stack_argument_offset, |
| 174 | => false, | 167 | => false, |
| ... | @@ -1358,24 +1351,28 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1358,24 +1351,28 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1358 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1351 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1359 | } | 1352 | } |
| 1360 | | 1353 | |
| | 1354 | fn slicePtr(self: *Self, mcv: MCValue) !MCValue { |
| | 1355 | switch (mcv) { |
| | 1356 | .dead, .unreach => unreachable, |
| | 1357 | .register => unreachable, // a slice doesn't fit in one register |
| | 1358 | .stack_argument_offset => |off| { |
| | 1359 | return MCValue{ .stack_argument_offset = off + 4 }; |
| | 1360 | }, |
| | 1361 | .stack_offset => |off| { |
| | 1362 | return MCValue{ .stack_offset = off + 4 }; |
| | 1363 | }, |
| | 1364 | .memory => |addr| { |
| | 1365 | return MCValue{ .memory = addr }; |
| | 1366 | }, |
| | 1367 | else => return self.fail("TODO implement slice_ptr for {}", .{mcv}), |
| | 1368 | } |
| | 1369 | } |
| | 1370 | |
| 1361 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1371 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1362 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1372 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1363 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1373 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1364 | const mcv = try self.resolveInst(ty_op.operand); | 1374 | const mcv = try self.resolveInst(ty_op.operand); |
| 1365 | switch (mcv) { | 1375 | break :result try self.slicePtr(mcv); |
| 1366 | .dead, .unreach => unreachable, | | |
| 1367 | .register => unreachable, // a slice doesn't fit in one register | | |
| 1368 | .stack_argument_offset => |off| { | | |
| 1369 | break :result MCValue{ .stack_argument_offset = off + 4 }; | | |
| 1370 | }, | | |
| 1371 | .stack_offset => |off| { | | |
| 1372 | break :result MCValue{ .stack_offset = off + 4 }; | | |
| 1373 | }, | | |
| 1374 | .memory => |addr| { | | |
| 1375 | break :result MCValue{ .memory = addr }; | | |
| 1376 | }, | | |
| 1377 | else => return self.fail("TODO implement slice_ptr for {}", .{mcv}), | | |
| 1378 | } | | |
| 1379 | }; | 1376 | }; |
| 1380 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1377 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1381 | } | 1378 | } |
| ... | @@ -1409,7 +1406,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1409,7 +1406,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1409 | switch (mcv) { | 1406 | switch (mcv) { |
| 1410 | .dead, .unreach => unreachable, | 1407 | .dead, .unreach => unreachable, |
| 1411 | .ptr_stack_offset => |off| { | 1408 | .ptr_stack_offset => |off| { |
| 1412 | break :result MCValue{ .ptr_stack_offset = off + 4 }; | 1409 | break :result MCValue{ .ptr_stack_offset = off }; |
| 1413 | }, | 1410 | }, |
| 1414 | else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}), | 1411 | else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}), |
| 1415 | } | 1412 | } |
| ... | @@ -1424,7 +1421,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1424,7 +1421,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1424 | switch (mcv) { | 1421 | switch (mcv) { |
| 1425 | .dead, .unreach => unreachable, | 1422 | .dead, .unreach => unreachable, |
| 1426 | .ptr_stack_offset => |off| { | 1423 | .ptr_stack_offset => |off| { |
| 1427 | break :result MCValue{ .ptr_stack_offset = off }; | 1424 | break :result MCValue{ .ptr_stack_offset = off + 4 }; |
| 1428 | }, | 1425 | }, |
| 1429 | else => return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{mcv}), | 1426 | else => return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{mcv}), |
| 1430 | } | 1427 | } |
| ... | @@ -1455,15 +1452,17 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1455,15 +1452,17 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1455 | if (index_is_register) self.register_manager.freezeRegs(&.{index_mcv.register}); | 1452 | if (index_is_register) self.register_manager.freezeRegs(&.{index_mcv.register}); |
| 1456 | defer if (index_is_register) self.register_manager.unfreezeRegs(&.{index_mcv.register}); | 1453 | defer if (index_is_register) self.register_manager.unfreezeRegs(&.{index_mcv.register}); |
| 1457 | | 1454 | |
| 1458 | const base_mcv: MCValue = switch (slice_mcv) { | 1455 | const base_mcv = try self.slicePtr(slice_mcv); |
| 1459 | .stack_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_offset = off + 4 }) }, | | |
| 1460 | .stack_argument_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_argument_offset = off + 4 }) }, | | |
| 1461 | else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}), | | |
| 1462 | }; | | |
| 1463 | self.register_manager.freezeRegs(&.{base_mcv.register}); | | |
| 1464 | | 1456 | |
| 1465 | switch (elem_size) { | 1457 | switch (elem_size) { |
| 1466 | 1, 4 => { | 1458 | 1, 4 => { |
| | 1459 | const base_reg = switch (base_mcv) { |
| | 1460 | .register => |r| r, |
| | 1461 | else => try self.copyToTmpRegister(slice_ptr_field_type, base_mcv), |
| | 1462 | }; |
| | 1463 | self.register_manager.freezeRegs(&.{base_reg}); |
| | 1464 | defer self.register_manager.unfreezeRegs(&.{base_reg}); |
| | 1465 | |
| 1467 | const dst_reg = try self.register_manager.allocReg(inst); | 1466 | const dst_reg = try self.register_manager.allocReg(inst); |
| 1468 | const dst_mcv = MCValue{ .register = dst_reg }; | 1467 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 1469 | self.register_manager.freezeRegs(&.{dst_reg}); | 1468 | self.register_manager.freezeRegs(&.{dst_reg}); |
| ... | @@ -1491,13 +1490,11 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1491,13 +1490,11 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1491 | .tag = tag, | 1490 | .tag = tag, |
| 1492 | .data = .{ .rr_offset = .{ | 1491 | .data = .{ .rr_offset = .{ |
| 1493 | .rt = dst_reg, | 1492 | .rt = dst_reg, |
| 1494 | .rn = base_mcv.register, | 1493 | .rn = base_reg, |
| 1495 | .offset = .{ .offset = Instruction.Offset.reg(index_reg, .{ .lsl = shift }) }, | 1494 | .offset = .{ .offset = Instruction.Offset.reg(index_reg, .{ .lsl = shift }) }, |
| 1496 | } }, | 1495 | } }, |
| 1497 | }); | 1496 | }); |
| 1498 | | 1497 | |
| 1499 | self.register_manager.unfreezeRegs(&.{base_mcv.register}); | | |
| 1500 | | | |
| 1501 | break :result dst_mcv; | 1498 | break :result dst_mcv; |
| 1502 | }, | 1499 | }, |
| 1503 | else => { | 1500 | else => { |
| ... | @@ -1515,7 +1512,16 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1515,7 +1512,16 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1515 | fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { | 1512 | fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1516 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1513 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1517 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 1514 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1518 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_elem_ptr for {}", .{self.target.cpu.arch}); | 1515 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| | 1516 | const slice_mcv = try self.resolveInst(extra.lhs); |
| | 1517 | const index_mcv = try self.resolveInst(extra.rhs); |
| | 1518 | const base_mcv = try self.slicePtr(slice_mcv); |
| | 1519 | |
| | 1520 | const slice_ty = self.air.typeOf(extra.lhs); |
| | 1521 | |
| | 1522 | const addr = try self.binOp(.ptr_add, null, base_mcv, index_mcv, slice_ty, Type.usize); |
| | 1523 | break :result addr; |
| | 1524 | }; |
| 1519 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); | 1525 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); |
| 1520 | } | 1526 | } |
| 1521 | | 1527 | |
| ... | @@ -1535,7 +1541,15 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1535,7 +1541,15 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1535 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { | 1541 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1536 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1542 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1537 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 1543 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1538 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_ptr for {}", .{self.target.cpu.arch}); | 1544 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| | 1545 | const ptr_mcv = try self.resolveInst(extra.lhs); |
| | 1546 | const index_mcv = try self.resolveInst(extra.rhs); |
| | 1547 | |
| | 1548 | const ptr_ty = self.air.typeOf(extra.lhs); |
| | 1549 | |
| | 1550 | const addr = try self.binOp(.ptr_add, null, ptr_mcv, index_mcv, ptr_ty, Type.usize); |
| | 1551 | break :result addr; |
| | 1552 | }; |
| 1539 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); | 1553 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); |
| 1540 | } | 1554 | } |
| 1541 | | 1555 | |
| ... | @@ -1641,9 +1655,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1641,9 +1655,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1641 | .compare_flags_signed => unreachable, | 1655 | .compare_flags_signed => unreachable, |
| 1642 | .immediate => |imm| try self.setRegOrMem(elem_ty, dst_mcv, .{ .memory = imm }), | 1656 | .immediate => |imm| try self.setRegOrMem(elem_ty, dst_mcv, .{ .memory = imm }), |
| 1643 | .ptr_stack_offset => |off| try self.setRegOrMem(elem_ty, dst_mcv, .{ .stack_offset = off }), | 1657 | .ptr_stack_offset => |off| try self.setRegOrMem(elem_ty, dst_mcv, .{ .stack_offset = off }), |
| 1644 | .ptr_embedded_in_code => |off| { | | |
| 1645 | try self.setRegOrMem(elem_ty, dst_mcv, .{ .embedded_in_code = off }); | | |
| 1646 | }, | | |
| 1647 | .register => |reg| { | 1658 | .register => |reg| { |
| 1648 | self.register_manager.freezeRegs(&.{reg}); | 1659 | self.register_manager.freezeRegs(&.{reg}); |
| 1649 | defer self.register_manager.unfreezeRegs(&.{reg}); | 1660 | defer self.register_manager.unfreezeRegs(&.{reg}); |
| ... | @@ -1652,7 +1663,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1652,7 +1663,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1652 | .dead => unreachable, | 1663 | .dead => unreachable, |
| 1653 | .undef => unreachable, | 1664 | .undef => unreachable, |
| 1654 | .compare_flags_signed, .compare_flags_unsigned => unreachable, | 1665 | .compare_flags_signed, .compare_flags_unsigned => unreachable, |
| 1655 | .embedded_in_code => unreachable, | | |
| 1656 | .register => |dst_reg| { | 1666 | .register => |dst_reg| { |
| 1657 | try self.genLdrRegister(dst_reg, reg, elem_ty); | 1667 | try self.genLdrRegister(dst_reg, reg, elem_ty); |
| 1658 | }, | 1668 | }, |
| ... | @@ -1690,7 +1700,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1690,7 +1700,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1690 | } | 1700 | } |
| 1691 | }, | 1701 | }, |
| 1692 | .memory, | 1702 | .memory, |
| 1693 | .embedded_in_code, | | |
| 1694 | .stack_offset, | 1703 | .stack_offset, |
| 1695 | .stack_argument_offset, | 1704 | .stack_argument_offset, |
| 1696 | => { | 1705 | => { |
| ... | @@ -1746,9 +1755,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -1746,9 +1755,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1746 | .ptr_stack_offset => |off| { | 1755 | .ptr_stack_offset => |off| { |
| 1747 | try self.genSetStack(value_ty, off, value); | 1756 | try self.genSetStack(value_ty, off, value); |
| 1748 | }, | 1757 | }, |
| 1749 | .ptr_embedded_in_code => |off| { | | |
| 1750 | try self.setRegOrMem(value_ty, .{ .embedded_in_code = off }, value); | | |
| 1751 | }, | | |
| 1752 | .register => |addr_reg| { | 1758 | .register => |addr_reg| { |
| 1753 | self.register_manager.freezeRegs(&.{addr_reg}); | 1759 | self.register_manager.freezeRegs(&.{addr_reg}); |
| 1754 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); | 1760 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); |
| ... | @@ -1760,7 +1766,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -1760,7 +1766,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1760 | try self.genStrRegister(value_reg, addr_reg, value_ty); | 1766 | try self.genStrRegister(value_reg, addr_reg, value_ty); |
| 1761 | }, | 1767 | }, |
| 1762 | else => { | 1768 | else => { |
| 1763 | if (value_ty.abiSize(self.target.*) <= 4) { | 1769 | if (elem_size <= 4) { |
| 1764 | const tmp_reg = try self.register_manager.allocReg(null); | 1770 | const tmp_reg = try self.register_manager.allocReg(null); |
| 1765 | self.register_manager.freezeRegs(&.{tmp_reg}); | 1771 | self.register_manager.freezeRegs(&.{tmp_reg}); |
| 1766 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); | 1772 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); |
| ... | @@ -1784,6 +1790,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -1784,6 +1790,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1784 | try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); | 1790 | try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); |
| 1785 | }, | 1791 | }, |
| 1786 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }), | 1792 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }), |
| | 1793 | .stack_argument_offset => |unadjusted_off| { |
| | 1794 | const adj_off = unadjusted_off + elem_size; |
| | 1795 | |
| | 1796 | _ = try self.addInst(.{ |
| | 1797 | .tag = .ldr_ptr_stack_argument, |
| | 1798 | .data = .{ .r_stack_offset = .{ |
| | 1799 | .rt = src_reg, |
| | 1800 | .stack_offset = adj_off, |
| | 1801 | } }, |
| | 1802 | }); |
| | 1803 | }, |
| 1787 | else => return self.fail("TODO store {} to register", .{value}), | 1804 | else => return self.fail("TODO store {} to register", .{value}), |
| 1788 | } | 1805 | } |
| 1789 | | 1806 | |
| ... | @@ -1797,7 +1814,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -1797,7 +1814,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1797 | } | 1814 | } |
| 1798 | }, | 1815 | }, |
| 1799 | .memory, | 1816 | .memory, |
| 1800 | .embedded_in_code, | | |
| 1801 | .stack_offset, | 1817 | .stack_offset, |
| 1802 | .stack_argument_offset, | 1818 | .stack_argument_offset, |
| 1803 | => { | 1819 | => { |
| ... | @@ -2680,12 +2696,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -2680,12 +2696,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 2680 | .immediate => unreachable, | 2696 | .immediate => unreachable, |
| 2681 | .unreach => unreachable, | 2697 | .unreach => unreachable, |
| 2682 | .dead => unreachable, | 2698 | .dead => unreachable, |
| 2683 | .embedded_in_code => unreachable, | | |
| 2684 | .memory => unreachable, | 2699 | .memory => unreachable, |
| 2685 | .compare_flags_signed => unreachable, | 2700 | .compare_flags_signed => unreachable, |
| 2686 | .compare_flags_unsigned => unreachable, | 2701 | .compare_flags_unsigned => unreachable, |
| 2687 | .ptr_stack_offset => unreachable, | 2702 | .ptr_stack_offset => unreachable, |
| 2688 | .ptr_embedded_in_code => unreachable, | | |
| 2689 | .register => |reg| { | 2703 | .register => |reg| { |
| 2690 | try self.register_manager.getReg(reg, null); | 2704 | try self.register_manager.getReg(reg, null); |
| 2691 | try self.genSetReg(arg_ty, reg, arg_mcv); | 2705 | try self.genSetReg(arg_ty, reg, arg_mcv); |
| ... | @@ -3584,7 +3598,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3584,7 +3598,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3584 | .compare_flags_signed, | 3598 | .compare_flags_signed, |
| 3585 | .immediate, | 3599 | .immediate, |
| 3586 | .ptr_stack_offset, | 3600 | .ptr_stack_offset, |
| 3587 | .ptr_embedded_in_code, | | |
| 3588 | => { | 3601 | => { |
| 3589 | const reg = try self.copyToTmpRegister(ty, mcv); | 3602 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 3590 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 3603 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| ... | @@ -3637,7 +3650,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3637,7 +3650,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3637 | } | 3650 | } |
| 3638 | }, | 3651 | }, |
| 3639 | .memory, | 3652 | .memory, |
| 3640 | .embedded_in_code, | | |
| 3641 | .stack_argument_offset, | 3653 | .stack_argument_offset, |
| 3642 | .stack_offset, | 3654 | .stack_offset, |
| 3643 | => { | 3655 | => { |
| ... | @@ -3684,7 +3696,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3684,7 +3696,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3684 | } }, | 3696 | } }, |
| 3685 | }); | 3697 | }); |
| 3686 | }, | 3698 | }, |
| 3687 | .embedded_in_code => return self.fail("TODO genSetStack with src={}", .{mcv}), | | |
| 3688 | else => unreachable, | 3699 | else => unreachable, |
| 3689 | } | 3700 | } |
| 3690 | | 3701 | |
| ... | @@ -3704,7 +3715,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3704,7 +3715,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3704 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { | 3715 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 3705 | switch (mcv) { | 3716 | switch (mcv) { |
| 3706 | .dead => unreachable, | 3717 | .dead => unreachable, |
| 3707 | .ptr_embedded_in_code => unreachable, | | |
| 3708 | .unreach, .none => return, // Nothing to do. | 3718 | .unreach, .none => return, // Nothing to do. |
| 3709 | .undef => { | 3719 | .undef => { |
| 3710 | if (!self.wantSafety()) | 3720 | if (!self.wantSafety()) |
| ... | @@ -3964,7 +3974,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -3964,7 +3974,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3964 | } }, | 3974 | } }, |
| 3965 | }); | 3975 | }); |
| 3966 | }, | 3976 | }, |
| 3967 | else => return self.fail("TODO implement getSetReg for arm {}", .{mcv}), | | |
| 3968 | } | 3977 | } |
| 3969 | } | 3978 | } |
| 3970 | | 3979 | |
| ... | @@ -4028,7 +4037,6 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -4028,7 +4037,6 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4028 | .stack_offset, | 4037 | .stack_offset, |
| 4029 | .memory, | 4038 | .memory, |
| 4030 | .stack_argument_offset, | 4039 | .stack_argument_offset, |
| 4031 | .embedded_in_code, | | |
| 4032 | => { | 4040 | => { |
| 4033 | if (abi_size <= 4) { | 4041 | if (abi_size <= 4) { |
| 4034 | const reg = try self.copyToTmpRegister(ty, mcv); | 4042 | const reg = try self.copyToTmpRegister(ty, mcv); |
| ... | @@ -4054,9 +4062,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -4054,9 +4062,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4054 | try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); | 4062 | try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); |
| 4055 | }, | 4063 | }, |
| 4056 | .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), | 4064 | .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), |
| 4057 | .stack_argument_offset, | 4065 | .stack_argument_offset => return self.fail("TODO genSetStackArgument src={}", .{mcv}), |
| 4058 | .embedded_in_code, | | |
| 4059 | => return self.fail("TODO genSetStackArgument src={}", .{mcv}), | | |
| 4060 | else => unreachable, | 4066 | else => unreachable, |
| 4061 | } | 4067 | } |
| 4062 | | 4068 | |
| ... | @@ -4085,7 +4091,6 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -4085,7 +4091,6 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4085 | .compare_flags_signed, | 4091 | .compare_flags_signed, |
| 4086 | .immediate, | 4092 | .immediate, |
| 4087 | .ptr_stack_offset, | 4093 | .ptr_stack_offset, |
| 4088 | .ptr_embedded_in_code, | | |
| 4089 | => { | 4094 | => { |
| 4090 | const reg = try self.copyToTmpRegister(ty, mcv); | 4095 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 4091 | return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); | 4096 | return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); |