authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-03-29 08:19:52-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-05-11 02:17:11-07:00
logc0629c3539f1c944636b6cc9cb531113759b089a
tree790f5cdcec0afb95d9c586a525be77541abb1fde
parent4ce85f930e82c987c0759f528e4876fb45286389

riscv: implement `airNot`


3 files changed, 41 insertions(+), 2 deletions(-)

src/arch/riscv64/CodeGen.zig+35-1
...@@ -1036,7 +1036,41 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {...@@ -1036,7 +1036,41 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
10361036
1037fn airNot(self: *Self, inst: Air.Inst.Index) !void {1037fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1038 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1038 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1039 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement NOT for {}", .{self.target.cpu.arch});1039 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1040 const mod = self.bin_file.comp.module.?;
1041
1042 const operand = try self.resolveInst(ty_op.operand);
1043 const ty = self.typeOf(ty_op.operand);
1044
1045 switch (ty.zigTypeTag(mod)) {
1046 .Bool => {
1047 const operand_reg = blk: {
1048 if (operand == .register) break :blk operand.register;
1049 break :blk try self.copyToTmpRegister(ty, operand);
1050 };
1051
1052 const dst_reg: Register =
1053 if (self.reuseOperand(inst, ty_op.operand, 0, operand) and operand == .register)
1054 operand.register
1055 else
1056 try self.register_manager.allocReg(inst, gp);
1057
1058 _ = try self.addInst(.{
1059 .tag = .not,
1060 .data = .{
1061 .rr = .{
1062 .rs = operand_reg,
1063 .rd = dst_reg,
1064 },
1065 },
1066 });
1067
1068 break :result .{ .register = dst_reg };
1069 },
1070 .Int => return self.fail("TODO: airNot ints", .{}),
1071 else => unreachable,
1072 }
1073 };
1040 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1074 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1041}1075}
10421076
src/arch/riscv64/Emit.zig+2
...@@ -83,6 +83,7 @@ pub fn emitMir(...@@ -83,6 +83,7 @@ pub fn emitMir(
83 .j => try emit.mirPsuedo(inst),83 .j => try emit.mirPsuedo(inst),
8484
85 .mv => try emit.mirRR(inst),85 .mv => try emit.mirRR(inst),
86 .not => try emit.mirRR(inst),
8687
87 .nop => try emit.mirNop(inst),88 .nop => try emit.mirNop(inst),
88 .ret => try emit.mirNop(inst),89 .ret => try emit.mirNop(inst),
...@@ -414,6 +415,7 @@ fn mirRR(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -414,6 +415,7 @@ fn mirRR(emit: *Emit, inst: Mir.Inst.Index) !void {
414415
415 switch (tag) {416 switch (tag) {
416 .mv => try emit.writeInstruction(Instruction.addi(rd, rs, 0)),417 .mv => try emit.writeInstruction(Instruction.addi(rd, rs, 0)),
418 .not => try emit.writeInstruction(Instruction.xori(rd, rs, 1)),
417 else => unreachable,419 else => unreachable,
418 }420 }
419}421}
src/arch/riscv64/Mir.zig+4-1
...@@ -76,7 +76,7 @@ pub const Inst = struct {...@@ -76,7 +76,7 @@ pub const Inst = struct {
7676
77 /// Immediate `==`, uses i_type77 /// Immediate `==`, uses i_type
78 cmp_imm_eq,78 cmp_imm_eq,
79 /// Immediate `<=`, uses i_typei79 /// Immediate `<=`, uses i_type
80 cmp_imm_lte,80 cmp_imm_lte,
8181
82 /// Branch if equal, Uses b_type82 /// Branch if equal, Uses b_type
...@@ -84,6 +84,9 @@ pub const Inst = struct {...@@ -84,6 +84,9 @@ pub const Inst = struct {
84 /// Branch if not equal, Uses b_type84 /// Branch if not equal, Uses b_type
85 bne,85 bne,
8686
87 /// Boolean NOT, Uses rr payload
88 not,
89
87 nop,90 nop,
88 ret,91 ret,
8992