| author | |
| committer | |
| log | 9d098318e2b16a35803d84b70b48c04111f2dddf |
| tree | df9d5d2e3aa86c46bcc1ae4f577e35c92babb9e6 |
| parent | 136a43934bc08dc3aee85f1182904b97456601d3 |
| parent | f91fe9afb92dda2b7b1ae37147ce7af40101d5ea |
| signature |
stage2 AArch64: more support for PIE targets (Mach-O)10 files changed, 92 insertions(+), 118 deletions(-)
src/arch/aarch64/CodeGen.zig+30-32| ... | @@ -1717,6 +1717,8 @@ fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_ind | ... | @@ -1717,6 +1717,8 @@ fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_ind |
| 1717 | 1717 | ||
| 1718 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { | 1718 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 1719 | const elem_ty = ptr_ty.elemType(); | 1719 | const elem_ty = ptr_ty.elemType(); |
| 1720 | const elem_size = elem_ty.abiSize(self.target.*); | ||
| 1721 | |||
| 1720 | switch (ptr) { | 1722 | switch (ptr) { |
| 1721 | .none => unreachable, | 1723 | .none => unreachable, |
| 1722 | .undef => unreachable, | 1724 | .undef => unreachable, |
| ... | @@ -1736,17 +1738,16 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1736,17 +1738,16 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1736 | self.register_manager.freezeRegs(&.{addr_reg}); | 1738 | self.register_manager.freezeRegs(&.{addr_reg}); |
| 1737 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); | 1739 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); |
| 1738 | 1740 | ||
| 1739 | const abi_size = elem_ty.abiSize(self.target.*); | ||
| 1740 | switch (dst_mcv) { | 1741 | switch (dst_mcv) { |
| 1741 | .dead => unreachable, | 1742 | .dead => unreachable, |
| 1742 | .undef => unreachable, | 1743 | .undef => unreachable, |
| 1743 | .compare_flags_signed, .compare_flags_unsigned => unreachable, | 1744 | .compare_flags_signed, .compare_flags_unsigned => unreachable, |
| 1744 | .embedded_in_code => unreachable, | 1745 | .embedded_in_code => unreachable, |
| 1745 | .register => |dst_reg| { | 1746 | .register => |dst_reg| { |
| 1746 | try self.genLdrRegister(dst_reg, addr_reg, abi_size); | 1747 | try self.genLdrRegister(dst_reg, addr_reg, elem_size); |
| 1747 | }, | 1748 | }, |
| 1748 | .stack_offset => |off| { | 1749 | .stack_offset => |off| { |
| 1749 | if (abi_size <= 8) { | 1750 | if (elem_size <= 8) { |
| 1750 | const tmp_reg = try self.register_manager.allocReg(null); | 1751 | const tmp_reg = try self.register_manager.allocReg(null); |
| 1751 | self.register_manager.freezeRegs(&.{tmp_reg}); | 1752 | self.register_manager.freezeRegs(&.{tmp_reg}); |
| 1752 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); | 1753 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); |
| ... | @@ -1766,17 +1767,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1766,17 +1767,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1766 | const tmp_reg = regs[3]; | 1767 | const tmp_reg = regs[3]; |
| 1767 | 1768 | ||
| 1768 | // sub dst_reg, fp, #off | 1769 | // sub dst_reg, fp, #off |
| 1769 | const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*)); | 1770 | try self.genSetReg(ptr_ty, dst_reg, .{ .ptr_stack_offset = off }); |
| 1770 | const adj_off = off + elem_size; | ||
| 1771 | const offset = math.cast(u12, adj_off) catch return self.fail("TODO load: larger stack offsets", .{}); | ||
| 1772 | _ = try self.addInst(.{ | ||
| 1773 | .tag = .sub_immediate, | ||
| 1774 | .data = .{ .rr_imm12_sh = .{ | ||
| 1775 | .rd = dst_reg, | ||
| 1776 | .rn = .x29, | ||
| 1777 | .imm12 = offset, | ||
| 1778 | } }, | ||
| 1779 | }); | ||
| 1780 | 1771 | ||
| 1781 | // mov len, #elem_size | 1772 | // mov len, #elem_size |
| 1782 | try self.genSetReg(Type.usize, len_reg, .{ .immediate = elem_size }); | 1773 | try self.genSetReg(Type.usize, len_reg, .{ .immediate = elem_size }); |
| ... | @@ -2046,14 +2037,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2046,14 +2037,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2046 | }, | 2037 | }, |
| 2047 | .memory, | 2038 | .memory, |
| 2048 | .stack_offset, | 2039 | .stack_offset, |
| 2049 | => { | ||
| 2050 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); | ||
| 2051 | try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty); | ||
| 2052 | }, | ||
| 2053 | .got_load, | 2040 | .got_load, |
| 2054 | .direct_load, | 2041 | .direct_load, |
| 2055 | => { | 2042 | => { |
| 2056 | return self.fail("TODO implement storing to {}", .{ptr}); | 2043 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 2044 | try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty); | ||
| 2057 | }, | 2045 | }, |
| 2058 | } | 2046 | } |
| 2059 | } | 2047 | } |
| ... | @@ -3142,10 +3130,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3142,10 +3130,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3142 | }, | 3130 | }, |
| 3143 | .got_load, | 3131 | .got_load, |
| 3144 | .direct_load, | 3132 | .direct_load, |
| 3145 | => |sym_index| { | ||
| 3146 | _ = sym_index; | ||
| 3147 | return self.fail("TODO implement set stack variable from {}", .{mcv}); | ||
| 3148 | }, | ||
| 3149 | .memory, | 3133 | .memory, |
| 3150 | .stack_offset, | 3134 | .stack_offset, |
| 3151 | => { | 3135 | => { |
| ... | @@ -3187,6 +3171,25 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3187,6 +3171,25 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3187 | }); | 3171 | }); |
| 3188 | }, | 3172 | }, |
| 3189 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }), | 3173 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }), |
| 3174 | .got_load, | ||
| 3175 | .direct_load, | ||
| 3176 | => |sym_index| { | ||
| 3177 | const tag: Mir.Inst.Tag = switch (mcv) { | ||
| 3178 | .got_load => .load_memory_ptr_got, | ||
| 3179 | .direct_load => .load_memory_ptr_direct, | ||
| 3180 | else => unreachable, | ||
| 3181 | }; | ||
| 3182 | _ = try self.addInst(.{ | ||
| 3183 | .tag = tag, | ||
| 3184 | .data = .{ | ||
| 3185 | .payload = try self.addExtra(Mir.LoadMemoryPie{ | ||
| 3186 | .register = @enumToInt(src_reg), | ||
| 3187 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, | ||
| 3188 | .sym_index = sym_index, | ||
| 3189 | }), | ||
| 3190 | }, | ||
| 3191 | }); | ||
| 3192 | }, | ||
| 3190 | else => unreachable, | 3193 | else => unreachable, |
| 3191 | } | 3194 | } |
| 3192 | 3195 | ||
| ... | @@ -3318,15 +3321,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -3318,15 +3321,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3318 | }); | 3321 | }); |
| 3319 | }, | 3322 | }, |
| 3320 | .memory => |addr| { | 3323 | .memory => |addr| { |
| 3321 | _ = try self.addInst(.{ | 3324 | // The value is in memory at a hard-coded address. |
| 3322 | .tag = .load_memory, | 3325 | // If the type is a pointer, it means the pointer address is at this memory location. |
| 3323 | .data = .{ | 3326 | try self.genSetReg(ty, reg, .{ .immediate = addr }); |
| 3324 | .load_memory = .{ | 3327 | try self.genLdrRegister(reg, reg, ty.abiSize(self.target.*)); |
| 3325 | .register = @enumToInt(reg), | ||
| 3326 | .addr = @intCast(u32, addr), | ||
| 3327 | }, | ||
| 3328 | }, | ||
| 3329 | }); | ||
| 3330 | }, | 3328 | }, |
| 3331 | .stack_offset => |unadjusted_off| { | 3329 | .stack_offset => |unadjusted_off| { |
| 3332 | const abi_size = ty.abiSize(self.target.*); | 3330 | const abi_size = ty.abiSize(self.target.*); |
src/arch/aarch64/Emit.zig+47-71| ... | @@ -108,9 +108,10 @@ pub fn emitMir( | ... | @@ -108,9 +108,10 @@ pub fn emitMir( |
| 108 | 108 | ||
| 109 | .eor_shifted_register => try emit.mirLogicalShiftedRegister(inst), | 109 | .eor_shifted_register => try emit.mirLogicalShiftedRegister(inst), |
| 110 | 110 | ||
| 111 | .load_memory => try emit.mirLoadMemory(inst), | ||
| 112 | .load_memory_got => try emit.mirLoadMemoryPie(inst), | 111 | .load_memory_got => try emit.mirLoadMemoryPie(inst), |
| 113 | .load_memory_direct => try emit.mirLoadMemoryPie(inst), | 112 | .load_memory_direct => try emit.mirLoadMemoryPie(inst), |
| 113 | .load_memory_ptr_got => try emit.mirLoadMemoryPie(inst), | ||
| 114 | .load_memory_ptr_direct => try emit.mirLoadMemoryPie(inst), | ||
| 114 | 115 | ||
| 115 | .ldp => try emit.mirLoadStoreRegisterPair(inst), | 116 | .ldp => try emit.mirLoadStoreRegisterPair(inst), |
| 116 | .stp => try emit.mirLoadStoreRegisterPair(inst), | 117 | .stp => try emit.mirLoadStoreRegisterPair(inst), |
| ... | @@ -209,17 +210,9 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize { | ... | @@ -209,17 +210,9 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize { |
| 209 | switch (tag) { | 210 | switch (tag) { |
| 210 | .load_memory_got, | 211 | .load_memory_got, |
| 211 | .load_memory_direct, | 212 | .load_memory_direct, |
| 213 | .load_memory_ptr_got, | ||
| 214 | .load_memory_ptr_direct, | ||
| 212 | => return 2 * 4, | 215 | => return 2 * 4, |
| 213 | .load_memory => { | ||
| 214 | const load_memory = emit.mir.instructions.items(.data)[inst].load_memory; | ||
| 215 | const addr = load_memory.addr; | ||
| 216 | |||
| 217 | // movz, [movk, ...], ldr | ||
| 218 | if (addr <= math.maxInt(u16)) return 2 * 4; | ||
| 219 | if (addr <= math.maxInt(u32)) return 3 * 4; | ||
| 220 | if (addr <= math.maxInt(u48)) return 4 * 4; | ||
| 221 | return 5 * 4; | ||
| 222 | }, | ||
| 223 | .pop_regs, .push_regs => { | 216 | .pop_regs, .push_regs => { |
| 224 | const reg_list = emit.mir.instructions.items(.data)[inst].reg_list; | 217 | const reg_list = emit.mir.instructions.items(.data)[inst].reg_list; |
| 225 | const number_of_regs = @popCount(u32, reg_list); | 218 | const number_of_regs = @popCount(u32, reg_list); |
| ... | @@ -655,21 +648,6 @@ fn mirLogicalShiftedRegister(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -655,21 +648,6 @@ fn mirLogicalShiftedRegister(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 655 | } | 648 | } |
| 656 | } | 649 | } |
| 657 | 650 | ||
| 658 | fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void { | ||
| 659 | assert(emit.mir.instructions.items(.tag)[inst] == .load_memory); | ||
| 660 | const load_memory = emit.mir.instructions.items(.data)[inst].load_memory; | ||
| 661 | const reg = @intToEnum(Register, load_memory.register); | ||
| 662 | const addr = load_memory.addr; | ||
| 663 | // The value is in memory at a hard-coded address. | ||
| 664 | // If the type is a pointer, it means the pointer address is at this memory location. | ||
| 665 | try emit.moveImmediate(reg, addr); | ||
| 666 | try emit.writeInstruction(Instruction.ldr( | ||
| 667 | reg, | ||
| 668 | reg, | ||
| 669 | Instruction.LoadStoreOffset.none, | ||
| 670 | )); | ||
| 671 | } | ||
| 672 | |||
| 673 | fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { | 651 | fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 674 | const tag = emit.mir.instructions.items(.tag)[inst]; | 652 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 675 | const payload = emit.mir.instructions.items(.data)[inst].payload; | 653 | const payload = emit.mir.instructions.items(.data)[inst].payload; |
| ... | @@ -681,12 +659,25 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -681,12 +659,25 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 681 | const offset = @intCast(u32, emit.code.items.len); | 659 | const offset = @intCast(u32, emit.code.items.len); |
| 682 | try emit.writeInstruction(Instruction.adrp(reg, 0)); | 660 | try emit.writeInstruction(Instruction.adrp(reg, 0)); |
| 683 | 661 | ||
| 684 | // ldr reg, reg, offset | 662 | switch (tag) { |
| 685 | try emit.writeInstruction(Instruction.ldr( | 663 | .load_memory_got, |
| 686 | reg, | 664 | .load_memory_direct, |
| 687 | reg, | 665 | => { |
| 688 | Instruction.LoadStoreOffset.imm(0), | 666 | // ldr reg, reg, offset |
| 689 | )); | 667 | try emit.writeInstruction(Instruction.ldr( |
| 668 | reg, | ||
| 669 | reg, | ||
| 670 | Instruction.LoadStoreOffset.imm(0), | ||
| 671 | )); | ||
| 672 | }, | ||
| 673 | .load_memory_ptr_got, | ||
| 674 | .load_memory_ptr_direct, | ||
| 675 | => { | ||
| 676 | // add reg, reg, offset | ||
| 677 | try emit.writeInstruction(Instruction.add(reg, reg, 0, false)); | ||
| 678 | }, | ||
| 679 | else => unreachable, | ||
| 680 | } | ||
| 690 | 681 | ||
| 691 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | 682 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 692 | const atom = macho_file.atom_by_index_table.get(data.atom_index).?; | 683 | const atom = macho_file.atom_by_index_table.get(data.atom_index).?; |
| ... | @@ -699,8 +690,12 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -699,8 +690,12 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 699 | .pcrel = true, | 690 | .pcrel = true, |
| 700 | .length = 2, | 691 | .length = 2, |
| 701 | .@"type" = switch (tag) { | 692 | .@"type" = switch (tag) { |
| 702 | .load_memory_got => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21), | 693 | .load_memory_got, |
| 703 | .load_memory_direct => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGE21), | 694 | .load_memory_ptr_got, |
| 695 | => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21), | ||
| 696 | .load_memory_direct, | ||
| 697 | .load_memory_ptr_direct, | ||
| 698 | => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGE21), | ||
| 704 | else => unreachable, | 699 | else => unreachable, |
| 705 | }, | 700 | }, |
| 706 | }); | 701 | }); |
| ... | @@ -713,8 +708,12 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -713,8 +708,12 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 713 | .pcrel = false, | 708 | .pcrel = false, |
| 714 | .length = 2, | 709 | .length = 2, |
| 715 | .@"type" = switch (tag) { | 710 | .@"type" = switch (tag) { |
| 716 | .load_memory_got => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12), | 711 | .load_memory_got, |
| 717 | .load_memory_direct => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGEOFF12), | 712 | .load_memory_ptr_got, |
| 713 | => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12), | ||
| 714 | .load_memory_direct, | ||
| 715 | .load_memory_ptr_direct, | ||
| 716 | => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGEOFF12), | ||
| 718 | else => unreachable, | 717 | else => unreachable, |
| 719 | }, | 718 | }, |
| 720 | }); | 719 | }); |
| ... | @@ -741,6 +740,7 @@ fn mirLoadStoreRegisterPair(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -741,6 +740,7 @@ fn mirLoadStoreRegisterPair(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 741 | fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { | 740 | fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 742 | const tag = emit.mir.instructions.items(.tag)[inst]; | 741 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 743 | const load_store_stack = emit.mir.instructions.items(.data)[inst].load_store_stack; | 742 | const load_store_stack = emit.mir.instructions.items(.data)[inst].load_store_stack; |
| 743 | const rt = load_store_stack.rt; | ||
| 744 | 744 | ||
| 745 | const raw_offset = emit.stack_size - load_store_stack.offset; | 745 | const raw_offset = emit.stack_size - load_store_stack.offset; |
| 746 | const offset = switch (tag) { | 746 | const offset = switch (tag) { |
| ... | @@ -760,7 +760,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -760,7 +760,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 760 | } | 760 | } |
| 761 | }, | 761 | }, |
| 762 | .ldr_stack, .str_stack => blk: { | 762 | .ldr_stack, .str_stack => blk: { |
| 763 | const alignment: u32 = switch (load_store_stack.rt.size()) { | 763 | const alignment: u32 = switch (rt.size()) { |
| 764 | 32 => 4, | 764 | 32 => 4, |
| 765 | 64 => 8, | 765 | 64 => 8, |
| 766 | else => unreachable, | 766 | else => unreachable, |
| ... | @@ -777,36 +777,12 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -777,36 +777,12 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 777 | }; | 777 | }; |
| 778 | 778 | ||
| 779 | switch (tag) { | 779 | switch (tag) { |
| 780 | .ldr_stack => try emit.writeInstruction(Instruction.ldr( | 780 | .ldr_stack => try emit.writeInstruction(Instruction.ldr(rt, .sp, offset)), |
| 781 | load_store_stack.rt, | 781 | .ldrb_stack => try emit.writeInstruction(Instruction.ldrb(rt, .sp, offset)), |
| 782 | Register.sp, | 782 | .ldrh_stack => try emit.writeInstruction(Instruction.ldrh(rt, .sp, offset)), |
| 783 | offset, | 783 | .str_stack => try emit.writeInstruction(Instruction.str(rt, .sp, offset)), |
| 784 | )), | 784 | .strb_stack => try emit.writeInstruction(Instruction.strb(rt, .sp, offset)), |
| 785 | .ldrb_stack => try emit.writeInstruction(Instruction.ldrb( | 785 | .strh_stack => try emit.writeInstruction(Instruction.strh(rt, .sp, offset)), |
| 786 | load_store_stack.rt, | ||
| 787 | Register.sp, | ||
| 788 | offset, | ||
| 789 | )), | ||
| 790 | .ldrh_stack => try emit.writeInstruction(Instruction.ldrh( | ||
| 791 | load_store_stack.rt, | ||
| 792 | Register.sp, | ||
| 793 | offset, | ||
| 794 | )), | ||
| 795 | .str_stack => try emit.writeInstruction(Instruction.str( | ||
| 796 | load_store_stack.rt, | ||
| 797 | Register.sp, | ||
| 798 | offset, | ||
| 799 | )), | ||
| 800 | .strb_stack => try emit.writeInstruction(Instruction.strb( | ||
| 801 | load_store_stack.rt, | ||
| 802 | Register.sp, | ||
| 803 | offset, | ||
| 804 | )), | ||
| 805 | .strh_stack => try emit.writeInstruction(Instruction.strh( | ||
| 806 | load_store_stack.rt, | ||
| 807 | Register.sp, | ||
| 808 | offset, | ||
| 809 | )), | ||
| 810 | else => unreachable, | 786 | else => unreachable, |
| 811 | } | 787 | } |
| 812 | } | 788 | } |
| ... | @@ -914,7 +890,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -914,7 +890,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 914 | if (count == number_of_regs - 1) { | 890 | if (count == number_of_regs - 1) { |
| 915 | try emit.writeInstruction(Instruction.ldr( | 891 | try emit.writeInstruction(Instruction.ldr( |
| 916 | reg, | 892 | reg, |
| 917 | Register.sp, | 893 | .sp, |
| 918 | Instruction.LoadStoreOffset.imm_post_index(16), | 894 | Instruction.LoadStoreOffset.imm_post_index(16), |
| 919 | )); | 895 | )); |
| 920 | } else { | 896 | } else { |
| ... | @@ -924,7 +900,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -924,7 +900,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 924 | try emit.writeInstruction(Instruction.ldp( | 900 | try emit.writeInstruction(Instruction.ldp( |
| 925 | reg, | 901 | reg, |
| 926 | other_reg, | 902 | other_reg, |
| 927 | Register.sp, | 903 | .sp, |
| 928 | Instruction.LoadStorePairOffset.post_index(16), | 904 | Instruction.LoadStorePairOffset.post_index(16), |
| 929 | )); | 905 | )); |
| 930 | } | 906 | } |
| ... | @@ -944,7 +920,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -944,7 +920,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 944 | if (count == number_of_regs - 1) { | 920 | if (count == number_of_regs - 1) { |
| 945 | try emit.writeInstruction(Instruction.str( | 921 | try emit.writeInstruction(Instruction.str( |
| 946 | reg, | 922 | reg, |
| 947 | Register.sp, | 923 | .sp, |
| 948 | Instruction.LoadStoreOffset.imm_pre_index(-16), | 924 | Instruction.LoadStoreOffset.imm_pre_index(-16), |
| 949 | )); | 925 | )); |
| 950 | } else { | 926 | } else { |
| ... | @@ -954,7 +930,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -954,7 +930,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 954 | try emit.writeInstruction(Instruction.stp( | 930 | try emit.writeInstruction(Instruction.stp( |
| 955 | other_reg, | 931 | other_reg, |
| 956 | reg, | 932 | reg, |
| 957 | Register.sp, | 933 | .sp, |
| 958 | Instruction.LoadStorePairOffset.pre_index(-16), | 934 | Instruction.LoadStorePairOffset.pre_index(-16), |
| 959 | )); | 935 | )); |
| 960 | } | 936 | } |
src/arch/aarch64/Mir.zig+11-3| ... | @@ -56,14 +56,22 @@ pub const Inst = struct { | ... | @@ -56,14 +56,22 @@ pub const Inst = struct { |
| 56 | dbg_line, | 56 | dbg_line, |
| 57 | /// Bitwise Exclusive OR (shifted register) | 57 | /// Bitwise Exclusive OR (shifted register) |
| 58 | eor_shifted_register, | 58 | eor_shifted_register, |
| 59 | /// Pseudo-instruction: Load memory | 59 | /// Loads the contents into a register |
| 60 | /// | 60 | /// |
| 61 | /// Payload is `load_memory` | ||
| 62 | load_memory, | ||
| 63 | /// Payload is `LoadMemoryPie` | 61 | /// Payload is `LoadMemoryPie` |
| 64 | load_memory_got, | 62 | load_memory_got, |
| 63 | /// Loads the contents into a register | ||
| 64 | /// | ||
| 65 | /// Payload is `LoadMemoryPie` | 65 | /// Payload is `LoadMemoryPie` |
| 66 | load_memory_direct, | 66 | load_memory_direct, |
| 67 | /// Loads the address into a register | ||
| 68 | /// | ||
| 69 | /// Payload is `LoadMemoryPie` | ||
| 70 | load_memory_ptr_got, | ||
| 71 | /// Loads the address into a register | ||
| 72 | /// | ||
| 73 | /// Payload is `LoadMemoryPie` | ||
| 74 | load_memory_ptr_direct, | ||
| 67 | /// Load Pair of Registers | 75 | /// Load Pair of Registers |
| 68 | ldp, | 76 | ldp, |
| 69 | /// Pseudo-instruction: Load from stack | 77 | /// Pseudo-instruction: Load from stack |
src/arch/aarch64/bits.zig+4-4| ... | @@ -1486,19 +1486,19 @@ test "serialize instructions" { | ... | @@ -1486,19 +1486,19 @@ test "serialize instructions" { |
| 1486 | .expected = 0b1_00_10000_1111111111111111110_00010, | 1486 | .expected = 0b1_00_10000_1111111111111111110_00010, |
| 1487 | }, | 1487 | }, |
| 1488 | .{ // stp x1, x2, [sp, #8] | 1488 | .{ // stp x1, x2, [sp, #8] |
| 1489 | .inst = Instruction.stp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.signed(8)), | 1489 | .inst = Instruction.stp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.signed(8)), |
| 1490 | .expected = 0b10_101_0_010_0_0000001_00010_11111_00001, | 1490 | .expected = 0b10_101_0_010_0_0000001_00010_11111_00001, |
| 1491 | }, | 1491 | }, |
| 1492 | .{ // ldp x1, x2, [sp, #8] | 1492 | .{ // ldp x1, x2, [sp, #8] |
| 1493 | .inst = Instruction.ldp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.signed(8)), | 1493 | .inst = Instruction.ldp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.signed(8)), |
| 1494 | .expected = 0b10_101_0_010_1_0000001_00010_11111_00001, | 1494 | .expected = 0b10_101_0_010_1_0000001_00010_11111_00001, |
| 1495 | }, | 1495 | }, |
| 1496 | .{ // stp x1, x2, [sp, #-16]! | 1496 | .{ // stp x1, x2, [sp, #-16]! |
| 1497 | .inst = Instruction.stp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.pre_index(-16)), | 1497 | .inst = Instruction.stp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.pre_index(-16)), |
| 1498 | .expected = 0b10_101_0_011_0_1111110_00010_11111_00001, | 1498 | .expected = 0b10_101_0_011_0_1111110_00010_11111_00001, |
| 1499 | }, | 1499 | }, |
| 1500 | .{ // ldp x1, x2, [sp], #16 | 1500 | .{ // ldp x1, x2, [sp], #16 |
| 1501 | .inst = Instruction.ldp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.post_index(16)), | 1501 | .inst = Instruction.ldp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.post_index(16)), |
| 1502 | .expected = 0b10_101_0_001_1_0000010_00010_11111_00001, | 1502 | .expected = 0b10_101_0_001_1_0000010_00010_11111_00001, |
| 1503 | }, | 1503 | }, |
| 1504 | .{ // and x0, x4, x2 | 1504 | .{ // and x0, x4, x2 |
test/behavior/align.zig-1| ... | @@ -305,7 +305,6 @@ fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) !void { | ... | @@ -305,7 +305,6 @@ fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) !void { |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | test "alignment of function with c calling convention" { | 307 | test "alignment of function with c calling convention" { |
| 308 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 309 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 308 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 310 | 309 | ||
| 311 | var runtime_nothing = &nothing; | 310 | var runtime_nothing = &nothing; |
test/behavior/basic.zig-3| ... | @@ -48,7 +48,6 @@ const g1: i32 = 1233 + 1; | ... | @@ -48,7 +48,6 @@ const g1: i32 = 1233 + 1; |
| 48 | var g2: i32 = 0; | 48 | var g2: i32 = 0; |
| 49 | 49 | ||
| 50 | test "global variables" { | 50 | test "global variables" { |
| 51 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 52 | try expect(g2 == 0); | 51 | try expect(g2 == 0); |
| 53 | g2 = g1; | 52 | g2 = g1; |
| 54 | try expect(g2 == 1234); | 53 | try expect(g2 == 1234); |
| ... | @@ -604,7 +603,6 @@ test "comptime cast fn to ptr" { | ... | @@ -604,7 +603,6 @@ test "comptime cast fn to ptr" { |
| 604 | } | 603 | } |
| 605 | 604 | ||
| 606 | test "equality compare fn ptrs" { | 605 | test "equality compare fn ptrs" { |
| 607 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 608 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 606 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 609 | 607 | ||
| 610 | var a = &emptyFn; | 608 | var a = &emptyFn; |
| ... | @@ -612,7 +610,6 @@ test "equality compare fn ptrs" { | ... | @@ -612,7 +610,6 @@ test "equality compare fn ptrs" { |
| 612 | } | 610 | } |
| 613 | 611 | ||
| 614 | test "self reference through fn ptr field" { | 612 | test "self reference through fn ptr field" { |
| 615 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 616 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 613 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 617 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 614 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 618 | 615 |
test/behavior/bugs/2006.zig-1| ... | @@ -6,7 +6,6 @@ const S = struct { | ... | @@ -6,7 +6,6 @@ const S = struct { |
| 6 | p: *S, | 6 | p: *S, |
| 7 | }; | 7 | }; |
| 8 | test "bug 2006" { | 8 | test "bug 2006" { |
| 9 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 10 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 11 | var a: S = undefined; | 10 | var a: S = undefined; |
| 12 | a = S{ .p = undefined }; | 11 | a = S{ .p = undefined }; |
test/behavior/cast.zig-1| ... | @@ -1013,7 +1013,6 @@ test "cast from array reference to fn: comptime fn ptr" { | ... | @@ -1013,7 +1013,6 @@ test "cast from array reference to fn: comptime fn ptr" { |
| 1013 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); | 1013 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); |
| 1014 | } | 1014 | } |
| 1015 | test "cast from array reference to fn: runtime fn ptr" { | 1015 | test "cast from array reference to fn: runtime fn ptr" { |
| 1016 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 1017 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 1016 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1018 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1017 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1019 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1018 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
test/behavior/slice.zig-1| ... | @@ -81,7 +81,6 @@ fn assertLenIsZero(msg: []const u8) !void { | ... | @@ -81,7 +81,6 @@ fn assertLenIsZero(msg: []const u8) !void { |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | test "access len index of sentinel-terminated slice" { | 83 | test "access len index of sentinel-terminated slice" { |
| 84 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 85 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 84 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 86 | 85 | ||
| 87 | const S = struct { | 86 | const S = struct { |
test/behavior/struct.zig-1| ... | @@ -66,7 +66,6 @@ const SmallStruct = struct { | ... | @@ -66,7 +66,6 @@ const SmallStruct = struct { |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | test "lower unnamed constants" { | 68 | test "lower unnamed constants" { |
| 69 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; | ||
| 70 | var foo = SmallStruct{ .a = 1, .b = 255 }; | 69 | var foo = SmallStruct{ .a = 1, .b = 255 }; |
| 71 | try expect(foo.first() == 1); | 70 | try expect(foo.first() == 1); |
| 72 | try expect(foo.second() == 255); | 71 | try expect(foo.second() == 255); |