| author | |
| committer | |
| log | d3a099c14fe9b7b575a0cd7bb9cd05b49625a71e |
| tree | a7ba0e0d9771c6a83493dd0feb931723a1ad2256 |
| parent | 71388b980bfc4c7eb267ed7c168c2395098f6db2 |
| parent | 96e715d5a3a5e75e691bedd6a2dcebffc09639bb |
| signature |
stage2 AArch64: fix loading/storing to/from stack5 files changed, 190 insertions(+), 124 deletions(-)
src/arch/aarch64/CodeGen.zig+24-38| ... | ... | @@ -302,6 +302,7 @@ pub fn generate( |
| 302 | 302 | .prev_di_pc = 0, |
| 303 | 303 | .prev_di_line = module_fn.lbrace_line, |
| 304 | 304 | .prev_di_column = module_fn.lbrace_column, |
| 305 | .stack_size = mem.alignForwardGeneric(u32, function.max_end_stack, function.stack_align), | |
| 305 | 306 | }; |
| 306 | 307 | defer emit.deinit(); |
| 307 | 308 | |
| ... | ... | @@ -1346,9 +1347,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1346 | 1347 | const stack_offset = try self.allocMem(inst, abi_size, abi_align); |
| 1347 | 1348 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 1348 | 1349 | |
| 1349 | // TODO correct loading and storing from memory | |
| 1350 | // break :blk MCValue{ .stack_offset = stack_offset }; | |
| 1351 | break :blk result; | |
| 1350 | break :blk MCValue{ .stack_offset = stack_offset }; | |
| 1352 | 1351 | }, |
| 1353 | 1352 | else => result, |
| 1354 | 1353 | }; |
| ... | ... | @@ -2261,28 +2260,23 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 2261 | 2260 | |
| 2262 | 2261 | switch (abi_size) { |
| 2263 | 2262 | 1, 2, 4, 8 => { |
| 2264 | const offset = if (math.cast(i9, adj_off)) |imm| | |
| 2265 | Instruction.LoadStoreOffset.imm_post_index(-imm) | |
| 2266 | else |_| | |
| 2267 | Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.u64), MCValue{ .immediate = adj_off })); | |
| 2268 | const rn: Register = switch (self.target.cpu.arch) { | |
| 2269 | .aarch64, .aarch64_be => .x29, | |
| 2270 | .aarch64_32 => .w29, | |
| 2271 | else => unreachable, | |
| 2272 | }; | |
| 2273 | 2263 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 2274 | 1 => .strb, | |
| 2275 | 2 => .strh, | |
| 2276 | 4, 8 => .str, | |
| 2264 | 1 => .strb_stack, | |
| 2265 | 2 => .strh_stack, | |
| 2266 | 4, 8 => .str_stack, | |
| 2267 | else => unreachable, // unexpected abi size | |
| 2268 | }; | |
| 2269 | const rt: Register = switch (abi_size) { | |
| 2270 | 1, 2, 4 => reg.to32(), | |
| 2271 | 8 => reg.to64(), | |
| 2277 | 2272 | else => unreachable, // unexpected abi size |
| 2278 | 2273 | }; |
| 2279 | 2274 | |
| 2280 | 2275 | _ = try self.addInst(.{ |
| 2281 | 2276 | .tag = tag, |
| 2282 | .data = .{ .load_store_register = .{ | |
| 2283 | .rt = reg, | |
| 2284 | .rn = rn, | |
| 2285 | .offset = offset, | |
| 2277 | .data = .{ .load_store_stack = .{ | |
| 2278 | .rt = rt, | |
| 2279 | .offset = @intCast(u32, adj_off), | |
| 2286 | 2280 | } }, |
| 2287 | 2281 | }); |
| 2288 | 2282 | }, |
| ... | ... | @@ -2384,36 +2378,28 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 2384 | 2378 | }); |
| 2385 | 2379 | }, |
| 2386 | 2380 | .stack_offset => |unadjusted_off| { |
| 2387 | // TODO: maybe addressing from sp instead of fp | |
| 2388 | 2381 | const abi_size = ty.abiSize(self.target.*); |
| 2389 | 2382 | const adj_off = unadjusted_off + abi_size; |
| 2390 | 2383 | |
| 2391 | const rn: Register = switch (self.target.cpu.arch) { | |
| 2392 | .aarch64, .aarch64_be => .x29, | |
| 2393 | .aarch64_32 => .w29, | |
| 2394 | else => unreachable, | |
| 2395 | }; | |
| 2396 | ||
| 2397 | const offset = if (math.cast(i9, adj_off)) |imm| | |
| 2398 | Instruction.LoadStoreOffset.imm_post_index(-imm) | |
| 2399 | else |_| | |
| 2400 | Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.u64), MCValue{ .immediate = adj_off })); | |
| 2401 | ||
| 2402 | 2384 | switch (abi_size) { |
| 2403 | 2385 | 1, 2, 4, 8 => { |
| 2404 | 2386 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 2405 | 1 => .ldrb, | |
| 2406 | 2 => .ldrh, | |
| 2407 | 4, 8 => .ldr, | |
| 2387 | 1 => .ldrb_stack, | |
| 2388 | 2 => .ldrh_stack, | |
| 2389 | 4, 8 => .ldr_stack, | |
| 2390 | else => unreachable, // unexpected abi size | |
| 2391 | }; | |
| 2392 | const rt: Register = switch (abi_size) { | |
| 2393 | 1, 2, 4 => reg.to32(), | |
| 2394 | 8 => reg.to64(), | |
| 2408 | 2395 | else => unreachable, // unexpected abi size |
| 2409 | 2396 | }; |
| 2410 | 2397 | |
| 2411 | 2398 | _ = try self.addInst(.{ |
| 2412 | 2399 | .tag = tag, |
| 2413 | .data = .{ .load_store_register = .{ | |
| 2414 | .rt = reg, | |
| 2415 | .rn = rn, | |
| 2416 | .offset = offset, | |
| 2400 | .data = .{ .load_store_stack = .{ | |
| 2401 | .rt = rt, | |
| 2402 | .offset = @intCast(u32, adj_off), | |
| 2417 | 2403 | } }, |
| 2418 | 2404 | }); |
| 2419 | 2405 | }, |
src/arch/aarch64/Emit.zig+96-13| ... | ... | @@ -42,6 +42,8 @@ branch_forward_origins: std.AutoHashMapUnmanaged(Mir.Inst.Index, std.ArrayListUn |
| 42 | 42 | /// instruction |
| 43 | 43 | code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .{}, |
| 44 | 44 | |
| 45 | stack_size: u32, | |
| 46 | ||
| 45 | 47 | const InnerError = error{ |
| 46 | 48 | OutOfMemory, |
| 47 | 49 | EmitFail, |
| ... | ... | @@ -103,6 +105,13 @@ pub fn emitMir( |
| 103 | 105 | .ldp => try emit.mirLoadStoreRegisterPair(inst), |
| 104 | 106 | .stp => try emit.mirLoadStoreRegisterPair(inst), |
| 105 | 107 | |
| 108 | .ldr_stack => try emit.mirLoadStoreStack(inst), | |
| 109 | .ldrb_stack => try emit.mirLoadStoreStack(inst), | |
| 110 | .ldrh_stack => try emit.mirLoadStoreStack(inst), | |
| 111 | .str_stack => try emit.mirLoadStoreStack(inst), | |
| 112 | .strb_stack => try emit.mirLoadStoreStack(inst), | |
| 113 | .strh_stack => try emit.mirLoadStoreStack(inst), | |
| 114 | ||
| 106 | 115 | .ldr => try emit.mirLoadStoreRegister(inst), |
| 107 | 116 | .ldrb => try emit.mirLoadStoreRegister(inst), |
| 108 | 117 | .ldrh => try emit.mirLoadStoreRegister(inst), |
| ... | ... | @@ -587,12 +596,11 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 587 | 596 | try emit.writeInstruction(Instruction.adrp(reg, 0)); |
| 588 | 597 | |
| 589 | 598 | // ldr reg, reg, offset |
| 590 | try emit.writeInstruction(Instruction.ldr(reg, .{ | |
| 591 | .register = .{ | |
| 592 | .rn = reg, | |
| 593 | .offset = Instruction.LoadStoreOffset.imm(0), | |
| 594 | }, | |
| 595 | })); | |
| 599 | try emit.writeInstruction(Instruction.ldr( | |
| 600 | reg, | |
| 601 | reg, | |
| 602 | Instruction.LoadStoreOffset.imm(0), | |
| 603 | )); | |
| 596 | 604 | |
| 597 | 605 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 598 | 606 | // TODO I think the reloc might be in the wrong place. |
| ... | ... | @@ -626,7 +634,8 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 626 | 634 | try emit.moveImmediate(reg, addr); |
| 627 | 635 | try emit.writeInstruction(Instruction.ldr( |
| 628 | 636 | reg, |
| 629 | .{ .register = .{ .rn = reg, .offset = Instruction.LoadStoreOffset.none } }, | |
| 637 | reg, | |
| 638 | Instruction.LoadStoreOffset.none, | |
| 630 | 639 | )); |
| 631 | 640 | } |
| 632 | 641 | } |
| ... | ... | @@ -652,6 +661,79 @@ fn mirLoadStoreRegisterPair(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 652 | 661 | } |
| 653 | 662 | } |
| 654 | 663 | |
| 664 | fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { | |
| 665 | const tag = emit.mir.instructions.items(.tag)[inst]; | |
| 666 | const load_store_stack = emit.mir.instructions.items(.data)[inst].load_store_stack; | |
| 667 | ||
| 668 | const raw_offset = emit.stack_size - load_store_stack.offset; | |
| 669 | const offset = switch (tag) { | |
| 670 | .ldrb_stack, .strb_stack => blk: { | |
| 671 | if (math.cast(u12, raw_offset)) |imm| { | |
| 672 | break :blk Instruction.LoadStoreOffset.imm(imm); | |
| 673 | } else |_| { | |
| 674 | return emit.fail("TODO load/store stack byte with larger offset", .{}); | |
| 675 | } | |
| 676 | }, | |
| 677 | .ldrh_stack, .strh_stack => blk: { | |
| 678 | assert(std.mem.isAlignedGeneric(u32, raw_offset, 2)); // misaligned stack entry | |
| 679 | if (math.cast(u12, @divExact(raw_offset, 2))) |imm| { | |
| 680 | break :blk Instruction.LoadStoreOffset.imm(imm); | |
| 681 | } else |_| { | |
| 682 | return emit.fail("TODO load/store stack halfword with larger offset", .{}); | |
| 683 | } | |
| 684 | }, | |
| 685 | .ldr_stack, .str_stack => blk: { | |
| 686 | const alignment: u32 = switch (load_store_stack.rt.size()) { | |
| 687 | 32 => 4, | |
| 688 | 64 => 8, | |
| 689 | else => unreachable, | |
| 690 | }; | |
| 691 | ||
| 692 | assert(std.mem.isAlignedGeneric(u32, raw_offset, alignment)); // misaligned stack entry | |
| 693 | if (math.cast(u12, @divExact(raw_offset, alignment))) |imm| { | |
| 694 | break :blk Instruction.LoadStoreOffset.imm(imm); | |
| 695 | } else |_| { | |
| 696 | return emit.fail("TODO load/store stack with larger offset", .{}); | |
| 697 | } | |
| 698 | }, | |
| 699 | else => unreachable, | |
| 700 | }; | |
| 701 | ||
| 702 | switch (tag) { | |
| 703 | .ldr_stack => try emit.writeInstruction(Instruction.ldr( | |
| 704 | load_store_stack.rt, | |
| 705 | Register.sp, | |
| 706 | offset, | |
| 707 | )), | |
| 708 | .ldrb_stack => try emit.writeInstruction(Instruction.ldrb( | |
| 709 | load_store_stack.rt, | |
| 710 | Register.sp, | |
| 711 | offset, | |
| 712 | )), | |
| 713 | .ldrh_stack => try emit.writeInstruction(Instruction.ldrh( | |
| 714 | load_store_stack.rt, | |
| 715 | Register.sp, | |
| 716 | offset, | |
| 717 | )), | |
| 718 | .str_stack => try emit.writeInstruction(Instruction.str( | |
| 719 | load_store_stack.rt, | |
| 720 | Register.sp, | |
| 721 | offset, | |
| 722 | )), | |
| 723 | .strb_stack => try emit.writeInstruction(Instruction.strb( | |
| 724 | load_store_stack.rt, | |
| 725 | Register.sp, | |
| 726 | offset, | |
| 727 | )), | |
| 728 | .strh_stack => try emit.writeInstruction(Instruction.strh( | |
| 729 | load_store_stack.rt, | |
| 730 | Register.sp, | |
| 731 | offset, | |
| 732 | )), | |
| 733 | else => unreachable, | |
| 734 | } | |
| 735 | } | |
| 736 | ||
| 655 | 737 | fn mirLoadStoreRegister(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 656 | 738 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 657 | 739 | const load_store_register = emit.mir.instructions.items(.data)[inst].load_store_register; |
| ... | ... | @@ -659,32 +741,33 @@ fn mirLoadStoreRegister(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 659 | 741 | switch (tag) { |
| 660 | 742 | .ldr => try emit.writeInstruction(Instruction.ldr( |
| 661 | 743 | load_store_register.rt, |
| 662 | .{ .register = .{ .rn = load_store_register.rn, .offset = load_store_register.offset } }, | |
| 744 | load_store_register.rn, | |
| 745 | load_store_register.offset, | |
| 663 | 746 | )), |
| 664 | 747 | .ldrb => try emit.writeInstruction(Instruction.ldrb( |
| 665 | 748 | load_store_register.rt, |
| 666 | 749 | load_store_register.rn, |
| 667 | .{ .offset = load_store_register.offset }, | |
| 750 | load_store_register.offset, | |
| 668 | 751 | )), |
| 669 | 752 | .ldrh => try emit.writeInstruction(Instruction.ldrh( |
| 670 | 753 | load_store_register.rt, |
| 671 | 754 | load_store_register.rn, |
| 672 | .{ .offset = load_store_register.offset }, | |
| 755 | load_store_register.offset, | |
| 673 | 756 | )), |
| 674 | 757 | .str => try emit.writeInstruction(Instruction.str( |
| 675 | 758 | load_store_register.rt, |
| 676 | 759 | load_store_register.rn, |
| 677 | .{ .offset = load_store_register.offset }, | |
| 760 | load_store_register.offset, | |
| 678 | 761 | )), |
| 679 | 762 | .strb => try emit.writeInstruction(Instruction.strb( |
| 680 | 763 | load_store_register.rt, |
| 681 | 764 | load_store_register.rn, |
| 682 | .{ .offset = load_store_register.offset }, | |
| 765 | load_store_register.offset, | |
| 683 | 766 | )), |
| 684 | 767 | .strh => try emit.writeInstruction(Instruction.strh( |
| 685 | 768 | load_store_register.rt, |
| 686 | 769 | load_store_register.rn, |
| 687 | .{ .offset = load_store_register.offset }, | |
| 770 | load_store_register.offset, | |
| 688 | 771 | )), |
| 689 | 772 | else => unreachable, |
| 690 | 773 | } |
src/arch/aarch64/Mir.zig+20-1| ... | ... | @@ -56,12 +56,18 @@ pub const Inst = struct { |
| 56 | 56 | load_memory, |
| 57 | 57 | /// Load Pair of Registers |
| 58 | 58 | ldp, |
| 59 | /// Pseudo-instruction: Load from stack | |
| 60 | ldr_stack, | |
| 59 | 61 | /// Load Register |
| 60 | 62 | // TODO: split into ldr_immediate and ldr_register |
| 61 | 63 | ldr, |
| 64 | /// Pseudo-instruction: Load byte from stack | |
| 65 | ldrb_stack, | |
| 62 | 66 | /// Load Register Byte |
| 63 | 67 | // TODO: split into ldrb_immediate and ldrb_register |
| 64 | 68 | ldrb, |
| 69 | /// Pseudo-instruction: Load halfword from stack | |
| 70 | ldrh_stack, | |
| 65 | 71 | /// Load Register Halfword |
| 66 | 72 | // TODO: split into ldrh_immediate and ldrh_register |
| 67 | 73 | ldrh, |
| ... | ... | @@ -79,12 +85,18 @@ pub const Inst = struct { |
| 79 | 85 | ret, |
| 80 | 86 | /// Store Pair of Registers |
| 81 | 87 | stp, |
| 88 | /// Pseudo-instruction: Store to stack | |
| 89 | str_stack, | |
| 82 | 90 | /// Store Register |
| 83 | 91 | // TODO: split into str_immediate and str_register |
| 84 | 92 | str, |
| 93 | /// Pseudo-instruction: Store byte to stack | |
| 94 | strb_stack, | |
| 85 | 95 | /// Store Register Byte |
| 86 | 96 | // TODO: split into strb_immediate and strb_register |
| 87 | 97 | strb, |
| 98 | /// Pseudo-instruction: Store halfword to stack | |
| 99 | strh_stack, | |
| 88 | 100 | /// Store Register Halfword |
| 89 | 101 | // TODO: split into strh_immediate and strh_register |
| 90 | 102 | strh, |
| ... | ... | @@ -175,7 +187,7 @@ pub const Inst = struct { |
| 175 | 187 | rm: Register, |
| 176 | 188 | cond: bits.Instruction.Condition, |
| 177 | 189 | }, |
| 178 | /// Three registers and a LoadStoreOffset | |
| 190 | /// Two registers and a LoadStoreOffset | |
| 179 | 191 | /// |
| 180 | 192 | /// Used by e.g. str_register |
| 181 | 193 | load_store_register: struct { |
| ... | ... | @@ -183,6 +195,13 @@ pub const Inst = struct { |
| 183 | 195 | rn: Register, |
| 184 | 196 | offset: bits.Instruction.LoadStoreOffset, |
| 185 | 197 | }, |
| 198 | /// A registers and a stack offset | |
| 199 | /// | |
| 200 | /// Used by e.g. str_register | |
| 201 | load_store_stack: struct { | |
| 202 | rt: Register, | |
| 203 | offset: u32, | |
| 204 | }, | |
| 186 | 205 | /// Three registers and a LoadStorePairOffset |
| 187 | 206 | /// |
| 188 | 207 | /// Used by e.g. stp |
src/arch/aarch64/bits.zig+36-57| ... | ... | @@ -742,27 +742,17 @@ pub const Instruction = union(enum) { |
| 742 | 742 | } |
| 743 | 743 | |
| 744 | 744 | fn loadLiteral(rt: Register, imm19: u19) Instruction { |
| 745 | switch (rt.size()) { | |
| 746 | 32 => { | |
| 747 | return Instruction{ | |
| 748 | .load_literal = .{ | |
| 749 | .rt = rt.id(), | |
| 750 | .imm19 = imm19, | |
| 751 | .opc = 0b00, | |
| 752 | }, | |
| 753 | }; | |
| 754 | }, | |
| 755 | 64 => { | |
| 756 | return Instruction{ | |
| 757 | .load_literal = .{ | |
| 758 | .rt = rt.id(), | |
| 759 | .imm19 = imm19, | |
| 760 | .opc = 0b01, | |
| 761 | }, | |
| 762 | }; | |
| 745 | return Instruction{ | |
| 746 | .load_literal = .{ | |
| 747 | .rt = rt.id(), | |
| 748 | .imm19 = imm19, | |
| 749 | .opc = switch (rt.size()) { | |
| 750 | 32 => 0b00, | |
| 751 | 64 => 0b01, | |
| 752 | else => unreachable, // unexpected register size | |
| 753 | }, | |
| 763 | 754 | }, |
| 764 | else => unreachable, // unexpected register size | |
| 765 | } | |
| 755 | }; | |
| 766 | 756 | } |
| 767 | 757 | |
| 768 | 758 | fn exceptionGeneration( |
| ... | ... | @@ -1001,43 +991,32 @@ pub const Instruction = union(enum) { |
| 1001 | 991 | |
| 1002 | 992 | // Load or store register |
| 1003 | 993 | |
| 1004 | pub const LdrArgs = union(enum) { | |
| 1005 | register: struct { | |
| 1006 | rn: Register, | |
| 1007 | offset: LoadStoreOffset = LoadStoreOffset.none, | |
| 1008 | }, | |
| 1009 | literal: u19, | |
| 1010 | }; | |
| 1011 | ||
| 1012 | pub fn ldr(rt: Register, args: LdrArgs) Instruction { | |
| 1013 | switch (args) { | |
| 1014 | .register => |info| return loadStoreRegister(rt, info.rn, info.offset, .ldr), | |
| 1015 | .literal => |literal| return loadLiteral(rt, literal), | |
| 1016 | } | |
| 994 | pub fn ldrLiteral(rt: Register, literal: u19) Instruction { | |
| 995 | return loadLiteral(rt, literal); | |
| 1017 | 996 | } |
| 1018 | 997 | |
| 1019 | pub fn ldrh(rt: Register, rn: Register, args: StrArgs) Instruction { | |
| 1020 | return loadStoreRegister(rt, rn, args.offset, .ldrh); | |
| 998 | pub fn ldr(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction { | |
| 999 | return loadStoreRegister(rt, rn, offset, .ldr); | |
| 1021 | 1000 | } |
| 1022 | 1001 | |
| 1023 | pub fn ldrb(rt: Register, rn: Register, args: StrArgs) Instruction { | |
| 1024 | return loadStoreRegister(rt, rn, args.offset, .ldrb); | |
| 1002 | pub fn ldrh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction { | |
| 1003 | return loadStoreRegister(rt, rn, offset, .ldrh); | |
| 1025 | 1004 | } |
| 1026 | 1005 | |
| 1027 | pub const StrArgs = struct { | |
| 1028 | offset: LoadStoreOffset = LoadStoreOffset.none, | |
| 1029 | }; | |
| 1006 | pub fn ldrb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction { | |
| 1007 | return loadStoreRegister(rt, rn, offset, .ldrb); | |
| 1008 | } | |
| 1030 | 1009 | |
| 1031 | pub fn str(rt: Register, rn: Register, args: StrArgs) Instruction { | |
| 1032 | return loadStoreRegister(rt, rn, args.offset, .str); | |
| 1010 | pub fn str(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction { | |
| 1011 | return loadStoreRegister(rt, rn, offset, .str); | |
| 1033 | 1012 | } |
| 1034 | 1013 | |
| 1035 | pub fn strh(rt: Register, rn: Register, args: StrArgs) Instruction { | |
| 1036 | return loadStoreRegister(rt, rn, args.offset, .strh); | |
| 1014 | pub fn strh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction { | |
| 1015 | return loadStoreRegister(rt, rn, offset, .strh); | |
| 1037 | 1016 | } |
| 1038 | 1017 | |
| 1039 | pub fn strb(rt: Register, rn: Register, args: StrArgs) Instruction { | |
| 1040 | return loadStoreRegister(rt, rn, args.offset, .strb); | |
| 1018 | pub fn strb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction { | |
| 1019 | return loadStoreRegister(rt, rn, offset, .strb); | |
| 1041 | 1020 | } |
| 1042 | 1021 | |
| 1043 | 1022 | // Load or store pair of registers |
| ... | ... | @@ -1324,47 +1303,47 @@ test "serialize instructions" { |
| 1324 | 1303 | .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100, |
| 1325 | 1304 | }, |
| 1326 | 1305 | .{ // ldr x2, [x1] |
| 1327 | .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1 } }), | |
| 1306 | .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.none), | |
| 1328 | 1307 | .expected = 0b11_111_0_01_01_000000000000_00001_00010, |
| 1329 | 1308 | }, |
| 1330 | 1309 | .{ // ldr x2, [x1, #1]! |
| 1331 | .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_pre_index(1) } }), | |
| 1310 | .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.imm_pre_index(1)), | |
| 1332 | 1311 | .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010, |
| 1333 | 1312 | }, |
| 1334 | 1313 | .{ // ldr x2, [x1], #-1 |
| 1335 | .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_post_index(-1) } }), | |
| 1314 | .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.imm_post_index(-1)), | |
| 1336 | 1315 | .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010, |
| 1337 | 1316 | }, |
| 1338 | 1317 | .{ // ldr x2, [x1], (x3) |
| 1339 | .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.reg(.x3) } }), | |
| 1318 | .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.reg(.x3)), | |
| 1340 | 1319 | .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010, |
| 1341 | 1320 | }, |
| 1342 | 1321 | .{ // ldr x2, label |
| 1343 | .inst = Instruction.ldr(.x2, .{ .literal = 0x1 }), | |
| 1322 | .inst = Instruction.ldrLiteral(.x2, 0x1), | |
| 1344 | 1323 | .expected = 0b01_011_0_00_0000000000000000001_00010, |
| 1345 | 1324 | }, |
| 1346 | 1325 | .{ // ldrh x7, [x4], #0xaa |
| 1347 | .inst = Instruction.ldrh(.x7, .x4, .{ .offset = Instruction.LoadStoreOffset.imm_post_index(0xaa) }), | |
| 1326 | .inst = Instruction.ldrh(.x7, .x4, Instruction.LoadStoreOffset.imm_post_index(0xaa)), | |
| 1348 | 1327 | .expected = 0b01_111_0_00_01_0_010101010_01_00100_00111, |
| 1349 | 1328 | }, |
| 1350 | 1329 | .{ // ldrb x9, [x15, #0xff]! |
| 1351 | .inst = Instruction.ldrb(.x9, .x15, .{ .offset = Instruction.LoadStoreOffset.imm_pre_index(0xff) }), | |
| 1330 | .inst = Instruction.ldrb(.x9, .x15, Instruction.LoadStoreOffset.imm_pre_index(0xff)), | |
| 1352 | 1331 | .expected = 0b00_111_0_00_01_0_011111111_11_01111_01001, |
| 1353 | 1332 | }, |
| 1354 | 1333 | .{ // str x2, [x1] |
| 1355 | .inst = Instruction.str(.x2, .x1, .{}), | |
| 1334 | .inst = Instruction.str(.x2, .x1, Instruction.LoadStoreOffset.none), | |
| 1356 | 1335 | .expected = 0b11_111_0_01_00_000000000000_00001_00010, |
| 1357 | 1336 | }, |
| 1358 | 1337 | .{ // str x2, [x1], (x3) |
| 1359 | .inst = Instruction.str(.x2, .x1, .{ .offset = Instruction.LoadStoreOffset.reg(.x3) }), | |
| 1338 | .inst = Instruction.str(.x2, .x1, Instruction.LoadStoreOffset.reg(.x3)), | |
| 1360 | 1339 | .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010, |
| 1361 | 1340 | }, |
| 1362 | 1341 | .{ // strh w0, [x1] |
| 1363 | .inst = Instruction.strh(.w0, .x1, .{}), | |
| 1342 | .inst = Instruction.strh(.w0, .x1, Instruction.LoadStoreOffset.none), | |
| 1364 | 1343 | .expected = 0b01_111_0_01_00_000000000000_00001_00000, |
| 1365 | 1344 | }, |
| 1366 | 1345 | .{ // strb w8, [x9] |
| 1367 | .inst = Instruction.strb(.w8, .x9, .{}), | |
| 1346 | .inst = Instruction.strb(.w8, .x9, Instruction.LoadStoreOffset.none), | |
| 1368 | 1347 | .expected = 0b00_111_0_01_00_000000000000_01001_01000, |
| 1369 | 1348 | }, |
| 1370 | 1349 | .{ // adr x2, #0x8 |
src/link/MachO.zig+14-15| ... | ... | @@ -2041,12 +2041,11 @@ fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 2041 | 2041 | .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21), |
| 2042 | 2042 | }); |
| 2043 | 2043 | // ldr x16, [x16, 0] |
| 2044 | mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(.x16, .{ | |
| 2045 | .register = .{ | |
| 2046 | .rn = .x16, | |
| 2047 | .offset = aarch64.Instruction.LoadStoreOffset.imm(0), | |
| 2048 | }, | |
| 2049 | }).toU32()); | |
| 2044 | mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr( | |
| 2045 | .x16, | |
| 2046 | .x16, | |
| 2047 | aarch64.Instruction.LoadStoreOffset.imm(0), | |
| 2048 | ).toU32()); | |
| 2050 | 2049 | atom.relocs.appendAssumeCapacity(.{ |
| 2051 | 2050 | .offset = 16, |
| 2052 | 2051 | .target = .{ .global = self.undefs.items[self.dyld_stub_binder_index.?].n_strx }, |
| ... | ... | @@ -2119,9 +2118,10 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { |
| 2119 | 2118 | break :blk try math.cast(u18, div_res); |
| 2120 | 2119 | }; |
| 2121 | 2120 | // ldr w16, literal |
| 2122 | mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldr(.w16, .{ | |
| 2123 | .literal = literal, | |
| 2124 | }).toU32()); | |
| 2121 | mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldrLiteral( | |
| 2122 | .w16, | |
| 2123 | literal, | |
| 2124 | ).toU32()); | |
| 2125 | 2125 | // b disp |
| 2126 | 2126 | mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.b(0).toU32()); |
| 2127 | 2127 | atom.relocs.appendAssumeCapacity(.{ |
| ... | ... | @@ -2222,12 +2222,11 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { |
| 2222 | 2222 | .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), |
| 2223 | 2223 | }); |
| 2224 | 2224 | // ldr x16, x16, offset |
| 2225 | mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(.x16, .{ | |
| 2226 | .register = .{ | |
| 2227 | .rn = .x16, | |
| 2228 | .offset = aarch64.Instruction.LoadStoreOffset.imm(0), | |
| 2229 | }, | |
| 2230 | }).toU32()); | |
| 2225 | mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr( | |
| 2226 | .x16, | |
| 2227 | .x16, | |
| 2228 | aarch64.Instruction.LoadStoreOffset.imm(0), | |
| 2229 | ).toU32()); | |
| 2231 | 2230 | atom.relocs.appendAssumeCapacity(.{ |
| 2232 | 2231 | .offset = 4, |
| 2233 | 2232 | .target = .{ .local = laptr_sym_index }, |