aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-02-21 23:25:49 +0100
committerJakub Konka <kubkon@jakubkonka.com>2024-02-21 23:34:05 +0100
commit2ad2e2f6f5c327187b37619c0d7dd207c29916a1 (patch)
treee10fae8a8f773afe076486c3c456cd3065a7b342 /src
parentddb33baa11525a4896be850b4e88d9db337b9c2c (diff)
downloadzig-2ad2e2f6f5c327187b37619c0d7dd207c29916a1.tar.gz
zig-2ad2e2f6f5c327187b37619c0d7dd207c29916a1.zip
link+riscv: use riscv64/bits.zig to implement write helpers
Diffstat (limited to 'src')
-rw-r--r--src/link/riscv.zig44
1 files changed, 28 insertions, 16 deletions
diff --git a/src/link/riscv.zig b/src/link/riscv.zig
index 2cdc050996..3c530b7818 100644
--- a/src/link/riscv.zig
+++ b/src/link/riscv.zig
@@ -25,34 +25,46 @@ pub fn writeAddend(
}
pub fn writeInstU(code: *[4]u8, value: u32) void {
- const inst_mask: u32 = 0b00000000000000000000_11111_1111111;
- const val_mask: u32 = 0xffff_f000;
- var inst = mem.readInt(u32, code, .little);
- inst &= inst_mask;
+ var inst = Instruction{
+ .U = mem.bytesToValue(std.meta.TagPayload(
+ Instruction,
+ Instruction.U,
+ ), code),
+ };
const compensated: u32 = @bitCast(@as(i32, @bitCast(value)) + 0x800);
- inst |= (compensated & val_mask);
- mem.writeInt(u32, code, inst, .little);
+ inst.U.imm12_31 = @truncate(bitSlice(compensated, 31, 12));
+ mem.writeInt(u32, code, inst.toU32(), .little);
}
pub fn writeInstI(code: *[4]u8, value: u32) void {
- const mask: u32 = 0b00000000000_11111_111_11111_1111111;
- var inst = mem.readInt(u32, code, .little);
- inst &= mask;
- inst |= (bitSlice(value, 11, 0) << 20);
- mem.writeInt(u32, code, inst, .little);
+ var inst = Instruction{
+ .I = mem.bytesToValue(std.meta.TagPayload(
+ Instruction,
+ Instruction.I,
+ ), code),
+ };
+ inst.I.imm0_11 = @truncate(bitSlice(value, 11, 0));
+ mem.writeInt(u32, code, inst.toU32(), .little);
}
pub fn writeInstS(code: *[4]u8, value: u32) void {
- const mask: u32 = 0b000000_11111_11111_111_00000_1111111;
- var inst = mem.readInt(u32, code, .little);
- inst &= mask;
- inst |= (bitSlice(value, 11, 5) << 25) | (bitSlice(value, 4, 0) << 7);
- mem.writeInt(u32, code, inst, .little);
+ var inst = Instruction{
+ .S = mem.bytesToValue(std.meta.TagPayload(
+ Instruction,
+ Instruction.S,
+ ), code),
+ };
+ inst.S.imm0_4 = @truncate(bitSlice(value, 4, 0));
+ inst.S.imm5_11 = @truncate(bitSlice(value, 11, 5));
+ mem.writeInt(u32, code, inst.toU32(), .little);
}
fn bitSlice(value: anytype, high: std.math.Log2Int(@TypeOf(value)), low: std.math.Log2Int(@TypeOf(value))) @TypeOf(value) {
return (value >> low) & ((@as(@TypeOf(value), 1) << (high - low + 1)) - 1);
}
+const bits = @import("../arch/riscv64/bits.zig");
const mem = std.mem;
const std = @import("std");
+
+pub const Instruction = bits.Instruction;