authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-25 23:01:44-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-26 04:19:57-07:00
log7ff5709e1b04de4c33988ce6a27bc593dcf20f63
treeda08f073bec966042a0815579b5b68ceb9399c29
parenta1f6a8ef90f0778e4fc5d314eeb1f0a0a93fa53a
signaturelock-open Commit is signed but in an unrecognized format.

riscv: implement `lr/sr` loop logic for non-native atomics


7 files changed, 138 insertions(+), 113 deletions(-)

lib/std/start.zig+2-4
...@@ -478,10 +478,8 @@ inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {...@@ -478,10 +478,8 @@ inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
478 std.os.argv = argv[0..argc];478 std.os.argv = argv[0..argc];
479 std.os.environ = envp;479 std.os.environ = envp;
480480
481 if (builtin.zig_backend != .stage2_riscv64) {481 std.debug.maybeEnableSegfaultHandler();
482 std.debug.maybeEnableSegfaultHandler();482 maybeIgnoreSigpipe();
483 maybeIgnoreSigpipe();
484 }
485483
486 return callMain();484 return callMain();
487}485}
src/arch/riscv64/CodeGen.zig+113-53
...@@ -4717,14 +4717,11 @@ fn airFence(func: *Func, inst: Air.Inst.Index) !void {...@@ -4717,14 +4717,11 @@ fn airFence(func: *Func, inst: Air.Inst.Index) !void {
4717 };4717 };
47184718
4719 _ = try func.addInst(.{4719 _ = try func.addInst(.{
4720 .tag = .pseudo_fence,4720 .tag = if (order == .acq_rel) .fencetso else .fence,
4721 .data = .{4721 .data = .{ .fence = .{
4722 .fence = .{4722 .pred = pred,
4723 .pred = pred,4723 .succ = succ,
4724 .succ = succ,4724 } },
4725 .fm = if (order == .acq_rel) .tso else .none,
4726 },
4727 },
4728 });4725 });
4729 return func.finishAirBookkeeping();4726 return func.finishAirBookkeeping();
4730}4727}
...@@ -5278,12 +5275,12 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -5278,12 +5275,12 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
5278 .dead,5275 .dead,
5279 .undef,5276 .undef,
5280 .immediate,5277 .immediate,
5281 .register_pair,
5282 .register_offset,5278 .register_offset,
5283 .lea_frame,5279 .lea_frame,
5284 .lea_symbol,5280 .lea_symbol,
5285 .reserved_frame,5281 .reserved_frame,
5286 .air_ref,5282 .air_ref,
5283 .register_pair,
5287 => unreachable,5284 => unreachable,
52885285
5289 .register => |opt_reg| {5286 .register => |opt_reg| {
...@@ -7109,6 +7106,7 @@ fn airCmpxchg(func: *Func, inst: Air.Inst.Index) !void {...@@ -7109,6 +7106,7 @@ fn airCmpxchg(func: *Func, inst: Air.Inst.Index) !void {
71097106
7110fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {7107fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {
7111 const pt = func.pt;7108 const pt = func.pt;
7109 const zcu = pt.zcu;
7112 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7110 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
7113 const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;7111 const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;
71147112
...@@ -7131,11 +7129,11 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {...@@ -7131,11 +7129,11 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {
7131 else => unreachable,7129 else => unreachable,
7132 }7130 }
71337131
7134 switch (val_size) {7132 const method: enum { amo, loop } = switch (val_size) {
7135 1, 2 => return func.fail("TODO: airAtomicRmw {s} Int {}", .{ @tagName(op), val_size }),7133 1, 2 => .loop,
7136 4, 8 => {},7134 4, 8 => .amo,
7137 else => unreachable,7135 else => unreachable,
7138 }7136 };
71397137
7140 const ptr_register, const ptr_lock = try func.promoteReg(ptr_ty, ptr_mcv);7138 const ptr_register, const ptr_lock = try func.promoteReg(ptr_ty, ptr_mcv);
7141 defer if (ptr_lock) |lock| func.register_manager.unlockReg(lock);7139 defer if (ptr_lock) |lock| func.register_manager.unlockReg(lock);
...@@ -7145,6 +7143,7 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {...@@ -7145,6 +7143,7 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {
71457143
7146 const result_mcv = try func.allocRegOrMem(val_ty, inst, true);7144 const result_mcv = try func.allocRegOrMem(val_ty, inst, true);
7147 assert(result_mcv == .register); // should fit into 8 bytes7145 assert(result_mcv == .register); // should fit into 8 bytes
7146 const result_reg = result_mcv.register;
71487147
7149 const aq, const rl = switch (order) {7148 const aq, const rl = switch (order) {
7150 .unordered => unreachable,7149 .unordered => unreachable,
...@@ -7155,28 +7154,96 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {...@@ -7155,28 +7154,96 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {
7155 .seq_cst => .{ true, true },7154 .seq_cst => .{ true, true },
7156 };7155 };
71577156
7158 _ = try func.addInst(.{7157 switch (method) {
7159 .tag = .pseudo_amo,7158 .amo => {
7160 .data = .{ .amo = .{7159 const is_d = val_ty.abiSize(pt) == 8;
7161 .rd = result_mcv.register,7160 const is_un = val_ty.isUnsignedInt(zcu);
7162 .rs1 = ptr_register,7161
7163 .rs2 = val_register,7162 const mnem: Mnemonic = switch (op) {
7164 .aq = if (aq) .aq else .none,7163 // zig fmt: off
7165 .rl = if (rl) .rl else .none,7164 .Xchg => if (is_d) .amoswapd else .amoswapw,
7166 .op = switch (op) {7165 .Add => if (is_d) .amoaddd else .amoaddw,
7167 .Xchg => .SWAP,7166 .And => if (is_d) .amoandd else .amoandw,
7168 .Add => .ADD,7167 .Or => if (is_d) .amoord else .amoorw,
7169 .Sub => return func.fail("TODO: airAtomicRmw SUB", .{}),7168 .Xor => if (is_d) .amoxord else .amoxorw,
7170 .And => .AND,7169 .Max => if (is_d) if (is_un) .amomaxud else .amomaxd else if (is_un) .amomaxuw else .amomaxw,
7171 .Nand => return func.fail("TODO: airAtomicRmw NAND", .{}),7170 .Min => if (is_d) if (is_un) .amominud else .amomind else if (is_un) .amominuw else .amominw,
7172 .Or => .OR,7171 else => return func.fail("TODO: airAtomicRmw amo {s}", .{@tagName(op)}),
7173 .Xor => .XOR,7172 // zig fmt: on
7174 .Max => .MAX,7173 };
7175 .Min => .MIN,7174
7176 },7175 _ = try func.addInst(.{
7177 .ty = val_ty,7176 .tag = mnem,
7178 } },7177 .data = .{ .amo = .{
7179 });7178 .rd = result_reg,
7179 .rs1 = ptr_register,
7180 .rs2 = val_register,
7181 .aq = if (aq) .aq else .none,
7182 .rl = if (rl) .rl else .none,
7183 } },
7184 });
7185 },
7186 .loop => {
7187 // where we'll jump back when the sc fails
7188 const jump_back = try func.addInst(.{
7189 .tag = .lrw,
7190 .data = .{ .amo = .{
7191 .rd = result_reg,
7192 .rs1 = ptr_register,
7193 .rs2 = .zero,
7194 .aq = if (aq) .aq else .none,
7195 .rl = if (rl) .rl else .none,
7196 } },
7197 });
7198
7199 const after_reg, const after_lock = try func.allocReg(.int);
7200 defer func.register_manager.unlockReg(after_lock);
7201
7202 switch (op) {
7203 .Add => {
7204 _ = try func.genBinOp(
7205 .add,
7206 .{ .register = result_reg },
7207 val_ty,
7208 .{ .register = val_register },
7209 val_ty,
7210 after_reg,
7211 );
7212 },
7213 .Sub => {
7214 _ = try func.genBinOp(
7215 .sub,
7216 .{ .register = result_reg },
7217 val_ty,
7218 .{ .register = val_register },
7219 val_ty,
7220 after_reg,
7221 );
7222 },
7223 else => return func.fail("TODO: airAtomicRmw loop {s}", .{@tagName(op)}),
7224 }
7225
7226 _ = try func.addInst(.{
7227 .tag = .scw,
7228 .data = .{ .amo = .{
7229 .rd = after_reg,
7230 .rs1 = ptr_register,
7231 .rs2 = after_reg,
7232 .aq = if (aq) .aq else .none,
7233 .rl = if (rl) .rl else .none,
7234 } },
7235 });
7236
7237 _ = try func.addInst(.{
7238 .tag = .bne,
7239 .data = .{ .b_type = .{
7240 .inst = jump_back,
7241 .rs1 = after_reg,
7242 .rs2 = .zero,
7243 } },
7244 });
7245 },
7246 }
71807247
7181 return func.finishAir(inst, result_mcv, .{ pl_op.operand, extra.operand, .none });7248 return func.finishAir(inst, result_mcv, .{ pl_op.operand, extra.operand, .none });
7182}7249}
...@@ -7199,11 +7266,10 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {...@@ -7199,11 +7266,10 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {
71997266
7200 if (order == .seq_cst) {7267 if (order == .seq_cst) {
7201 _ = try func.addInst(.{7268 _ = try func.addInst(.{
7202 .tag = .pseudo_fence,7269 .tag = .fence,
7203 .data = .{ .fence = .{7270 .data = .{ .fence = .{
7204 .pred = .rw,7271 .pred = .rw,
7205 .succ = .rw,7272 .succ = .rw,
7206 .fm = .none,
7207 } },7273 } },
7208 });7274 });
7209 }7275 }
...@@ -7217,14 +7283,11 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {...@@ -7217,14 +7283,11 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {
7217 // Make sure all previous reads happen before any reading or writing accurs.7283 // Make sure all previous reads happen before any reading or writing accurs.
7218 .seq_cst, .acquire => {7284 .seq_cst, .acquire => {
7219 _ = try func.addInst(.{7285 _ = try func.addInst(.{
7220 .tag = .pseudo_fence,7286 .tag = .fence,
7221 .data = .{7287 .data = .{ .fence = .{
7222 .fence = .{7288 .pred = .r,
7223 .pred = .r,7289 .succ = .rw,
7224 .succ = .rw,7290 } },
7225 .fm = .none,
7226 },
7227 },
7228 });7291 });
7229 },7292 },
7230 else => unreachable,7293 else => unreachable,
...@@ -7249,14 +7312,11 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr...@@ -7249,14 +7312,11 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr
7249 .unordered, .monotonic => {},7312 .unordered, .monotonic => {},
7250 .release, .seq_cst => {7313 .release, .seq_cst => {
7251 _ = try func.addInst(.{7314 _ = try func.addInst(.{
7252 .tag = .pseudo_fence,7315 .tag = .fence,
7253 .data = .{7316 .data = .{ .fence = .{
7254 .fence = .{7317 .pred = .rw,
7255 .pred = .rw,7318 .succ = .w,
7256 .succ = .w,7319 } },
7257 .fm = .none,
7258 },
7259 },
7260 });7320 });
7261 },7321 },
7262 else => unreachable,7322 else => unreachable,
src/arch/riscv64/Lower.zig+11-38
...@@ -446,44 +446,6 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct {...@@ -446,44 +446,6 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct {
446 .{ .imm = Immediate.s(0) },446 .{ .imm = Immediate.s(0) },
447 });447 });
448 },448 },
449
450 .pseudo_amo => {
451 const amo = inst.data.amo;
452 const is_d = amo.ty.abiSize(pt) == 8;
453 const is_un = amo.ty.isUnsignedInt(pt.zcu);
454
455 const mnem: Mnemonic = switch (amo.op) {
456 // zig fmt: off
457 .SWAP => if (is_d) .amoswapd else .amoswapw,
458 .ADD => if (is_d) .amoaddd else .amoaddw,
459 .AND => if (is_d) .amoandd else .amoandw,
460 .OR => if (is_d) .amoord else .amoorw,
461 .XOR => if (is_d) .amoxord else .amoxorw,
462 .MAX => if (is_d) if (is_un) .amomaxud else .amomaxd else if (is_un) .amomaxuw else .amomaxw,
463 .MIN => if (is_d) if (is_un) .amominud else .amomind else if (is_un) .amominuw else .amominw,
464 // zig fmt: on
465 };
466
467 try lower.emit(mnem, &.{
468 .{ .reg = inst.data.amo.rd },
469 .{ .reg = inst.data.amo.rs1 },
470 .{ .reg = inst.data.amo.rs2 },
471 .{ .barrier = inst.data.amo.rl },
472 .{ .barrier = inst.data.amo.aq },
473 });
474 },
475
476 .pseudo_fence => {
477 const fence = inst.data.fence;
478
479 try lower.emit(switch (fence.fm) {
480 .tso => .fencetso,
481 .none => .fence,
482 }, &.{
483 .{ .barrier = fence.succ },
484 .{ .barrier = fence.pred },
485 });
486 },
487 }449 }
488450
489 return .{451 return .{
...@@ -524,6 +486,17 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -524,6 +486,17 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
524 .{ .reg = csr.rs1 },486 .{ .reg = csr.rs1 },
525 .{ .reg = csr.rd },487 .{ .reg = csr.rd },
526 },488 },
489 .amo => |amo| &.{
490 .{ .reg = amo.rd },
491 .{ .reg = amo.rs1 },
492 .{ .reg = amo.rs2 },
493 .{ .barrier = amo.rl },
494 .{ .barrier = amo.aq },
495 },
496 .fence => |fence| &.{
497 .{ .barrier = fence.succ },
498 .{ .barrier = fence.pred },
499 },
527 else => return lower.fail("TODO: generic lower {s}", .{@tagName(inst.data)}),500 else => return lower.fail("TODO: generic lower {s}", .{@tagName(inst.data)}),
528 });501 });
529}502}
src/arch/riscv64/Mir.zig-6
...@@ -73,10 +73,6 @@ pub const Inst = struct {...@@ -73,10 +73,6 @@ pub const Inst = struct {
73 fence: struct {73 fence: struct {
74 pred: Barrier,74 pred: Barrier,
75 succ: Barrier,75 succ: Barrier,
76 fm: enum {
77 none,
78 tso,
79 },
80 },76 },
81 amo: struct {77 amo: struct {
82 rd: Register,78 rd: Register,
...@@ -84,8 +80,6 @@ pub const Inst = struct {...@@ -84,8 +80,6 @@ pub const Inst = struct {
84 rs2: Register,80 rs2: Register,
85 aq: Barrier,81 aq: Barrier,
86 rl: Barrier,82 rl: Barrier,
87 op: AmoOp,
88 ty: Type,
89 },83 },
90 csr: struct {84 csr: struct {
91 csr: CSR,85 csr: CSR,
src/arch/riscv64/abi.zig+1-4
...@@ -125,10 +125,7 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {...@@ -125,10 +125,7 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {
125 result[0] = .integer;125 result[0] = .integer;
126 return result;126 return result;
127 }127 }
128 result[0] = .integer;128 return memory_class;
129 if (ty.optionalChild(zcu).abiSize(pt) == 0) return result;
130 result[1] = .integer;
131 return result;
132 },129 },
133 .Int, .Enum, .ErrorSet => {130 .Int, .Enum, .ErrorSet => {
134 const int_bits = ty.intInfo(pt.zcu).bits;131 const int_bits = ty.intInfo(pt.zcu).bits;
src/arch/riscv64/encoding.zig+6-6
...@@ -353,6 +353,7 @@ pub const Lir = struct {...@@ -353,6 +353,7 @@ pub const Lir = struct {
353 // BRANCH353 // BRANCH
354354
355 .beq => .{ .opcode = .BRANCH, .format = .B, .data = .{ .f = .{ .funct3 = 0b000 } } },355 .beq => .{ .opcode = .BRANCH, .format = .B, .data = .{ .f = .{ .funct3 = 0b000 } } },
356 .bne => .{ .opcode = .BRANCH, .format = .B, .data = .{ .f = .{ .funct3 = 0b001 } } },
356357
357358
358 // SYSTEM359 // SYSTEM
...@@ -378,8 +379,8 @@ pub const Lir = struct {...@@ -378,8 +379,8 @@ pub const Lir = struct {
378379
379 .amoaddw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00000 } } },380 .amoaddw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00000 } } },
380 .amoswapw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00001 } } },381 .amoswapw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00001 } } },
381 // LR.W382 .lrw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00010 } } },
382 // SC.W383 .scw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00011 } } },
383 .amoxorw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00100 } } },384 .amoxorw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00100 } } },
384 .amoandw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b01100 } } },385 .amoandw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b01100 } } },
385 .amoorw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b01000 } } },386 .amoorw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b01000 } } },
...@@ -388,10 +389,11 @@ pub const Lir = struct {...@@ -388,10 +389,11 @@ pub const Lir = struct {
388 .amominuw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b11000 } } },389 .amominuw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b11000 } } },
389 .amomaxuw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b11100 } } },390 .amomaxuw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b11100 } } },
390391
392
391 .amoaddd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00000 } } },393 .amoaddd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00000 } } },
392 .amoswapd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00001 } } },394 .amoswapd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00001 } } },
393 // LR.D395 .lrd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00010 } } },
394 // SC.D396 .scd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00011 } } },
395 .amoxord => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00100 } } },397 .amoxord => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00100 } } },
396 .amoandd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b01100 } } },398 .amoandd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b01100 } } },
397 .amoord => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b01000 } } },399 .amoord => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b01000 } } },
...@@ -434,8 +436,6 @@ pub const Lir = struct {...@@ -434,8 +436,6 @@ pub const Lir = struct {
434 .pseudo_compare,436 .pseudo_compare,
435 .pseudo_not,437 .pseudo_not,
436 .pseudo_extern_fn_reloc,438 .pseudo_extern_fn_reloc,
437 .pseudo_fence,
438 .pseudo_amo,
439 .nop,439 .nop,
440 => std.debug.panic("lir: didn't catch pseudo {s}", .{@tagName(mnem)}),440 => std.debug.panic("lir: didn't catch pseudo {s}", .{@tagName(mnem)}),
441 // zig fmt: on441 // zig fmt: on
src/arch/riscv64/mnem.zig+5-2
...@@ -40,6 +40,7 @@ pub const Mnemonic = enum(u16) {...@@ -40,6 +40,7 @@ pub const Mnemonic = enum(u16) {
40 jal,40 jal,
4141
42 beq,42 beq,
43 bne,
4344
44 // Memory45 // Memory
45 lui,46 lui,
...@@ -178,6 +179,8 @@ pub const Mnemonic = enum(u16) {...@@ -178,6 +179,8 @@ pub const Mnemonic = enum(u16) {
178 fence,179 fence,
179 fencetso,180 fencetso,
180181
182 lrw,
183 scw,
181 amoswapw,184 amoswapw,
182 amoaddw,185 amoaddw,
183 amoandw,186 amoandw,
...@@ -188,6 +191,8 @@ pub const Mnemonic = enum(u16) {...@@ -188,6 +191,8 @@ pub const Mnemonic = enum(u16) {
188 amomaxuw,191 amomaxuw,
189 amominuw,192 amominuw,
190193
194 lrd,
195 scd,
191 amoswapd,196 amoswapd,
192 amoaddd,197 amoaddd,
193 amoandd,198 amoandd,
...@@ -237,8 +242,6 @@ pub const Mnemonic = enum(u16) {...@@ -237,8 +242,6 @@ pub const Mnemonic = enum(u16) {
237 pseudo_compare,242 pseudo_compare,
238 pseudo_not,243 pseudo_not,
239 pseudo_extern_fn_reloc,244 pseudo_extern_fn_reloc,
240 pseudo_fence,
241 pseudo_amo,
242};245};
243246
244pub const Pseudo = enum(u8) {247pub const Pseudo = enum(u8) {