aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/aarch64.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/aarch64.zig')
-rw-r--r--src/codegen/aarch64.zig62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/codegen/aarch64.zig b/src/codegen/aarch64.zig
index 5999f8888c..e7860790f4 100644
--- a/src/codegen/aarch64.zig
+++ b/src/codegen/aarch64.zig
@@ -274,6 +274,16 @@ pub const Instruction = union(enum) {
opc: u2,
sf: u1,
},
+ AddSubtractImmediate: packed struct {
+ rd: u5,
+ rn: u5,
+ imm12: u12,
+ sh: u1,
+ fixed: u6 = 0b100010,
+ s: u1,
+ op: u1,
+ sf: u1,
+ },
pub const Shift = struct {
shift: Type = .lsl,
@@ -304,6 +314,7 @@ pub const Instruction = union(enum) {
.UnconditionalBranchImmediate => |v| @bitCast(u32, v),
.NoOperation => |v| @bitCast(u32, v),
.LogicalShiftedRegister => |v| @bitCast(u32, v),
+ .AddSubtractImmediate => |v| @bitCast(u32, v),
};
}
@@ -671,6 +682,31 @@ pub const Instruction = union(enum) {
}
}
+ fn addSubtractImmediate(
+ op: u1,
+ s: u1,
+ rd: Register,
+ rn: Register,
+ imm12: u12,
+ shift: bool,
+ ) Instruction {
+ return Instruction{
+ .AddSubtractImmediate = .{
+ .rd = rd.id(),
+ .rn = rn.id(),
+ .imm12 = imm12,
+ .sh = @boolToInt(shift),
+ .s = s,
+ .op = op,
+ .sf = switch (rd.size()) {
+ 32 => 0b0,
+ 64 => 0b1,
+ else => unreachable, // unexpected register size
+ },
+ },
+ };
+ }
+
// Helper functions for assembly syntax functions
// Move wide (immediate)
@@ -850,6 +886,24 @@ pub const Instruction = union(enum) {
pub fn bics(rd: Register, rn: Register, rm: Register, shift: Shift) Instruction {
return logicalShiftedRegister(0b11, 0b1, shift, rd, rn, rm);
}
+
+ // Add/subtract (immediate)
+
+ pub fn add(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
+ return addSubtractImmediate(0b0, 0b0, rd, rn, imm, shift);
+ }
+
+ pub fn adds(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
+ return addSubtractImmediate(0b0, 0b1, rd, rn, imm, shift);
+ }
+
+ pub fn sub(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
+ return addSubtractImmediate(0b1, 0b0, rd, rn, imm, shift);
+ }
+
+ pub fn subs(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
+ return addSubtractImmediate(0b1, 0b1, rd, rn, imm, shift);
+ }
};
test "" {
@@ -979,6 +1033,14 @@ test "serialize instructions" {
.inst = Instruction.@"and"(.x0, .x4, .x2, .{ .shift = .lsl, .amount = 0x8 }),
.expected = 0b1_00_01010_00_0_00010_001000_00100_00000,
},
+ .{ // add x0, x10, #10
+ .inst = Instruction.add(.x0, .x10, 10, false),
+ .expected = 0b1_0_0_100010_0_0000_0000_1010_01010_00000,
+ },
+ .{ // subs x0, x5, #11, lsl #12
+ .inst = Instruction.subs(.x0, .x5, 11, true),
+ .expected = 0b1_1_1_100010_1_0000_0000_1011_00101_00000,
+ },
};
for (testcases) |case| {