diff options
| author | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2021-11-07 15:41:28 +0100 |
|---|---|---|
| committer | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2021-11-10 19:48:16 +0100 |
| commit | 8cb00519cddadae8728d2b2e51a36da71d5bfe67 (patch) | |
| tree | ead57c6ffab5f925d6e5a5897087fcb11c3ce7ef /src/arch/aarch64/bits.zig | |
| parent | e5bc092408d7a02b74011e07beaee3c98ec9a268 (diff) | |
| download | zig-8cb00519cddadae8728d2b2e51a36da71d5bfe67.tar.gz zig-8cb00519cddadae8728d2b2e51a36da71d5bfe67.zip | |
stage2 AArch64: implement airCmp
Diffstat (limited to 'src/arch/aarch64/bits.zig')
| -rw-r--r-- | src/arch/aarch64/bits.zig | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/arch/aarch64/bits.zig b/src/arch/aarch64/bits.zig index f751170818..740cbdd3de 100644 --- a/src/arch/aarch64/bits.zig +++ b/src/arch/aarch64/bits.zig @@ -295,6 +295,18 @@ pub const Instruction = union(enum) { op: u1, sf: u1, }, + add_subtract_shifted_register: packed struct { + rd: u5, + rn: u5, + imm6: u6, + rm: u5, + fixed_1: u1 = 0b0, + shift: u2, + fixed_2: u5 = 0b01011, + s: u1, + op: u1, + sf: u1, + }, conditional_branch: struct { cond: u4, o0: u1, @@ -391,6 +403,7 @@ pub const Instruction = union(enum) { .no_operation => |v| @bitCast(u32, v), .logical_shifted_register => |v| @bitCast(u32, v), .add_subtract_immediate => |v| @bitCast(u32, v), + .add_subtract_shifted_register => |v| @bitCast(u32, v), // TODO once packed structs work, this can be refactored .conditional_branch => |v| @as(u32, v.cond) | (@as(u32, v.o0) << 4) | (@as(u32, v.imm19) << 5) | (@as(u32, v.o1) << 24) | (@as(u32, v.fixed) << 25), .compare_and_branch => |v| @as(u32, v.rt) | (@as(u32, v.imm19) << 5) | (@as(u32, v.op) << 24) | (@as(u32, v.fixed) << 25) | (@as(u32, v.sf) << 31), @@ -804,6 +817,35 @@ pub const Instruction = union(enum) { }; } + pub const AddSubtractShiftedRegisterShift = enum(u2) { lsl, lsr, asr, _ }; + + fn addSubtractShiftedRegister( + op: u1, + s: u1, + shift: AddSubtractShiftedRegisterShift, + rd: Register, + rn: Register, + rm: Register, + imm6: u6, + ) Instruction { + return Instruction{ + .add_subtract_shifted_register = .{ + .rd = rd.id(), + .rn = rn.id(), + .imm6 = imm6, + .rm = rm.id(), + .shift = @enumToInt(shift), + .s = s, + .op = op, + .sf = switch (rd.size()) { + 32 => 0b0, + 64 => 0b1, + else => unreachable, // unexpected register size + }, + }, + }; + } + fn conditionalBranch( o0: u1, o1: u1, @@ -1055,6 +1097,48 @@ pub const Instruction = union(enum) { return addSubtractImmediate(0b1, 0b1, rd, rn, imm, shift); } + // Add/subtract (shifted register) + + pub fn addShiftedRegister( + rd: Register, + rn: Register, + rm: Register, + shift: AddSubtractShiftedRegisterShift, + imm6: u6, + ) Instruction { + return addSubtractShiftedRegister(0b0, 0b0, shift, rd, rn, rm, imm6); + } + + pub fn addsShiftedRegister( + rd: Register, + rn: Register, + rm: Register, + shift: AddSubtractShiftedRegisterShift, + imm6: u6, + ) Instruction { + return addSubtractShiftedRegister(0b0, 0b1, shift, rd, rn, rm, imm6); + } + + pub fn subShiftedRegister( + rd: Register, + rn: Register, + rm: Register, + shift: AddSubtractShiftedRegisterShift, + imm6: u6, + ) Instruction { + return addSubtractShiftedRegister(0b1, 0b0, shift, rd, rn, rm, imm6); + } + + pub fn subsShiftedRegister( + rd: Register, + rn: Register, + rm: Register, + shift: AddSubtractShiftedRegisterShift, + imm6: u6, + ) Instruction { + return addSubtractShiftedRegister(0b1, 0b1, shift, rd, rn, rm, imm6); + } + // Conditional branch pub fn bCond(cond: Condition, offset: i21) Instruction { @@ -1231,6 +1315,10 @@ test "serialize instructions" { .inst = Instruction.cbz(.x10, 40), .expected = 0b1_011010_0_0000000000000001010_01010, }, + .{ // add x0, x1, x2, lsl #5 + .inst = Instruction.addShiftedRegister(.x0, .x1, .x2, .lsl, 5), + .expected = 0b1_0_0_01011_00_0_00010_000101_00001_00000, + }, }; for (testcases) |case| { |
