Adds Bswap to the Cranelift IR. Implements the Bswap instruction in the x64 and aarch64 codegen backends. Cranelift users can now: ``` builder.ins().bswap(value) ``` to get a native byteswap instruction. * x64: implements the 32- and 64-bit bswap instruction, following the pattern set by similar unary instrutions (Neg and Not) - it only operates on a dst register, but is parameterized with both a src and dst which are expected to be the same register. As x64 bswap instruction is only for 32- or 64-bit registers, the 16-bit swap is implemented as a rotate left by 8. Updated x64 RexFlags type to support emitting for single-operand instructions like bswap * aarch64: Bswap gets emitted as aarch64 rev16, rev32, or rev64 instruction as appropriate. * s390x: Bswap was already supported in backend, just had to add a bit of plumbing * For completeness, added bswap to the interpreter as well. * added filetests and runtests for each ISA * added bswap to fuzzgen, thanks to afonso360 for the code there * 128-bit swaps are not yet implemented, that can be done later
This commit is contained in:
@@ -68,6 +68,7 @@ impl Inst {
|
||||
Inst::AluRmiR { .. }
|
||||
| Inst::AluRM { .. }
|
||||
| Inst::AtomicRmwSeq { .. }
|
||||
| Inst::Bswap { .. }
|
||||
| Inst::CallKnown { .. }
|
||||
| Inst::CallUnknown { .. }
|
||||
| Inst::CheckedDivOrRemSeq { .. }
|
||||
@@ -1373,6 +1374,17 @@ impl PrettyPrint for Inst {
|
||||
format!("{} {}", ljustify2("set".to_string(), cc.to_string()), dst)
|
||||
}
|
||||
|
||||
Inst::Bswap { size, src, dst } => {
|
||||
let src = pretty_print_reg(src.to_reg(), size.to_bytes(), allocs);
|
||||
let dst = pretty_print_reg(dst.to_reg().to_reg(), size.to_bytes(), allocs);
|
||||
format!(
|
||||
"{} {}, {}",
|
||||
ljustify2("bswap".to_string(), suffix_bwlq(*size)),
|
||||
src,
|
||||
dst
|
||||
)
|
||||
}
|
||||
|
||||
Inst::Cmove {
|
||||
size,
|
||||
cc,
|
||||
@@ -1953,6 +1965,10 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
|
||||
Inst::Setcc { dst, .. } => {
|
||||
collector.reg_def(dst.to_writable_reg());
|
||||
}
|
||||
Inst::Bswap { src, dst, .. } => {
|
||||
collector.reg_use(src.to_reg());
|
||||
collector.reg_reuse_def(dst.to_writable_reg(), 0);
|
||||
}
|
||||
Inst::Cmove {
|
||||
consequent,
|
||||
alternative,
|
||||
|
||||
Reference in New Issue
Block a user