@@ -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