<s> if ( ! MI -> isFullCopy ( ) ) return MI ; if ( ! TRI -> isVirtualRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return nullptr ;

MachineInstr * Def = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ;


<s> MachineInstr * A15SDOptimizer :: elideCopies ( MachineInstr * MI ) { if ( ! MI -> isFullCopy ( ) ) return MI ; if ( ! TRI -> isVirtualRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return nullptr ; MachineInstr * Def = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( ! Def ) return nullptr ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << * MI << <STR_LIT> ) ; Front . push_back ( MI ) ; while ( Front . size ( ) != <NUM_LIT> ) { MI = Front . back ( ) ; Front . pop_back ( ) ; for ( unsigned int i = <NUM_LIT> ; i < MI -> getNumOperands ( ) ; ++ i ) { MachineOperand & MO = MI -> getOperand ( i ) ; if ( ( ! MO . isReg ( ) ) || ( ! MO . isUse ( ) ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( Reg ) ) continue ; MachineOperand * Op = MI -> findRegisterDefOperand ( Reg ) ; if ( ! Op ) continue ; MachineInstr * Def = Op -> getParent ( ) ; if ( DeadInstr . find ( Def ) != DeadInstr . end ( ) ) continue ; bool IsDead = true ; for ( unsigned int j = <NUM_LIT> ; j < Def -> getNumOperands ( ) ; ++ j ) { MachineOperand & MODef = Def -> getOperand ( j ) ; if ( ( ! MODef . isReg ( ) ) || ( ! MODef . isDef ( ) ) ) continue ; unsigned DefReg = MODef . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( DefReg ) ) { IsDead = false ; break ; } for ( MachineRegisterInfo :: use_instr_iterator II = MRI -> use_instr_begin ( Reg ) , EE = MRI -> use_instr_end ( ) ; II != EE ; ++ II ) { if ( & * II == Def ) continue ; if ( DeadInstr . find ( & * II ) == DeadInstr . end ( ) ) { IsDead = false ; break ; } } } if ( ! IsDead ) continue ; DEBUG ( dbgs ( ) << <STR_LIT> << * Def << <STR_LIT> ) ; DeadInstr . insert ( Def ) ; }


<s> if ( ! MO . isReg ( ) || ! MO . isUse ( ) ) continue ; if ( ! usesRegClass ( MO , & <STR_LIT> ) && ! usesRegClass ( MO , & <STR_LIT> ) && ! usesRegClass ( MO , & <STR_LIT> ) ) continue ; Defs . push_back ( MO . getReg ( ) ) ; }


<s> unsigned DSub1 = createExtractSubreg ( MBB , InsertPt , DL , Reg , <STR_LIT> , & <STR_LIT> ) ; unsigned Out1 = createDupLane ( MBB , InsertPt , DL , DSub0 , <NUM_LIT> ) ; unsigned Out2 = createDupLane ( MBB , InsertPt , DL , DSub0 , <NUM_LIT> ) ; Out = createVExt ( MBB , InsertPt , DL , Out1 , Out2 ) ; unsigned Out3 = createDupLane ( MBB , InsertPt , DL , DSub1 , <NUM_LIT> ) ; unsigned Out4 = createDupLane ( MBB , InsertPt , DL , DSub1 , <NUM_LIT> ) ; Out2 = createVExt ( MBB , InsertPt , DL , Out3 , Out4 ) ; Out = createRegSequence ( MBB , InsertPt , DL , Out , Out2 ) ; } else if ( MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( & <STR_LIT> ) ) { unsigned Out1 = createDupLane ( MBB , InsertPt , DL , Reg , <NUM_LIT> ) ; unsigned Out2 = createDupLane ( MBB , InsertPt , DL , Reg , <NUM_LIT> ) ; Out = createVExt ( MBB , InsertPt , DL , Out1 , Out2 ) ; } else { assert ( MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( & <STR_LIT> ) && <STR_LIT> ) ; unsigned PrefLane = getPrefSPRLane ( Reg ) ; unsigned Lane ; switch ( PrefLane ) { case <STR_LIT> : Lane = <NUM_LIT> ; break ; case <STR_LIT> : Lane = <NUM_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } bool UsesQPR = usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) || usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ; Out = createImplicitDef ( MBB , InsertPt , DL ) ; Out = createInsertSubreg ( MBB , InsertPt , DL , Out , PrefLane , Reg ) ; Out = createDupLane ( MBB , InsertPt , DL , Out , Lane , UsesQPR ) ; eraseInstrWithNoUses ( MI ) ; }


<s> MachineInstr * EC = elideCopies ( SPRMI ) ; if ( EC && EC -> isCopy ( ) && EC -> getOperand ( <NUM_LIT> ) . getSubReg ( ) == <STR_LIT> ) { DEBUG ( dbgs ( ) << <STR_LIT> << * SPRMI ) ; unsigned FullReg = SPRMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; const TargetRegisterClass * TRC = MRI -> getRegClass ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( TRC -> hasSuperClassEq ( MRI -> getRegClass ( FullReg ) ) ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; DEBUG ( dbgs ( ) << PrintReg ( FullReg ) << <STR_LIT> ) ; eraseInstrWithNoUses ( MI ) ; return FullReg ; } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } if ( MI -> isRegSequence ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { unsigned NumImplicit = <NUM_LIT> , NumTotal = <NUM_LIT> ; unsigned NonImplicitReg = ~ <NUM_LIT> ; for ( unsigned I = <NUM_LIT> ; I < MI -> getNumExplicitOperands ( ) ; ++ I ) { if ( ! MI -> getOperand ( I ) . isReg ( ) ) continue ; ++ NumTotal ;

unsigned OpReg = MI -> getOperand ( I ) . getReg ( ) ;


<s> unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << PrintReg ( NewReg ) << <STR_LIT> ) ;

( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ;


<s> Replacements . clear ( ) ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { for ( MachineBasicBlock :: iterator MI = MFI -> begin ( ) , ME = MFI -> end ( ) ; MI != ME ; ) { Modified |= runOnInstruction ( MI ++ ) ; } }

for ( std :: set < MachineInstr * > :: iterator I = DeadInstr . begin ( ) , E = DeadInstr . end ( ) ;


<s> DeadInstr . clear ( ) ; Replacements . clear ( ) ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { for ( MachineBasicBlock :: iterator MI = MFI -> begin ( ) , ME = MFI -> end ( ) ; MI != ME ; ) { Modified |= runOnInstruction ( MI ++ ) ; }


<s> A15SDOptimizer ( ) : MachineFunctionPass ( ID ) {


<s> FunctionPass * llvm :: createA15SDOptimizerPass ( ) {


<s> AddDefaultPred ( BuildMI ( MBB , InsertBefore , DL , TII -> get ( QPR ? <STR_LIT> : <STR_LIT> ) , Out ) . addReg ( Reg ) . addImm ( Lane ) ) ;


<s> unsigned Out = MRI -> createVirtualRegister ( QPR ? & <STR_LIT> : & <STR_LIT> ) ; AddDefaultPred ( BuildMI ( MBB , InsertBefore , DL , TII -> get ( QPR ? <STR_LIT> : <STR_LIT> ) , Out ) . addReg ( Reg ) . addImm ( Lane ) ) ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: COPY ) , Out ) . addReg ( DReg , <NUM_LIT> , Lane ) ;


<s> unsigned A15SDOptimizer :: createExtractSubreg ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , DebugLoc DL , unsigned DReg , unsigned Lane , const TargetRegisterClass * TRC ) { unsigned Out = MRI -> createVirtualRegister ( TRC ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: COPY ) , Out ) . addReg ( DReg , <NUM_LIT> , Lane ) ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: IMPLICIT_DEF ) , Out ) ; return Out ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: INSERT_SUBREG ) , Out ) . addReg ( DReg ) . addReg ( ToInsert ) . addImm ( Lane ) ;


<s> unsigned A15SDOptimizer :: createRegSequence ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , DebugLoc DL , unsigned Reg1 , unsigned Reg2 ) { unsigned Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: REG_SEQUENCE ) , Out ) . addReg ( Reg1 ) . addImm ( <STR_LIT> ) . addReg ( Reg2 ) . addImm ( <STR_LIT> ) ;


<s> unsigned Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: REG_SEQUENCE ) , Out ) . addReg ( Reg1 ) . addImm ( <STR_LIT> ) . addReg ( Reg2 ) . addImm ( <STR_LIT> ) ;


<s> unsigned Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ;

AddDefaultPred ( BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , Out ) . addReg ( Ssub0 ) . addReg ( Ssub1 ) . addImm ( <NUM_LIT> ) ) ;


<s> if ( ! MI -> isFullCopy ( ) ) return MI ;

if ( ! TRI -> isVirtualRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return NULL ;


<s> if ( Reached . find ( MI ) != Reached . end ( ) ) continue ; Reached . insert ( MI ) ; if ( MI -> isPHI ( ) ) { for ( unsigned I = <NUM_LIT> , E = MI -> getNumOperands ( ) ; I != E ; I += <NUM_LIT> ) { unsigned Reg = MI -> getOperand ( I ) . getReg ( ) ;

if ( ! TRI -> isVirtualRegister ( Reg ) ) {


<s> unsigned DefReg = MODef . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( DefReg ) ) { IsDead = false ; break ; } for ( MachineRegisterInfo :: use_iterator II = MRI -> use_begin ( Reg ) , EE = MRI -> use_end ( ) ; II != EE ; ++ II ) { if ( & * II == Def ) continue ; if ( DeadInstr . find ( & * II ) == DeadInstr . end ( ) ) { IsDead = false ; break ; } } } if ( ! IsDead ) continue ; DEBUG ( dbgs ( ) << <STR_LIT> << * Def << <STR_LIT> ) ; DeadInstr . insert ( Def ) ;


<s> unsigned A15SDOptimizer :: getDPRLaneFromSPR ( unsigned SReg ) { unsigned DReg = TRI -> getMatchingSuperReg ( SReg , <STR_LIT> , & <STR_LIT> ) ; if ( DReg != <STR_LIT> ) return <STR_LIT> ;


<s> unsigned A15SDOptimizer :: getDPRLaneFromSPR ( unsigned SReg ) { unsigned DReg = TRI -> getMatchingSuperReg ( SReg , <STR_LIT> , & <STR_LIT> ) ;

if ( DReg != <STR_LIT> ) return <STR_LIT> ;


<s> assert ( MO -> isReg ( ) && <STR_LIT> ) ; if ( ! MO ) return <STR_LIT> ; if ( MI -> isCopy ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { SReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ;


<s> for ( unsigned i = <NUM_LIT> ; i < MI -> getNumOperands ( ) ; ++ i ) { MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || ! MO . isUse ( ) ) continue ;

if ( ! usesRegClass ( MO , & <STR_LIT> ) && ! usesRegClass ( MO , & <STR_LIT> ) ) continue ;


<s> if ( MI -> isRegSequence ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) return true ; return false ;


<s> if ( MI -> isCopy ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) return true ; if ( MI -> isInsertSubreg ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) return true ; if ( MI -> isRegSequence ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) return true ;


<s> if ( MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( & <STR_LIT> ) ) { unsigned DSub0 = createExtractSubreg ( MBB , InsertPt , DL , Reg , <STR_LIT> , & <STR_LIT> ) ; unsigned DSub1 = createExtractSubreg ( MBB , InsertPt , DL , Reg , <STR_LIT> , & <STR_LIT> ) ; unsigned Out1 = createDupLane ( MBB , InsertPt , DL , DSub0 , <NUM_LIT> ) ; unsigned Out2 = createDupLane ( MBB , InsertPt , DL , DSub0 , <NUM_LIT> ) ; Out = createVExt ( MBB , InsertPt , DL , Out1 , Out2 ) ; unsigned Out3 = createDupLane ( MBB , InsertPt , DL , DSub1 , <NUM_LIT> ) ; unsigned Out4 = createDupLane ( MBB , InsertPt , DL , DSub1 , <NUM_LIT> ) ; Out2 = createVExt ( MBB , InsertPt , DL , Out3 , Out4 ) ; Out = createRegSequence ( MBB , InsertPt , DL , Out , Out2 ) ; } else if ( MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( & <STR_LIT> ) ) { unsigned Out1 = createDupLane ( MBB , InsertPt , DL , Reg , <NUM_LIT> ) ; unsigned Out2 = createDupLane ( MBB , InsertPt , DL , Reg , <NUM_LIT> ) ; Out = createVExt ( MBB , InsertPt , DL , Out1 , Out2 ) ; } else { assert ( MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( & <STR_LIT> ) && <STR_LIT> ) ; unsigned PrefLane = getPrefSPRLane ( Reg ) ; unsigned Lane ; switch ( PrefLane ) { case <STR_LIT> : Lane = <NUM_LIT> ; break ; case <STR_LIT> : Lane = <NUM_LIT> ; break ;

default : llvm_unreachable ( <STR_LIT> ) ;


<s> eraseInstrWithNoUses ( MI ) ; return FullReg ; } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } if ( MI -> isRegSequence ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { unsigned NumImplicit = <NUM_LIT> , NumTotal = <NUM_LIT> ; unsigned NonImplicitReg = ~ <NUM_LIT> ; for ( unsigned I = <NUM_LIT> ; I < MI -> getNumExplicitOperands ( ) ; ++ I ) { if ( ! MI -> getOperand ( I ) . isReg ( ) ) continue ; ++ NumTotal ; unsigned OpReg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( OpReg ) ) break ; MachineInstr * Def = MRI -> getVRegDef ( OpReg ) ; if ( ! Def ) break ; if ( Def -> isImplicitDef ( ) ) ++ NumImplicit ; else NonImplicitReg = MI -> getOperand ( I ) . getReg ( ) ; } if ( NumImplicit == NumTotal - <NUM_LIT> ) return optimizeAllLanesPattern ( MI , NonImplicitReg ) ;

else return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ;


<s> if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << PrintReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; } } Replacements [ MI ] = NewReg ;


<s> if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & I . getOperand ( ) ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << PrintReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; } }


<s> for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { for ( MachineBasicBlock :: iterator MI = MFI -> begin ( ) , ME = MFI -> end ( ) ; MI != ME ; ) { Modified |= runOnInstruction ( MI ++ ) ; } } for ( std :: set < MachineInstr * > :: iterator I = DeadInstr . begin ( ) , E = DeadInstr . end ( ) ; I != E ; ++ I ) { ( * I ) -> eraseFromParent ( ) ;


<s> bool A15SDOptimizer :: usesRegClass ( MachineOperand & MO , const TargetRegisterClass * TRC ) { if ( ! MO . isReg ( ) ) return false ; unsigned Reg = MO . getReg ( ) ; if ( TargetRegisterInfo :: isVirtualRegister ( Reg ) ) return MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( TRC ) ; else return TRC -> contains ( Reg ) ;


<s> if ( TargetRegisterInfo :: isVirtualRegister ( Reg ) ) return MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( TRC ) ;


<s> unsigned A15SDOptimizer :: createDupLane ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL , unsigned Reg , unsigned Lane , bool QPR ) { Register Out = MRI -> createVirtualRegister ( QPR ? & <STR_LIT> : & <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( QPR ? <STR_LIT> : <STR_LIT> ) , Out ) . addReg ( Reg ) . addImm ( Lane ) . add ( predOps ( <STR_LIT> ) ) ; return Out ;


<s> unsigned A15SDOptimizer :: createDupLane ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL , unsigned Reg , unsigned Lane , bool QPR ) {

Register Out = MRI -> createVirtualRegister ( QPR ? & <STR_LIT> : & <STR_LIT> ) ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: COPY ) , Out ) . addReg ( DReg , <NUM_LIT> , Lane ) ;


<s> unsigned A15SDOptimizer :: createImplicitDef ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL ) { Register Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: IMPLICIT_DEF ) , Out ) ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: INSERT_SUBREG ) , Out ) . addReg ( DReg ) . addReg ( ToInsert ) . addImm ( Lane ) ;


<s> unsigned A15SDOptimizer :: createRegSequence ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL , unsigned Reg1 , unsigned Reg2 ) { Register Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: REG_SEQUENCE ) , Out ) . addReg ( Reg1 ) . addImm ( <STR_LIT> ) . addReg ( Reg2 ) . addImm ( <STR_LIT> ) ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: REG_SEQUENCE ) , Out ) . addReg ( Reg1 ) . addImm ( <STR_LIT> ) . addReg ( Reg2 ) . addImm ( <STR_LIT> ) ; return Out ;


<s> unsigned A15SDOptimizer :: createVExt ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL , unsigned Ssub0 , unsigned Ssub1 ) { Register Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ;

BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , Out ) . addReg ( Ssub0 ) . addReg ( Ssub1 ) . addImm ( <NUM_LIT> ) . add ( predOps ( <STR_LIT> ) ) ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , Out ) . addReg ( Ssub0 ) . addReg ( Ssub1 ) . addImm ( <NUM_LIT> ) . add ( predOps ( <STR_LIT> ) ) ;


<s> if ( ! Register :: isVirtualRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return nullptr ; MachineInstr * Def = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ;


<s> MachineInstr * A15SDOptimizer :: elideCopies ( MachineInstr * MI ) { if ( ! MI -> isFullCopy ( ) ) return MI ; if ( ! Register :: isVirtualRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return nullptr ; MachineInstr * Def = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( ! Def ) return nullptr ;


<s> std :: set < MachineInstr * > Reached ; SmallVector < MachineInstr * , <NUM_LIT> > Front ; Front . push_back ( MI ) ; while ( Front . size ( ) != <NUM_LIT> ) { MI = Front . back ( ) ; Front . pop_back ( ) ; if ( Reached . find ( MI ) != Reached . end ( ) ) continue ; Reached . insert ( MI ) ; if ( MI -> isPHI ( ) ) { for ( unsigned I = <NUM_LIT> , E = MI -> getNumOperands ( ) ; I != E ; I += <NUM_LIT> ) { Register Reg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! Register :: isVirtualRegister ( Reg ) ) {


<s> Front . pop_back ( ) ; if ( Reached . find ( MI ) != Reached . end ( ) ) continue ; Reached . insert ( MI ) ; if ( MI -> isPHI ( ) ) { for ( unsigned I = <NUM_LIT> , E = MI -> getNumOperands ( ) ; I != E ; I += <NUM_LIT> ) { Register Reg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! Register :: isVirtualRegister ( Reg ) ) { continue ; } MachineInstr * NewMI = MRI -> getVRegDef ( Reg ) ; if ( ! NewMI ) continue ;


<s> if ( ! Register :: isVirtualRegister ( Reg ) ) continue ; MachineOperand * Op = MI -> findRegisterDefOperand ( Reg ) ; if ( ! Op ) continue ; MachineInstr * Def = Op -> getParent ( ) ; if ( DeadInstr . find ( Def ) != DeadInstr . end ( ) ) continue ; bool IsDead = true ; for ( MachineOperand & MODef : Def -> operands ( ) ) { if ( ( ! MODef . isReg ( ) ) || ( ! MODef . isDef ( ) ) ) continue ; Register DefReg = MODef . getReg ( ) ; if ( ! Register :: isVirtualRegister ( DefReg ) ) { IsDead = false ; break ; }

for ( MachineInstr & Use : MRI -> use_instructions ( Reg ) ) {


<s> MachineInstr * MI = MRI -> getVRegDef ( SReg ) ; if ( ! MI ) return <STR_LIT> ; MachineOperand * MO = MI -> findRegisterDefOperand ( SReg ) ; if ( ! MO ) return <STR_LIT> ; assert ( MO -> isReg ( ) && <STR_LIT> ) ;

if ( MI -> isCopy ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) {


<s> for ( SmallVectorImpl < unsigned > :: iterator I = Defs . begin ( ) , E = Defs . end ( ) ; I != E ; ++ I ) { SmallVector < MachineInstr * , <NUM_LIT> > DefSrcs ; if ( ! Register :: isVirtualRegister ( * I ) ) continue ; MachineInstr * Def = MRI -> getVRegDef ( * I ) ; if ( ! Def ) continue ; elideCopiesAndPHIs ( Def , DefSrcs ) ; for ( MachineInstr * MI : DefSrcs ) { if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; Register DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << printReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; } }


<s> SmallVector < MachineInstr * , <NUM_LIT> > DefSrcs ; if ( ! Register :: isVirtualRegister ( * I ) ) continue ; MachineInstr * Def = MRI -> getVRegDef ( * I ) ; if ( ! Def ) continue ; elideCopiesAndPHIs ( Def , DefSrcs ) ; for ( MachineInstr * MI : DefSrcs ) { if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; Register DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << printReg ( NewReg ) << <STR_LIT> ) ;


<s> if ( skipFunction ( Fn . getFunction ( ) ) ) return false ; const <ISA_LIT>Subtarget & STI = Fn . getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( ! ( STI . useSplatVFPToNeon ( ) && STI . hasNEON ( ) ) ) return false ; TII = STI . getInstrInfo ( ) ; TRI = STI . getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; bool Modified = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Fn . getName ( ) << <STR_LIT> ) ;


<s> bool A15SDOptimizer :: usesRegClass ( MachineOperand & MO , const TargetRegisterClass * TRC ) { if ( ! MO . isReg ( ) ) return false ; Register Reg = MO . getReg ( ) ;

if ( Register :: isVirtualRegister ( Reg ) ) return MRI -> getRegClass ( Reg ) -> hasSuperClassEq ( TRC ) ;


<s> for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { for ( MachineBasicBlock :: iterator MI = MFI -> begin ( ) , ME = MFI -> end ( ) ; MI != ME ; ) { Modified |= runOnInstruction ( & * MI ++ ) ; } } for ( std :: set < MachineInstr * > :: iterator I = DeadInstr . begin ( ) , E = DeadInstr . end ( ) ; I != E ; ++ I ) {


<s> if ( ECDef && ECDef -> isImplicitDef ( ) ) { MachineInstr * EC = elideCopies ( SPRMI ) ; if ( EC && EC -> isCopy ( ) && EC -> getOperand ( <NUM_LIT> ) . getSubReg ( ) == <STR_LIT> ) { DEBUG ( dbgs ( ) << <STR_LIT> << * SPRMI ) ; unsigned FullReg = SPRMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; const TargetRegisterClass * TRC = MRI -> getRegClass ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( TRC -> hasSuperClassEq ( MRI -> getRegClass ( FullReg ) ) ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; DEBUG ( dbgs ( ) << PrintReg ( FullReg ) << <STR_LIT> ) ; eraseInstrWithNoUses ( MI ) ; return FullReg ; } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } if ( MI -> isRegSequence ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { unsigned NumImplicit = <NUM_LIT> , NumTotal = <NUM_LIT> ; unsigned NonImplicitReg = ~ <NUM_LIT> ; for ( unsigned I = <NUM_LIT> ; I < MI -> getNumExplicitOperands ( ) ; ++ I ) { if ( ! MI -> getOperand ( I ) . isReg ( ) ) continue ; ++ NumTotal ; unsigned OpReg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( OpReg ) ) break ; MachineInstr * Def = MRI -> getVRegDef ( OpReg ) ; if ( ! Def ) break ; if ( Def -> isImplicitDef ( ) ) ++ NumImplicit ; else NonImplicitReg = MI -> getOperand ( I ) . getReg ( ) ;


<s> unsigned A15SDOptimizer :: createDupLane ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL , unsigned Reg , unsigned Lane , bool QPR ) {

unsigned Out = MRI -> createVirtualRegister ( QPR ? & <STR_LIT> :


<s> for ( SmallVectorImpl < unsigned > :: iterator I = Defs . begin ( ) , E = Defs . end ( ) ; I != E ; ++ I ) { SmallVector < MachineInstr * , <NUM_LIT> > DefSrcs ; if ( ! TRI -> isVirtualRegister ( * I ) ) continue ; MachineInstr * Def = MRI -> getVRegDef ( * I ) ; if ( ! Def ) continue ; elideCopiesAndPHIs ( Def , DefSrcs ) ; for ( MachineInstr * MI : DefSrcs ) { if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << PrintReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; }


<s> for ( MachineInstr * MI : DefSrcs ) { if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << PrintReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; } } Replacements [ MI ] = NewReg ; } }


<s> const <ISA_LIT>Subtarget & STI = Fn . getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( ! ( STI . isCortexA15 ( ) && STI . hasNEON ( ) ) ) return false ; TII = STI . getInstrInfo ( ) ; TRI = STI . getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; bool Modified = false ; DEBUG ( dbgs ( ) << <STR_LIT> << Fn . getName ( ) << <STR_LIT> ) ; DeadInstr . clear ( ) ; Replacements . clear ( ) ; for ( MachineBasicBlock & MBB : Fn ) {


<s> unsigned Out = MRI -> createVirtualRegister ( QPR ? & <STR_LIT> : & <STR_LIT> ) ;

BuildMI ( MBB , InsertBefore , DL , TII -> get ( QPR ? <STR_LIT> : <STR_LIT> ) , Out ) . addReg ( Reg ) . addImm ( Lane ) . add ( predOps ( <STR_LIT> ) ) ;


<s> BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: COPY ) , Out ) . addReg ( DReg , <NUM_LIT> , Lane ) ; return Out ;


<s> unsigned Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: IMPLICIT_DEF ) , Out ) ; return Out ;


<s> unsigned Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ;

BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: IMPLICIT_DEF ) , Out ) ;


<s> unsigned A15SDOptimizer :: createInsertSubreg ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL , unsigned DReg , unsigned Lane , unsigned ToInsert ) { unsigned Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( TargetOpcode :: INSERT_SUBREG ) , Out ) . addReg ( DReg ) . addReg ( ToInsert ) . addImm ( Lane ) ;


<s> unsigned A15SDOptimizer :: createVExt ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , const DebugLoc & DL , unsigned Ssub0 , unsigned Ssub1 ) { unsigned Out = MRI -> createVirtualRegister ( & <STR_LIT> ) ;


<s> for ( MachineOperand & MODef : Def -> operands ( ) ) { if ( ( ! MODef . isReg ( ) ) || ( ! MODef . isDef ( ) ) ) continue ; unsigned DefReg = MODef . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( DefReg ) ) { IsDead = false ; break ; } for ( MachineInstr & Use : MRI -> use_instructions ( Reg ) ) { if ( & Use == Def ) continue ; if ( DeadInstr . find ( & Use ) == DeadInstr . end ( ) ) { IsDead = false ;


<s> StringRef getPassName ( ) const override {


<s> SmallVector < unsigned , <NUM_LIT> > A15SDOptimizer :: getReadDPRs ( MachineInstr * MI ) { if ( MI -> isCopyLike ( ) || MI -> isInsertSubreg ( ) || MI -> isRegSequence ( ) || MI -> isKill ( ) ) return SmallVector < unsigned , <NUM_LIT> > ( ) ;

SmallVector < unsigned , <NUM_LIT> > Defs ;


<s> if ( TRC -> hasSuperClassEq ( MRI -> getRegClass ( FullReg ) ) ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; DEBUG ( dbgs ( ) << printReg ( FullReg ) << <STR_LIT> ) ; eraseInstrWithNoUses ( MI ) ; return FullReg ; } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } if ( MI -> isRegSequence ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { unsigned NumImplicit = <NUM_LIT> , NumTotal = <NUM_LIT> ; unsigned NonImplicitReg = ~ <NUM_LIT> ; for ( unsigned I = <NUM_LIT> ; I < MI -> getNumExplicitOperands ( ) ; ++ I ) { if ( ! MI -> getOperand ( I ) . isReg ( ) ) continue ; ++ NumTotal ; unsigned OpReg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( OpReg ) ) break ;

MachineInstr * Def = MRI -> getVRegDef ( OpReg ) ;


<s> unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << printReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ;


<s> bool Modified = false ; for ( SmallVectorImpl < unsigned > :: iterator I = Defs . begin ( ) , E = Defs . end ( ) ; I != E ; ++ I ) { SmallVector < MachineInstr * , <NUM_LIT> > DefSrcs ; if ( ! TRI -> isVirtualRegister ( * I ) ) continue ; MachineInstr * Def = MRI -> getVRegDef ( * I ) ; if ( ! Def ) continue ; elideCopiesAndPHIs ( Def , DefSrcs ) ; for ( MachineInstr * MI : DefSrcs ) { if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) {


<s> TRI = STI . getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; bool Modified = false ; DEBUG ( dbgs ( ) << <STR_LIT> << Fn . getName ( ) << <STR_LIT> ) ; DeadInstr . clear ( ) ; Replacements . clear ( ) ; for ( MachineBasicBlock & MBB : Fn ) { for ( MachineInstr & MI : MBB ) { Modified |= runOnInstruction ( & MI ) ; } } for ( MachineInstr * MI : DeadInstr ) { MI -> eraseFromParent ( ) ;


<s> bool A15SDOptimizer :: runOnMachineFunction ( MachineFunction & Fn ) { if ( skipFunction ( Fn . getFunction ( ) ) ) return false ; const <ISA_LIT>Subtarget & STI = Fn . getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( ! ( STI . isCortexA15 ( ) && STI . hasNEON ( ) ) ) return false ; TII = STI . getInstrInfo ( ) ; TRI = STI . getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ;


<s> for ( MachineBasicBlock :: iterator MI = MFI -> begin ( ) , ME = MFI -> end ( ) ; MI != ME ; ) { Modified |= runOnInstruction ( MI ++ ) ; } } for ( std :: set < MachineInstr * > :: iterator I = DeadInstr . begin ( ) , E = DeadInstr . end ( ) ; I != E ; ++ I ) { ( * I ) -> eraseFromParent ( ) ; }


<s> void A15SDOptimizer :: elideCopiesAndPHIs ( MachineInstr * MI , SmallVectorImpl < MachineInstr * > & Outs ) { std :: set < MachineInstr * > Reached ; SmallVector < MachineInstr * , <NUM_LIT> > Front ; Front . push_back ( MI ) ; while ( Front . size ( ) != <NUM_LIT> ) { MI = Front . back ( ) ; Front . pop_back ( ) ; if ( Reached . find ( MI ) != Reached . end ( ) ) continue ; Reached . insert ( MI ) ; if ( MI -> isPHI ( ) ) { for ( unsigned I = <NUM_LIT> , E = MI -> getNumOperands ( ) ; I != E ; I += <NUM_LIT> ) { unsigned Reg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( Reg ) ) { continue ; } MachineInstr * NewMI = MRI -> getVRegDef ( Reg ) ;


<s> if ( Reached . find ( MI ) != Reached . end ( ) ) continue ; Reached . insert ( MI ) ; if ( MI -> isPHI ( ) ) { for ( unsigned I = <NUM_LIT> , E = MI -> getNumOperands ( ) ; I != E ; I += <NUM_LIT> ) { unsigned Reg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( Reg ) ) { continue ; } MachineInstr * NewMI = MRI -> getVRegDef ( Reg ) ; if ( ! NewMI ) continue ; Front . push_back ( NewMI ) ; } } else if ( MI -> isFullCopy ( ) ) { if ( ! TRI -> isVirtualRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) continue ; MachineInstr * NewMI = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( ! NewMI ) continue ; Front . push_back ( NewMI ) ; } else { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * MI << <STR_LIT> ) ; Outs . push_back ( MI ) ; }


<s> Front . pop_back ( ) ; for ( MachineOperand & MO : MI -> operands ( ) ) { if ( ( ! MO . isReg ( ) ) || ( ! MO . isUse ( ) ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( Reg ) ) continue ; MachineOperand * Op = MI -> findRegisterDefOperand ( Reg ) ; if ( ! Op ) continue ; MachineInstr * Def = Op -> getParent ( ) ; if ( DeadInstr . find ( Def ) != DeadInstr . end ( ) ) continue ; bool IsDead = true ; for ( MachineOperand & MODef : Def -> operands ( ) ) { if ( ( ! MODef . isReg ( ) ) || ( ! MODef . isDef ( ) ) ) continue ; unsigned DefReg = MODef . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( DefReg ) ) { IsDead = false ; break ; } for ( MachineInstr & Use : MRI -> use_instructions ( Reg ) ) { if ( & Use == Def ) continue ;

if ( DeadInstr . find ( & Use ) == DeadInstr . end ( ) ) {


<s> MachineInstr * DPRMI = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; MachineInstr * SPRMI = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( DPRMI && SPRMI ) { MachineInstr * ECDef = elideCopies ( DPRMI ) ; if ( ECDef && ECDef -> isImplicitDef ( ) ) { MachineInstr * EC = elideCopies ( SPRMI ) ; if ( EC && EC -> isCopy ( ) && EC -> getOperand ( <NUM_LIT> ) . getSubReg ( ) == <STR_LIT> ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * SPRMI ) ; unsigned FullReg = SPRMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; const TargetRegisterClass * TRC = MRI -> getRegClass ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( TRC -> hasSuperClassEq ( MRI -> getRegClass ( FullReg ) ) ) {


<s> MachineInstr * DPRMI = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; MachineInstr * SPRMI = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( DPRMI && SPRMI ) { MachineInstr * ECDef = elideCopies ( DPRMI ) ; if ( ECDef && ECDef -> isImplicitDef ( ) ) { MachineInstr * EC = elideCopies ( SPRMI ) ; if ( EC && EC -> isCopy ( ) && EC -> getOperand ( <NUM_LIT> ) . getSubReg ( ) == <STR_LIT> ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * SPRMI ) ; unsigned FullReg = SPRMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; const TargetRegisterClass * TRC = MRI -> getRegClass ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; if ( TRC -> hasSuperClassEq ( MRI -> getRegClass ( FullReg ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; LLVM_DEBUG ( dbgs ( ) << printReg ( FullReg ) << <STR_LIT> ) ; eraseInstrWithNoUses ( MI ) ; return FullReg ; } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } } } return optimizeAllLanesPattern ( MI , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } if ( MI -> isRegSequence ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { unsigned NumImplicit = <NUM_LIT> , NumTotal = <NUM_LIT> ; unsigned NonImplicitReg = ~ <NUM_LIT> ; for ( unsigned I = <NUM_LIT> ; I < MI -> getNumExplicitOperands ( ) ; ++ I ) { if ( ! MI -> getOperand ( I ) . isReg ( ) ) continue ; ++ NumTotal ; unsigned OpReg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! TRI -> isVirtualRegister ( OpReg ) ) break ; MachineInstr * Def = MRI -> getVRegDef ( OpReg ) ; if ( ! Def ) break ; if ( Def -> isImplicitDef ( ) ) ++ NumImplicit ; else NonImplicitReg = MI -> getOperand ( I ) . getReg ( ) ; }

if ( NumImplicit == NumTotal - <NUM_LIT> ) return optimizeAllLanesPattern ( MI , NonImplicitReg ) ;


<s> if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & * I ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( ( * I ) -> getReg ( ) ) ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << printReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; } } Replacements [ MI ] = NewReg ; } } return Modified ;


<s> if ( ! ( STI . isCortexA15 ( ) && STI . hasNEON ( ) ) ) return false ; TII = STI . getInstrInfo ( ) ; TRI = STI . getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; bool Modified = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Fn . getName ( ) << <STR_LIT> ) ;


<s> Reached . insert ( MI ) ; if ( MI -> isPHI ( ) ) { for ( unsigned I = <NUM_LIT> , E = MI -> getNumOperands ( ) ; I != E ; I += <NUM_LIT> ) { Register Reg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! Register :: isVirtualRegister ( Reg ) ) { continue ; } MachineInstr * NewMI = MRI -> getVRegDef ( Reg ) ; if ( ! NewMI ) continue ; Front . push_back ( NewMI ) ; } } else if ( MI -> isFullCopy ( ) ) { if ( ! Register :: isVirtualRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) continue ;

MachineInstr * NewMI = MRI -> getVRegDef ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ;


<s> MI = Front . pop_back_val ( ) ; if ( Reached . find ( MI ) != Reached . end ( ) ) continue ; Reached . insert ( MI ) ; if ( MI -> isPHI ( ) ) { for ( unsigned I = <NUM_LIT> , E = MI -> getNumOperands ( ) ; I != E ; I += <NUM_LIT> ) { Register Reg = MI -> getOperand ( I ) . getReg ( ) ; if ( ! Register :: isVirtualRegister ( Reg ) ) { continue ; } MachineInstr * NewMI = MRI -> getVRegDef ( Reg ) ; if ( ! NewMI ) continue ;


<s> Register Reg = MO . getReg ( ) ; if ( ! Register :: isVirtualRegister ( Reg ) ) continue ; MachineOperand * Op = MI -> findRegisterDefOperand ( Reg ) ; if ( ! Op ) continue ; MachineInstr * Def = Op -> getParent ( ) ; if ( DeadInstr . find ( Def ) != DeadInstr . end ( ) ) continue ; bool IsDead = true ; for ( MachineOperand & MODef : Def -> operands ( ) ) { if ( ( ! MODef . isReg ( ) ) || ( ! MODef . isDef ( ) ) ) continue ; Register DefReg = MODef . getReg ( ) ; if ( ! Register :: isVirtualRegister ( DefReg ) ) { IsDead = false ; break ; } for ( MachineInstr & Use : MRI -> use_instructions ( Reg ) ) { if ( & Use == Def ) continue ; if ( DeadInstr . find ( & Use ) == DeadInstr . end ( ) ) { IsDead = false ; break ; }


<s> bool IsDead = true ; for ( MachineOperand & MODef : Def -> operands ( ) ) { if ( ( ! MODef . isReg ( ) ) || ( ! MODef . isDef ( ) ) ) continue ; Register DefReg = MODef . getReg ( ) ; if ( ! Register :: isVirtualRegister ( DefReg ) ) { IsDead = false ; break ; } for ( MachineInstr & Use : MRI -> use_instructions ( Reg ) ) { if ( & Use == Def ) continue ; if ( DeadInstr . find ( & Use ) == DeadInstr . end ( ) ) {


<s> SmallVector < unsigned , <NUM_LIT> > Defs = getReadDPRs ( MI ) ; bool Modified = false ; for ( unsigned I : Defs ) { SmallVector < MachineInstr * , <NUM_LIT> > DefSrcs ; if ( ! Register :: isVirtualRegister ( I ) ) continue ; MachineInstr * Def = MRI -> getVRegDef ( I ) ; if ( ! Def ) continue ; elideCopiesAndPHIs ( Def , DefSrcs ) ; for ( MachineInstr * MI : DefSrcs ) { if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; Register DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineOperand & MO : MRI -> use_operands ( DPRDefReg ) ) Uses . push_back ( & MO ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( MachineOperand * Use : Uses ) { MRI -> constrainRegClass ( NewReg , MRI -> getRegClass ( Use -> getReg ( ) ) ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * Use << <STR_LIT> << printReg ( NewReg ) << <STR_LIT> ) ; Use -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; } } Replacements [ MI ] = NewReg ;


<s> TRI = Fn . getSubtarget ( ) . getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; bool Modified = false ; DEBUG ( dbgs ( ) << <STR_LIT> << Fn . getName ( ) << <STR_LIT> ) ; DeadInstr . clear ( ) ; Replacements . clear ( ) ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { for ( MachineBasicBlock :: iterator MI = MFI -> begin ( ) , ME = MFI -> end ( ) ; MI != ME ; ) { Modified |= runOnInstruction ( MI ++ ) ; }


<s> if ( ! MI ) return <STR_LIT> ; MachineOperand * MO = MI -> findRegisterDefOperand ( SReg ) ; assert ( MO -> isReg ( ) && <STR_LIT> ) ; if ( ! MO ) return <STR_LIT> ; if ( MI -> isCopy ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { SReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; } if ( TargetRegisterInfo :: isVirtualRegister ( SReg ) ) { if ( MO -> getSubReg ( ) == <STR_LIT> ) return <STR_LIT> ;


<s> if ( MI -> isCopy ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { SReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; } if ( TargetRegisterInfo :: isVirtualRegister ( SReg ) ) { if ( MO -> getSubReg ( ) == <STR_LIT> ) return <STR_LIT> ;


<s> MachineOperand * MO = MI -> findRegisterDefOperand ( SReg ) ; assert ( MO -> isReg ( ) && <STR_LIT> ) ; if ( ! MO ) return <STR_LIT> ; if ( MI -> isCopy ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { SReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; } if ( Register :: isVirtualRegister ( SReg ) ) { if ( MO -> getSubReg ( ) == <STR_LIT> ) return <STR_LIT> ; return <STR_LIT> ; }


<s> MachineInstr * MI = MRI -> getVRegDef ( SReg ) ; if ( ! MI ) return <STR_LIT> ; MachineOperand * MO = MI -> findRegisterDefOperand ( SReg ) ; assert ( MO -> isReg ( ) && <STR_LIT> ) ; if ( ! MO ) return <STR_LIT> ; if ( MI -> isCopy ( ) && usesRegClass ( MI -> getOperand ( <NUM_LIT> ) , & <STR_LIT> ) ) { SReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; } if ( Register :: isVirtualRegister ( SReg ) ) { if ( MO -> getSubReg ( ) == <STR_LIT> ) return <STR_LIT> ; return <STR_LIT> ; } return getDPRLaneFromSPR ( SReg ) ;


<s> for ( SmallVector < MachineInstr * , <NUM_LIT> > :: iterator II = DefSrcs . begin ( ) , EE = DefSrcs . end ( ) ; II != EE ; ++ II ) { MachineInstr * MI = * II ; if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & I . getOperand ( ) ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ;

for ( SmallVector < MachineOperand * , <NUM_LIT> > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) {


<s> if ( ! TRI -> isVirtualRegister ( * I ) ) continue ; MachineInstr * Def = MRI -> getVRegDef ( * I ) ; if ( ! Def ) continue ; elideCopiesAndPHIs ( Def , DefSrcs ) ; for ( SmallVectorImpl < MachineInstr * > :: iterator II = DefSrcs . begin ( ) , EE = DefSrcs . end ( ) ; II != EE ; ++ II ) { MachineInstr * MI = * II ; if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ; unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & I . getOperand ( ) ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << PrintReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ;


<s> unsigned DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( MachineRegisterInfo :: use_iterator I = MRI -> use_begin ( DPRDefReg ) , E = MRI -> use_end ( ) ; I != E ; ++ I ) Uses . push_back ( & I . getOperand ( ) ) ; unsigned NewReg = optimizeSDPattern ( MI ) ; if ( NewReg != <NUM_LIT> ) { Modified = true ; for ( SmallVectorImpl < MachineOperand * > :: const_iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { DEBUG ( dbgs ( ) << <STR_LIT> << * * I << <STR_LIT> << PrintReg ( NewReg ) << <STR_LIT> ) ; ( * I ) -> substVirtReg ( NewReg , <NUM_LIT> , * TRI ) ; } } Replacements [ MI ] = NewReg ; } }


<s> if ( ! Register :: isVirtualRegister ( * I ) ) continue ; MachineInstr * Def = MRI -> getVRegDef ( * I ) ; if ( ! Def ) continue ; elideCopiesAndPHIs ( Def , DefSrcs ) ; for ( MachineInstr * MI : DefSrcs ) { if ( Replacements . find ( MI ) != Replacements . end ( ) ) continue ; if ( ! hasPartialWrite ( MI ) ) continue ; SmallVector < MachineOperand * , <NUM_LIT> > Uses ;

Register DPRDefReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ;


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> inline static CondCodes getOppositeCondition ( CondCodes CC ) { switch ( CC ) { default : llvm_unreachable ( <STR_LIT> ) ; case EQ : return NE ; case NE : return EQ ; case HS : return LO ; case LO : return HS ; case MI : return PL ; case PL : return MI ; case VS : return VC ;


<s> case LO : return HS ; case MI : return PL ; case PL : return MI ; case VS : return VC ; case VC : return VS ; case HI : return LS ; case LS : return HI ; case GE : return LT ; case LT : return GE ;


<s> case ST : return <STR_LIT> ; case ISH : return <STR_LIT> ; case ISHST : return <STR_LIT> ;


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> case MI : return PL ; case PL : return MI ; case VS : return VC ; case VC : return VS ; case HI : return LS ; case LS : return HI ; case GE : return LT ;


<s> case HS : return LO ; case LO : return HS ; case MI : return PL ; case PL : return MI ; case VS : return VC ;


<s> inline unsigned createNEONModImm ( unsigned OpCmode , unsigned Val ) { return ( OpCmode << <NUM_LIT> ) | Val ;


<s> assert ( isNEONi16splat ( Value ) && <STR_LIT> ) ; if ( Value >= <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ; else Value |= <NUM_LIT> ; return Value ;


<s> inline unsigned encodeNEONi32splat ( unsigned Value ) { assert ( isNEONi32splat ( Value ) && <STR_LIT> ) ; if ( Value >= <NUM_LIT> && Value <= <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ; else if ( Value > <NUM_LIT> && Value <= <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ; else if ( Value > <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ; return Value ;


<s> return Op == sub ? <STR_LIT> : <STR_LIT> ;


<s> return AM2Opc & ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) ;


<s> inline unsigned getAM2Offset ( unsigned AM2Opc ) { return AM2Opc & ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) ;


<s> inline AddrOpc getAM2Op ( unsigned AM2Opc ) { return ( ( AM2Opc >> <NUM_LIT> ) & <NUM_LIT> ) ? sub : add ;


<s> inline unsigned getAM2Opc ( AddrOpc Opc , unsigned Imm12 , ShiftOpc SO , unsigned IdxMode = <NUM_LIT> ) {

assert ( Imm12 < ( <NUM_LIT> << <NUM_LIT> ) && <STR_LIT> ) ;


return Imm12 | ( ( int ) isSub << <NUM_LIT> ) | ( SO << <NUM_LIT> ) | ( IdxMode << <NUM_LIT> ) ;


<s> inline ShiftOpc getAM2ShiftOpc ( unsigned AM2Opc ) {

return ( ShiftOpc ) ( ( AM2Opc >> <NUM_LIT> ) & <NUM_LIT> ) ;


<s> inline unsigned getAM3IdxMode ( unsigned AM3Opc ) {


<s> inline unsigned char getAM3Offset ( unsigned AM3Opc ) {


<s> return ( ( int ) isSub << <NUM_LIT> ) | Offset | ( IdxMode << <NUM_LIT> ) ;


<s> inline unsigned getAM4ModeImm ( AMSubMode SubMode ) { return ( int ) SubMode ;


<s> inline unsigned char getAM5FP16Offset ( unsigned AM5Opc ) { return AM5Opc & <NUM_LIT> ;


<s> return ( ( int ) isSub << <NUM_LIT> ) | Offset ;


<s> inline unsigned char getAM5Offset ( unsigned AM5Opc ) { return AM5Opc & <NUM_LIT> ;


<s> bool isSub = Opc == sub ; return ( ( int ) isSub << <NUM_LIT> ) | Offset ;


<s> switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> return getFP16Imm ( FPImm . bitcastToAPInt ( ) ) ;


<s> inline int getFP64Imm ( const APFloat & FPImm ) {

return getFP64Imm ( FPImm . bitcastToAPInt ( ) ) ;


<s> uint8_t Sign = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Exp = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Mantissa = Imm & <NUM_LIT> ; uint32_t I = <NUM_LIT> ; I |= Sign << <NUM_LIT> ; I |= ( ( Exp & <NUM_LIT> ) != <NUM_LIT> ? <NUM_LIT> : <NUM_LIT> ) << <NUM_LIT> ;


<s> return ( ModImm >> <NUM_LIT> ) & <NUM_LIT> ;


<s> case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : return <NUM_LIT> ;


<s> inline const char * getShiftOpcStr ( ShiftOpc Op ) { switch ( Op ) {

default : llvm_unreachable ( <STR_LIT> ) ;


<s> return rotr32 ( <NUM_LIT> , getSOImmValRotate ( V ) ) & V ;


<s> inline unsigned getSOImmTwoPartFirst ( unsigned V ) { return rotr32 ( <NUM_LIT> , getSOImmValRotate ( V ) ) & V ;


<s> V = rotr32 ( ~ <NUM_LIT> , getSOImmValRotate ( V ) ) & V ;

assert ( V == ( rotr32 ( <NUM_LIT> , getSOImmValRotate ( V ) ) & V ) ) ;


<s> if ( rotr32 ( ~ <NUM_LIT> , RotAmt ) & Arg ) return - <NUM_LIT> ;

return rotl32 ( Arg , RotAmt ) | ( ( RotAmt >> <NUM_LIT> ) << <NUM_LIT> ) ;


<s> unsigned RotAmt = getSOImmValRotate ( Arg ) ;

if ( rotr32 ( ~ <NUM_LIT> , RotAmt ) & Arg ) return - <NUM_LIT> ;


<s> inline unsigned getSOImmValImm ( unsigned Imm ) { return Imm & <NUM_LIT> ;


<s> return ( Imm >> <NUM_LIT> ) * <NUM_LIT> ;


<s> inline unsigned getSOImmValRotate ( unsigned Imm ) { if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ; unsigned TZ = countTrailingZeros ( Imm ) ; unsigned RotAmt = TZ & ~ <NUM_LIT> ;

if ( ( rotr32 ( Imm , RotAmt ) & ~ <NUM_LIT> ) == <NUM_LIT> ) return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ;


<s> inline unsigned getSORegOffset ( unsigned Op ) {


<s> return ShOp | ( Imm << <NUM_LIT> ) ;


<s> assert ( isT2SOImmTwoPartVal ( Imm ) && <STR_LIT> ) ;

unsigned V = rotr32 ( ~ <NUM_LIT> , getT2SOImmValRotate ( Imm ) ) & Imm ;


<s> inline unsigned getT2SOImmTwoPartFirst ( unsigned Imm ) { assert ( isT2SOImmTwoPartVal ( Imm ) && <STR_LIT> ) ; unsigned V = rotr32 ( ~ <NUM_LIT> , getT2SOImmValRotate ( Imm ) ) & Imm ; if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return V ; if ( getT2SOImmValSplatVal ( Imm & <NUM_LIT> ) != - <NUM_LIT> ) return Imm & <NUM_LIT> ;

assert ( getT2SOImmValSplatVal ( Imm & <NUM_LIT> ) != - <NUM_LIT> ) ;


<s> int Splat = getT2SOImmValSplatVal ( Arg ) ; if ( Splat != - <NUM_LIT> ) return Splat ;

int Rot = getT2SOImmValRotateVal ( Arg ) ;


<s> unsigned RotAmt = countTrailingZeros ( V ) ;

return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ;


<s> unsigned RotAmt = countLeadingZeros ( V ) ; if ( RotAmt >= <NUM_LIT> ) return - <NUM_LIT> ;

if ( ( rotr32 ( <NUM_LIT> , RotAmt ) & V ) == V ) return ( rotr32 ( V , <NUM_LIT> - RotAmt ) & <NUM_LIT> ) | ( ( RotAmt + <NUM_LIT> ) << <NUM_LIT> ) ;


<s> Imm = Vs & <NUM_LIT> ; u = Imm | ( Imm << <NUM_LIT> ) ;

if ( Vs == u ) return ( ( ( Vs == V ) ? <NUM_LIT> : <NUM_LIT> ) << <NUM_LIT> ) | Imm ;


<s> u = Imm | ( Imm << <NUM_LIT> ) ; if ( Vs == u ) return ( ( ( Vs == V ) ? <NUM_LIT> : <NUM_LIT> ) << <NUM_LIT> ) | Imm ;

if ( Vs == ( u | ( u << <NUM_LIT> ) ) ) return ( <NUM_LIT> << <NUM_LIT> ) | Imm ;


<s> if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ;


<s> inline unsigned getThumbImmNonShiftedVal ( unsigned V ) { return V >> getThumbImmValShift ( V ) ;


<s> inline unsigned getThumbImmValShift ( unsigned Imm ) {

if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ;


<s> inline bool isNEONi16splat ( unsigned Value ) {


<s> return Value == <NUM_LIT> || isNEONBytesplat ( Value , <NUM_LIT> ) ;


<s> V = rotr32 ( ~ <NUM_LIT> , getSOImmValRotate ( V ) ) & V ; if ( V == <NUM_LIT> ) return false ; V = rotr32 ( ~ <NUM_LIT> , getSOImmValRotate ( V ) ) & V ; return V == <NUM_LIT> ;


<s> V = rotr32 ( ~ <NUM_LIT> , getT2SOImmValRotate ( V ) ) & V ; if ( V == <NUM_LIT> ) return false ; if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return true ; V = Imm ; if ( getT2SOImmValSplatVal ( V & <NUM_LIT> ) != - <NUM_LIT> ) V &= ~ <NUM_LIT> ; else if ( getT2SOImmValSplatVal ( V & <NUM_LIT> ) != - <NUM_LIT> ) V &= ~ <NUM_LIT> ;


<s> if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return true ; V = Imm ; if ( getT2SOImmValSplatVal ( V & <NUM_LIT> ) != - <NUM_LIT> ) V &= ~ <NUM_LIT> ; else if ( getT2SOImmValSplatVal ( V & <NUM_LIT> ) != - <NUM_LIT> ) V &= ~ <NUM_LIT> ; if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return true ;


<s> inline bool isThumbImm16ShiftedVal ( unsigned V ) { V = ( ~ <NUM_LIT> << getThumbImm16ValShift ( V ) ) & V ;


<s> inline bool isThumbImmShiftedVal ( unsigned V ) { V = ( ~ <NUM_LIT> << getThumbImmValShift ( V ) ) & V ; return V == <NUM_LIT> ;


<s> V = ( ~ <NUM_LIT> << getThumbImmValShift ( V ) ) & V ; return V == <NUM_LIT> ;


<s> assert ( Amt < <NUM_LIT> && <STR_LIT> ) ; return ( Val << Amt ) | ( Val >> ( ( <NUM_LIT> - Amt ) & <NUM_LIT> ) ) ;


<s> inline unsigned rotl32 ( unsigned Val , unsigned Amt ) { assert ( Amt < <NUM_LIT> && <STR_LIT> ) ;

return ( Val << Amt ) | ( Val >> ( ( <NUM_LIT> - Amt ) & <NUM_LIT> ) ) ;


<s> inline unsigned rotr32 ( unsigned Val , unsigned Amt ) { assert ( Amt < <NUM_LIT> && <STR_LIT> ) ; return ( Val >> Amt ) | ( Val << ( ( <NUM_LIT> - Amt ) & <NUM_LIT> ) ) ;


<s> unsigned ByteNum = ( OpCmode & <NUM_LIT> ) >> <NUM_LIT> ; Val = Imm8 << ( <NUM_LIT> * ByteNum ) ; EltBits = <NUM_LIT> ; } else if ( ( OpCmode & <NUM_LIT> ) == <NUM_LIT> ) { unsigned ByteNum = ( OpCmode & <NUM_LIT> ) >> <NUM_LIT> ; Val = Imm8 << ( <NUM_LIT> * ByteNum ) ; EltBits = <NUM_LIT> ; } else if ( ( OpCmode & <NUM_LIT> ) == <NUM_LIT> ) { unsigned ByteNum = <NUM_LIT> + ( OpCmode & <NUM_LIT> ) ; Val = ( Imm8 << ( <NUM_LIT> * ByteNum ) ) | ( <NUM_LIT> >> ( <NUM_LIT> * ( <NUM_LIT> - ByteNum ) ) ) ; EltBits = <NUM_LIT> ;


<s> static inline unsigned encodeNEONi16splat ( unsigned Value ) { assert ( isNEONi16splat ( Value ) && <STR_LIT> ) ; if ( Value >= <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ;


<s> if ( Value >= <NUM_LIT> && Value <= <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ; else if ( Value > <NUM_LIT> && Value <= <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ; else if ( Value > <NUM_LIT> ) Value = ( Value >> <NUM_LIT> ) | <NUM_LIT> ;


<s> case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : return <NUM_LIT> ;


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> if ( ( rotr32 ( Imm , RotAmt ) & ~ <NUM_LIT> ) == <NUM_LIT> ) return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ; if ( Imm & <NUM_LIT> ) { unsigned TZ2 = countTrailingZeros ( Imm & ~ <NUM_LIT> ) ; unsigned RotAmt2 = TZ2 & ~ <NUM_LIT> ; if ( ( rotr32 ( Imm , RotAmt2 ) & ~ <NUM_LIT> ) == <NUM_LIT> ) return ( <NUM_LIT> - RotAmt2 ) & <NUM_LIT> ; } return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ;


<s> static inline unsigned getT2SOImmValRotate ( unsigned V ) {

if ( ( V & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ;


<s> if ( ( rotr32 ( <NUM_LIT> , RotAmt ) & V ) == V ) return ( rotr32 ( V , <NUM_LIT> - RotAmt ) & <NUM_LIT> ) | ( ( RotAmt + <NUM_LIT> ) << <NUM_LIT> ) ; return - <NUM_LIT> ;


<s> if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ; return countTrailingZeros ( Imm ) ;


<s> if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ;


<s> unsigned count = <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i < Size ; ++ i ) { if ( Value & <NUM_LIT> ) count ++ ; Value >>= <NUM_LIT> ; } return count == <NUM_LIT> ;


<s> return Value == <NUM_LIT> || isNEONBytesplat ( Value , <NUM_LIT> ) ;


<s> return ( ( AM5Opc >> <NUM_LIT> ) & <NUM_LIT> ) ? sub : add ;


<s> return ( ( int ) isSub << <NUM_LIT> ) | Offset ;


<s> return getFP16Imm ( FPImm . bitcastToAPInt ( ) ) ;


<s> inline int getFP32FP16Imm ( const APFloat & FPImm ) {

return getFP32FP16Imm ( FPImm . bitcastToAPInt ( ) ) ;


<s> inline const char * getShiftOpcStr ( ShiftOpc Op ) { switch ( Op ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> inline unsigned getVMOVModImmOpCmode ( unsigned ModImm ) {

return ( ModImm >> <NUM_LIT> ) & <NUM_LIT> ;


<s> return ! ( rotr32 ( ~ <NUM_LIT> , getSOImmValRotate ( First ) ) & First ) ;


<s> First = ~ ( - First ) ; return ! ( rotr32 ( ~ <NUM_LIT> , getSOImmValRotate ( First ) ) & First ) ;


<s> union { uint32_t I ; float F ; } FPUnion ; uint8_t Sign = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Exp = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Mantissa = Imm & <NUM_LIT> ; FPUnion . I = <NUM_LIT> ; FPUnion . I |= Sign << <NUM_LIT> ; FPUnion . I |= ( ( Exp & <NUM_LIT> ) != <NUM_LIT> ? <NUM_LIT> : <NUM_LIT> ) << <NUM_LIT> ;


<s> uint8_t Sign = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Exp = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Mantissa = Imm & <NUM_LIT> ; FPUnion . I = <NUM_LIT> ; FPUnion . I |= Sign << <NUM_LIT> ;


<s> static inline unsigned getAM2Opc ( AddrOpc Opc , unsigned Imm12 , ShiftOpc SO ) { assert ( Imm12 < ( <NUM_LIT> << <NUM_LIT> ) && <STR_LIT> ) ; bool isSub = Opc == sub ; return Imm12 | ( ( int ) isSub << <NUM_LIT> ) | ( SO << <NUM_LIT> ) ;


<s> static inline ShiftOpc getAM2ShiftOpc ( unsigned AM2Opc ) { return ( ShiftOpc ) ( AM2Opc >> <NUM_LIT> ) ;


<s> static inline unsigned getAM3Opc ( AddrOpc Opc , unsigned char Offset ) { bool isSub = Opc == sub ; return ( ( int ) isSub << <NUM_LIT> ) | Offset ;


<s> static inline unsigned getAM3Opc ( AddrOpc Opc , unsigned char Offset ) {


<s> return ( int ) SubMode | ( ( int ) WB << <NUM_LIT> ) ;


<s> static inline bool getAM4WBFlag ( unsigned Mode ) {

return ( Mode >> <NUM_LIT> ) & <NUM_LIT> ;


<s> return ( Mode >> <NUM_LIT> ) & <NUM_LIT> ;


<s> assert ( ( SubMode == ia || SubMode == db ) && <STR_LIT> ) ;

return ( ( int ) SubMode << <NUM_LIT> ) | ( ( int ) WB << <NUM_LIT> ) | Offset ;


<s> static inline AMSubMode getAM5SubMode ( unsigned AM5Opc ) { return ( AMSubMode ) ( ( AM5Opc >> <NUM_LIT> ) & <NUM_LIT> ) ;


<s> static inline bool getAM5WBFlag ( unsigned AM5Opc ) { return ( ( AM5Opc >> <NUM_LIT> ) & <NUM_LIT> ) ;


<s> return ( ( AM5Opc >> <NUM_LIT> ) & <NUM_LIT> ) ;


<s> static inline const char * getAMSubModeAltStr ( AMSubMode Mode , bool isLD ) { switch ( Mode ) { default : assert ( <NUM_LIT> && <STR_LIT> ) ; case <STR_LIT> : return isLD ? <STR_LIT> : <STR_LIT> ; case <STR_LIT> : return isLD ? <STR_LIT> : <STR_LIT> ; case <STR_LIT> : return isLD ? <STR_LIT> : <STR_LIT> ; case <STR_LIT> : return isLD ? <STR_LIT> : <STR_LIT> ;


<s> static inline ShiftOpc getShiftOpcForNode ( SDValue N ) { switch ( N . getOpcode ( ) ) { default : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> unsigned TZ2 = CountTrailingZeros_32 ( Imm & ~ ( ( <NUM_LIT> << TrailingOnes ) - <NUM_LIT> ) ) ; unsigned RotAmt2 = TZ2 & ~ <NUM_LIT> ; if ( RotAmt2 != <NUM_LIT> && ( rotr32 ( Imm , RotAmt2 ) & ~ <NUM_LIT> ) == <NUM_LIT> ) return ( <NUM_LIT> - RotAmt2 ) & <NUM_LIT> ; } }


<s> static inline unsigned getAM6Opc ( bool WB = false ) {


<s> static inline bool getAM6WBFlag ( unsigned Mode ) {


<s> static inline bool getAM6WBFlag ( unsigned Mode ) { return Mode & <NUM_LIT> ;


<s> static inline const char * getAMSubModeAltStr ( AMSubMode Mode , bool isLD ) { switch ( Mode ) {

default : llvm_unreachable ( <STR_LIT> ) ;


<s> static inline unsigned createNEONModImm ( unsigned OpCmode , unsigned Val ) {


<s> uint64_t Val = <NUM_LIT> ; if ( OpCmode == <NUM_LIT> ) { Val = Imm8 ; EltBits = <NUM_LIT> ; } else if ( ( OpCmode & <NUM_LIT> ) == <NUM_LIT> ) { unsigned ByteNum = ( OpCmode & <NUM_LIT> ) >> <NUM_LIT> ; Val = Imm8 << ( <NUM_LIT> * ByteNum ) ; EltBits = <NUM_LIT> ; } else if ( ( OpCmode & <NUM_LIT> ) == <NUM_LIT> ) { unsigned ByteNum = ( OpCmode & <NUM_LIT> ) >> <NUM_LIT> ; Val = Imm8 << ( <NUM_LIT> * ByteNum ) ; EltBits = <NUM_LIT> ; } else if ( ( OpCmode & <NUM_LIT> ) == <NUM_LIT> ) {

unsigned ByteNum = <NUM_LIT> + ( OpCmode & <NUM_LIT> ) ;


<s> unsigned OpCmode = getNEONModImmOpCmode ( ModImm ) ; unsigned Imm8 = getNEONModImmVal ( ModImm ) ; uint64_t Val = <NUM_LIT> ; if ( OpCmode == <NUM_LIT> ) { Val = Imm8 ; EltBits = <NUM_LIT> ; } else if ( ( OpCmode & <NUM_LIT> ) == <NUM_LIT> ) { unsigned ByteNum = ( OpCmode & <NUM_LIT> ) >> <NUM_LIT> ; Val = Imm8 << ( <NUM_LIT> * ByteNum ) ; EltBits = <NUM_LIT> ; } else if ( ( OpCmode & <NUM_LIT> ) == <NUM_LIT> ) { unsigned ByteNum = ( OpCmode & <NUM_LIT> ) >> <NUM_LIT> ; Val = Imm8 << ( <NUM_LIT> * ByteNum ) ;


<s> static inline const char * getAddrOpcStr ( AddrOpc Op ) {

return Op == sub ? <STR_LIT> : <STR_LIT> ;


<s> return Op == sub ? <STR_LIT> : <STR_LIT> ;


<s> static inline AddrOpc getAM2Op ( unsigned AM2Opc ) { return ( ( AM2Opc >> <NUM_LIT> ) & <NUM_LIT> ) ? sub : add ;


<s> static inline unsigned getAM2Opc ( AddrOpc Opc , unsigned Imm12 , ShiftOpc SO , unsigned IdxMode = <NUM_LIT> ) { assert ( Imm12 < ( <NUM_LIT> << <NUM_LIT> ) && <STR_LIT> ) ; bool isSub = Opc == sub ; return Imm12 | ( ( int ) isSub << <NUM_LIT> ) | ( SO << <NUM_LIT> ) | ( IdxMode << <NUM_LIT> ) ;


<s> assert ( Imm12 < ( <NUM_LIT> << <NUM_LIT> ) && <STR_LIT> ) ;


<s> static inline ShiftOpc getAM2ShiftOpc ( unsigned AM2Opc ) { return ( ShiftOpc ) ( ( AM2Opc >> <NUM_LIT> ) & <NUM_LIT> ) ;


<s> static inline unsigned char getAM3Offset ( unsigned AM3Opc ) {


<s> static inline AddrOpc getAM3Op ( unsigned AM3Opc ) {

return ( ( AM3Opc >> <NUM_LIT> ) & <NUM_LIT> ) ? sub : add ;


<s> static inline unsigned getAM3Opc ( AddrOpc Opc , unsigned char Offset , unsigned IdxMode = <NUM_LIT> ) { bool isSub = Opc == sub ;

return ( ( int ) isSub << <NUM_LIT> ) | Offset | ( IdxMode << <NUM_LIT> ) ;


<s> static inline unsigned getAM4ModeImm ( AMSubMode SubMode ) {


<s> return ( AMSubMode ) ( Mode & <NUM_LIT> ) ;


<s> static inline unsigned char getAM5Offset ( unsigned AM5Opc ) { return AM5Opc & <NUM_LIT> ;


<s> static inline AddrOpc getAM5Op ( unsigned AM5Opc ) { return ( ( AM5Opc >> <NUM_LIT> ) & <NUM_LIT> ) ? sub : add ;


<s> static inline unsigned getAM5Opc ( AddrOpc Opc , unsigned char Offset ) { bool isSub = Opc == sub ;

return ( ( int ) isSub << <NUM_LIT> ) | Offset ;


<s> default : assert ( <NUM_LIT> && <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ;


<s> static inline float getFPImmFloat ( unsigned Imm ) { union { uint32_t I ; float F ; } FPUnion ; uint8_t Sign = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Exp = ( Imm >> <NUM_LIT> ) & <NUM_LIT> ; uint8_t Mantissa = Imm & <NUM_LIT> ; FPUnion . I = <NUM_LIT> ; FPUnion . I |= Sign << <NUM_LIT> ; FPUnion . I |= ( ( Exp & <NUM_LIT> ) != <NUM_LIT> ? <NUM_LIT> : <NUM_LIT> ) << <NUM_LIT> ; FPUnion . I |= ( ( Exp & <NUM_LIT> ) != <NUM_LIT> ? <NUM_LIT> : <NUM_LIT> ) << <NUM_LIT> ; FPUnion . I |= ( Exp & <NUM_LIT> ) << <NUM_LIT> ;


<s> return ( ModImm >> <NUM_LIT> ) & <NUM_LIT> ;


<s> static inline unsigned getNEONModImmOpCmode ( unsigned ModImm ) { return ( ModImm >> <NUM_LIT> ) & <NUM_LIT> ;


<s> static inline unsigned getNEONModImmVal ( unsigned ModImm ) {


<s> default : assert ( <NUM_LIT> && <STR_LIT> ) ; case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : return <NUM_LIT> ;


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ;


<s> return rotr32 ( <NUM_LIT> , getSOImmValRotate ( V ) ) & V ;


<s> V = rotr32 ( ~ <NUM_LIT> , getSOImmValRotate ( V ) ) & V ;

assert ( V == ( rotr32 ( <NUM_LIT> , getSOImmValRotate ( V ) ) & V ) ) ;


<s> static inline int getSOImmVal ( unsigned Arg ) { if ( ( Arg & ~ <NUM_LIT> ) == <NUM_LIT> ) return Arg ; unsigned RotAmt = getSOImmValRotate ( Arg ) ; if ( rotr32 ( ~ <NUM_LIT> , RotAmt ) & Arg ) return - <NUM_LIT> ;

return rotl32 ( Arg , RotAmt ) | ( ( RotAmt >> <NUM_LIT> ) << <NUM_LIT> ) ;


<s> unsigned TZ2 = CountTrailingZeros_32 ( Imm & ~ <NUM_LIT> ) ; unsigned RotAmt2 = TZ2 & ~ <NUM_LIT> ; if ( ( rotr32 ( Imm , RotAmt2 ) & ~ <NUM_LIT> ) == <NUM_LIT> ) return ( <NUM_LIT> - RotAmt2 ) & <NUM_LIT> ; } return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ;


<s> static inline unsigned getSOImmValRotate ( unsigned Imm ) { if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ; unsigned TZ = CountTrailingZeros_32 ( Imm ) ; unsigned RotAmt = TZ & ~ <NUM_LIT> ; if ( ( rotr32 ( Imm , RotAmt ) & ~ <NUM_LIT> ) == <NUM_LIT> ) return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ; if ( Imm & <NUM_LIT> ) { unsigned TZ2 = CountTrailingZeros_32 ( Imm & ~ <NUM_LIT> ) ; unsigned RotAmt2 = TZ2 & ~ <NUM_LIT> ; if ( ( rotr32 ( Imm , RotAmt2 ) & ~ <NUM_LIT> ) == <NUM_LIT> ) return ( <NUM_LIT> - RotAmt2 ) & <NUM_LIT> ; } return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ;


<s> static inline unsigned getSORegOffset ( unsigned Op ) { return Op >> <NUM_LIT> ;


<s> static inline unsigned getSORegOffset ( unsigned Op ) {


<s> static inline unsigned getSORegOpc ( ShiftOpc ShOp , unsigned Imm ) {


<s> return ShOp | ( Imm << <NUM_LIT> ) ;


<s> return ( ShiftOpc ) ( Op & <NUM_LIT> ) ;


<s> static inline ShiftOpc getSORegShOp ( unsigned Op ) { return ( ShiftOpc ) ( Op & <NUM_LIT> ) ;


<s> unsigned V = rotr32 ( ~ <NUM_LIT> , getT2SOImmValRotate ( Imm ) ) & Imm ;

if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return V ;


<s> if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return V ;

if ( getT2SOImmValSplatVal ( Imm & <NUM_LIT> ) != - <NUM_LIT> ) return Imm & <NUM_LIT> ;


<s> static inline unsigned getT2SOImmTwoPartSecond ( unsigned Imm ) {


<s> if ( Splat != - <NUM_LIT> ) return Splat ; int Rot = getT2SOImmValRotateVal ( Arg ) ; if ( Rot != - <NUM_LIT> ) return Rot ;


<s> int Splat = getT2SOImmValSplatVal ( Arg ) ; if ( Splat != - <NUM_LIT> ) return Splat ; int Rot = getT2SOImmValRotateVal ( Arg ) ;


<s> unsigned RotAmt = CountTrailingZeros_32 ( V ) ; return ( <NUM_LIT> - RotAmt ) & <NUM_LIT> ;


<s> static inline unsigned getT2SOImmValRotate ( unsigned V ) { if ( ( V & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ;

unsigned RotAmt = CountTrailingZeros_32 ( V ) ;


<s> if ( RotAmt >= <NUM_LIT> ) return - <NUM_LIT> ; if ( ( rotr32 ( <NUM_LIT> , RotAmt ) & V ) == V ) return ( rotr32 ( V , <NUM_LIT> - RotAmt ) & <NUM_LIT> ) | ( ( RotAmt + <NUM_LIT> ) << <NUM_LIT> ) ; return - <NUM_LIT> ;


<s> static inline int getT2SOImmValSplatVal ( unsigned V ) { unsigned u , Vs , Imm ; if ( ( V & <NUM_LIT> ) == <NUM_LIT> ) return V ;

Vs = ( ( V & <NUM_LIT> ) == <NUM_LIT> ) ? V >> <NUM_LIT> : V ;


<s> if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ; return CountTrailingZeros_32 ( Imm ) ;


<s> static inline unsigned getThumbImmNonShiftedVal ( unsigned V ) {


<s> static inline unsigned getThumbImmValShift ( unsigned Imm ) {

if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ;


<s> static inline unsigned getThumbImmValShift ( unsigned Imm ) { if ( ( Imm & ~ <NUM_LIT> ) == <NUM_LIT> ) return <NUM_LIT> ;


<s> V = rotr32 ( ~ <NUM_LIT> , getSOImmValRotate ( V ) ) & V ;


<s> if ( getT2SOImmValSplatVal ( V ) != - <NUM_LIT> ) return false ; V = rotr32 ( ~ <NUM_LIT> , getT2SOImmValRotate ( V ) ) & V ; if ( V == <NUM_LIT> ) return false ; if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return true ;


<s> static inline bool isT2SOImmTwoPartVal ( unsigned Imm ) { unsigned V = Imm ; if ( getT2SOImmValSplatVal ( V ) != - <NUM_LIT> ) return false ; V = rotr32 ( ~ <NUM_LIT> , getT2SOImmValRotate ( V ) ) & V ; if ( V == <NUM_LIT> ) return false ; if ( getT2SOImmVal ( V ) != - <NUM_LIT> ) return true ; V = Imm ; if ( getT2SOImmValSplatVal ( V & <NUM_LIT> ) != - <NUM_LIT> ) V &= ~ <NUM_LIT> ;

else if ( getT2SOImmValSplatVal ( V & <NUM_LIT> ) != - <NUM_LIT> ) V &= ~ <NUM_LIT> ;


<s> static inline bool isThumbImm16ShiftedVal ( unsigned V ) { V = ( ~ <NUM_LIT> << getThumbImm16ValShift ( V ) ) & V ; return V == <NUM_LIT> ;


<s> static inline bool isThumbImmShiftedVal ( unsigned V ) {

V = ( ~ <NUM_LIT> << getThumbImmValShift ( V ) ) & V ;


<s> static inline unsigned rotl32 ( unsigned Val , unsigned Amt ) { assert ( Amt < <NUM_LIT> && <STR_LIT> ) ; return ( Val << Amt ) | ( Val >> ( ( <NUM_LIT> - Amt ) & <NUM_LIT> ) ) ;


<s> assert ( Amt < <NUM_LIT> && <STR_LIT> ) ;

return ( Val << Amt ) | ( Val >> ( ( <NUM_LIT> - Amt ) & <NUM_LIT> ) ) ;


return ( Val >> Amt ) | ( Val << ( ( <NUM_LIT> - Amt ) & <NUM_LIT> ) ) ;


<s> <ISA_LIT>ALFWriter :: <ISA_LIT>ALFWriter ( const MCInstrInfo * _MII , const MCRegisterInfo * _MRI ) : MII ( _MII ) , MRI ( _MRI ) , ALFWriter ( <STR_LIT> , ID ) {


<s> const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string Rn = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; SExpr * arg2_sexpr ; auto arg2 = MI . getOperand ( <NUM_LIT> ) ; if ( arg2 . isImm ( ) ) { arg2_sexpr = ctx -> dec_unsigned ( <NUM_LIT> , arg2 . getImm ( ) ) ; } else if ( arg2 . isReg ( ) ) { arg2_sexpr = ctx -> load ( <NUM_LIT> , TRI -> getName ( arg2 . getReg ( ) ) ) ; } SExpr * csub = ctx -> c_sub ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , Rn ) , arg2_sexpr , <NUM_LIT> ) ; SExpr * output = ctx -> sub ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , Rn ) , arg2_sexpr , <NUM_LIT> ) ; SExpr * arg1_pos = ctx -> s_ge ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , Rn ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * arg2_pos = ctx -> s_ge ( <NUM_LIT> , arg2_sexpr , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * output_pos = ctx -> s_ge ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * arg1_neg = ctx -> s_lt ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , Rn ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * arg2_neg = ctx -> s_lt ( <NUM_LIT> , arg2_sexpr , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * output_neg = ctx -> s_lt ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * V = ctx -> or_ ( <NUM_LIT> , ctx -> and_ ( <NUM_LIT> , ctx -> and_ ( <NUM_LIT> , arg1_pos , arg2_neg ) , output_neg ) , ctx -> and_ ( <NUM_LIT> , ctx -> and_ ( <NUM_LIT> , arg1_neg , arg2_pos ) , output_pos ) ) ; SExpr * expr_nzcv = ctx -> conc ( <NUM_LIT> , <NUM_LIT> , ctx -> conc ( <NUM_LIT> , <NUM_LIT> , ctx -> conc ( <NUM_LIT> , <NUM_LIT> , ctx -> s_lt ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) , ctx -> conc ( <NUM_LIT> , <NUM_LIT> , csub , V ) ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * stor_nzcv = ctx -> store ( ctx -> address ( <STR_LIT> ) , expr_nzcv ) ;

alfbb . addStatement ( label , TII -> getName ( MI . getOpcode ( ) ) , stor_nzcv ) ;


<s> SExpr * output_pos = ctx -> s_ge ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * arg1_neg = ctx -> s_lt ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , Rn ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * arg2_neg = ctx -> s_lt ( <NUM_LIT> , arg2_sexpr , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * output_neg = ctx -> s_lt ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * V = ctx -> or_ ( <NUM_LIT> , ctx -> and_ ( <NUM_LIT> , ctx -> and_ ( <NUM_LIT> , arg1_pos , arg2_neg ) , output_neg ) , ctx -> and_ ( <NUM_LIT> , ctx -> and_ ( <NUM_LIT> , arg1_neg , arg2_pos ) , output_pos ) ) ; SExpr * expr_nzcv = ctx -> conc ( <NUM_LIT> , <NUM_LIT> , ctx -> conc ( <NUM_LIT> , <NUM_LIT> , ctx -> conc ( <NUM_LIT> , <NUM_LIT> , ctx -> s_lt ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , output , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) , ctx -> conc ( <NUM_LIT> , <NUM_LIT> , csub , V ) ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ;

SExpr * stor_nzcv = ctx -> store ( ctx -> address ( <STR_LIT> ) , expr_nzcv ) ;


<s> return new <ISA_LIT>ALFWriter ( nullptr , nullptr ) ;


<s> void <ISA_LIT>ALFWriter :: extraFrames ( const MachineConstantPool * MCP ) { auto csts = MCP -> getConstants ( ) ; for ( MachineConstantPoolEntry mcpe : csts ) {

const Constant * cv = mcpe . Val . ConstVal ;


<s> if ( ! cv -> getName ( ) . empty ( ) ) b -> addFrame ( string ( <STR_LIT> ) + cv -> getName ( ) , <NUM_LIT> , InternalFrame ) ;


<s> StringRef <ISA_LIT>ALFWriter :: getPassName ( ) const { return <STR_LIT> ;


<s> } else if ( mcop . isImm ( ) ) { if ( i == <NUM_LIT> && ( mc . getOpcode ( ) == <STR_LIT> || mc . getOpcode ( ) == <STR_LIT> ) ) { mi -> addOperand ( MachineOperand :: CreateMBB ( bb -> jump -> mbb ) ) ; } else mi -> addOperand ( MachineOperand :: CreateImm ( mcop . getImm ( ) ) ) ; } else if ( mcop . isFPImm ( ) ) { } else if ( mcop . isExpr ( ) ) {


<s> if ( mcop . isReg ( ) ) { mi -> addOperand ( MachineOperand :: CreateReg ( mcop . getReg ( ) , true ) ) ; } else if ( mcop . isImm ( ) ) { if ( i == <NUM_LIT> && ( mc . getOpcode ( ) == <STR_LIT> || mc . getOpcode ( ) == <STR_LIT> ) ) { mi -> addOperand ( MachineOperand :: CreateMBB ( bb -> jump -> mbb ) ) ; } else mi -> addOperand ( MachineOperand :: CreateImm ( mcop . getImm ( ) ) ) ; } else if ( mcop . isFPImm ( ) ) { } else if ( mcop . isExpr ( ) ) { } else if ( mcop . isInst ( ) ) {


<s> void <ISA_LIT>ALFWriter :: initFrames ( ) { b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ;


<s> b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ; b -> addInit ( <STR_LIT> , <NUM_LIT> , b -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , false ) ;


<s> bool <ISA_LIT>ALFWriter :: shouldSetCondFlags ( const MachineInstr & MI ) { const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ;


<s> bool setsStatusFlags = false ; for ( unsigned i = <NUM_LIT> ; i < MI . getNumOperands ( ) ; i ++ ) {

if ( MI . getOperand ( i ) . isReg ( ) && TRI -> getName ( MI . getOperand ( i ) . getReg ( ) ) == string ( <STR_LIT> ) ) {


<s> string SP = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; auto I = MI . getOperand ( <NUM_LIT> ) . getImm ( ) ; SExpr * offset = ctx -> dec_unsigned ( <NUM_LIT> , I * <NUM_LIT> ) ;

SExpr * add = ctx -> add ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , SP ) , offset ) ;


<s> SExpr * add = ctx -> add ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , SP ) , offset ) ; SExpr * stor = ctx -> store ( ctx -> address ( SP ) , add ) ; alfbb . addStatement ( label , TII -> getName ( MI . getOpcode ( ) ) , stor ) ;


<s> switch ( MI . getOperand ( <NUM_LIT> ) . getImm ( ) ) { case ( <STR_LIT> ) : cond = loadZ ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; break ; case ( <STR_LIT> ) : cond = loadC ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadC , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; break ; case ( <STR_LIT> ) : cond = loadN ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadN , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; break ; case ( <STR_LIT> ) : cond = loadV ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadV , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> and_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadC , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> or_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadC , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadN , loadV ) ; break ; case ( <STR_LIT> ) : cond = ctx -> neq ( <NUM_LIT> , loadN , loadV ) ; break ; case ( <STR_LIT> ) : cond = ctx -> and_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , loadN , loadV ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> or_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> neq ( <NUM_LIT> , loadN , loadV ) ) ; break ;


<s> break ; case ( <STR_LIT> ) : cond = loadN ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadN , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; break ; case ( <STR_LIT> ) : cond = loadV ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadV , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> and_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadC , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> or_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadC , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> eq ( <NUM_LIT> , loadN , loadV ) ; break ; case ( <STR_LIT> ) : cond = ctx -> neq ( <NUM_LIT> , loadN , loadV ) ; break ; case ( <STR_LIT> ) : cond = ctx -> and_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> eq ( <NUM_LIT> , loadN , loadV ) ) ; break ; case ( <STR_LIT> ) : cond = ctx -> or_ ( <NUM_LIT> , ctx -> eq ( <NUM_LIT> , loadZ , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) , ctx -> neq ( <NUM_LIT> , loadN , loadV ) ) ; break ;


<s> const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string jumpLabel = <STR_LIT> ; if ( MI . getOperand ( <NUM_LIT> ) . isGlobal ( ) ) jumpLabel = MI . getOperand ( <NUM_LIT> ) . getGlobal ( ) -> getName ( ) ;

SExpr * call = ctx -> call ( ctx -> labelRef ( jumpLabel ) ) ;


<s> const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string jumpLabel = <STR_LIT> ; if ( MI . getOperand ( <NUM_LIT> ) . isGlobal ( ) ) jumpLabel = MI . getOperand ( <NUM_LIT> ) . getGlobal ( ) -> getName ( ) ; SExpr * call = ctx -> call ( ctx -> labelRef ( jumpLabel ) ) ;

alfbb . addStatement ( label , TII -> getName ( MI . getOpcode ( ) ) , call ) ;


<s> static void tLDRpci_customALF ( const MachineInstr & MI , ALFStatementGroup & alfbb , ALFContext * ctx , string label ) { const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; const MachineConstantPool * MCP = MI . getParent ( ) -> getParent ( ) -> getConstantPool ( ) ; MachineConstantPoolEntry mcpe = MCP -> getConstants ( ) [ MI . getOperand ( <NUM_LIT> ) . getIndex ( ) ] ; const Constant * cv = mcpe . Val . ConstVal ;


<s> string source = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; SExpr * load = ctx -> load ( <NUM_LIT> , source ) ; SExpr * stor = ctx -> store ( ctx -> address ( target ) , load ) ;

alfbb . addStatement ( label , TII -> getName ( MI . getOpcode ( ) ) , stor ) ;


<s> const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string target = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; string source = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; SExpr * load = ctx -> load ( <NUM_LIT> , source ) ; SExpr * stor = ctx -> store ( ctx -> address ( target ) , load ) ;


<s> string MO_name = TRI -> getName ( MO . getReg ( ) ) ; SExpr * SP_times_8 = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , <STR_LIT> ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; SExpr * addrInSP = ctx -> load ( <NUM_LIT> , ctx -> address ( <STR_LIT> , SP_times_8 ) ) ; SExpr * ldr = ctx -> store ( ctx -> address ( MO_name ) , addrInSP ) ; alfbb . addStatement ( label + <STR_LIT> + MO_name , string ( <STR_LIT> ) + MO_name + <STR_LIT> , ldr ) ; SExpr * SP_incr = ctx -> add ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , <STR_LIT> ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * incr = ctx -> store ( ctx -> address ( <STR_LIT> ) , SP_incr ) ;

alfbb . addStatement ( label + <STR_LIT> + MO_name + <STR_LIT> , <STR_LIT> , incr ) ;


<s> static void tPOP_RET_customALF ( const MachineInstr & MI , ALFStatementGroup & alfbb , ALFContext * ctx , string label ) { const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; tPOP_customALF ( MI , alfbb , ctx , label ) ; alfbb . addStatement ( MI . getParent ( ) -> getParent ( ) -> getName ( ) + string ( <STR_LIT> ) , <STR_LIT> , ctx -> null ( ) ) ; alfbb . addStatement ( label , TII -> getName ( MI . getOpcode ( ) ) , ctx -> ret ( ) ) ;


<s> alfbb . addStatement ( MI . getParent ( ) -> getParent ( ) -> getName ( ) + string ( <STR_LIT> ) , <STR_LIT> , ctx -> null ( ) ) ; alfbb . addStatement ( label , TII -> getName ( MI . getOpcode ( ) ) , ctx -> ret ( ) ) ;


<s> alfbb . addStatement ( label + <STR_LIT> + MO_name + <STR_LIT> , <STR_LIT> , subtr ) ; SExpr * SP_times_8 = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , <STR_LIT> ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; SExpr * str = ctx -> store ( ctx -> address ( <STR_LIT> , SP_times_8 ) , ctx -> load ( <NUM_LIT> , MO_name ) ) ;

alfbb . addStatement ( label + <STR_LIT> + MO_name , string ( <STR_LIT> ) + MO_name + <STR_LIT> , str ) ;


<s> const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; for ( unsigned i = MI . getNumOperands ( ) - <NUM_LIT> , NumOps = <NUM_LIT> ; i != NumOps ; -- i ) { const MachineOperand & MO = MI . getOperand ( i ) ; string MO_name = TRI -> getName ( MO . getReg ( ) ) ; SExpr * SP_decr = ctx -> sub ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , <STR_LIT> ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ; SExpr * subtr = ctx -> store ( ctx -> address ( <STR_LIT> ) , SP_decr ) ; alfbb . addStatement ( label + <STR_LIT> + MO_name + <STR_LIT> , <STR_LIT> , subtr ) ; SExpr * SP_times_8 = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , <STR_LIT> ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ;

SExpr * str = ctx -> store ( ctx -> address ( <STR_LIT> , SP_times_8 ) , ctx -> load ( <NUM_LIT> , MO_name ) ) ;


<s> string Rop1 = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; auto op2 = MI . getOperand ( <NUM_LIT> ) . getImm ( ) ; SExpr * sub = ctx -> sub ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , Rop1 ) , ctx -> dec_signed ( <NUM_LIT> , op2 ) ) ; SExpr * sub_c = ctx -> c_sub ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , Rop1 ) , ctx -> dec_signed ( <NUM_LIT> , op2 ) ) ; SExpr * stor = ctx -> store ( ctx -> address ( R ) , sub ) ;


<s> static void tSUBspi_customALF ( const MachineInstr & MI , ALFStatementGroup & alfbb , ALFContext * ctx , string label ) { const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string SP = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; auto I = MI . getOperand ( <NUM_LIT> ) . getImm ( ) ;

SExpr * offset = ctx -> dec_unsigned ( <NUM_LIT> , I * <NUM_LIT> ) ;


<s> SExpr * offset = ctx -> dec_unsigned ( <NUM_LIT> , I * <NUM_LIT> ) ; SExpr * subtr = ctx -> sub ( <NUM_LIT> , ctx -> load ( <NUM_LIT> , SP ) , offset ) ; SExpr * stor = ctx -> store ( ctx -> address ( SP ) , subtr ) ; alfbb . addStatement ( label , TII -> getName ( MI . getOpcode ( ) ) , stor ) ;


<s> const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; SExpr * load1 = ctx -> load ( <NUM_LIT> , TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; SExpr * load2 = ctx -> load ( <NUM_LIT> , TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ;

SExpr * andexpr = ctx -> and_ ( <NUM_LIT> , load1 , load2 ) ;


<s> SExpr * load1 = ctx -> load ( <NUM_LIT> , TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; SExpr * load2 = ctx -> load ( <NUM_LIT> , TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; SExpr * andexpr = ctx -> and_ ( <NUM_LIT> , load1 , load2 ) ; SExpr * stor = calcNZCV ( ctx , load1 , load2 , andexpr , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ) ;


<s> string SP = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; auto I = MI . getOperand ( <NUM_LIT> ) . getImm ( ) ; SExpr * offset = ctx -> dec_unsigned ( <NUM_LIT> , I * <NUM_LIT> * <NUM_LIT> ) ;

SExpr * Reg_times_8 = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , SP ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ;


<s> const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string SP = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; auto I = MI . getOperand ( <NUM_LIT> ) . getImm ( ) ; SExpr * offset = ctx -> dec_unsigned ( <NUM_LIT> , I * <NUM_LIT> * <NUM_LIT> ) ;


<s> static SExpr * t_addrmode_rr_customALF ( const MachineInstr & MI , ALFStatementGroup & alfbb , ALFContext * ctx , string label ) { const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string Reg = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; string RegOff = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; SExpr * offset = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , RegOff ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; SExpr * bytes_to_bits = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , Reg ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; SExpr * add = ctx -> add ( <NUM_LIT> , bytes_to_bits , offset , <NUM_LIT> ) ;

return ctx -> list ( <STR_LIT> ) -> append ( <NUM_LIT> ) -> append ( ctx -> fref ( <STR_LIT> ) ) -> append ( add ) ;


<s> string Reg = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; string RegOff = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; SExpr * offset = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , RegOff ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ; SExpr * bytes_to_bits = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , Reg ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ;

SExpr * add = ctx -> add ( <NUM_LIT> , bytes_to_bits , offset , <NUM_LIT> ) ;


<s> static SExpr * t_addrmode_sp_customALF ( const MachineInstr & MI , ALFStatementGroup & alfbb , ALFContext * ctx , string label ) { const TargetInstrInfo * TII = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = MI . getParent ( ) -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; string SP = TRI -> getName ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) ; auto I = MI . getOperand ( <NUM_LIT> ) . getImm ( ) ;

SExpr * offset = ctx -> dec_unsigned ( <NUM_LIT> , I * <NUM_LIT> * <NUM_LIT> ) ;


<s> auto I = MI . getOperand ( <NUM_LIT> ) . getImm ( ) ; SExpr * offset = ctx -> dec_unsigned ( <NUM_LIT> , I * <NUM_LIT> * <NUM_LIT> ) ;

SExpr * SP_times_8 = ctx -> select ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , ctx -> u_mul ( <NUM_LIT> , <NUM_LIT> , ctx -> load ( <NUM_LIT> , SP ) , ctx -> dec_unsigned ( <NUM_LIT> , <NUM_LIT> ) ) ) ;


<s> <ISA_LIT>ALFWriter :: ~ <ISA_LIT>ALFWriter ( ) {


<s> if ( ! Value ) return ; unsigned Offset = Fixup . getOffset ( ) ; assert ( Offset + NumBytes <= DataSize && <STR_LIT> ) ; unsigned FullSizeBytes ; if ( ! IsLittleEndian ) { FullSizeBytes = getFixupKindContainerSizeBytes ( Fixup . getKind ( ) ) ; assert ( ( Offset + FullSizeBytes ) <= DataSize && <STR_LIT> ) ; assert ( NumBytes <= FullSizeBytes && <STR_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i != NumBytes ; ++ i ) { unsigned Idx = IsLittleEndian ? i : ( FullSizeBytes - <NUM_LIT> - i ) ;

Data [ Offset + Idx ] |= uint8_t ( ( Value >> ( i * <NUM_LIT> ) ) & <NUM_LIT> ) ;


<s> llvm_unreachable ( <STR_LIT> ) ; case Triple :: MachO : { MachO :: CPUSubType<ISA_LIT> CS = getMachOSubTypeFromArch ( TheTriple . getArchName ( ) ) ; return new <ISA_LIT>AsmBackendDarwin ( T , TheTriple , MRI , CS ) ; } case Triple :: COFF : assert ( TheTriple . isOSWindows ( ) && <STR_LIT> ) ; return new <ISA_LIT>AsmBackendWinCOFF ( T , TheTriple ) ; case Triple :: ELF : assert ( TheTriple . isOSBinFormatELF ( ) && <STR_LIT> ) ; uint8_t OSABI = MCELFObjectTargetWriter :: getOSABI ( TheTriple . getOS ( ) ) ; return new <ISA_LIT>AsmBackendELF ( T , TheTriple , OSABI , isLittle ) ;


<s> switch ( TheTriple . getObjectFormat ( ) ) { default : llvm_unreachable ( <STR_LIT> ) ; case Triple :: MachO : { MachO :: CPUSubType<ISA_LIT> CS = getMachOSubTypeFromArch ( TheTriple . getArchName ( ) ) ; return new <ISA_LIT>AsmBackendDarwin ( T , TheTriple , MRI , CS ) ; } case Triple :: COFF : assert ( TheTriple . isOSWindows ( ) && <STR_LIT> ) ; return new <ISA_LIT>AsmBackendWinCOFF ( T , TheTriple ) ; case Triple :: ELF : assert ( TheTriple . isOSBinFormatELF ( ) && <STR_LIT> ) ; uint8_t OSABI = MCELFObjectTargetWriter :: getOSABI ( TheTriple . getOS ( ) ) ; return new <ISA_LIT>AsmBackendELF ( T , TheTriple , OSABI , isLittle ) ;


<s> return create<ISA_LIT>AsmBackend ( T , MRI , TT , CPU , false ) ;


<s> MCAsmBackend * llvm :: create<ISA_LIT>LEAsmBackend ( const Target & T , const MCRegisterInfo & MRI , const Triple & TT , StringRef CPU ) {

return create<ISA_LIT>AsmBackend ( T , MRI , TT , CPU , true ) ;


<s> MCAsmBackend * llvm :: createThumbBEAsmBackend ( const Target & T , const MCRegisterInfo & MRI , const Triple & TT , StringRef CPU ) { return create<ISA_LIT>AsmBackend ( T , MRI , TT , CPU , false ) ;


<s> MCAsmBackend * llvm :: createThumbLEAsmBackend ( const Target & T , const MCRegisterInfo & MRI , const Triple & TT , StringRef CPU ) {


<s> bool <ISA_LIT>AsmBackend :: fixupNeedsRelaxation ( const MCFixup & Fixup , uint64_t Value , const MCRelaxableFragment * DF , const MCAsmLayout & Layout ) const {

return reasonForFixupRelaxation ( Fixup , Value ) ;


<s> if ( RegOffsets . lookup ( <STR_LIT> ) != ( - <NUM_LIT> - StackAdjust ) ) { DEBUG_WITH_TYPE ( <STR_LIT> , llvm :: dbgs ( ) << <STR_LIT> << StackAdjust << <STR_LIT> << CFARegisterOffset << <STR_LIT> << RegOffsets [ <NUM_LIT> ] << <STR_LIT> ) ; return CU :: UNWIND_<ISA_LIT>_MODE_DWARF ; } if ( RegOffsets . lookup ( <STR_LIT> ) != ( - <NUM_LIT> - StackAdjust ) ) { DEBUG_WITH_TYPE ( <STR_LIT> , llvm :: dbgs ( ) << <STR_LIT> ) ; return CU :: UNWIND_<ISA_LIT>_MODE_DWARF ; } uint32_t CompactUnwindEncoding = CU :: UNWIND_<ISA_LIT>_MODE_FRAME ; switch ( StackAdjust ) { case <NUM_LIT> : break ; case <NUM_LIT> : CompactUnwindEncoding |= <NUM_LIT> ; break ; case <NUM_LIT> : CompactUnwindEncoding |= <NUM_LIT> ; break ; case <NUM_LIT> : CompactUnwindEncoding |= <NUM_LIT> ; break ; default : DEBUG_WITH_TYPE ( <STR_LIT> , llvm :: dbgs ( ) << <STR_LIT> << StackAdjust << <STR_LIT> ) ; return CU :: UNWIND_<ISA_LIT>_MODE_DWARF ; } static struct { unsigned Reg ; unsigned Encoding ; } GPRCSRegs [ ] = { { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_FIRST_PUSH_R6 } , { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_FIRST_PUSH_R5 } , { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_FIRST_PUSH_R4 } , { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_SECOND_PUSH_R12 } , { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_SECOND_PUSH_R11 } , { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_SECOND_PUSH_R10 } , { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_SECOND_PUSH_R9 } , { <STR_LIT> , CU :: UNWIND_<ISA_LIT>_FRAME_SECOND_PUSH_R8 } } ; int CurOffset = - <NUM_LIT> - StackAdjust ; for ( auto CSReg : GPRCSRegs ) { auto Offset = RegOffsets . find ( CSReg . Reg ) ; if ( Offset == RegOffsets . end ( ) ) continue ; int RegOffset = Offset -> second ; if ( RegOffset != CurOffset - <NUM_LIT> ) { DEBUG_WITH_TYPE ( <STR_LIT> , llvm :: dbgs ( ) << MRI . getName ( CSReg . Reg ) << <STR_LIT> << RegOffset << <STR_LIT> << CurOffset << <STR_LIT> ) ; return CU :: UNWIND_<ISA_LIT>_MODE_DWARF ; } CompactUnwindEncoding |= CSReg . Encoding ; CurOffset -= <NUM_LIT> ; } if ( FloatRegCount == <NUM_LIT> ) return CompactUnwindEncoding ; CompactUnwindEncoding &= ~ CU :: UNWIND_<ISA_LIT>_MODE_MASK ; CompactUnwindEncoding |= CU :: UNWIND_<ISA_LIT>_MODE_FRAME_D ; if ( FloatRegCount > <NUM_LIT> ) { DEBUG_WITH_TYPE ( <STR_LIT> , llvm :: dbgs ( ) << <STR_LIT> << FloatRegCount << <STR_LIT> ) ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :


<s> case <STR_LIT> : case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :