authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-28 19:13:15+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-05 08:56:01+01:00
loge3121accacaa2b9debaa60e0d4e8188de0b6a2f4
treeefd10cf4f4f674ed2773bddfcf2c17cad9c4d8fa
parentf2a5d0bf94897554e25e889dc1c6c4c7fc6c1217
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: introduce logical immediate instructions


4 files changed, 186 insertions(+), 40 deletions(-)

src/arch/aarch64/CodeGen.zig+81-23
...@@ -950,10 +950,69 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -950,10 +950,69 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
950 switch (operand_ty.zigTypeTag()) {950 switch (operand_ty.zigTypeTag()) {
951 .Bool => {951 .Bool => {
952 // TODO convert this to mvn + and952 // TODO convert this to mvn + and
953 const dest = try self.binOp(.xor, null, operand, .{ .immediate = 1 }, operand_ty, Type.bool);953 const op_reg = switch (operand) {
954 break :result dest;954 .register => |r| r,
955 else => try self.copyToTmpRegister(operand_ty, operand),
956 };
957 self.register_manager.freezeRegs(&.{op_reg});
958 defer self.register_manager.unfreezeRegs(&.{op_reg});
959
960 const dest_reg = blk: {
961 if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
962 break :blk op_reg;
963 }
964
965 break :blk try self.register_manager.allocReg(null);
966 };
967
968 _ = try self.addInst(.{
969 .tag = .eor_immediate,
970 .data = .{ .rr_bitmask = .{
971 .rd = dest_reg,
972 .rn = op_reg,
973 .imms = 0b000000,
974 .immr = 0b000000,
975 .n = 0b1,
976 } },
977 });
978
979 break :result MCValue{ .register = dest_reg };
980 },
981 .Vector => return self.fail("TODO bitwise not for vectors", .{}),
982 .Int => {
983 const int_info = operand_ty.intInfo(self.target.*);
984 if (int_info.bits <= 64) {
985 const op_reg = switch (operand) {
986 .register => |r| r,
987 else => try self.copyToTmpRegister(operand_ty, operand),
988 };
989 self.register_manager.freezeRegs(&.{op_reg});
990 defer self.register_manager.unfreezeRegs(&.{op_reg});
991
992 const dest_reg = blk: {
993 if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
994 break :blk op_reg;
995 }
996
997 break :blk try self.register_manager.allocReg(null);
998 };
999
1000 _ = try self.addInst(.{
1001 .tag = .mvn,
1002 .data = .{ .rr_imm6_shift = .{
1003 .rd = dest_reg,
1004 .rm = op_reg,
1005 .imm6 = 0,
1006 .shift = .lsl,
1007 } },
1008 });
1009
1010 break :result MCValue{ .register = dest_reg };
1011 } else {
1012 return self.fail("TODO AArch64 not on integers > u64/i64", .{});
1013 }
955 },1014 },
956 else => return self.fail("TODO bitwise not", .{}),1015 else => unreachable,
957 }1016 }
958 },1017 },
959 }1018 }
...@@ -1259,15 +1318,13 @@ fn binOp(...@@ -1259,15 +1318,13 @@ fn binOp(
1259 }1318 }
1260 },1319 },
1261 // Bitwise operations on integers1320 // Bitwise operations on integers
1262 .xor => {1321 .bit_and,
1322 .bit_or,
1323 .xor,
1324 => {
1263 switch (lhs_ty.zigTypeTag()) {1325 switch (lhs_ty.zigTypeTag()) {
1264 .Vector => return self.fail("TODO binary operations on vectors", .{}),1326 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1265 .Int => return self.fail("TODO binary operations on vectors", .{}),1327 .Int => return self.fail("TODO binary operations on integers", .{}),
1266 .Bool => {
1267 assert(lhs_ty.eql(rhs_ty));
1268 // TODO boolean operations with immediates
1269 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1270 },
1271 else => unreachable,1328 else => unreachable,
1272 }1329 }
1273 },1330 },
...@@ -3136,11 +3193,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3136,11 +3193,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3136 4, 8 => .str_stack,3193 4, 8 => .str_stack,
3137 else => unreachable, // unexpected abi size3194 else => unreachable, // unexpected abi size
3138 };3195 };
3139 const rt: Register = switch (abi_size) {3196 const rt = registerAlias(reg, abi_size);
3140 1, 2, 4 => reg.to32(),
3141 8 => reg.to64(),
3142 else => unreachable, // unexpected abi size
3143 };
31443197
3145 _ = try self.addInst(.{3198 _ = try self.addInst(.{
3146 .tag = tag,3199 .tag = tag,
...@@ -3622,7 +3675,6 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {...@@ -3622,7 +3675,6 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
3622fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {3675fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3623 if (typed_value.val.isUndef())3676 if (typed_value.val.isUndef())
3624 return MCValue{ .undef = {} };3677 return MCValue{ .undef = {} };
3625 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
36263678
3627 if (typed_value.val.castTag(.decl_ref)) |payload| {3679 if (typed_value.val.castTag(.decl_ref)) |payload| {
3628 return self.lowerDeclRef(typed_value, payload.data);3680 return self.lowerDeclRef(typed_value, payload.data);
...@@ -3652,13 +3704,19 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3652,13 +3704,19 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3652 },3704 },
3653 .Int => {3705 .Int => {
3654 const info = typed_value.ty.intInfo(self.target.*);3706 const info = typed_value.ty.intInfo(self.target.*);
3655 if (info.bits <= ptr_bits and info.signedness == .signed) {3707 if (info.bits <= 64) {
3656 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };3708 const unsigned = switch (info.signedness) {
3657 }3709 .signed => blk: {
3658 if (info.bits > ptr_bits or info.signedness == .signed) {3710 const signed = typed_value.val.toSignedInt();
3659 return self.fail("TODO const int bigger than ptr and signed int", .{});3711 break :blk @bitCast(u64, signed);
3712 },
3713 .unsigned => typed_value.val.toUnsignedInt(),
3714 };
3715
3716 return MCValue{ .immediate = unsigned };
3717 } else {
3718 return self.lowerUnnamedConst(typed_value);
3660 }3719 }
3661 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
3662 },3720 },
3663 .Bool => {3721 .Bool => {
3664 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };3722 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };
...@@ -3875,7 +3933,7 @@ fn parseRegName(name: []const u8) ?Register {...@@ -3875,7 +3933,7 @@ fn parseRegName(name: []const u8) ?Register {
3875 return std.meta.stringToEnum(Register, name);3933 return std.meta.stringToEnum(Register, name);
3876}3934}
38773935
3878fn registerAlias(reg: Register, size_bytes: u32) Register {3936fn registerAlias(reg: Register, size_bytes: u64) Register {
3879 if (size_bytes == 0) {3937 if (size_bytes == 0) {
3880 unreachable; // should be comptime known3938 unreachable; // should be comptime known
3881 } else if (size_bytes <= 4) {3939 } else if (size_bytes <= 4) {
src/arch/aarch64/Emit.zig+20-3
...@@ -95,6 +95,8 @@ pub fn emitMir(...@@ -95,6 +95,8 @@ pub fn emitMir(
9595
96 .call_extern => try emit.mirCallExtern(inst),96 .call_extern => try emit.mirCallExtern(inst),
9797
98 .eor_immediate => try emit.mirLogicalImmediate(inst),
99
98 .add_shifted_register => try emit.mirAddSubtractShiftedRegister(inst),100 .add_shifted_register => try emit.mirAddSubtractShiftedRegister(inst),
99 .cmp_shifted_register => try emit.mirAddSubtractShiftedRegister(inst),101 .cmp_shifted_register => try emit.mirAddSubtractShiftedRegister(inst),
100 .sub_shifted_register => try emit.mirAddSubtractShiftedRegister(inst),102 .sub_shifted_register => try emit.mirAddSubtractShiftedRegister(inst),
...@@ -605,6 +607,21 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -605,6 +607,21 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
605 }607 }
606}608}
607609
610fn mirLogicalImmediate(emit: *Emit, inst: Mir.Inst.Index) !void {
611 const tag = emit.mir.instructions.items(.tag)[inst];
612 const rr_bitmask = emit.mir.instructions.items(.data)[inst].rr_bitmask;
613 const rd = rr_bitmask.rd;
614 const rn = rr_bitmask.rn;
615 const imms = rr_bitmask.imms;
616 const immr = rr_bitmask.immr;
617 const n = rr_bitmask.n;
618
619 switch (tag) {
620 .eor_immediate => try emit.writeInstruction(Instruction.eorImmediate(rd, rn, imms, immr, n)),
621 else => unreachable,
622 }
623}
624
608fn mirAddSubtractShiftedRegister(emit: *Emit, inst: Mir.Inst.Index) !void {625fn mirAddSubtractShiftedRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
609 const tag = emit.mir.instructions.items(.tag)[inst];626 const tag = emit.mir.instructions.items(.tag)[inst];
610 const rrr_imm6_shift = emit.mir.instructions.items(.data)[inst].rrr_imm6_shift;627 const rrr_imm6_shift = emit.mir.instructions.items(.data)[inst].rrr_imm6_shift;
...@@ -643,7 +660,7 @@ fn mirLogicalShiftedRegister(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -643,7 +660,7 @@ fn mirLogicalShiftedRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
643 const imm6 = rrr_imm6_logical_shift.imm6;660 const imm6 = rrr_imm6_logical_shift.imm6;
644661
645 switch (tag) {662 switch (tag) {
646 .eor_shifted_register => try emit.writeInstruction(Instruction.eor(rd, rn, rm, shift, imm6)),663 .eor_shifted_register => try emit.writeInstruction(Instruction.eorShiftedRegister(rd, rn, rm, shift, imm6)),
647 else => unreachable,664 else => unreachable,
648 }665 }
649}666}
...@@ -844,7 +861,7 @@ fn mirMoveRegister(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -844,7 +861,7 @@ fn mirMoveRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
844 switch (tag) {861 switch (tag) {
845 .mov_register => {862 .mov_register => {
846 const rr = emit.mir.instructions.items(.data)[inst].rr;863 const rr = emit.mir.instructions.items(.data)[inst].rr;
847 try emit.writeInstruction(Instruction.orr(rr.rd, .xzr, rr.rn, .lsl, 0));864 try emit.writeInstruction(Instruction.orrShiftedRegister(rr.rd, .xzr, rr.rn, .lsl, 0));
848 },865 },
849 .mov_to_from_sp => {866 .mov_to_from_sp => {
850 const rr = emit.mir.instructions.items(.data)[inst].rr;867 const rr = emit.mir.instructions.items(.data)[inst].rr;
...@@ -852,7 +869,7 @@ fn mirMoveRegister(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -852,7 +869,7 @@ fn mirMoveRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
852 },869 },
853 .mvn => {870 .mvn => {
854 const rr_imm6_shift = emit.mir.instructions.items(.data)[inst].rr_imm6_shift;871 const rr_imm6_shift = emit.mir.instructions.items(.data)[inst].rr_imm6_shift;
855 try emit.writeInstruction(Instruction.orn(rr_imm6_shift.rd, .xzr, rr_imm6_shift.rm, .lsl, 0));872 try emit.writeInstruction(Instruction.ornShiftedRegister(rr_imm6_shift.rd, .xzr, rr_imm6_shift.rm, rr_imm6_shift.shift, rr_imm6_shift.imm6));
856 },873 },
857 else => unreachable,874 else => unreachable,
858 }875 }
src/arch/aarch64/Mir.zig+15-2
...@@ -54,6 +54,8 @@ pub const Inst = struct {...@@ -54,6 +54,8 @@ pub const Inst = struct {
54 dbg_epilogue_begin,54 dbg_epilogue_begin,
55 /// Pseudo-instruction: Update debug line55 /// Pseudo-instruction: Update debug line
56 dbg_line,56 dbg_line,
57 /// Bitwise Exclusive OR (immediate)
58 eor_immediate,
57 /// Bitwise Exclusive OR (shifted register)59 /// Bitwise Exclusive OR (shifted register)
58 eor_shifted_register,60 eor_shifted_register,
59 /// Loads the contents into a register61 /// Loads the contents into a register
...@@ -231,14 +233,25 @@ pub const Inst = struct {...@@ -231,14 +233,25 @@ pub const Inst = struct {
231 imm12: u12,233 imm12: u12,
232 sh: u1 = 0,234 sh: u1 = 0,
233 },235 },
234 /// Two registers and a shift (shift type and 6-bit amount)236 /// Two registers and a shift (logical instruction version)
237 /// (shift type and 6-bit amount)
235 ///238 ///
236 /// Used by e.g. mvn239 /// Used by e.g. mvn
237 rr_imm6_shift: struct {240 rr_imm6_shift: struct {
238 rd: Register,241 rd: Register,
239 rm: Register,242 rm: Register,
240 imm6: u6,243 imm6: u6,
241 shift: bits.Instruction.AddSubtractShiftedRegisterShift,244 shift: bits.Instruction.LogicalShiftedRegisterShift,
245 },
246 /// Two registers and a bitmask immediate
247 ///
248 /// Used by e.g. eor_immediate
249 rr_bitmask: struct {
250 rd: Register,
251 rn: Register,
252 imms: u6,
253 immr: u6,
254 n: u1,
242 },255 },
243 /// Two registers256 /// Two registers
244 ///257 ///
src/arch/aarch64/bits.zig+70-12
...@@ -323,6 +323,16 @@ pub const Instruction = union(enum) {...@@ -323,6 +323,16 @@ pub const Instruction = union(enum) {
323 op: u1,323 op: u1,
324 sf: u1,324 sf: u1,
325 },325 },
326 logical_immediate: packed struct {
327 rd: u5,
328 rn: u5,
329 imms: u6,
330 immr: u6,
331 n: u1,
332 fixed: u6 = 0b100100,
333 opc: u2,
334 sf: u1,
335 },
326 add_subtract_shifted_register: packed struct {336 add_subtract_shifted_register: packed struct {
327 rd: u5,337 rd: u5,
328 rn: u5,338 rn: u5,
...@@ -487,6 +497,7 @@ pub const Instruction = union(enum) {...@@ -487,6 +497,7 @@ pub const Instruction = union(enum) {
487 .no_operation => |v| @bitCast(u32, v),497 .no_operation => |v| @bitCast(u32, v),
488 .logical_shifted_register => |v| @bitCast(u32, v),498 .logical_shifted_register => |v| @bitCast(u32, v),
489 .add_subtract_immediate => |v| @bitCast(u32, v),499 .add_subtract_immediate => |v| @bitCast(u32, v),
500 .logical_immediate => |v| @bitCast(u32, v),
490 .add_subtract_shifted_register => |v| @bitCast(u32, v),501 .add_subtract_shifted_register => |v| @bitCast(u32, v),
491 // TODO once packed structs work, this can be refactored502 // TODO once packed structs work, this can be refactored
492 .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),503 .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),
...@@ -900,6 +911,31 @@ pub const Instruction = union(enum) {...@@ -900,6 +911,31 @@ pub const Instruction = union(enum) {
900 };911 };
901 }912 }
902913
914 fn logicalImmediate(
915 opc: u2,
916 rd: Register,
917 rn: Register,
918 imms: u6,
919 immr: u6,
920 n: u1,
921 ) Instruction {
922 return Instruction{
923 .logical_immediate = .{
924 .rd = rd.enc(),
925 .rn = rn.enc(),
926 .imms = imms,
927 .immr = immr,
928 .n = n,
929 .opc = opc,
930 .sf = switch (rd.size()) {
931 32 => 0b0,
932 64 => 0b1,
933 else => unreachable, // unexpected register size
934 },
935 },
936 };
937 }
938
903 pub const AddSubtractShiftedRegisterShift = enum(u2) { lsl, lsr, asr, _ };939 pub const AddSubtractShiftedRegisterShift = enum(u2) { lsl, lsr, asr, _ };
904940
905 fn addSubtractShiftedRegister(941 fn addSubtractShiftedRegister(
...@@ -1173,7 +1209,7 @@ pub const Instruction = union(enum) {...@@ -1173,7 +1209,7 @@ pub const Instruction = union(enum) {
11731209
1174 // Logical (shifted register)1210 // Logical (shifted register)
11751211
1176 pub fn @"and"(1212 pub fn andShiftedRegister(
1177 rd: Register,1213 rd: Register,
1178 rn: Register,1214 rn: Register,
1179 rm: Register,1215 rm: Register,
...@@ -1183,7 +1219,7 @@ pub const Instruction = union(enum) {...@@ -1183,7 +1219,7 @@ pub const Instruction = union(enum) {
1183 return logicalShiftedRegister(0b00, 0b0, rd, rn, rm, shift, amount);1219 return logicalShiftedRegister(0b00, 0b0, rd, rn, rm, shift, amount);
1184 }1220 }
11851221
1186 pub fn bic(1222 pub fn bicShiftedRegister(
1187 rd: Register,1223 rd: Register,
1188 rn: Register,1224 rn: Register,
1189 rm: Register,1225 rm: Register,
...@@ -1193,7 +1229,7 @@ pub const Instruction = union(enum) {...@@ -1193,7 +1229,7 @@ pub const Instruction = union(enum) {
1193 return logicalShiftedRegister(0b00, 0b1, rd, rn, rm, shift, amount);1229 return logicalShiftedRegister(0b00, 0b1, rd, rn, rm, shift, amount);
1194 }1230 }
11951231
1196 pub fn orr(1232 pub fn orrShiftedRegister(
1197 rd: Register,1233 rd: Register,
1198 rn: Register,1234 rn: Register,
1199 rm: Register,1235 rm: Register,
...@@ -1203,7 +1239,7 @@ pub const Instruction = union(enum) {...@@ -1203,7 +1239,7 @@ pub const Instruction = union(enum) {
1203 return logicalShiftedRegister(0b01, 0b0, rd, rn, rm, shift, amount);1239 return logicalShiftedRegister(0b01, 0b0, rd, rn, rm, shift, amount);
1204 }1240 }
12051241
1206 pub fn orn(1242 pub fn ornShiftedRegister(
1207 rd: Register,1243 rd: Register,
1208 rn: Register,1244 rn: Register,
1209 rm: Register,1245 rm: Register,
...@@ -1213,7 +1249,7 @@ pub const Instruction = union(enum) {...@@ -1213,7 +1249,7 @@ pub const Instruction = union(enum) {
1213 return logicalShiftedRegister(0b01, 0b1, rd, rn, rm, shift, amount);1249 return logicalShiftedRegister(0b01, 0b1, rd, rn, rm, shift, amount);
1214 }1250 }
12151251
1216 pub fn eor(1252 pub fn eorShiftedRegister(
1217 rd: Register,1253 rd: Register,
1218 rn: Register,1254 rn: Register,
1219 rm: Register,1255 rm: Register,
...@@ -1223,7 +1259,7 @@ pub const Instruction = union(enum) {...@@ -1223,7 +1259,7 @@ pub const Instruction = union(enum) {
1223 return logicalShiftedRegister(0b10, 0b0, rd, rn, rm, shift, amount);1259 return logicalShiftedRegister(0b10, 0b0, rd, rn, rm, shift, amount);
1224 }1260 }
12251261
1226 pub fn eon(1262 pub fn eonShiftedRegister(
1227 rd: Register,1263 rd: Register,
1228 rn: Register,1264 rn: Register,
1229 rm: Register,1265 rm: Register,
...@@ -1233,7 +1269,7 @@ pub const Instruction = union(enum) {...@@ -1233,7 +1269,7 @@ pub const Instruction = union(enum) {
1233 return logicalShiftedRegister(0b10, 0b1, rd, rn, rm, shift, amount);1269 return logicalShiftedRegister(0b10, 0b1, rd, rn, rm, shift, amount);
1234 }1270 }
12351271
1236 pub fn ands(1272 pub fn andsShiftedRegister(
1237 rd: Register,1273 rd: Register,
1238 rn: Register,1274 rn: Register,
1239 rm: Register,1275 rm: Register,
...@@ -1243,7 +1279,7 @@ pub const Instruction = union(enum) {...@@ -1243,7 +1279,7 @@ pub const Instruction = union(enum) {
1243 return logicalShiftedRegister(0b11, 0b0, rd, rn, rm, shift, amount);1279 return logicalShiftedRegister(0b11, 0b0, rd, rn, rm, shift, amount);
1244 }1280 }
12451281
1246 pub fn bics(1282 pub fn bicsShiftedRegister(
1247 rd: Register,1283 rd: Register,
1248 rn: Register,1284 rn: Register,
1249 rm: Register,1285 rm: Register,
...@@ -1271,6 +1307,24 @@ pub const Instruction = union(enum) {...@@ -1271,6 +1307,24 @@ pub const Instruction = union(enum) {
1271 return addSubtractImmediate(0b1, 0b1, rd, rn, imm, shift);1307 return addSubtractImmediate(0b1, 0b1, rd, rn, imm, shift);
1272 }1308 }
12731309
1310 // Logical (immediate)
1311
1312 pub fn andImmediate(rd: Register, rn: Register, imms: u6, immr: u6, n: u1) Instruction {
1313 return logicalImmediate(0b00, rd, rn, imms, immr, n);
1314 }
1315
1316 pub fn orrImmediate(rd: Register, rn: Register, imms: u6, immr: u6, n: u1) Instruction {
1317 return logicalImmediate(0b01, rd, rn, imms, immr, n);
1318 }
1319
1320 pub fn eorImmediate(rd: Register, rn: Register, imms: u6, immr: u6, n: u1) Instruction {
1321 return logicalImmediate(0b10, rd, rn, imms, immr, n);
1322 }
1323
1324 pub fn andsImmediate(rd: Register, rn: Register, imms: u6, immr: u6, n: u1) Instruction {
1325 return logicalImmediate(0b11, rd, rn, imms, immr, n);
1326 }
1327
1274 // Add/subtract (shifted register)1328 // Add/subtract (shifted register)
12751329
1276 pub fn addShiftedRegister(1330 pub fn addShiftedRegister(
...@@ -1378,11 +1432,11 @@ test "serialize instructions" {...@@ -1378,11 +1432,11 @@ test "serialize instructions" {
13781432
1379 const testcases = [_]Testcase{1433 const testcases = [_]Testcase{
1380 .{ // orr x0, xzr, x11434 .{ // orr x0, xzr, x1
1381 .inst = Instruction.orr(.x0, .xzr, .x1, .lsl, 0),1435 .inst = Instruction.orrShiftedRegister(.x0, .xzr, .x1, .lsl, 0),
1382 .expected = 0b1_01_01010_00_0_00001_000000_11111_00000,1436 .expected = 0b1_01_01010_00_0_00001_000000_11111_00000,
1383 },1437 },
1384 .{ // orn x0, xzr, x11438 .{ // orn x0, xzr, x1
1385 .inst = Instruction.orn(.x0, .xzr, .x1, .lsl, 0),1439 .inst = Instruction.ornShiftedRegister(.x0, .xzr, .x1, .lsl, 0),
1386 .expected = 0b1_01_01010_00_1_00001_000000_11111_00000,1440 .expected = 0b1_01_01010_00_1_00001_000000_11111_00000,
1387 },1441 },
1388 .{ // movz x1, #41442 .{ // movz x1, #4
...@@ -1502,11 +1556,11 @@ test "serialize instructions" {...@@ -1502,11 +1556,11 @@ test "serialize instructions" {
1502 .expected = 0b10_101_0_001_1_0000010_00010_11111_00001,1556 .expected = 0b10_101_0_001_1_0000010_00010_11111_00001,
1503 },1557 },
1504 .{ // and x0, x4, x21558 .{ // and x0, x4, x2
1505 .inst = Instruction.@"and"(.x0, .x4, .x2, .lsl, 0),1559 .inst = Instruction.andShiftedRegister(.x0, .x4, .x2, .lsl, 0),
1506 .expected = 0b1_00_01010_00_0_00010_000000_00100_00000,1560 .expected = 0b1_00_01010_00_0_00010_000000_00100_00000,
1507 },1561 },
1508 .{ // and x0, x4, x2, lsl #0x81562 .{ // and x0, x4, x2, lsl #0x8
1509 .inst = Instruction.@"and"(.x0, .x4, .x2, .lsl, 0x8),1563 .inst = Instruction.andShiftedRegister(.x0, .x4, .x2, .lsl, 0x8),
1510 .expected = 0b1_00_01010_00_0_00010_001000_00100_00000,1564 .expected = 0b1_00_01010_00_0_00010_001000_00100_00000,
1511 },1565 },
1512 .{ // add x0, x10, #101566 .{ // add x0, x10, #10
...@@ -1537,6 +1591,10 @@ test "serialize instructions" {...@@ -1537,6 +1591,10 @@ test "serialize instructions" {
1537 .inst = Instruction.mul(.x1, .x4, .x9),1591 .inst = Instruction.mul(.x1, .x4, .x9),
1538 .expected = 0b1_00_11011_000_01001_0_11111_00100_00001,1592 .expected = 0b1_00_11011_000_01001_0_11111_00100_00001,
1539 },1593 },
1594 .{ // eor x3, x5, #1
1595 .inst = Instruction.eorImmediate(.x3, .x5, 0b000000, 0b000000, 0b1),
1596 .expected = 0b1_10_100100_1_000000_000000_00101_00011,
1597 },
1540 };1598 };
15411599
1542 for (testcases) |case| {1600 for (testcases) |case| {