mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
riscv: 16 bit @byteSwap
This commit is contained in:
parent
b2150094ba
commit
f67fa73fe8
@ -1537,9 +1537,47 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
|
||||
fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
|
||||
if (true)
|
||||
return self.fail("TODO: airByteSwap", .{});
|
||||
break :result undefined;
|
||||
const mod = self.bin_file.comp.module.?;
|
||||
const ty = self.typeOf(ty_op.operand);
|
||||
const operand = try self.resolveInst(ty_op.operand);
|
||||
|
||||
const int_bits = ty.intInfo(mod).bits;
|
||||
|
||||
// bytes are no-op
|
||||
if (int_bits == 8 and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
|
||||
return self.finishAir(inst, operand, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
const dest_reg = try self.register_manager.allocReg(null, gp);
|
||||
try self.genSetReg(ty, dest_reg, operand);
|
||||
|
||||
const dest_mcv: MCValue = .{ .register = dest_reg };
|
||||
|
||||
switch (int_bits) {
|
||||
16 => {
|
||||
const temp = try self.binOp(.shr, null, dest_mcv, .{ .immediate = 8 }, ty, Type.u8);
|
||||
assert(temp == .register);
|
||||
_ = try self.addInst(.{
|
||||
.tag = .slli,
|
||||
.data = .{ .i_type = .{
|
||||
.imm12 = 8,
|
||||
.rd = dest_reg,
|
||||
.rs1 = dest_reg,
|
||||
} },
|
||||
});
|
||||
_ = try self.addInst(.{
|
||||
.tag = .@"or",
|
||||
.data = .{ .r_type = .{
|
||||
.rd = dest_reg,
|
||||
.rs1 = dest_reg,
|
||||
.rs2 = temp.register,
|
||||
} },
|
||||
});
|
||||
},
|
||||
else => return self.fail("TODO: {d} bits for airByteSwap", .{int_bits}),
|
||||
}
|
||||
|
||||
break :result dest_mcv;
|
||||
};
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@ pub fn emitMir(
|
||||
switch (tag) {
|
||||
.add => try emit.mirRType(inst),
|
||||
.sub => try emit.mirRType(inst),
|
||||
.@"or" => try emit.mirRType(inst),
|
||||
|
||||
.cmp_eq => try emit.mirRType(inst),
|
||||
.cmp_gt => try emit.mirRType(inst),
|
||||
@ -191,6 +192,7 @@ fn mirRType(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
},
|
||||
.sllw => try emit.writeInstruction(Instruction.sllw(rd, rs1, rs2)),
|
||||
.srlw => try emit.writeInstruction(Instruction.srlw(rd, rs1, rs2)),
|
||||
.@"or" => try emit.writeInstruction(Instruction.@"or"(rd, rs1, rs2)),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,9 @@ pub const Inst = struct {
|
||||
ebreak,
|
||||
ecall,
|
||||
|
||||
/// OR instruction. Uses r_type payload.
|
||||
@"or",
|
||||
|
||||
/// Addition
|
||||
add,
|
||||
/// Subtraction
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user