| author | |
| committer | |
| log | 7e76aab98abe94e01cfd8b01ce288360ed67dbc7 |
| tree | 8a6f96e1edca471e5571f60be72e5c3b659cd37d |
| parent | e945619728110affb389402ff1ce06d65470cdd2 |
3 files changed, 132 insertions(+), 110 deletions(-)
src/arch/aarch64/Emit.zig+42-38| ... | @@ -112,12 +112,19 @@ pub fn emitMir( | ... | @@ -112,12 +112,19 @@ pub fn emitMir( |
| 112 | .strb_stack => try emit.mirLoadStoreStack(inst), | 112 | .strb_stack => try emit.mirLoadStoreStack(inst), |
| 113 | .strh_stack => try emit.mirLoadStoreStack(inst), | 113 | .strh_stack => try emit.mirLoadStoreStack(inst), |
| 114 | 114 | ||
| 115 | .ldr => try emit.mirLoadStoreRegister(inst), | 115 | .ldr_register => try emit.mirLoadStoreRegisterRegister(inst), |
| 116 | .ldrb => try emit.mirLoadStoreRegister(inst), | 116 | .ldrb_register => try emit.mirLoadStoreRegisterRegister(inst), |
| 117 | .ldrh => try emit.mirLoadStoreRegister(inst), | 117 | .ldrh_register => try emit.mirLoadStoreRegisterRegister(inst), |
| 118 | .str => try emit.mirLoadStoreRegister(inst), | 118 | .str_register => try emit.mirLoadStoreRegisterRegister(inst), |
| 119 | .strb => try emit.mirLoadStoreRegister(inst), | 119 | .strb_register => try emit.mirLoadStoreRegisterRegister(inst), |
| 120 | .strh => try emit.mirLoadStoreRegister(inst), | 120 | .strh_register => try emit.mirLoadStoreRegisterRegister(inst), |
| 121 | |||
| 122 | .ldr_immediate => try emit.mirLoadStoreRegisterImmediate(inst), | ||
| 123 | .ldrb_immediate => try emit.mirLoadStoreRegisterImmediate(inst), | ||
| 124 | .ldrh_immediate => try emit.mirLoadStoreRegisterImmediate(inst), | ||
| 125 | .str_immediate => try emit.mirLoadStoreRegisterImmediate(inst), | ||
| 126 | .strb_immediate => try emit.mirLoadStoreRegisterImmediate(inst), | ||
| 127 | .strh_immediate => try emit.mirLoadStoreRegisterImmediate(inst), | ||
| 121 | 128 | ||
| 122 | .mov_register => try emit.mirMoveRegister(inst), | 129 | .mov_register => try emit.mirMoveRegister(inst), |
| 123 | .mov_to_from_sp => try emit.mirMoveRegister(inst), | 130 | .mov_to_from_sp => try emit.mirMoveRegister(inst), |
| ... | @@ -737,41 +744,38 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -737,41 +744,38 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 737 | } | 744 | } |
| 738 | } | 745 | } |
| 739 | 746 | ||
| 740 | fn mirLoadStoreRegister(emit: *Emit, inst: Mir.Inst.Index) !void { | 747 | fn mirLoadStoreRegisterImmediate(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 741 | const tag = emit.mir.instructions.items(.tag)[inst]; | 748 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 742 | const load_store_register = emit.mir.instructions.items(.data)[inst].load_store_register; | 749 | const load_store_register_immediate = emit.mir.instructions.items(.data)[inst].load_store_register_immediate; |
| 750 | const rt = load_store_register_immediate.rt; | ||
| 751 | const rn = load_store_register_immediate.rn; | ||
| 752 | const offset = Instruction.LoadStoreOffset{ .immediate = load_store_register_immediate.offset }; | ||
| 743 | 753 | ||
| 744 | switch (tag) { | 754 | switch (tag) { |
| 745 | .ldr => try emit.writeInstruction(Instruction.ldr( | 755 | .ldr_immediate => try emit.writeInstruction(Instruction.ldr(rt, rn, offset)), |
| 746 | load_store_register.rt, | 756 | .ldrb_immediate => try emit.writeInstruction(Instruction.ldrb(rt, rn, offset)), |
| 747 | load_store_register.rn, | 757 | .ldrh_immediate => try emit.writeInstruction(Instruction.ldrh(rt, rn, offset)), |
| 748 | load_store_register.offset, | 758 | .str_immediate => try emit.writeInstruction(Instruction.str(rt, rn, offset)), |
| 749 | )), | 759 | .strb_immediate => try emit.writeInstruction(Instruction.strb(rt, rn, offset)), |
| 750 | .ldrb => try emit.writeInstruction(Instruction.ldrb( | 760 | .strh_immediate => try emit.writeInstruction(Instruction.strh(rt, rn, offset)), |
| 751 | load_store_register.rt, | 761 | else => unreachable, |
| 752 | load_store_register.rn, | 762 | } |
| 753 | load_store_register.offset, | 763 | } |
| 754 | )), | 764 | |
| 755 | .ldrh => try emit.writeInstruction(Instruction.ldrh( | 765 | fn mirLoadStoreRegisterRegister(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 756 | load_store_register.rt, | 766 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 757 | load_store_register.rn, | 767 | const load_store_register_register = emit.mir.instructions.items(.data)[inst].load_store_register_register; |
| 758 | load_store_register.offset, | 768 | const rt = load_store_register_register.rt; |
| 759 | )), | 769 | const rn = load_store_register_register.rn; |
| 760 | .str => try emit.writeInstruction(Instruction.str( | 770 | const offset = Instruction.LoadStoreOffset{ .register = load_store_register_register.offset }; |
| 761 | load_store_register.rt, | 771 | |
| 762 | load_store_register.rn, | 772 | switch (tag) { |
| 763 | load_store_register.offset, | 773 | .ldr_register => try emit.writeInstruction(Instruction.ldr(rt, rn, offset)), |
| 764 | )), | 774 | .ldrb_register => try emit.writeInstruction(Instruction.ldrb(rt, rn, offset)), |
| 765 | .strb => try emit.writeInstruction(Instruction.strb( | 775 | .ldrh_register => try emit.writeInstruction(Instruction.ldrh(rt, rn, offset)), |
| 766 | load_store_register.rt, | 776 | .str_register => try emit.writeInstruction(Instruction.str(rt, rn, offset)), |
| 767 | load_store_register.rn, | 777 | .strb_register => try emit.writeInstruction(Instruction.strb(rt, rn, offset)), |
| 768 | load_store_register.offset, | 778 | .strh_register => try emit.writeInstruction(Instruction.strh(rt, rn, offset)), |
| 769 | )), | ||
| 770 | .strh => try emit.writeInstruction(Instruction.strh( | ||
| 771 | load_store_register.rt, | ||
| 772 | load_store_register.rn, | ||
| 773 | load_store_register.offset, | ||
| 774 | )), | ||
| 775 | else => unreachable, | 779 | else => unreachable, |
| 776 | } | 780 | } |
| 777 | } | 781 | } |
src/arch/aarch64/Mir.zig+40-26| ... | @@ -58,19 +58,22 @@ pub const Inst = struct { | ... | @@ -58,19 +58,22 @@ pub const Inst = struct { |
| 58 | ldp, | 58 | ldp, |
| 59 | /// Pseudo-instruction: Load from stack | 59 | /// Pseudo-instruction: Load from stack |
| 60 | ldr_stack, | 60 | ldr_stack, |
| 61 | /// Load Register | 61 | /// Load Register (immediate) |
| 62 | // TODO: split into ldr_immediate and ldr_register | 62 | ldr_immediate, |
| 63 | ldr, | 63 | /// Load Register (register) |
| 64 | ldr_register, | ||
| 64 | /// Pseudo-instruction: Load byte from stack | 65 | /// Pseudo-instruction: Load byte from stack |
| 65 | ldrb_stack, | 66 | ldrb_stack, |
| 66 | /// Load Register Byte | 67 | /// Load Register Byte (immediate) |
| 67 | // TODO: split into ldrb_immediate and ldrb_register | 68 | ldrb_immediate, |
| 68 | ldrb, | 69 | /// Load Register Byte (register) |
| 70 | ldrb_register, | ||
| 69 | /// Pseudo-instruction: Load halfword from stack | 71 | /// Pseudo-instruction: Load halfword from stack |
| 70 | ldrh_stack, | 72 | ldrh_stack, |
| 71 | /// Load Register Halfword | 73 | /// Load Register Halfword (immediate) |
| 72 | // TODO: split into ldrh_immediate and ldrh_register | 74 | ldrh_immediate, |
| 73 | ldrh, | 75 | /// Load Register Halfword (register) |
| 76 | ldrh_register, | ||
| 74 | /// Move (to/from SP) | 77 | /// Move (to/from SP) |
| 75 | mov_to_from_sp, | 78 | mov_to_from_sp, |
| 76 | /// Move (register) | 79 | /// Move (register) |
| ... | @@ -91,19 +94,22 @@ pub const Inst = struct { | ... | @@ -91,19 +94,22 @@ pub const Inst = struct { |
| 91 | stp, | 94 | stp, |
| 92 | /// Pseudo-instruction: Store to stack | 95 | /// Pseudo-instruction: Store to stack |
| 93 | str_stack, | 96 | str_stack, |
| 94 | /// Store Register | 97 | /// Store Register (immediate) |
| 95 | // TODO: split into str_immediate and str_register | 98 | str_immediate, |
| 96 | str, | 99 | /// Store Register (register) |
| 100 | str_register, | ||
| 97 | /// Pseudo-instruction: Store byte to stack | 101 | /// Pseudo-instruction: Store byte to stack |
| 98 | strb_stack, | 102 | strb_stack, |
| 99 | /// Store Register Byte | 103 | /// Store Register Byte (immediate) |
| 100 | // TODO: split into strb_immediate and strb_register | 104 | strb_immediate, |
| 101 | strb, | 105 | /// Store Register Byte (register) |
| 106 | strb_register, | ||
| 102 | /// Pseudo-instruction: Store halfword to stack | 107 | /// Pseudo-instruction: Store halfword to stack |
| 103 | strh_stack, | 108 | strh_stack, |
| 104 | /// Store Register Halfword | 109 | /// Store Register Halfword (immediate) |
| 105 | // TODO: split into strh_immediate and strh_register | 110 | strh_immediate, |
| 106 | strh, | 111 | /// Store Register Halfword (register) |
| 112 | strh_register, | ||
| 107 | /// Subtract (immediate) | 113 | /// Subtract (immediate) |
| 108 | sub_immediate, | 114 | sub_immediate, |
| 109 | /// Supervisor Call | 115 | /// Supervisor Call |
| ... | @@ -195,13 +201,21 @@ pub const Inst = struct { | ... | @@ -195,13 +201,21 @@ pub const Inst = struct { |
| 195 | rm: Register, | 201 | rm: Register, |
| 196 | cond: bits.Instruction.Condition, | 202 | cond: bits.Instruction.Condition, |
| 197 | }, | 203 | }, |
| 198 | /// Two registers and a LoadStoreOffset | 204 | /// Two registers and a LoadStoreOffsetImmediate |
| 199 | /// | 205 | /// |
| 200 | /// Used by e.g. str_register | 206 | /// Used by e.g. str_register |
| 201 | load_store_register: struct { | 207 | load_store_register_immediate: struct { |
| 202 | rt: Register, | 208 | rt: Register, |
| 203 | rn: Register, | 209 | rn: Register, |
| 204 | offset: bits.Instruction.LoadStoreOffset, | 210 | offset: bits.Instruction.LoadStoreOffsetImmediate, |
| 211 | }, | ||
| 212 | /// Two registers and a LoadStoreOffsetRegister | ||
| 213 | /// | ||
| 214 | /// Used by e.g. str_register | ||
| 215 | load_store_register_register: struct { | ||
| 216 | rt: Register, | ||
| 217 | rn: Register, | ||
| 218 | offset: bits.Instruction.LoadStoreOffsetRegister, | ||
| 205 | }, | 219 | }, |
| 206 | /// A registers and a stack offset | 220 | /// A registers and a stack offset |
| 207 | /// | 221 | /// |
| ... | @@ -230,11 +244,11 @@ pub const Inst = struct { | ... | @@ -230,11 +244,11 @@ pub const Inst = struct { |
| 230 | 244 | ||
| 231 | // Make sure we don't accidentally make instructions bigger than expected. | 245 | // Make sure we don't accidentally make instructions bigger than expected. |
| 232 | // Note that in Debug builds, Zig is allowed to insert a secret field for safety checks. | 246 | // Note that in Debug builds, Zig is allowed to insert a secret field for safety checks. |
| 233 | // comptime { | 247 | comptime { |
| 234 | // if (builtin.mode != .Debug) { | 248 | if (builtin.mode != .Debug) { |
| 235 | // assert(@sizeOf(Inst) == 8); | 249 | assert(@sizeOf(Data) == 8); |
| 236 | // } | 250 | } |
| 237 | // } | 251 | } |
| 238 | }; | 252 | }; |
| 239 | 253 | ||
| 240 | pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { | 254 | pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { |
src/arch/aarch64/bits.zig+50-46| ... | @@ -521,69 +521,73 @@ pub const Instruction = union(enum) { | ... | @@ -521,69 +521,73 @@ pub const Instruction = union(enum) { |
| 521 | }; | 521 | }; |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | pub const LoadStoreOffsetImmediate = union(enum) { | ||
| 525 | post_index: i9, | ||
| 526 | pre_index: i9, | ||
| 527 | unsigned: u12, | ||
| 528 | }; | ||
| 529 | |||
| 530 | pub const LoadStoreOffsetRegister = struct { | ||
| 531 | rm: u5, | ||
| 532 | shift: union(enum) { | ||
| 533 | uxtw: u2, | ||
| 534 | lsl: u2, | ||
| 535 | sxtw: u2, | ||
| 536 | sxtx: u2, | ||
| 537 | }, | ||
| 538 | }; | ||
| 539 | |||
| 524 | /// Represents the offset operand of a load or store instruction. | 540 | /// Represents the offset operand of a load or store instruction. |
| 525 | /// Data can be loaded from memory with either an immediate offset | 541 | /// Data can be loaded from memory with either an immediate offset |
| 526 | /// or an offset that is stored in some register. | 542 | /// or an offset that is stored in some register. |
| 527 | pub const LoadStoreOffset = union(enum) { | 543 | pub const LoadStoreOffset = union(enum) { |
| 528 | Immediate: union(enum) { | 544 | immediate: LoadStoreOffsetImmediate, |
| 529 | PostIndex: i9, | 545 | register: LoadStoreOffsetRegister, |
| 530 | PreIndex: i9, | ||
| 531 | Unsigned: u12, | ||
| 532 | }, | ||
| 533 | Register: struct { | ||
| 534 | rm: u5, | ||
| 535 | shift: union(enum) { | ||
| 536 | Uxtw: u2, | ||
| 537 | Lsl: u2, | ||
| 538 | Sxtw: u2, | ||
| 539 | Sxtx: u2, | ||
| 540 | }, | ||
| 541 | }, | ||
| 542 | 546 | ||
| 543 | pub const none = LoadStoreOffset{ | 547 | pub const none = LoadStoreOffset{ |
| 544 | .Immediate = .{ .Unsigned = 0 }, | 548 | .immediate = .{ .unsigned = 0 }, |
| 545 | }; | 549 | }; |
| 546 | 550 | ||
| 547 | pub fn toU12(self: LoadStoreOffset) u12 { | 551 | pub fn toU12(self: LoadStoreOffset) u12 { |
| 548 | return switch (self) { | 552 | return switch (self) { |
| 549 | .Immediate => |imm_type| switch (imm_type) { | 553 | .immediate => |imm_type| switch (imm_type) { |
| 550 | .PostIndex => |v| (@intCast(u12, @bitCast(u9, v)) << 2) + 1, | 554 | .post_index => |v| (@intCast(u12, @bitCast(u9, v)) << 2) + 1, |
| 551 | .PreIndex => |v| (@intCast(u12, @bitCast(u9, v)) << 2) + 3, | 555 | .pre_index => |v| (@intCast(u12, @bitCast(u9, v)) << 2) + 3, |
| 552 | .Unsigned => |v| v, | 556 | .unsigned => |v| v, |
| 553 | }, | 557 | }, |
| 554 | .Register => |r| switch (r.shift) { | 558 | .register => |r| switch (r.shift) { |
| 555 | .Uxtw => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 16 + 2050, | 559 | .uxtw => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 16 + 2050, |
| 556 | .Lsl => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 24 + 2050, | 560 | .lsl => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 24 + 2050, |
| 557 | .Sxtw => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 48 + 2050, | 561 | .sxtw => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 48 + 2050, |
| 558 | .Sxtx => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 56 + 2050, | 562 | .sxtx => |v| (@intCast(u12, r.rm) << 6) + (@intCast(u12, v) << 2) + 56 + 2050, |
| 559 | }, | 563 | }, |
| 560 | }; | 564 | }; |
| 561 | } | 565 | } |
| 562 | 566 | ||
| 563 | pub fn imm(offset: u12) LoadStoreOffset { | 567 | pub fn imm(offset: u12) LoadStoreOffset { |
| 564 | return .{ | 568 | return .{ |
| 565 | .Immediate = .{ .Unsigned = offset }, | 569 | .immediate = .{ .unsigned = offset }, |
| 566 | }; | 570 | }; |
| 567 | } | 571 | } |
| 568 | 572 | ||
| 569 | pub fn imm_post_index(offset: i9) LoadStoreOffset { | 573 | pub fn imm_post_index(offset: i9) LoadStoreOffset { |
| 570 | return .{ | 574 | return .{ |
| 571 | .Immediate = .{ .PostIndex = offset }, | 575 | .immediate = .{ .post_index = offset }, |
| 572 | }; | 576 | }; |
| 573 | } | 577 | } |
| 574 | 578 | ||
| 575 | pub fn imm_pre_index(offset: i9) LoadStoreOffset { | 579 | pub fn imm_pre_index(offset: i9) LoadStoreOffset { |
| 576 | return .{ | 580 | return .{ |
| 577 | .Immediate = .{ .PreIndex = offset }, | 581 | .immediate = .{ .pre_index = offset }, |
| 578 | }; | 582 | }; |
| 579 | } | 583 | } |
| 580 | 584 | ||
| 581 | pub fn reg(rm: Register) LoadStoreOffset { | 585 | pub fn reg(rm: Register) LoadStoreOffset { |
| 582 | return .{ | 586 | return .{ |
| 583 | .Register = .{ | 587 | .register = .{ |
| 584 | .rm = rm.id(), | 588 | .rm = rm.id(), |
| 585 | .shift = .{ | 589 | .shift = .{ |
| 586 | .Lsl = 0, | 590 | .lsl = 0, |
| 587 | }, | 591 | }, |
| 588 | }, | 592 | }, |
| 589 | }; | 593 | }; |
| ... | @@ -592,10 +596,10 @@ pub const Instruction = union(enum) { | ... | @@ -592,10 +596,10 @@ pub const Instruction = union(enum) { |
| 592 | pub fn reg_uxtw(rm: Register, shift: u2) LoadStoreOffset { | 596 | pub fn reg_uxtw(rm: Register, shift: u2) LoadStoreOffset { |
| 593 | assert(rm.size() == 32 and (shift == 0 or shift == 2)); | 597 | assert(rm.size() == 32 and (shift == 0 or shift == 2)); |
| 594 | return .{ | 598 | return .{ |
| 595 | .Register = .{ | 599 | .register = .{ |
| 596 | .rm = rm.id(), | 600 | .rm = rm.id(), |
| 597 | .shift = .{ | 601 | .shift = .{ |
| 598 | .Uxtw = shift, | 602 | .uxtw = shift, |
| 599 | }, | 603 | }, |
| 600 | }, | 604 | }, |
| 601 | }; | 605 | }; |
| ... | @@ -604,10 +608,10 @@ pub const Instruction = union(enum) { | ... | @@ -604,10 +608,10 @@ pub const Instruction = union(enum) { |
| 604 | pub fn reg_lsl(rm: Register, shift: u2) LoadStoreOffset { | 608 | pub fn reg_lsl(rm: Register, shift: u2) LoadStoreOffset { |
| 605 | assert(rm.size() == 64 and (shift == 0 or shift == 3)); | 609 | assert(rm.size() == 64 and (shift == 0 or shift == 3)); |
| 606 | return .{ | 610 | return .{ |
| 607 | .Register = .{ | 611 | .register = .{ |
| 608 | .rm = rm.id(), | 612 | .rm = rm.id(), |
| 609 | .shift = .{ | 613 | .shift = .{ |
| 610 | .Lsl = shift, | 614 | .lsl = shift, |
| 611 | }, | 615 | }, |
| 612 | }, | 616 | }, |
| 613 | }; | 617 | }; |
| ... | @@ -616,10 +620,10 @@ pub const Instruction = union(enum) { | ... | @@ -616,10 +620,10 @@ pub const Instruction = union(enum) { |
| 616 | pub fn reg_sxtw(rm: Register, shift: u2) LoadStoreOffset { | 620 | pub fn reg_sxtw(rm: Register, shift: u2) LoadStoreOffset { |
| 617 | assert(rm.size() == 32 and (shift == 0 or shift == 2)); | 621 | assert(rm.size() == 32 and (shift == 0 or shift == 2)); |
| 618 | return .{ | 622 | return .{ |
| 619 | .Register = .{ | 623 | .register = .{ |
| 620 | .rm = rm.id(), | 624 | .rm = rm.id(), |
| 621 | .shift = .{ | 625 | .shift = .{ |
| 622 | .Sxtw = shift, | 626 | .sxtw = shift, |
| 623 | }, | 627 | }, |
| 624 | }, | 628 | }, |
| 625 | }; | 629 | }; |
| ... | @@ -628,10 +632,10 @@ pub const Instruction = union(enum) { | ... | @@ -628,10 +632,10 @@ pub const Instruction = union(enum) { |
| 628 | pub fn reg_sxtx(rm: Register, shift: u2) LoadStoreOffset { | 632 | pub fn reg_sxtx(rm: Register, shift: u2) LoadStoreOffset { |
| 629 | assert(rm.size() == 64 and (shift == 0 or shift == 3)); | 633 | assert(rm.size() == 64 and (shift == 0 or shift == 3)); |
| 630 | return .{ | 634 | return .{ |
| 631 | .Register = .{ | 635 | .register = .{ |
| 632 | .rm = rm.id(), | 636 | .rm = rm.id(), |
| 633 | .shift = .{ | 637 | .shift = .{ |
| 634 | .Sxtx = shift, | 638 | .sxtx = shift, |
| 635 | }, | 639 | }, |
| 636 | }, | 640 | }, |
| 637 | }; | 641 | }; |
| ... | @@ -663,8 +667,8 @@ pub const Instruction = union(enum) { | ... | @@ -663,8 +667,8 @@ pub const Instruction = union(enum) { |
| 663 | const off = offset.toU12(); | 667 | const off = offset.toU12(); |
| 664 | const op1: u2 = blk: { | 668 | const op1: u2 = blk: { |
| 665 | switch (offset) { | 669 | switch (offset) { |
| 666 | .Immediate => |imm| switch (imm) { | 670 | .immediate => |imm| switch (imm) { |
| 667 | .Unsigned => break :blk 0b01, | 671 | .unsigned => break :blk 0b01, |
| 668 | else => {}, | 672 | else => {}, |
| 669 | }, | 673 | }, |
| 670 | else => {}, | 674 | else => {}, |
| ... | @@ -1023,26 +1027,26 @@ pub const Instruction = union(enum) { | ... | @@ -1023,26 +1027,26 @@ pub const Instruction = union(enum) { |
| 1023 | 1027 | ||
| 1024 | pub const LoadStorePairOffset = struct { | 1028 | pub const LoadStorePairOffset = struct { |
| 1025 | encoding: enum(u2) { | 1029 | encoding: enum(u2) { |
| 1026 | PostIndex = 0b01, | 1030 | post_index = 0b01, |
| 1027 | Signed = 0b10, | 1031 | signed = 0b10, |
| 1028 | PreIndex = 0b11, | 1032 | pre_index = 0b11, |
| 1029 | }, | 1033 | }, |
| 1030 | offset: i9, | 1034 | offset: i9, |
| 1031 | 1035 | ||
| 1032 | pub fn none() LoadStorePairOffset { | 1036 | pub fn none() LoadStorePairOffset { |
| 1033 | return .{ .encoding = .Signed, .offset = 0 }; | 1037 | return .{ .encoding = .signed, .offset = 0 }; |
| 1034 | } | 1038 | } |
| 1035 | 1039 | ||
| 1036 | pub fn post_index(imm: i9) LoadStorePairOffset { | 1040 | pub fn post_index(imm: i9) LoadStorePairOffset { |
| 1037 | return .{ .encoding = .PostIndex, .offset = imm }; | 1041 | return .{ .encoding = .post_index, .offset = imm }; |
| 1038 | } | 1042 | } |
| 1039 | 1043 | ||
| 1040 | pub fn pre_index(imm: i9) LoadStorePairOffset { | 1044 | pub fn pre_index(imm: i9) LoadStorePairOffset { |
| 1041 | return .{ .encoding = .PreIndex, .offset = imm }; | 1045 | return .{ .encoding = .pre_index, .offset = imm }; |
| 1042 | } | 1046 | } |
| 1043 | 1047 | ||
| 1044 | pub fn signed(imm: i9) LoadStorePairOffset { | 1048 | pub fn signed(imm: i9) LoadStorePairOffset { |
| 1045 | return .{ .encoding = .Signed, .offset = imm }; | 1049 | return .{ .encoding = .signed, .offset = imm }; |
| 1046 | } | 1050 | } |
| 1047 | }; | 1051 | }; |
| 1048 | 1052 |