| ... | @@ -25,34 +25,46 @@ pub fn writeAddend( | ... | @@ -25,34 +25,46 @@ pub fn writeAddend( |
| 25 | } | 25 | } |
| 26 | | 26 | |
| 27 | pub fn writeInstU(code: *[4]u8, value: u32) void { | 27 | pub fn writeInstU(code: *[4]u8, value: u32) void { |
| 28 | const inst_mask: u32 = 0b00000000000000000000_11111_1111111; | 28 | var inst = Instruction{ |
| 29 | const val_mask: u32 = 0xffff_f000; | 29 | .U = mem.bytesToValue(std.meta.TagPayload( |
| 30 | var inst = mem.readInt(u32, code, .little); | 30 | Instruction, |
| 31 | inst &= inst_mask; | 31 | Instruction.U, |
| | 32 | ), code), |
| | 33 | }; |
| 32 | const compensated: u32 = @bitCast(@as(i32, @bitCast(value)) + 0x800); | 34 | const compensated: u32 = @bitCast(@as(i32, @bitCast(value)) + 0x800); |
| 33 | inst |= (compensated & val_mask); | 35 | inst.U.imm12_31 = @truncate(bitSlice(compensated, 31, 12)); |
| 34 | mem.writeInt(u32, code, inst, .little); | 36 | mem.writeInt(u32, code, inst.toU32(), .little); |
| 35 | } | 37 | } |
| 36 | | 38 | |
| 37 | pub fn writeInstI(code: *[4]u8, value: u32) void { | 39 | pub fn writeInstI(code: *[4]u8, value: u32) void { |
| 38 | const mask: u32 = 0b00000000000_11111_111_11111_1111111; | 40 | var inst = Instruction{ |
| 39 | var inst = mem.readInt(u32, code, .little); | 41 | .I = mem.bytesToValue(std.meta.TagPayload( |
| 40 | inst &= mask; | 42 | Instruction, |
| 41 | inst |= (bitSlice(value, 11, 0) << 20); | 43 | Instruction.I, |
| 42 | mem.writeInt(u32, code, inst, .little); | 44 | ), code), |
| | 45 | }; |
| | 46 | inst.I.imm0_11 = @truncate(bitSlice(value, 11, 0)); |
| | 47 | mem.writeInt(u32, code, inst.toU32(), .little); |
| 43 | } | 48 | } |
| 44 | | 49 | |
| 45 | pub fn writeInstS(code: *[4]u8, value: u32) void { | 50 | pub fn writeInstS(code: *[4]u8, value: u32) void { |
| 46 | const mask: u32 = 0b000000_11111_11111_111_00000_1111111; | 51 | var inst = Instruction{ |
| 47 | var inst = mem.readInt(u32, code, .little); | 52 | .S = mem.bytesToValue(std.meta.TagPayload( |
| 48 | inst &= mask; | 53 | Instruction, |
| 49 | inst |= (bitSlice(value, 11, 5) << 25) | (bitSlice(value, 4, 0) << 7); | 54 | Instruction.S, |
| 50 | mem.writeInt(u32, code, inst, .little); | 55 | ), code), |
| | 56 | }; |
| | 57 | inst.S.imm0_4 = @truncate(bitSlice(value, 4, 0)); |
| | 58 | inst.S.imm5_11 = @truncate(bitSlice(value, 11, 5)); |
| | 59 | mem.writeInt(u32, code, inst.toU32(), .little); |
| 51 | } | 60 | } |
| 52 | | 61 | |
| 53 | fn bitSlice(value: anytype, high: std.math.Log2Int(@TypeOf(value)), low: std.math.Log2Int(@TypeOf(value))) @TypeOf(value) { | 62 | fn bitSlice(value: anytype, high: std.math.Log2Int(@TypeOf(value)), low: std.math.Log2Int(@TypeOf(value))) @TypeOf(value) { |
| 54 | return (value >> low) & ((@as(@TypeOf(value), 1) << (high - low + 1)) - 1); | 63 | return (value >> low) & ((@as(@TypeOf(value), 1) << (high - low + 1)) - 1); |
| 55 | } | 64 | } |
| 56 | | 65 | |
| | 66 | const bits = @import("../arch/riscv64/bits.zig"); |
| 57 | const mem = std.mem; | 67 | const mem = std.mem; |
| 58 | const std = @import("std"); | 68 | const std = @import("std"); |
| | 69 | |
| | 70 | pub const Instruction = bits.Instruction; |