authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-01-17 22:40:14+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-01-17 22:40:14+01:00
logea6f3e3fd1ea47f7e5234852dccd7e988ba42b6d
tree9154c92e58225ef52d5bcf47792081393d63ec13
parentc6cb02c2265f181baaae4d57679baa8306431c11
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: add add/subtract (immediate) instructions


1 files changed, 62 insertions(+), 0 deletions(-)

src/codegen/aarch64.zig+62
......@@ -274,6 +274,16 @@ pub const Instruction = union(enum) {
274274 opc: u2,
275275 sf: u1,
276276 },
277 AddSubtractImmediate: packed struct {
278 rd: u5,
279 rn: u5,
280 imm12: u12,
281 sh: u1,
282 fixed: u6 = 0b100010,
283 s: u1,
284 op: u1,
285 sf: u1,
286 },
277287
278288 pub const Shift = struct {
279289 shift: Type = .lsl,
......@@ -304,6 +314,7 @@ pub const Instruction = union(enum) {
304314 .UnconditionalBranchImmediate => |v| @bitCast(u32, v),
305315 .NoOperation => |v| @bitCast(u32, v),
306316 .LogicalShiftedRegister => |v| @bitCast(u32, v),
317 .AddSubtractImmediate => |v| @bitCast(u32, v),
307318 };
308319 }
309320
......@@ -671,6 +682,31 @@ pub const Instruction = union(enum) {
671682 }
672683 }
673684
685 fn addSubtractImmediate(
686 op: u1,
687 s: u1,
688 rd: Register,
689 rn: Register,
690 imm12: u12,
691 shift: bool,
692 ) Instruction {
693 return Instruction{
694 .AddSubtractImmediate = .{
695 .rd = rd.id(),
696 .rn = rn.id(),
697 .imm12 = imm12,
698 .sh = @boolToInt(shift),
699 .s = s,
700 .op = op,
701 .sf = switch (rd.size()) {
702 32 => 0b0,
703 64 => 0b1,
704 else => unreachable, // unexpected register size
705 },
706 },
707 };
708 }
709
674710 // Helper functions for assembly syntax functions
675711
676712 // Move wide (immediate)
......@@ -850,6 +886,24 @@ pub const Instruction = union(enum) {
850886 pub fn bics(rd: Register, rn: Register, rm: Register, shift: Shift) Instruction {
851887 return logicalShiftedRegister(0b11, 0b1, shift, rd, rn, rm);
852888 }
889
890 // Add/subtract (immediate)
891
892 pub fn add(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
893 return addSubtractImmediate(0b0, 0b0, rd, rn, imm, shift);
894 }
895
896 pub fn adds(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
897 return addSubtractImmediate(0b0, 0b1, rd, rn, imm, shift);
898 }
899
900 pub fn sub(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
901 return addSubtractImmediate(0b1, 0b0, rd, rn, imm, shift);
902 }
903
904 pub fn subs(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
905 return addSubtractImmediate(0b1, 0b1, rd, rn, imm, shift);
906 }
853907};
854908
855909test "" {
......@@ -979,6 +1033,14 @@ test "serialize instructions" {
9791033 .inst = Instruction.@"and"(.x0, .x4, .x2, .{ .shift = .lsl, .amount = 0x8 }),
9801034 .expected = 0b1_00_01010_00_0_00010_001000_00100_00000,
9811035 },
1036 .{ // add x0, x10, #10
1037 .inst = Instruction.add(.x0, .x10, 10, false),
1038 .expected = 0b1_0_0_100010_0_0000_0000_1010_01010_00000,
1039 },
1040 .{ // subs x0, x5, #11, lsl #12
1041 .inst = Instruction.subs(.x0, .x5, 11, true),
1042 .expected = 0b1_1_1_100010_1_0000_0000_1011_00101_00000,
1043 },
9821044 };
9831045
9841046 for (testcases) |case| {