@@ -564,56 +564,71 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
564564 _ => unimplemented ! ( ) ,
565565 }
566566 } ,
567+ // They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
567568 InlineAsmRegOrRegClass :: RegClass ( reg) => match reg {
568- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: preg) => unimplemented ! ( ) ,
569- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: reg) => unimplemented ! ( ) ,
570- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg) => unimplemented ! ( ) ,
571- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg_low16) => unimplemented ! ( ) ,
572- InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
569+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: reg) => "r" ,
570+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg) => "w" ,
571+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg_low16) => "x" ,
572+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: preg) => {
573+ unreachable ! ( "clobber-only" )
574+ }
575+ InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: reg) => "r" ,
573576 InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg)
574577 | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low16)
575- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low8) => unimplemented ! ( ) ,
576- InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg_low16)
578+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low8)
579+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg_low16)
577580 | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low8)
578- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low4) => unimplemented ! ( ) ,
579- InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg)
580- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg) => unimplemented ! ( ) ,
581- InlineAsmRegClass :: Avr ( _) => unimplemented ! ( ) ,
582- InlineAsmRegClass :: Bpf ( _) => unimplemented ! ( ) ,
583- InlineAsmRegClass :: Hexagon ( HexagonInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
584- InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
585- InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: freg) => unimplemented ! ( ) ,
586- InlineAsmRegClass :: Msp430 ( _) => unimplemented ! ( ) ,
587- InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg16) => unimplemented ! ( ) ,
588- InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg32) => unimplemented ! ( ) ,
589- InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg64) => unimplemented ! ( ) ,
590- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
591- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg_nonzero) => unimplemented ! ( ) ,
592- InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: freg) => unimplemented ! ( ) ,
581+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low4)
582+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg)
583+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg) => "t" ,
584+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg) => "r" ,
585+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_upper) => "d" ,
586+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_pair) => "r" ,
587+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_iw) => "w" ,
588+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_ptr) => "e" ,
589+ InlineAsmRegClass :: Bpf ( BpfInlineAsmRegClass :: reg) => "r" ,
590+ InlineAsmRegClass :: Bpf ( BpfInlineAsmRegClass :: wreg) => "w" ,
591+ InlineAsmRegClass :: Hexagon ( HexagonInlineAsmRegClass :: reg) => "r" ,
592+ InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: reg) => "d" , // more specific than "r"
593+ InlineAsmRegClass :: Mips ( MipsInlineAsmRegClass :: freg) => "f" ,
594+ InlineAsmRegClass :: Msp430 ( Msp430InlineAsmRegClass :: reg) => "r" ,
595+ // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for
596+ // "define_constraint".
597+ InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg16) => "h" ,
598+ InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg32) => "r" ,
599+ InlineAsmRegClass :: Nvptx ( NvptxInlineAsmRegClass :: reg64) => "l" ,
600+
601+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg) => "r" ,
602+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: reg_nonzero) => "b" ,
603+ InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: freg) => "f" ,
593604 InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: cr)
594605 | InlineAsmRegClass :: PowerPC ( PowerPCInlineAsmRegClass :: xer) => {
595606 unreachable ! ( "clobber-only" )
596607 } ,
597- InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
598- InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: freg) => unimplemented ! ( ) ,
599- InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: vreg) => unimplemented ! ( ) ,
608+ InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: reg) => "r" ,
609+ InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: freg) => "f" ,
610+ InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: vreg) => {
611+ unreachable ! ( "clobber-only" )
612+ }
600613 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg) => "r" ,
601614 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg_abcd) => "Q" ,
602615 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg_byte) => "q" ,
603616 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: xmm_reg)
604617 | InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: ymm_reg) => "x" ,
605618 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: zmm_reg) => "v" ,
606619 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: kreg) => "Yk" ,
607- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: kreg0) => unimplemented ! ( ) ,
608- InlineAsmRegClass :: Wasm ( WasmInlineAsmRegClass :: local) => unimplemented ! ( ) ,
609620 InlineAsmRegClass :: X86 (
610- X86InlineAsmRegClass :: x87_reg | X86InlineAsmRegClass :: mmx_reg | X86InlineAsmRegClass :: tmm_reg,
621+ X86InlineAsmRegClass :: kreg0
622+ | X86InlineAsmRegClass :: x87_reg
623+ | X86InlineAsmRegClass :: mmx_reg
624+ | X86InlineAsmRegClass :: tmm_reg,
611625 ) => unreachable ! ( "clobber-only" ) ,
612626 InlineAsmRegClass :: SpirV ( SpirVInlineAsmRegClass :: reg) => {
613627 bug ! ( "GCC backend does not support SPIR-V" )
614628 }
615- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
616- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: freg) => unimplemented ! ( ) ,
629+ InlineAsmRegClass :: Wasm ( WasmInlineAsmRegClass :: local) => "r" ,
630+ InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: reg) => "r" ,
631+ InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: freg) => "f" ,
617632 InlineAsmRegClass :: Err => unreachable ! ( ) ,
618633 }
619634 } ;
@@ -691,7 +706,10 @@ impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
691706 && options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
692707
693708 // Build the template string
694- let mut template_str = String :: new ( ) ;
709+ let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
710+ if att_dialect {
711+ template_str. push_str ( ".att_syntax\n " ) ;
712+ }
695713 for piece in template {
696714 match * piece {
697715 InlineAsmTemplatePiece :: String ( ref string) => {
@@ -739,48 +757,51 @@ impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
739757 }
740758 }
741759
742- let template_str =
743- if att_dialect {
744- format ! ( ".att_syntax\n \t {}\n \t .intel_syntax noprefix" , template_str)
745- }
746- else {
747- template_str
748- } ;
760+ if att_dialect {
761+ template_str. push_str ( "\n \t .intel_syntax noprefix" ) ;
762+ }
749763 // NOTE: seems like gcc will put the asm in the wrong section, so set it to .text manually.
750- let template_str = format ! ( ".pushsection .text \n {} \n .popsection", template_str ) ;
764+ template_str. push_str ( " \n .popsection") ;
751765 self . context . add_top_level_asm ( None , & template_str) ;
752766 }
753767}
754768
755769fn modifier_to_gcc ( arch : InlineAsmArch , reg : InlineAsmRegClass , modifier : Option < char > ) -> Option < char > {
770+ // The modifiers can be retrieved from
771+ // https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html#Modifiers
756772 match reg {
757773 InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: reg) => modifier,
758- InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: preg) => modifier,
759774 InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg)
760775 | InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: vreg_low16) => {
761- unimplemented ! ( )
776+ if modifier == Some ( 'v' ) { None } else { modifier }
777+ }
778+ InlineAsmRegClass :: AArch64 ( AArch64InlineAsmRegClass :: preg) => {
779+ unreachable ! ( "clobber-only" )
762780 }
763- InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
781+ InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: reg) => None ,
764782 InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg)
765- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg_low16) => unimplemented ! ( ) ,
783+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: sreg_low16) => None ,
766784 InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg)
767785 | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low16)
768- | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low8) => unimplemented ! ( ) ,
786+ | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: dreg_low8) => Some ( 'P' ) ,
769787 InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg)
770788 | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low8)
771789 | InlineAsmRegClass :: Arm ( ArmInlineAsmRegClass :: qreg_low4) => {
772- unimplemented ! ( )
790+ if modifier. is_none ( ) {
791+ Some ( 'q' )
792+ } else {
793+ modifier
794+ }
773795 }
774- InlineAsmRegClass :: Avr ( _) => unimplemented ! ( ) ,
775- InlineAsmRegClass :: Bpf ( _) => unimplemented ! ( ) ,
776- InlineAsmRegClass :: Hexagon ( _) => unimplemented ! ( ) ,
777- InlineAsmRegClass :: Mips ( _) => unimplemented ! ( ) ,
778- InlineAsmRegClass :: Msp430 ( _) => unimplemented ! ( ) ,
779- InlineAsmRegClass :: Nvptx ( _) => unimplemented ! ( ) ,
780- InlineAsmRegClass :: PowerPC ( _) => unimplemented ! ( ) ,
796+ InlineAsmRegClass :: Hexagon ( _) => None ,
797+ InlineAsmRegClass :: Mips ( _) => None ,
798+ InlineAsmRegClass :: Nvptx ( _) => None ,
799+ InlineAsmRegClass :: PowerPC ( _) => None ,
781800 InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: reg)
782- | InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: freg) => unimplemented ! ( ) ,
783- InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: vreg) => unimplemented ! ( ) ,
801+ | InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: freg) => None ,
802+ InlineAsmRegClass :: RiscV ( RiscVInlineAsmRegClass :: vreg) => {
803+ unreachable ! ( "clobber-only" )
804+ }
784805 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg)
785806 | InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: reg_abcd) => match modifier {
786807 None => if arch == InlineAsmArch :: X86_64 { Some ( 'q' ) } else { Some ( 'k' ) } ,
@@ -804,16 +825,29 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
804825 _ => unreachable ! ( ) ,
805826 } ,
806827 InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: kreg) => None ,
807- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: kreg0) => None ,
808- InlineAsmRegClass :: X86 ( X86InlineAsmRegClass :: x87_reg | X86InlineAsmRegClass :: mmx_reg | X86InlineAsmRegClass :: tmm_reg) => {
828+ InlineAsmRegClass :: X86 (
829+ X86InlineAsmRegClass :: x87_reg
830+ | X86InlineAsmRegClass :: mmx_reg
831+ | X86InlineAsmRegClass :: kreg0
832+ | X86InlineAsmRegClass :: tmm_reg,
833+ ) => {
809834 unreachable ! ( "clobber-only" )
810835 }
811- InlineAsmRegClass :: Wasm ( WasmInlineAsmRegClass :: local) => unimplemented ! ( ) ,
836+ InlineAsmRegClass :: Wasm ( WasmInlineAsmRegClass :: local) => None ,
837+ InlineAsmRegClass :: Bpf ( _) => None ,
838+ InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_pair)
839+ | InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_iw)
840+ | InlineAsmRegClass :: Avr ( AvrInlineAsmRegClass :: reg_ptr) => match modifier {
841+ Some ( 'h' ) => Some ( 'B' ) ,
842+ Some ( 'l' ) => Some ( 'A' ) ,
843+ _ => None ,
844+ } ,
845+ InlineAsmRegClass :: Avr ( _) => None ,
846+ InlineAsmRegClass :: S390x ( _) => None ,
847+ InlineAsmRegClass :: Msp430 ( _) => None ,
812848 InlineAsmRegClass :: SpirV ( SpirVInlineAsmRegClass :: reg) => {
813849 bug ! ( "LLVM backend does not support SPIR-V" )
814- } ,
815- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: reg) => unimplemented ! ( ) ,
816- InlineAsmRegClass :: S390x ( S390xInlineAsmRegClass :: freg) => unimplemented ! ( ) ,
850+ }
817851 InlineAsmRegClass :: Err => unreachable ! ( ) ,
818852 }
819853}
0 commit comments