Skip to content

Commit 7bc02ad

Browse files
feat(aarch64): implement llvm.aarch64.crc32{,c}{b,h,w,x} intrinsics
Lower the eight CRC32 LLVM intrinsics to crc32{,c}{b,h,w,x} inline assembly via the existing codegen_inline_asm_inner helper, mirroring the existing x86 sse42.crc32 lowering. Unblocks crc32fast on aarch64-{apple-darwin,unknown-linux-*}, which is pulled in transitively by png -> image and Bevy's PNG screenshot path.
1 parent e517ab9 commit 7bc02ad

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

src/intrinsics/llvm_aarch64.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,56 @@ pub(super) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
494494
});
495495
}
496496
*/
497+
"llvm.aarch64.crc32b"
498+
| "llvm.aarch64.crc32h"
499+
| "llvm.aarch64.crc32w"
500+
| "llvm.aarch64.crc32x"
501+
| "llvm.aarch64.crc32cb"
502+
| "llvm.aarch64.crc32ch"
503+
| "llvm.aarch64.crc32cw"
504+
| "llvm.aarch64.crc32cx" => {
505+
// ARM ARM v8-A: CRC32{,C}{B,H,W,X}.
506+
// Backs core::arch::aarch64::__crc32{,c}{b,h,w,d}.
507+
intrinsic_args!(fx, args => (crc, v); intrinsic);
508+
509+
let crc = crc.load_scalar(fx);
510+
let v = v.load_scalar(fx);
511+
512+
let asm = match intrinsic {
513+
"llvm.aarch64.crc32b" => "crc32b w0, w0, w1",
514+
"llvm.aarch64.crc32h" => "crc32h w0, w0, w1",
515+
"llvm.aarch64.crc32w" => "crc32w w0, w0, w1",
516+
"llvm.aarch64.crc32x" => "crc32x w0, w0, x1",
517+
"llvm.aarch64.crc32cb" => "crc32cb w0, w0, w1",
518+
"llvm.aarch64.crc32ch" => "crc32ch w0, w0, w1",
519+
"llvm.aarch64.crc32cw" => "crc32cw w0, w0, w1",
520+
"llvm.aarch64.crc32cx" => "crc32cx w0, w0, x1",
521+
_ => unreachable!(),
522+
};
523+
524+
codegen_inline_asm_inner(
525+
fx,
526+
&[InlineAsmTemplatePiece::String(asm.into())],
527+
&[
528+
CInlineAsmOperand::InOut {
529+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
530+
AArch64InlineAsmReg::x0,
531+
)),
532+
_late: true,
533+
in_value: crc,
534+
out_place: Some(ret),
535+
},
536+
CInlineAsmOperand::In {
537+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::AArch64(
538+
AArch64InlineAsmReg::x1,
539+
)),
540+
value: v,
541+
},
542+
],
543+
InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
544+
);
545+
}
546+
497547
_ => {
498548
fx.tcx.dcx().warn(format!(
499549
"unsupported AArch64 llvm intrinsic {}; replacing with trap",

0 commit comments

Comments
 (0)