Commit 28df64cba4
Changed files (6)
lib
std
src
arch
lib/std/builtin.zig
@@ -760,9 +760,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
@setCold(true);
// stage2_riscv64 backend doesn't support loops yet.
- if (builtin.zig_backend == .stage2_riscv64 or
- builtin.cpu.arch == .riscv64)
- {
+ if (builtin.zig_backend == .stage2_riscv64) {
unreachable;
}
src/arch/riscv64/bits.zig
@@ -250,7 +250,7 @@ pub const Instruction = union(enum) {
}
pub fn srai(rd: Register, r1: Register, shamt: u6) Instruction {
- return iType(0b0010011, 0b101, rd, r1, (1 << 10) + shamt);
+ return iType(0b0010011, 0b101, rd, r1, (@as(i12, 1) << 10) + shamt);
}
pub fn slti(rd: Register, r1: Register, imm: i12) Instruction {
@@ -267,16 +267,16 @@ pub const Instruction = union(enum) {
return iType(0b0011011, 0b000, rd, r1, imm);
}
- pub fn slliw(rd: Register, r1: Register, shamt: u5) Instruction {
+ pub fn slliw(rd: Register, r1: Register, shamt: u6) Instruction {
return iType(0b0011011, 0b001, rd, r1, shamt);
}
- pub fn srliw(rd: Register, r1: Register, shamt: u5) Instruction {
+ pub fn srliw(rd: Register, r1: Register, shamt: u6) Instruction {
return iType(0b0011011, 0b101, rd, r1, shamt);
}
- pub fn sraiw(rd: Register, r1: Register, shamt: u5) Instruction {
- return iType(0b0011011, 0b101, rd, r1, (1 << 10) + shamt);
+ pub fn sraiw(rd: Register, r1: Register, shamt: u6) Instruction {
+ return iType(0b0011011, 0b101, rd, r1, (@as(i12, 1) << 10) + shamt);
}
// Upper Immediate
src/arch/riscv64/CodeGen.zig
@@ -1385,8 +1385,44 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.comp.module.?;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
- const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airAbs for {}", .{self.target.cpu.arch});
+ const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
+ const ty = self.typeOf(ty_op.operand);
+ const scalar_ty = ty.scalarType(mod);
+ const operand = try self.resolveInst(ty_op.operand);
+
+ switch (scalar_ty.zigTypeTag(mod)) {
+ .Int => if (ty.zigTypeTag(mod) == .Vector) {
+ return self.fail("TODO implement airAbs for {}", .{ty.fmt(mod)});
+ } else {
+ const int_bits = ty.intInfo(mod).bits;
+
+ if (int_bits > 32) {
+ return self.fail("TODO: airAbs for larger than 32 bits", .{});
+ }
+
+ // promote the src into a register
+ const src_mcv = try self.copyToNewRegister(inst, operand);
+ // temp register for shift
+ const temp_reg = try self.register_manager.allocReg(inst, gp);
+
+ _ = try self.addInst(.{
+ .tag = .abs,
+ .data = .{
+ .i_type = .{
+ .rs1 = src_mcv.register,
+ .rd = temp_reg,
+ .imm12 = @intCast(int_bits - 1),
+ },
+ },
+ });
+
+ break :result src_mcv;
+ },
+ else => return self.fail("TODO: implement airAbs {}", .{scalar_ty.fmt(mod)}),
+ }
+ };
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@@ -1603,8 +1639,6 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
self.register_manager.getRegAssumeFree(src_reg, inst);
break :dst src_mcv;
},
- // don't need to allocate anything, can just be used immediately.
- .stack_offset => src_mcv,
else => return self.fail("TODO: airArg {s}", .{@tagName(src_mcv)}),
};
src/arch/riscv64/Emit.zig
@@ -58,6 +58,7 @@ pub fn emitMir(
.addi => try emit.mirIType(inst),
.jalr => try emit.mirIType(inst),
+ .abs => try emit.mirIType(inst),
.jal => try emit.mirJType(inst),
@@ -200,6 +201,12 @@ fn mirIType(emit: *Emit, inst: Mir.Inst.Index) !void {
.ldr_ptr_stack => try emit.writeInstruction(Instruction.add(i_type.rd, i_type.rs1, .sp)),
+ .abs => {
+ try emit.writeInstruction(Instruction.sraiw(i_type.rd, i_type.rs1, @intCast(i_type.imm12)));
+ try emit.writeInstruction(Instruction.xor(i_type.rs1, i_type.rs1, i_type.rd));
+ try emit.writeInstruction(Instruction.subw(i_type.rs1, i_type.rs1, i_type.rd));
+ },
+
else => unreachable,
}
}
src/arch/riscv64/Mir.zig
@@ -38,6 +38,9 @@ pub const Inst = struct {
/// Subtraction
sub,
+ /// Absolute Value, uses i_type payload.
+ abs,
+
jal,
/// Jumps. Uses `inst` payload.
j,
src/target.zig
@@ -507,7 +507,7 @@ pub fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBacken
if (use_llvm) return .stage2_llvm;
if (target.ofmt == .c) return .stage2_c;
return switch (target.cpu.arch) {
- .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm,
+ .wasm32, .wasm64 => .stage2_wasm,
.arm, .armeb, .thumb, .thumbeb => .stage2_arm,
.x86_64 => .stage2_x86_64,
.x86 => .stage2_x86,