@@ -611,114 +611,127 @@ fn estimate_template_length(
611611}
612612
613613/// Converts a register class to a GCC constraint code.
614- fn reg_to_gcc ( reg : InlineAsmRegOrRegClass ) -> ConstraintOrRegister {
615- let constraint = match reg {
616- // For vector registers LLVM wants the register name to match the type size.
614+ fn reg_to_gcc ( reg_or_reg_class : InlineAsmRegOrRegClass ) -> ConstraintOrRegister {
615+ match reg_or_reg_class {
617616 InlineAsmRegOrRegClass :: Reg ( reg) => {
618- match reg {
619- InlineAsmReg :: X86 ( _) => {
620- // TODO(antoyo): add support for vector register.
621- //
622- // // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119
623- return ConstraintOrRegister :: Register ( match reg. name ( ) {
624- // Some of registers' names does not map 1-1 from rust to gcc
625- "st(0)" => "st" ,
617+ ConstraintOrRegister :: Register ( explicit_reg_to_gcc ( reg) )
618+ }
619+ InlineAsmRegOrRegClass :: RegClass ( reg_class) => {
620+ ConstraintOrRegister :: Constraint ( reg_class_to_gcc ( reg_class) )
621+ }
622+ }
623+ }
626624
627- name => name,
628- } ) ;
625+ fn explicit_reg_to_gcc ( reg : InlineAsmReg ) -> & ' static str {
626+ // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119
627+ match reg {
628+ InlineAsmReg :: X86 ( reg) => {
629+ // TODO(antoyo): add support for vector register.
630+ match reg. reg_class ( ) {
631+ X86InlineAsmRegClass :: reg_byte => {
632+ // GCC does not support the `b` suffix, so we just strip it
633+ // see https://github.com/rust-lang/rustc_codegen_gcc/issues/485
634+ reg. name ( ) . trim_end_matches ( 'b' )
629635 }
636+ _ => match reg. name ( ) {
637+ // Some of registers' names does not map 1-1 from rust to gcc
638+ "st(0)" => "st" ,
630639
631- _ => unimplemented ! ( ) ,
640+ name => name,
641+ } ,
632642 }
633643 }
634- // They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
635- InlineAsmRegOrRegClass :: RegClass ( reg) => match reg {
636- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: reg) => "r" ,
637- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg) => "w" ,
638- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg_low16) => "x" ,
639- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: preg) => {
640- unreachable ! ( "clobber-only" )
641- }
642- InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: reg) => "r" ,
643- InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg)
644- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low16)
645- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low8)
646- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg_low16)
647- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low8)
648- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low4)
649- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg)
650- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg) => "t" ,
651- InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg) => "r" ,
652- InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_upper) => "d" ,
653- InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_pair) => "r" ,
654- InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_iw) => "w" ,
655- InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_ptr) => "e" ,
656- InlineAsmRegClass :: Bpf ( BpfInlineAsmRegClass :: reg) => "r" ,
657- InlineAsmRegClass :: Bpf ( BpfInlineAsmRegClass :: wreg) => "w" ,
658- InlineAsmRegClass :: Hexagon ( HexagonInlineAsmRegClass :: reg) => "r" ,
659- InlineAsmRegClass :: Hexagon ( HexagonInlineAsmRegClass :: preg) => {
660- unreachable ! ( "clobber-only" )
661- }
662- InlineAsmRegClass :: LoongArch ( LoongArchInlineAsmRegClass :: reg) => "r" ,
663- InlineAsmRegClass :: LoongArch ( LoongArchInlineAsmRegClass :: freg) => "f" ,
664- InlineAsmRegClass :: M68k ( M68kInlineAsmRegClass :: reg) => "r" ,
665- InlineAsmRegClass :: M68k ( M68kInlineAsmRegClass :: reg_addr) => "a" ,
666- InlineAsmRegClass :: M68k ( M68kInlineAsmRegClass :: reg_data) => "d" ,
667- InlineAsmRegClass :: CSKY ( CSKYInlineAsmRegClass :: reg) => "r" ,
668- InlineAsmRegClass :: CSKY ( CSKYInlineAsmRegClass :: freg) => "f" ,
669- InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: reg) => "d" , // more specific than "r"
670- InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: freg) => "f" ,
671- InlineAsmRegClass :: Msp430 ( Msp430InlineAsmRegClass :: reg) => "r" ,
672- // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for
673- // "define_constraint".
674- InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg16) => "h" ,
675- InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg32) => "r" ,
676- InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg64) => "l" ,
677-
678- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg) => "r" ,
679- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg_nonzero) => "b" ,
680- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: freg) => "f" ,
681- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: vreg) => "v" ,
682- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: cr)
683- | InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: xer) => {
684- unreachable ! ( "clobber-only" )
685- }
686- InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: reg) => "r" ,
687- InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: freg) => "f" ,
688- InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: vreg) => {
689- unreachable ! ( "clobber-only" )
690- }
691- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg) => "r" ,
692- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg_abcd) => "Q" ,
693- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg_byte) => "q" ,
694- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: xmm_reg)
695- | InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: ymm_reg) => "x" ,
696- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: zmm_reg) => "v" ,
697- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: kreg) => "Yk" ,
698- InlineAsmRegClass :: X86 (
699- X86InlineAsmRegClass :: kreg0
700- | X86InlineAsmRegClass :: x87_reg
701- | X86InlineAsmRegClass :: mmx_reg
702- | X86InlineAsmRegClass :: tmm_reg,
703- ) => unreachable ! ( "clobber-only" ) ,
704- InlineAsmRegClass :: SpirV ( SpirVInlineAsmRegClass :: reg) => {
705- bug ! ( "GCC backend does not support SPIR-V" )
706- }
707- InlineAsmRegClass :: Wasm ( WasmInlineAsmRegClass :: local) => "r" ,
708- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: reg) => "r" ,
709- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: reg_addr) => "a" ,
710- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: freg) => "f" ,
711- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: vreg) => "v" ,
712- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: areg) => {
713- unreachable ! ( "clobber-only" )
714- }
715- InlineAsmRegClass :: Sparc ( SparcInlineAsmRegClass :: reg) => "r" ,
716- InlineAsmRegClass :: Sparc ( SparcInlineAsmRegClass :: yreg) => unreachable ! ( "clobber-only" ) ,
717- InlineAsmRegClass :: Err => unreachable ! ( ) ,
718- } ,
719- } ;
720644
721- ConstraintOrRegister :: Constraint ( constraint)
645+ _ => unimplemented ! ( ) ,
646+ }
647+ }
648+
649+ /// They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
650+ fn reg_class_to_gcc ( reg_class : InlineAsmRegClass ) -> & ' static str {
651+ match reg_class {
652+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: reg) => "r" ,
653+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg) => "w" ,
654+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg_low16) => "x" ,
655+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: preg) => {
656+ unreachable ! ( "clobber-only" )
657+ }
658+ InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: reg) => "r" ,
659+ InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg)
660+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low16)
661+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low8)
662+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg_low16)
663+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low8)
664+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low4)
665+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg)
666+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg) => "t" ,
667+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg) => "r" ,
668+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_upper) => "d" ,
669+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_pair) => "r" ,
670+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_iw) => "w" ,
671+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_ptr) => "e" ,
672+ InlineAsmRegClass :: Bpf ( BpfInlineAsmRegClass :: reg) => "r" ,
673+ InlineAsmRegClass :: Bpf ( BpfInlineAsmRegClass :: wreg) => "w" ,
674+ InlineAsmRegClass :: Hexagon ( HexagonInlineAsmRegClass :: reg) => "r" ,
675+ InlineAsmRegClass :: Hexagon ( HexagonInlineAsmRegClass :: preg) => {
676+ unreachable ! ( "clobber-only" )
677+ }
678+ InlineAsmRegClass :: LoongArch ( LoongArchInlineAsmRegClass :: reg) => "r" ,
679+ InlineAsmRegClass :: LoongArch ( LoongArchInlineAsmRegClass :: freg) => "f" ,
680+ InlineAsmRegClass :: M68k ( M68kInlineAsmRegClass :: reg) => "r" ,
681+ InlineAsmRegClass :: M68k ( M68kInlineAsmRegClass :: reg_addr) => "a" ,
682+ InlineAsmRegClass :: M68k ( M68kInlineAsmRegClass :: reg_data) => "d" ,
683+ InlineAsmRegClass :: CSKY ( CSKYInlineAsmRegClass :: reg) => "r" ,
684+ InlineAsmRegClass :: CSKY ( CSKYInlineAsmRegClass :: freg) => "f" ,
685+ InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: reg) => "d" , // more specific than "r"
686+ InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: freg) => "f" ,
687+ InlineAsmRegClass :: Msp430 ( Msp430InlineAsmRegClass :: reg) => "r" ,
688+ // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for
689+ // "define_constraint".
690+ InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg16) => "h" ,
691+ InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg32) => "r" ,
692+ InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg64) => "l" ,
693+
694+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg) => "r" ,
695+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg_nonzero) => "b" ,
696+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: freg) => "f" ,
697+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: vreg) => "v" ,
698+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: cr)
699+ | InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: xer) => {
700+ unreachable ! ( "clobber-only" )
701+ }
702+ InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: reg) => "r" ,
703+ InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: freg) => "f" ,
704+ InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: vreg) => {
705+ unreachable ! ( "clobber-only" )
706+ }
707+ InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg) => "r" ,
708+ InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg_abcd) => "Q" ,
709+ InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg_byte) => "q" ,
710+ InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: xmm_reg)
711+ | InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: ymm_reg) => "x" ,
712+ InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: zmm_reg) => "v" ,
713+ InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: kreg) => "Yk" ,
714+ InlineAsmRegClass :: X86 (
715+ X86InlineAsmRegClass :: kreg0
716+ | X86InlineAsmRegClass :: x87_reg
717+ | X86InlineAsmRegClass :: mmx_reg
718+ | X86InlineAsmRegClass :: tmm_reg,
719+ ) => unreachable ! ( "clobber-only" ) ,
720+ InlineAsmRegClass :: SpirV ( SpirVInlineAsmRegClass :: reg) => {
721+ bug ! ( "GCC backend does not support SPIR-V" )
722+ }
723+ InlineAsmRegClass :: Wasm ( WasmInlineAsmRegClass :: local) => "r" ,
724+ InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: reg) => "r" ,
725+ InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: reg_addr) => "a" ,
726+ InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: freg) => "f" ,
727+ InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: vreg) => "v" ,
728+ InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: areg) => {
729+ unreachable ! ( "clobber-only" )
730+ }
731+ InlineAsmRegClass :: Sparc ( SparcInlineAsmRegClass :: reg) => "r" ,
732+ InlineAsmRegClass :: Sparc ( SparcInlineAsmRegClass :: yreg) => unreachable ! ( "clobber-only" ) ,
733+ InlineAsmRegClass :: Err => unreachable ! ( ) ,
734+ }
722735}
723736
724737/// Type to use for outputs that are discarded. It doesn't really matter what
0 commit comments