| author | |
| committer | |
| log | c0629c3539f1c944636b6cc9cb531113759b089a |
| tree | 790f5cdcec0afb95d9c586a525be77541abb1fde |
| parent | 4ce85f930e82c987c0759f528e4876fb45286389 |
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 { |
| 1036 | 1036 | ||
| 1037 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { | 1037 | fn 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 | } |
| 1042 | 1076 |
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), |
| 84 | 84 | ||
| 85 | .mv => try emit.mirRR(inst), | 85 | .mv => try emit.mirRR(inst), |
| 86 | .not => try emit.mirRR(inst), | ||
| 86 | 87 | ||
| 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 { |
| 414 | 415 | ||
| 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 { |
| 76 | 76 | ||
| 77 | /// Immediate `==`, uses i_type | 77 | /// Immediate `==`, uses i_type |
| 78 | cmp_imm_eq, | 78 | cmp_imm_eq, |
| 79 | /// Immediate `<=`, uses i_typei | 79 | /// Immediate `<=`, uses i_type |
| 80 | cmp_imm_lte, | 80 | cmp_imm_lte, |
| 81 | 81 | ||
| 82 | /// Branch if equal, Uses b_type | 82 | /// 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_type | 84 | /// Branch if not equal, Uses b_type |
| 85 | bne, | 85 | bne, |
| 86 | 86 | ||
| 87 | /// Boolean NOT, Uses rr payload | ||
| 88 | not, | ||
| 89 | |||
| 87 | nop, | 90 | nop, |
| 88 | ret, | 91 | ret, |
| 89 | 92 |