mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
riscv: back to hello world panics
This commit is contained in:
parent
cc204e2365
commit
d19b77d63f
@ -775,7 +775,15 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (builtin.zig_backend == .stage2_riscv64) {
|
if (builtin.zig_backend == .stage2_riscv64) {
|
||||||
unreachable;
|
asm volatile ("ecall"
|
||||||
|
:
|
||||||
|
: [number] "{a7}" (64),
|
||||||
|
[arg1] "{a0}" (1),
|
||||||
|
[arg2] "{a1}" (@intFromPtr(msg.ptr)),
|
||||||
|
[arg3] "{a2}" (msg.len),
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
std.posix.exit(127);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (builtin.os.tag) {
|
switch (builtin.os.tag) {
|
||||||
|
|||||||
@ -1513,7 +1513,7 @@ fn splitType(self: *Self, ty: Type) ![2]Type {
|
|||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
},
|
},
|
||||||
else => break,
|
else => return self.fail("TODO: splitType class {}", .{class}),
|
||||||
};
|
};
|
||||||
} else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts;
|
} else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts;
|
||||||
return self.fail("TODO implement splitType for {}", .{ty.fmt(zcu)});
|
return self.fail("TODO implement splitType for {}", .{ty.fmt(zcu)});
|
||||||
@ -3434,6 +3434,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
|||||||
const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
|
const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
|
||||||
const src_mcv = self.args[arg_index];
|
const src_mcv = self.args[arg_index];
|
||||||
|
|
||||||
|
const arg_ty = self.typeOfIndex(inst);
|
||||||
|
|
||||||
const dst_mcv = switch (src_mcv) {
|
const dst_mcv = switch (src_mcv) {
|
||||||
.register => dst: {
|
.register => dst: {
|
||||||
const frame = try self.allocFrameIndex(FrameAlloc.init(.{
|
const frame = try self.allocFrameIndex(FrameAlloc.init(.{
|
||||||
@ -3441,9 +3443,16 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
|||||||
.alignment = Type.usize.abiAlignment(zcu),
|
.alignment = Type.usize.abiAlignment(zcu),
|
||||||
}));
|
}));
|
||||||
const dst_mcv: MCValue = .{ .load_frame = .{ .index = frame } };
|
const dst_mcv: MCValue = .{ .load_frame = .{ .index = frame } };
|
||||||
|
|
||||||
try self.genCopy(Type.usize, dst_mcv, src_mcv);
|
try self.genCopy(Type.usize, dst_mcv, src_mcv);
|
||||||
|
break :dst dst_mcv;
|
||||||
|
},
|
||||||
|
.register_pair => dst: {
|
||||||
|
const frame = try self.allocFrameIndex(FrameAlloc.init(.{
|
||||||
|
.size = Type.usize.abiSize(zcu) * 2,
|
||||||
|
.alignment = Type.usize.abiAlignment(zcu),
|
||||||
|
}));
|
||||||
|
const dst_mcv: MCValue = .{ .load_frame = .{ .index = frame } };
|
||||||
|
try self.genCopy(arg_ty, dst_mcv, src_mcv);
|
||||||
break :dst dst_mcv;
|
break :dst dst_mcv;
|
||||||
},
|
},
|
||||||
.load_frame => src_mcv,
|
.load_frame => src_mcv,
|
||||||
@ -4506,6 +4515,17 @@ fn genSetStack(
|
|||||||
else => unreachable, // register can hold a max of 8 bytes
|
else => unreachable, // register can hold a max of 8 bytes
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.register_pair => |pair| {
|
||||||
|
var part_disp: i32 = frame.off;
|
||||||
|
for (try self.splitType(ty), pair) |src_ty, src_reg| {
|
||||||
|
try self.genSetStack(
|
||||||
|
src_ty,
|
||||||
|
.{ .index = frame.index, .off = part_disp },
|
||||||
|
.{ .register = src_reg },
|
||||||
|
);
|
||||||
|
part_disp += @intCast(src_ty.abiSize(zcu));
|
||||||
|
}
|
||||||
|
},
|
||||||
.load_frame,
|
.load_frame,
|
||||||
.indirect,
|
.indirect,
|
||||||
.load_symbol,
|
.load_symbol,
|
||||||
@ -4564,8 +4584,8 @@ fn genInlineMemcpy(
|
|||||||
.ops = .rri,
|
.ops = .rri,
|
||||||
.data = .{
|
.data = .{
|
||||||
.i_type = .{
|
.i_type = .{
|
||||||
.rd = tmp,
|
.rd = dst,
|
||||||
.rs1 = dst,
|
.rs1 = tmp,
|
||||||
.imm12 = Immediate.s(0),
|
.imm12 = Immediate.s(0),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -41,7 +41,35 @@ pub fn emitMir(emit: *Emit) Error!void {
|
|||||||
.offset = 0,
|
.offset = 0,
|
||||||
.enc = std.meta.activeTag(lowered_inst.encoding.data),
|
.enc = std.meta.activeTag(lowered_inst.encoding.data),
|
||||||
}),
|
}),
|
||||||
else => |x| return emit.fail("TODO: emitMir {s}", .{@tagName(x)}),
|
.load_symbol_reloc => |symbol| {
|
||||||
|
if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||||
|
const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
|
||||||
|
const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);
|
||||||
|
const sym = elf_file.symbol(sym_index);
|
||||||
|
|
||||||
|
var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
|
||||||
|
var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
|
||||||
|
|
||||||
|
if (sym.flags.needs_zig_got) {
|
||||||
|
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
|
||||||
|
|
||||||
|
hi_r_type = Elf.R_ZIG_GOT_HI20;
|
||||||
|
lo_r_type = Elf.R_ZIG_GOT_LO12;
|
||||||
|
}
|
||||||
|
|
||||||
|
try atom_ptr.addReloc(elf_file, .{
|
||||||
|
.r_offset = start_offset,
|
||||||
|
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
|
||||||
|
.r_addend = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
try atom_ptr.addReloc(elf_file, .{
|
||||||
|
.r_offset = start_offset + 4,
|
||||||
|
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,
|
||||||
|
.r_addend = 0,
|
||||||
|
});
|
||||||
|
} else return emit.fail("TODO: load_symbol_reloc non-ELF", .{});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
std.debug.assert(lowered_relocs.len == 0);
|
std.debug.assert(lowered_relocs.len == 0);
|
||||||
@ -120,6 +148,7 @@ fn fixupRelocs(emit: *Emit) Error!void {
|
|||||||
|
|
||||||
switch (reloc.enc) {
|
switch (reloc.enc) {
|
||||||
.J => riscv_util.writeInstJ(code, @bitCast(disp)),
|
.J => riscv_util.writeInstJ(code, @bitCast(disp)),
|
||||||
|
.B => riscv_util.writeInstB(code, @bitCast(disp)),
|
||||||
else => return emit.fail("tried to reloc encoding type {s}", .{@tagName(reloc.enc)}),
|
else => return emit.fail("tried to reloc encoding type {s}", .{@tagName(reloc.enc)}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,3 +190,4 @@ const Lower = @import("Lower.zig");
|
|||||||
const Mir = @import("Mir.zig");
|
const Mir = @import("Mir.zig");
|
||||||
const riscv_util = @import("../../link/riscv.zig");
|
const riscv_util = @import("../../link/riscv.zig");
|
||||||
const Encoding = @import("Encoding.zig");
|
const Encoding = @import("Encoding.zig");
|
||||||
|
const Elf = @import("../../link/Elf.zig");
|
||||||
|
|||||||
@ -29,6 +29,9 @@ pub const Mnemonic = enum {
|
|||||||
// J Type
|
// J Type
|
||||||
jal,
|
jal,
|
||||||
|
|
||||||
|
// B Type
|
||||||
|
beq,
|
||||||
|
|
||||||
// System
|
// System
|
||||||
ecall,
|
ecall,
|
||||||
ebreak,
|
ebreak,
|
||||||
@ -58,7 +61,9 @@ pub const Mnemonic = enum {
|
|||||||
.sh => .{ .opcode = 0b0100011, .funct3 = 0b001, .funct7 = null },
|
.sh => .{ .opcode = 0b0100011, .funct3 = 0b001, .funct7 = null },
|
||||||
.sb => .{ .opcode = 0b0100011, .funct3 = 0b000, .funct7 = null },
|
.sb => .{ .opcode = 0b0100011, .funct3 = 0b000, .funct7 = null },
|
||||||
|
|
||||||
.jal => .{ .opcode = 0b1101111, .funct3 = null, .funct7 = null },
|
.jal => .{ .opcode = 0b1101111, .funct3 = null, .funct7 = null },
|
||||||
|
|
||||||
|
.beq => .{ .opcode = 0b1100011, .funct3 = 0b000, .funct7 = null },
|
||||||
|
|
||||||
.ecall => .{ .opcode = 0b1110011, .funct3 = 0b000, .funct7 = null },
|
.ecall => .{ .opcode = 0b1110011, .funct3 = 0b000, .funct7 = null },
|
||||||
.ebreak => .{ .opcode = 0b1110011, .funct3 = 0b000, .funct7 = null },
|
.ebreak => .{ .opcode = 0b1110011, .funct3 = 0b000, .funct7 = null },
|
||||||
@ -107,6 +112,9 @@ pub const InstEnc = enum {
|
|||||||
.jal,
|
.jal,
|
||||||
=> .J,
|
=> .J,
|
||||||
|
|
||||||
|
.beq,
|
||||||
|
=> .B,
|
||||||
|
|
||||||
.ecall,
|
.ecall,
|
||||||
.ebreak,
|
.ebreak,
|
||||||
.unimp,
|
.unimp,
|
||||||
@ -114,15 +122,17 @@ pub const InstEnc = enum {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opsList(enc: InstEnc) [4]std.meta.FieldEnum(Operand) {
|
pub fn opsList(enc: InstEnc) [3]std.meta.FieldEnum(Operand) {
|
||||||
return switch (enc) {
|
return switch (enc) {
|
||||||
.R => .{ .reg, .reg, .reg, .none },
|
// zig fmt: off
|
||||||
.I => .{ .reg, .reg, .imm, .none },
|
.R => .{ .reg, .reg, .reg, },
|
||||||
.S => .{ .reg, .reg, .imm, .none },
|
.I => .{ .reg, .reg, .imm, },
|
||||||
.B => .{ .imm, .reg, .reg, .imm },
|
.S => .{ .reg, .reg, .imm, },
|
||||||
.U => .{ .reg, .imm, .none, .none },
|
.B => .{ .reg, .reg, .imm, },
|
||||||
.J => .{ .reg, .imm, .none, .none },
|
.U => .{ .reg, .imm, .none, },
|
||||||
.system => .{ .none, .none, .none, .none },
|
.J => .{ .reg, .imm, .none, },
|
||||||
|
.system => .{ .none, .none, .none, },
|
||||||
|
// zig fmt: on
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -292,6 +302,26 @@ pub const Data = union(InstEnc) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
.B => {
|
||||||
|
assert(ops.len == 3);
|
||||||
|
|
||||||
|
const umm = ops[2].imm.asBits(u13);
|
||||||
|
assert(umm % 4 == 0); // misaligned branch target
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.B = .{
|
||||||
|
.rs1 = ops[0].reg.id(),
|
||||||
|
.rs2 = ops[1].reg.id(),
|
||||||
|
.imm1_4 = @truncate(umm >> 1),
|
||||||
|
.imm5_10 = @truncate(umm >> 5),
|
||||||
|
.imm11 = @truncate(umm >> 11),
|
||||||
|
.imm12 = @truncate(umm >> 12),
|
||||||
|
|
||||||
|
.opcode = enc.opcode,
|
||||||
|
.funct3 = enc.funct3.?,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
else => std.debug.panic("TODO: construct {s}", .{@tagName(inst_enc)}),
|
else => std.debug.panic("TODO: construct {s}", .{@tagName(inst_enc)}),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,9 @@ pub const Reloc = struct {
|
|||||||
|
|
||||||
const Target = union(enum) {
|
const Target = union(enum) {
|
||||||
inst: Mir.Inst.Index,
|
inst: Mir.Inst.Index,
|
||||||
linker_reloc: bits.Symbol,
|
|
||||||
|
/// Relocs the lowered_inst_index and the next one.
|
||||||
|
load_symbol_reloc: bits.Symbol,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,6 +61,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
|||||||
.pseudo_dbg_prologue_end,
|
.pseudo_dbg_prologue_end,
|
||||||
.pseudo_dead,
|
.pseudo_dead,
|
||||||
=> {},
|
=> {},
|
||||||
|
|
||||||
.pseudo_load_rm, .pseudo_store_rm => {
|
.pseudo_load_rm, .pseudo_store_rm => {
|
||||||
const rm = inst.data.rm;
|
const rm = inst.data.rm;
|
||||||
|
|
||||||
@ -106,6 +109,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
|||||||
.{ .imm = Immediate.s(0) },
|
.{ .imm = Immediate.s(0) },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
.pseudo_ret => {
|
.pseudo_ret => {
|
||||||
try lower.emit(.jalr, &.{
|
try lower.emit(.jalr, &.{
|
||||||
.{ .reg = .zero },
|
.{ .reg = .zero },
|
||||||
@ -113,6 +117,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
|||||||
.{ .imm = Immediate.s(0) },
|
.{ .imm = Immediate.s(0) },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
.pseudo_j => {
|
.pseudo_j => {
|
||||||
try lower.emit(.jal, &.{
|
try lower.emit(.jal, &.{
|
||||||
.{ .reg = .zero },
|
.{ .reg = .zero },
|
||||||
@ -123,7 +128,38 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
|||||||
.pseudo_spill_regs => try lower.pushPopRegList(true, inst.data.reg_list),
|
.pseudo_spill_regs => try lower.pushPopRegList(true, inst.data.reg_list),
|
||||||
.pseudo_restore_regs => try lower.pushPopRegList(false, inst.data.reg_list),
|
.pseudo_restore_regs => try lower.pushPopRegList(false, inst.data.reg_list),
|
||||||
|
|
||||||
else => return lower.fail("TODO: psuedo {s}", .{@tagName(inst.ops)}),
|
.pseudo_load_symbol => {
|
||||||
|
const payload = inst.data.payload;
|
||||||
|
const data = lower.mir.extraData(Mir.LoadSymbolPayload, payload).data;
|
||||||
|
|
||||||
|
try lower.emit(.lui, &.{
|
||||||
|
.{ .reg = @enumFromInt(data.register) },
|
||||||
|
.{ .imm = lower.reloc(.{ .load_symbol_reloc = .{
|
||||||
|
.atom_index = data.atom_index,
|
||||||
|
.sym_index = data.sym_index,
|
||||||
|
} }) },
|
||||||
|
});
|
||||||
|
|
||||||
|
// the above reloc implies this one
|
||||||
|
try lower.emit(.addi, &.{
|
||||||
|
.{ .reg = @enumFromInt(data.register) },
|
||||||
|
.{ .reg = @enumFromInt(data.register) },
|
||||||
|
.{ .imm = Immediate.s(0) },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
.pseudo_lea_rm => {
|
||||||
|
const rm = inst.data.rm;
|
||||||
|
const frame = rm.m.toFrameLoc(lower.mir);
|
||||||
|
|
||||||
|
try lower.emit(.addi, &.{
|
||||||
|
.{ .reg = rm.r },
|
||||||
|
.{ .reg = frame.base },
|
||||||
|
.{ .imm = Immediate.s(frame.disp) },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
else => return lower.fail("TODO Lower: psuedo {s}", .{@tagName(inst.ops)}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +171,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
|||||||
|
|
||||||
fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
|
fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
|
||||||
const mnemonic = std.meta.stringToEnum(Encoding.Mnemonic, @tagName(inst.tag)) orelse {
|
const mnemonic = std.meta.stringToEnum(Encoding.Mnemonic, @tagName(inst.tag)) orelse {
|
||||||
return lower.fail("generic inst name {s}-{s} doesn't match with a mnemonic", .{
|
return lower.fail("generic inst name '{s}' with op {s} doesn't match with a mnemonic", .{
|
||||||
@tagName(inst.tag),
|
@tagName(inst.tag),
|
||||||
@tagName(inst.ops),
|
@tagName(inst.ops),
|
||||||
});
|
});
|
||||||
@ -151,6 +187,11 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
|
|||||||
.{ .reg = inst.data.i_type.rs1 },
|
.{ .reg = inst.data.i_type.rs1 },
|
||||||
.{ .imm = inst.data.i_type.imm12 },
|
.{ .imm = inst.data.i_type.imm12 },
|
||||||
},
|
},
|
||||||
|
.rr_inst => &.{
|
||||||
|
.{ .reg = inst.data.b_type.rs1 },
|
||||||
|
.{ .reg = inst.data.b_type.rs2 },
|
||||||
|
.{ .imm = lower.reloc(.{ .inst = inst.data.b_type.inst }) },
|
||||||
|
},
|
||||||
else => return lower.fail("TODO: generic lower ops {s}", .{@tagName(inst.ops)}),
|
else => return lower.fail("TODO: generic lower ops {s}", .{@tagName(inst.ops)}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,17 +65,25 @@ pub const Memory = struct {
|
|||||||
|
|
||||||
/// Asserts `mem` can be represented as a `FrameLoc`.
|
/// Asserts `mem` can be represented as a `FrameLoc`.
|
||||||
pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc {
|
pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc {
|
||||||
|
const offset: i32 = switch (mem.mod) {
|
||||||
|
.off => |off| @intCast(off),
|
||||||
|
.rm => |rm| rm.disp,
|
||||||
|
};
|
||||||
|
|
||||||
switch (mem.base) {
|
switch (mem.base) {
|
||||||
.reg => |reg| {
|
.reg => |reg| {
|
||||||
return .{
|
return .{
|
||||||
.base = reg,
|
.base = reg,
|
||||||
.disp = switch (mem.mod) {
|
.disp = offset,
|
||||||
.off => unreachable, // TODO: toFrameLoc disp.off
|
};
|
||||||
.rm => |rm| rm.disp,
|
},
|
||||||
},
|
.frame => |index| {
|
||||||
|
const base_loc = mir.frame_locs.get(@intFromEnum(index));
|
||||||
|
return .{
|
||||||
|
.base = base_loc.base,
|
||||||
|
.disp = base_loc.disp + offset,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.frame => |index| return mir.frame_locs.get(@intFromEnum(index)),
|
|
||||||
.reloc => unreachable,
|
.reloc => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
pub const Instruction = struct {
|
pub const Instruction = struct {
|
||||||
encoding: Encoding,
|
encoding: Encoding,
|
||||||
ops: [4]Operand = .{.none} ** 4,
|
ops: [3]Operand = .{.none} ** 3,
|
||||||
|
|
||||||
pub const Operand = union(enum) {
|
pub const Operand = union(enum) {
|
||||||
none,
|
none,
|
||||||
@ -11,7 +11,7 @@ pub const Instruction = struct {
|
|||||||
|
|
||||||
pub fn new(mnemonic: Encoding.Mnemonic, ops: []const Operand) !Instruction {
|
pub fn new(mnemonic: Encoding.Mnemonic, ops: []const Operand) !Instruction {
|
||||||
const encoding = (try Encoding.findByMnemonic(mnemonic, ops)) orelse {
|
const encoding = (try Encoding.findByMnemonic(mnemonic, ops)) orelse {
|
||||||
log.err("no encoding found for: {s} {s} {s} {s} {s}", .{
|
std.log.err("no encoding found for: {s} {s} {s} {s} {s}", .{
|
||||||
@tagName(mnemonic),
|
@tagName(mnemonic),
|
||||||
@tagName(if (ops.len > 0) ops[0] else .none),
|
@tagName(if (ops.len > 0) ops[0] else .none),
|
||||||
@tagName(if (ops.len > 1) ops[1] else .none),
|
@tagName(if (ops.len > 1) ops[1] else .none),
|
||||||
@ -21,7 +21,7 @@ pub const Instruction = struct {
|
|||||||
return error.InvalidInstruction;
|
return error.InvalidInstruction;
|
||||||
};
|
};
|
||||||
|
|
||||||
var result_ops: [4]Operand = .{.none} ** 4;
|
var result_ops: [3]Operand = .{.none} ** 3;
|
||||||
@memcpy(result_ops[0..ops.len], ops);
|
@memcpy(result_ops[0..ops.len], ops);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
|
|||||||
@ -73,6 +73,20 @@ pub fn writeInstJ(code: *[4]u8, value: u32) void {
|
|||||||
mem.writeInt(u32, code, data.toU32(), .little);
|
mem.writeInt(u32, code, data.toU32(), .little);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeInstB(code: *[4]u8, value: u32) void {
|
||||||
|
var data = Encoding.Data{
|
||||||
|
.B = mem.bytesToValue(std.meta.TagPayload(
|
||||||
|
Encoding.Data,
|
||||||
|
Encoding.Data.B,
|
||||||
|
), code),
|
||||||
|
};
|
||||||
|
data.B.imm1_4 = bitSlice(value, 4, 1);
|
||||||
|
data.B.imm5_10 = bitSlice(value, 10, 5);
|
||||||
|
data.B.imm11 = bitSlice(value, 11, 11);
|
||||||
|
data.B.imm12 = bitSlice(value, 12, 12);
|
||||||
|
mem.writeInt(u32, code, data.toU32(), .little);
|
||||||
|
}
|
||||||
|
|
||||||
fn bitSlice(
|
fn bitSlice(
|
||||||
value: anytype,
|
value: anytype,
|
||||||
comptime high: comptime_int,
|
comptime high: comptime_int,
|
||||||
|
|||||||
@ -526,7 +526,7 @@ pub fn backendSupportsFeature(
|
|||||||
feature: Feature,
|
feature: Feature,
|
||||||
) bool {
|
) bool {
|
||||||
return switch (feature) {
|
return switch (feature) {
|
||||||
.panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64,
|
.panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64 or cpu_arch == .riscv64,
|
||||||
.panic_unwrap_error => ofmt == .c or use_llvm,
|
.panic_unwrap_error => ofmt == .c or use_llvm,
|
||||||
.safety_check_formatted => ofmt == .c or use_llvm,
|
.safety_check_formatted => ofmt == .c or use_llvm,
|
||||||
.error_return_trace => use_llvm,
|
.error_return_trace => use_llvm,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user