<s> static void aarch64_add_constant_internal ( machine_mode mode , int regnum , int scratchreg , HOST_WIDE_INT delta , bool frame_related_p , bool emit_move_imm ) { HOST_WIDE_INT mdelta = abs_hwi ( delta ) ; rtx this_rtx = gen_rtx_REG ( mode , regnum ) ; rtx_insn * insn ; if ( ! mdelta ) return ; if ( aarch64_uimm12_shift ( mdelta ) ) { insn = emit_insn ( gen_add2_insn ( this_rtx , GEN_INT ( delta ) ) ) ; RTX_FRAME_RELATED_P ( insn ) = frame_related_p ; return ; } if ( mdelta < 0x1000000 && ! aarch64_move_imm ( mdelta , mode ) ) { HOST_WIDE_INT low_off = mdelta & 0xfff ; low_off = delta < 0 ? - low_off : low_off ; insn = emit_insn ( gen_add2_insn ( this_rtx , GEN_INT ( low_off ) ) ) ; RTX_FRAME_RELATED_P ( insn ) = frame_related_p ; insn = emit_insn ( gen_add2_insn ( this_rtx , GEN_INT ( delta - low_off ) ) ) ; RTX_FRAME_RELATED_P ( insn ) = frame_related_p ; return ; } rtx scratch_rtx = gen_rtx_REG ( mode , scratchreg ) ; if ( emit_move_imm ) aarch64_internal_mov_immediate ( scratch_rtx , GEN_INT ( mdelta ) , true , mode ) ; insn = emit_insn ( delta < 0 ? gen_sub2_insn ( this_rtx , scratch_rtx ) : gen_add2_insn ( this_rtx , scratch_rtx ) ) ; if ( frame_related_p ) { RTX_FRAME_RELATED_P ( insn ) = frame_related_p ; rtx adj = plus_constant ( mode , this_rtx , delta ) ; add_reg_note ( insn , REG_CFA_ADJUST_CFA , gen_rtx_SET ( this_rtx , adj ) ) ; } } </s>

Add DELTA to REGNUM in mode MODE . SCRATCHREG can be used to hold a temporary value if necessary . FRAME_RELATED_P should be true if the RTX_FRAME_RELATED flag should be set and CFA adjustments added to the generated instructions . If SCRATCHREG is known to hold abs ( delta ) , EMIT_MOVE_IMM can be set to false to avoid emitting the immediate again . Since this function may be used to adjust the stack pointer , we must ensure that it can not cause transient stack deallocation ( for example by first incrementing SP and then decrementing when adjusting by a large immediate ) .


<s> bool ARMBaseInstrInfo :: isSchedulingBoundary ( const MachineInstr * MI , const MachineBasicBlock * MBB , const MachineFunction & MF ) const { if ( MI -> isDebugValue ( ) ) return false ; if ( MI -> isTerminator ( ) || MI -> isPosition ( ) ) return true ; MachineBasicBlock :: const_iterator I = MI ; while ( ++ I != MBB -> end ( ) && I -> isDebugValue ( ) ) ; if ( I != MBB -> end ( ) && I -> getOpcode ( ) == ARM :: t2IT ) return true ; if ( ! MI -> isCall ( ) && MI -> definesRegister ( ARM :: SP ) ) return true ; return false ; } </s>

isSchedulingBoundary - Overrides the isSchedulingBoundary from Codegen/TargetInstrInfo.cpp to make it capable of identifying ENDBR intructions and prevent it from being re-scheduled .


"The destination address is not aligned to a word"

Apply the Value for given Fixup into the provided data fragment , at the offset specified by the fixup and following the fixup kind as appropriate .


<s> int X86InstrInfo :: getSPAdjust ( const MachineInstr & MI ) const { const MachineFunction * MF = MI . getParent ( ) -> getParent ( ) ; const TargetFrameLowering * TFI = MF -> getSubtarget ( ) . getFrameLowering ( ) ; if ( isFrameInstr ( MI ) ) { int SPAdj = alignTo ( getFrameSize ( MI ) , TFI -> getStackAlign ( ) ) ; SPAdj -= getFrameAdjustment ( MI ) ; if ( ! isFrameSetup ( MI ) ) SPAdj = - SPAdj ; return SPAdj ; } if ( MI . isCall ( ) ) { const MachineBasicBlock * MBB = MI . getParent ( ) ; auto I = ++ MachineBasicBlock :: const_iterator ( MI ) ; for ( auto E = MBB -> end ( ) ; I != E ; ++ I ) { if ( I -> getOpcode ( ) == getCallFrameDestroyOpcode ( ) || I -> isCall ( ) ) break ; } if ( I -> getOpcode ( ) != getCallFrameDestroyOpcode ( ) ) return 0 ; return - ( I -> getOperand ( 1 ) . getImm ( ) ) ; } switch ( MI . getOpcode ( ) ) { default : return 0 ; case X86 :: PUSH32i8 : case X86 :: PUSH32r : case X86 :: PUSH32rmm : case X86 :: PUSH32rmr : case X86 :: PUSHi32 : return 4 ; case X86 :: PUSH64i8 : case X86 :: PUSH64r : case X86 :: PUSH64rmm : case X86 :: PUSH64rmr : case X86 :: PUSH64i32 : return 8 ; } } </s>

getSPAdjust - This returns the stack pointer adjustment made by this instruction .


<s> bool MandarinAsmPrinter :: PrintAsmMemoryOperand ( const MachineInstr * MI , unsigned OpNo , unsigned AsmVariant , const char * ExtraCode , raw_ostream & O ) { if ( ExtraCode && ExtraCode [ 0 ] ) return true ; O << '[' ; printMemOperand ( MI , OpNo , O ) ; O << ']' ; return false ; } </s>

Print the specified operand of MI , an INLINEASM instruction , using the specified assembler variant as an address .


<s>
bool
AArch64MIPeepholeOpt
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
skipFunction
(
MF
.
getFunction
(
)
)
)
return
false
;
TII
=
static_cast
<
const
AArch64InstrInfo
*
>
(
MF
.
getSubtarget
(
)
.
getInstrInfo
(
)
)
;
TRI
=
static_cast
<
const
AArch64RegisterInfo
*
>
(
MF
.
getSubtarget
(
)
.
getRegisterInfo
(
)
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
MRI
=
&
MF
.
getRegInfo
(
)
;
assert
(
MRI
->
isSSA
(
)
&&
"Expected to be run on SSA form!"
)
;
bool
Changed
=
false
;
SmallSetVector
<
MachineInstr
*
,
8
>
ToBeRemoved
;
for
(
MachineBasicBlock
&
MBB
:
MF
)
{
for
(
MachineInstr
&
MI
:
MBB
)
{
switch
(
MI
.
getOpcode
(
)
)
{
default
:
break
;
case
AArch64
::
ANDWrr
:
Changed
=
visitAND
<
uint32_t
>
(
AArch64
::
ANDWri
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
ANDXrr
:
Changed
=
visitAND
<
uint64_t
>
(
AArch64
::
ANDXri
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
ORRWrs
:
Changed
=
visitORR
(
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
ADDWrr
:
Changed
=
visitADDSUB
<
uint32_t
>
(
AArch64
::
ADDWri
,
AArch64
::
SUBWri
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
SUBWrr
:
Changed
=
visitADDSUB
<
uint32_t
>
(
AArch64
::
SUBWri
,
AArch64
::
ADDWri
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
ADDXrr
:
Changed
=
visitADDSUB
<
uint64_t
>
(
AArch64
::
ADDXri
,
AArch64
::
SUBXri
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
SUBXrr
:
Changed
=
visitADDSUB
<
uint64_t
>
(
AArch64
::
SUBXri
,
AArch64
::
ADDXri
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
ADDSWrr
:
Changed
=
visitADDSSUBS
<
uint32_t
>
(
{
AArch64
::
ADDWri
,
AArch64
::
ADDSWri
}
,
{
AArch64
::
SUBWri
,
AArch64
::
SUBSWri
}
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
SUBSWrr
:
Changed
=
visitADDSSUBS
<
uint32_t
>
(
{
AArch64
::
SUBWri
,
AArch64
::
SUBSWri
}
,
{
AArch64
::
ADDWri
,
AArch64
::
ADDSWri
}
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
ADDSXrr
:
Changed
=
visitADDSSUBS
<
uint64_t
>
(
{
AArch64
::
ADDXri
,
AArch64
::
ADDSXri
}
,
{
AArch64
::
SUBXri
,
AArch64
::
SUBSXri
}
,
MI
,
ToBeRemoved
)
;
break
;
case
AArch64
::
SUBSXrr
:
Changed
=
visitADDSSUBS
<
uint64_t
>
(
{
AArch64
::
SUBXri
,
AArch64
::
SUBSXri
}
,
{
AArch64
::
ADDXri
,
AArch64
::
ADDSXri
}
,
MI
,
ToBeRemoved
)
;
break
;
}
}
}
for
(
MachineInstr
*
MI
:
ToBeRemoved
)
MI
->
eraseFromParent
(
)
;
return
Changed
;
}
</s>

runOnMachineFunction - Emit the function body .


<s> void PPC64LinuxTargetObjectFile :: Initialize ( MCContext & Ctx , const TargetMachine & TM ) { TargetLoweringObjectFileELF :: Initialize ( Ctx , TM ) ; } </s>

This method must be called before any actual lowering is done .


<s> bool PPCTargetLowering :: SelectAddressRegReg ( SDValue N , SDValue & Base , SDValue & Index , SelectionDAG & DAG ) const { short imm = 0 ; if ( N . getOpcode ( ) == ISD :: ADD ) { if ( isIntS16Immediate ( N . getOperand ( 1 ) , imm ) ) return false ; if ( N . getOperand ( 1 ) . getOpcode ( ) == PPCISD :: Lo ) return false ; Base = N . getOperand ( 0 ) ; Index = N . getOperand ( 1 ) ; return true ; } else if ( N . getOpcode ( ) == ISD :: OR ) { if ( isIntS16Immediate ( N . getOperand ( 1 ) , imm ) ) return false ; APInt LHSKnownZero , LHSKnownOne ; APInt RHSKnownZero , RHSKnownOne ; DAG . ComputeMaskedBits ( N . getOperand ( 0 ) , LHSKnownZero , LHSKnownOne ) ; if ( LHSKnownZero . getBoolValue ( ) ) { DAG . ComputeMaskedBits ( N . getOperand ( 1 ) , RHSKnownZero , RHSKnownOne ) ; if ( ~ ( LHSKnownZero | RHSKnownZero ) == 0 ) { Base = N . getOperand ( 0 ) ; Index = N . getOperand ( 1 ) ; return true ; } } } return false ; } </s>

SelectAddressRegReg - Given the specified addressed , check to see if it can be more efficiently represented as [ r+imm ] .


<s> static tree mips_builtin_vectorized_function ( unsigned int fn , tree type_out , tree type_in ) { machine_mode in_mode , out_mode ; int in_n , out_n ; if ( TREE_CODE ( type_out ) != VECTOR_TYPE || TREE_CODE ( type_in ) != VECTOR_TYPE || ! ISA_HAS_MSA ) return NULL_TREE ; out_mode = TYPE_MODE ( TREE_TYPE ( type_out ) ) ; out_n = TYPE_VECTOR_SUBPARTS ( type_out ) ; in_mode = TYPE_MODE ( TREE_TYPE ( type_in ) ) ; in_n = TYPE_VECTOR_SUBPARTS ( type_in ) ; mips_builtin_decls [ mips_get_builtin_decl_index [ CODE_FOR_ ## INSN ] ] switch ( fn ) { case BUILT_IN_SQRT : if ( out_mode == DFmode && out_n == 2 && in_mode == DFmode && in_n == 2 ) return MIPS_GET_BUILTIN ( msa_fsqrt_d ) ; break ; case BUILT_IN_SQRTF : if ( out_mode == SFmode && out_n == 4 && in_mode == SFmode && in_n == 4 ) return MIPS_GET_BUILTIN ( msa_fsqrt_w ) ; break ; default : break ; } </s>


<s> unsigned MipsTargetLowering :: getJumpTableEncoding ( ) const { if ( ABI . IsN64 ( ) && isPositionIndependent ( ) ) return MachineJumpTableInfo :: EK_GPRel64BlockAddress ; return TargetLowering :: getJumpTableEncoding ( ) ; } </s>

Return the entry encoding for a jump table in the current function .


<s> void ARMAsmBackend :: handleAssemblerFlag ( MCAssemblerFlag Flag ) { switch ( Flag ) { default : break ; case MCAF_Code16 : setIsThumb ( true ) ; break ; case MCAF_Code32 : setIsThumb ( false ) ; break ; } } </s>

Handle any target-specific assembler flags . By default , do nothing .


"Can only put epilog before 'retl' instruction!"


"invalid id value for interrupt/exception attribute"

"invalid nmi function for reset attribute"

"invalid warm function for reset attribute"

Add some checking when inserting attributes .


<s> static bool ix86_vector_duplicate_value ( machine_mode mode , rtx target , rtx val ) { bool ok ; rtx_insn * insn ; rtx dup ; dup = gen_rtx_VEC_DUPLICATE ( mode , val ) ; insn = emit_insn ( gen_rtx_SET ( target , dup ) ) ; if ( recog_memoized ( insn ) < 0 ) { rtx_insn * seq ; machine_mode innermode = GET_MODE_INNER ( mode ) ; rtx reg ; start_sequence ( ) ; reg = force_reg ( innermode , val ) ; if ( GET_MODE ( reg ) != innermode ) reg = gen_lowpart ( innermode , reg ) ; XEXP ( dup , 0 ) = reg ; seq = get_insns ( ) ; end_sequence ( ) ; if ( seq ) emit_insn_before ( seq , insn ) ; ok = recog_memoized ( insn ) >= 0 ; gcc_assert ( ok ) ; } return true ; } </s>

A subroutine of ix86_expand_vector_init_duplicate . Tries to fill target with val via vec_duplicate .


<s>
void
LanaiDAGToDAGISel
::
Select
(
SDNode
*
Node
)
{
unsigned
Opcode
=
Node
->
getOpcode
(
)
;
if
(
Node
->
isMachineOpcode
(
)
)
{
DEBUG
(
errs
(
)
<<
"== "
;
Node
->
dump
(
CurDAG
)
;
errs
(
)
<<
"\n"
)
;
return
;
}
EVT
VT
=
Node
->
getValueType
(
0
)
;
switch
(
Opcode
)
{
case
ISD
::
Constant
:
if
(
VT
==
MVT
::
i32
)
{
ConstantSDNode
*
ConstNode
=
cast
<
ConstantSDNode
>
(
Node
)
;
if
(
ConstNode
->
isNullValue
(
)
)
{
SDValue
New
=
CurDAG
->
getCopyFromReg
(
CurDAG
->
getEntryNode
(
)
,
SDLoc
(
Node
)
,
Lanai
::
R0
,
MVT
::
i32
)
;
return
ReplaceNode
(
Node
,
New
.
getNode
(
)
)
;
}
if
(
ConstNode
->
isAllOnesValue
(
)
)
{
SDValue
New
=
CurDAG
->
getCopyFromReg
(
CurDAG
->
getEntryNode
(
)
,
SDLoc
(
Node
)
,
Lanai
::
R1
,
MVT
::
i32
)
;
return
ReplaceNode
(
Node
,
New
.
getNode
(
)
)
;
}
}
break
;
case
ISD
::
FrameIndex
:
selectFrameIndex
(
Node
)
;
return
;
default
:
break
;
}
SelectCode
(
Node
)
;
}
</s>

Main hook for targets to transform nodes into machine nodes .


<s> FastISel * PPC :: createFastISel ( FunctionLoweringInfo & FuncInfo , const TargetLibraryInfo * LibInfo ) { const TargetMachine & TM = FuncInfo . MF -> getTarget ( ) ; const PPCSubtarget * Subtarget = & TM . getSubtarget < PPCSubtarget > ( ) ; if ( Subtarget -> isPPC64 ( ) && Subtarget -> isSVR4ABI ( ) ) return new PPCFastISel ( FuncInfo , LibInfo ) ; return nullptr ; } </s>

This method returns a target specific FastISel object , or null if the target does not support `` fast '' ISel .

PowerPC PPC::createFastISel PPC PPC PPC PPC


<s> void Cpu0MCCodeEmitter :: EmitInstruction ( uint64_t Val , unsigned Size , raw_ostream & OS ) const { for ( unsigned i = 0 ; i < Size ; ++ i ) { unsigned Shift = IsLittleEndian ? i * 8 : ( Size - 1 - i ) * 8 ; EmitByte ( ( Val >> Shift ) & 0xff , OS ) ; } } </s>

EmitInstruction - This callback is invoked when an instruction is emitted , to advance the hazard state .


<s> bool DLXAsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , unsigned , const char * ExtraCode , raw_ostream & O ) { if ( ExtraCode && ExtraCode [ 0 ] ) { if ( ExtraCode [ 1 ] ) return true ; switch ( ExtraCode [ 0 ] ) { case 'H' : { if ( OpNo == 0 ) return true ; const MachineOperand & FlagsOP = MI -> getOperand ( OpNo - 1 ) ; if ( ! FlagsOP . isImm ( ) ) return true ; unsigned Flags = FlagsOP . getImm ( ) ; unsigned NumVals = InlineAsm :: getNumOperandRegisters ( Flags ) ; if ( NumVals != 2 ) return true ; unsigned RegOp = OpNo + 1 ; if ( RegOp >= MI -> getNumOperands ( ) ) return true ; const MachineOperand & MO = MI -> getOperand ( RegOp ) ; if ( ! MO . isReg ( ) ) return true ; unsigned Reg = MO . getReg ( ) ; O << DLXInstPrinter :: getRegisterName ( Reg ) ; return false ; } default : return true ; } } printOperand ( MI , OpNo , O ) ; return false ; } </s>

PrintAsmOperand - Print out an operand for an inline asm expression .


<s> static int mips_mode_rep_extended ( scalar_int_mode mode , scalar_int_mode mode_rep ) { if ( TARGET_64BIT && mode == SImode && mode_rep == DImode ) return SIGN_EXTEND ; return UNKNOWN ; } </s>


"getBranchTarget26OpValue expects only expressions or immediates"

getBranchTarget26OpValue - Return binary encoding of the branch target operand .


<s>
void
ARMTargetLowering
::
ReplaceNodeResults
(
SDNode
*
N
,
SmallVectorImpl
<
SDValue
>
&
Results
,
SelectionDAG
&
DAG
)
{
SDValue
Res
;
switch
(
N
->
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Don't know how to custom expand this!"
)
;
break
;
case
ISD
::
BIT_CONVERT
:
Res
=
ExpandBIT_CONVERT
(
N
,
DAG
)
;
break
;
case
ISD
::
SRL
:
case
ISD
::
SRA
:
Res
=
LowerShift
(
N
,
DAG
,
Subtarget
)
;
break
;
}
if
(
Res
.
getNode
(
)
)
Results
.
push_back
(
Res
)
;
}
</s>

ReplaceNodeResults - Replace the results of node with an illegal result type with new values built out of custom code .

ARM
ARM
"Don't know how to custom expand this!"
ISD::BIT_CONVERT
ISD::SRL
ISD::SRA


<s> int mmix_legitimate_constant_p ( rtx x ) { RTX_CODE code = GET_CODE ( x ) ; if ( code == CONST_INT || code == CONST_DOUBLE ) return 1 ; return CONSTANT_ADDRESS_P ( x ) ; } </s>


<s> ATTRIBUTE_UNUSED static section * x86_64_elf_select_section ( tree decl , int reloc , unsigned HOST_WIDE_INT align ) { if ( ix86_in_large_data_p ( decl ) ) { const char * sname = NULL ; unsigned int flags = SECTION_WRITE ; switch ( categorize_decl_for_section ( decl , reloc ) ) { case SECCAT_DATA : sname = ".ldata" ; break ; case SECCAT_DATA_REL : sname = ".ldata.rel" ; break ; case SECCAT_DATA_REL_LOCAL : sname = ".ldata.rel.local" ; break ; case SECCAT_DATA_REL_RO : sname = ".ldata.rel.ro" ; break ; case SECCAT_DATA_REL_RO_LOCAL : sname = ".ldata.rel.ro.local" ; break ; case SECCAT_BSS : sname = ".lbss" ; flags |= SECTION_BSS ; break ; case SECCAT_RODATA : case SECCAT_RODATA_MERGE_STR : case SECCAT_RODATA_MERGE_STR_INIT : case SECCAT_RODATA_MERGE_CONST : sname = ".lrodata" ; flags = 0 ; break ; case SECCAT_SRODATA : case SECCAT_SDATA : case SECCAT_SBSS : gcc_unreachable ( ) ; case SECCAT_TEXT : case SECCAT_TDATA : case SECCAT_TBSS : break ; } if ( sname ) { if ( ! DECL_P ( decl ) ) return get_section ( sname , flags , NULL ) ; return get_named_section ( decl , sname , reloc ) ; } } return default_elf_select_section ( decl , reloc , align ) ; } </s>

switch to the appropriate section for output of DECL . DECL is either a ` VAR_DECL ' node or a constant of some sort . RELOC indicates whether forming the initial value of DECL requires link-time relocations .


"instruction requires a CPU feature not currently enabled"

"flag setting instruction only valid outside IT block"

"instruction only valid inside IT block"

"instruction variant requires ARMv6 or later"

MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specified MCStreamer .


Write an ( optimal ) nop sequence of Count bytes to the given output .


<s> bool ARMBaseInstrInfo :: hasHighOperandLatency ( const InstrItineraryData * ItinData , const MachineRegisterInfo * MRI , const MachineInstr * DefMI , unsigned DefIdx , const MachineInstr * UseMI , unsigned UseIdx ) const { unsigned DDomain = DefMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; unsigned UDomain = UseMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Subtarget . isCortexA8 ( ) && ( DDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainVFP ) ) return true ; int Latency = computeOperandLatency ( ItinData , DefMI , DefIdx , UseMI , UseIdx ) ; if ( Latency < 0 ) Latency = getInstrLatency ( ItinData , DefMI ) ; if ( Latency <= 3 ) return false ; return DDomain == ARMII :: DomainVFP || DDomain == ARMII :: DomainNEON || UDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainNEON ; } </s>

Compute operand latency between a def of 'Reg ' and a use in the current loop .

ARM ARM ARMII::DomainMask ARMII::DomainMask ARMII::DomainVFP ARMII::DomainVFP 0 3 ARMII::DomainVFP ARMII::DomainNEON ARMII::DomainVFP ARMII::DomainNEON


<s> const char * host_detect_local_cpu ( int argc , const char * * argv ) { const char * cpu ; bool arch ; if ( argc < 1 ) return NULL ; arch = strcmp ( argv [ 0 ] , "cpu" ) == 0 ; if ( ! arch && strcmp ( argv [ 0 ] , "tune" ) ) return NULL ; if ( arch ) cpu = "powerpc" ; return concat ( "-m" , argv [ 0 ] , "=" , cpu , NULL ) ; } </s>

This will be called by the spec parser in gcc.cc when it sees a % : local_cpu_detect ( args ) construct . Currently it will be called with either `` cpu '' or `` tune '' as argument depending on if -mcpu=native or -mtune=native is to be substituted . It returns a string containing new command line parameters to be put at the place of the above two options , depending on what CPU this is executed . E.g . `` -mcpu=ultrasparc3 '' on an UltraSPARC III for -mcpu=native . If the routine ca n't detect a known processor , the -mcpu or -mtune option is discarded . ARGC and ARGV are set depending on the actual arguments given in the spec .


<s> SDValue PPCTargetLowering :: getNegatedExpression ( SDValue Op , SelectionDAG & DAG , bool LegalOps , bool OptForSize , NegatibleCost & Cost , unsigned Depth ) const { if ( Depth > SelectionDAG :: MaxRecursionDepth ) return SDValue ( ) ; unsigned Opc = Op . getOpcode ( ) ; EVT VT = Op . getValueType ( ) ; SDNodeFlags Flags = Op . getNode ( ) -> getFlags ( ) ; switch ( Opc ) { case PPCISD :: FNMSUB : if ( ! Op . hasOneUse ( ) || ! isTypeLegal ( VT ) || Subtarget . hasQPX ( ) ) break ; const TargetOptions & Options = getTargetMachine ( ) . Options ; SDValue N0 = Op . getOperand ( 0 ) ; SDValue N1 = Op . getOperand ( 1 ) ; SDValue N2 = Op . getOperand ( 2 ) ; SDLoc Loc ( Op ) ; NegatibleCost N2Cost = NegatibleCost :: Expensive ; SDValue NegN2 = getNegatedExpression ( N2 , DAG , LegalOps , OptForSize , N2Cost , Depth + 1 ) ; if ( ! NegN2 ) return SDValue ( ) ; if ( Flags . hasNoSignedZeros ( ) || Options . NoSignedZerosFPMath ) { NegatibleCost N0Cost = NegatibleCost :: Expensive ; SDValue NegN0 = getNegatedExpression ( N0 , DAG , LegalOps , OptForSize , N0Cost , Depth + 1 ) ; NegatibleCost N1Cost = NegatibleCost :: Expensive ; SDValue NegN1 = getNegatedExpression ( N1 , DAG , LegalOps , OptForSize , N1Cost , Depth + 1 ) ; if ( NegN0 && N0Cost <= N1Cost ) { Cost = std :: min ( N0Cost , N2Cost ) ; return DAG . getNode ( Opc , Loc , VT , NegN0 , N1 , NegN2 , Flags ) ; } else if ( NegN1 ) { Cost = std :: min ( N1Cost , N2Cost ) ; return DAG . getNode ( Opc , Loc , VT , N0 , NegN1 , NegN2 , Flags ) ; } } if ( isOperationLegal ( ISD :: FMA , VT ) ) { Cost = N2Cost ; return DAG . getNode ( ISD :: FMA , Loc , VT , N0 , N1 , NegN2 , Flags ) ; } break ; } return TargetLowering :: getNegatedExpression ( Op , DAG , LegalOps , OptForSize , Cost , Depth ) ; } </s>

Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate that if it is cheaper or neutral to do the negation .


<s>
bool
AArch64InstrInfo
::
isGPRCopy
(
const
MachineInstr
&
MI
)
{
switch
(
MI
.
getOpcode
(
)
)
{
default
:
break
;
case
TargetOpcode
::
COPY
:
{
unsigned
DstReg
=
MI
.
getOperand
(
0
)
.
getReg
(
)
;
return
(
AArch64
::
GPR32RegClass
.
contains
(
DstReg
)
||
AArch64
::
GPR64RegClass
.
contains
(
DstReg
)
)
;
}
case
AArch64
::
ORRXrs
:
if
(
MI
.
getOperand
(
1
)
.
getReg
(
)
==
AArch64
::
XZR
)
{
assert
(
MI
.
getDesc
(
)
.
getNumOperands
(
)
==
4
&&
MI
.
getOperand
(
3
)
.
getImm
(
)
==
0
&&
"invalid ORRrs operands"
)
;
return
true
;
}
break
;
case
AArch64
::
ADDXri
:
if
(
MI
.
getOperand
(
2
)
.
getImm
(
)
==
0
)
{
assert
(
MI
.
getDesc
(
)
.
getNumOperands
(
)
==
4
&&
MI
.
getOperand
(
3
)
.
getImm
(
)
==
0
&&
"invalid ADDXri operands"
)
;
return
true
;
}
break
;
}
return
false
;
}
</s>

Does this instruction rename a GPR without modifying bits ?


<s>
static
void
rs6000_elf_asm_out_constructor
(
rtx
symbol
,
int
priority
)
{
const
char
*
section
=
".ctors"
;
char
buf
[
18
]
;
if
(
priority
!=
DEFAULT_INIT_PRIORITY
)
{
sprintf
(
buf
,
".ctors.%.5u"
,
MAX_INIT_PRIORITY
priority
)
;
section
=
buf
;
}
switch_to_section
(
get_section
(
section
,
SECTION_WRITE
,
)
)
;
assemble_align
(
POINTER_SIZE
)
;
if
(
DEFAULT_ABI
==
ABI_V4
&&
(
TARGET_RELOCATABLE
||
flag_pic
>
1
)
)
{
fputs
(
"\t.long ("
,
asm_out_file
)
;
output_addr_const
(
asm_out_file
,
symbol
)
;
fputs
(
")@fixup\n"
,
asm_out_file
)
;
}
else
assemble_integer
(
symbol
,
POINTER_SIZE
/
BITS_PER_UNIT
,
POINTER_SIZE
,
1
)
;
}
</s>


<s> void SystemZAsmPrinter :: emitMachineConstantPoolValue ( MachineConstantPoolValue * MCPV ) { auto * ZCPV = static_cast < SystemZConstantPoolValue * > ( MCPV ) ; const MCExpr * Expr = MCSymbolRefExpr :: create ( getSymbol ( ZCPV -> getGlobalValue ( ) ) , getModifierVariantKind ( ZCPV -> getModifier ( ) ) , OutContext ) ; uint64_t Size = getDataLayout ( ) . getTypeAllocSize ( ZCPV -> getType ( ) ) ; OutStreamer -> emitValue ( Expr , Size ) ; } </s>

EmitMachineConstantPoolValue - Print a machine constantpool value to the .s file .


<s> FPGASubtarget & FPGASubtarget :: initializeSubtargetDependencies ( StringRef CPU , StringRef FS ) { initializeEnvironment ( ) ; initSubtargetFeatures ( CPU , FS ) ; return * this ; } </s>

initializeSubtargetDependencies - Initializes using a CPU , a TuneCPU , and feature string so that we can use initializer lists for subtarget initialization .


<s> int mips_class_max_nregs ( enum reg_class rclass , machine_mode mode ) { int size ; HARD_REG_SET left ; size = 0x8000 ; left = reg_class_contents [ rclass ] ; if ( hard_reg_set_intersect_p ( left , reg_class_contents [ ( int ) ST_REGS ] ) ) { if ( mips_hard_regno_mode_ok ( ST_REG_FIRST , mode ) ) size = MIN ( size , 4 ) ; left &= ~ reg_class_contents [ ST_REGS ] ; } if ( hard_reg_set_intersect_p ( left , reg_class_contents [ ( int ) FP_REGS ] ) ) { if ( mips_hard_regno_mode_ok ( FP_REG_FIRST , mode ) ) { if ( MSA_SUPPORTED_MODE_P ( mode ) ) size = MIN ( size , UNITS_PER_MSA_REG ) ; else size = MIN ( size , UNITS_PER_FPREG ) ; } left &= ~ reg_class_contents [ FP_REGS ] ; } if ( ! hard_reg_set_empty_p ( left ) ) size = MIN ( size , UNITS_PER_WORD ) ; return ( GET_MODE_SIZE ( mode ) + size - 1 ) / size ; } </s>

Implement CLASS_MAX_NREGS . Usually all registers are word-sized . The only supported exception is -mgp64 -msingle-float , which has 64-bit words but 32-bit float registers . A word-based calculation is correct even in that case , since -msingle-float disallows multi-FPR values . The FP status registers are an exception to this rule . They are always 4 bytes wide as they only hold condition code modes , and CCmode is always considered to be 4 bytes wide .


"%Klane index must be a constant immediate"

Expand a Neon builtin , i.e . those registered only if TARGET_NEON holds . Most of these are `` special '' because they do n't have symbolic constants defined per-instruction or per instruction-variant . Instead , the required info is looked up in the table neon_builtin_data .


<s> void OR1KAsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { MachineBasicBlock :: const_instr_iterator I = MI ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; do { customEmitInstruction ( I ++ ) ; } while ( ( I != E ) && I -> isInsideBundle ( ) ) ; } </s>


<s> void ARMTargetStreamer :: finish ( ) { ConstantPools -> emitAll ( Streamer ) ; } </s>

finish - after all the new live ranges have been created , compute the remaining live range , and rewrite instructions to use the new registers .


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { AU . addPreserved < DominatorTreeWrapperPass > ( ) ; AU . addPreserved < LoopInfoWrapperPass > ( ) ; AU . addRequired < TargetPassConfig > ( ) ; } </s>

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> void MipsTargetObjectFile :: Initialize ( MCContext & Ctx , const TargetMachine & TM ) { TargetLoweringObjectFileELF :: Initialize ( Ctx , TM ) ; InitializeELF ( TM . Options . UseInitArray ) ; SmallDataSection = getContext ( ) . getELFSection ( ".sdata" , ELF :: SHT_PROGBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC , SectionKind :: getDataRel ( ) ) ; SmallBSSSection = getContext ( ) . getELFSection ( ".sbss" , ELF :: SHT_NOBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC , SectionKind :: getBSS ( ) ) ; const MipsSubtarget & Subtarget = TM . getSubtarget < MipsSubtarget > ( ) ; if ( Subtarget . isTargetNaCl ( ) ) { StaticCtorSection = getContext ( ) . getELFSection ( ".init_array" , ELF :: SHT_INIT_ARRAY , ELF :: SHF_WRITE | ELF :: SHF_ALLOC , SectionKind :: getDataRel ( ) ) ; StaticDtorSection = getContext ( ) . getELFSection ( ".fini_array" , ELF :: SHT_FINI_ARRAY , ELF :: SHF_WRITE | ELF :: SHF_ALLOC , SectionKind :: getDataRel ( ) ) ; } } </s>

This method must be called before any actual lowering is done .


<s> void mips_expand_epilogue ( int sibcall_p ) { HOST_WIDE_INT step1 , step2 ; rtx base , target ; if ( ! sibcall_p && mips_can_use_return_insn ( ) ) { emit_jump_insn ( gen_return ( ) ) ; return ; } step1 = cfun -> machine -> frame . total_size ; step2 = 0 ; if ( ! frame_pointer_needed ) base = stack_pointer_rtx ; else { base = hard_frame_pointer_rtx ; if ( TARGET_MIPS16 ) step1 -= cfun -> machine -> frame . args_size ; } if ( ( cfun -> machine -> frame . mask | cfun -> machine -> frame . fmask ) != 0 ) { step2 = MIN ( step1 , MIPS_MAX_FIRST_STACK_STEP ) ; step1 -= step2 ; } target = base ; if ( step1 > 0 ) { rtx adjust ; adjust = GEN_INT ( step1 ) ; if ( ! SMALL_OPERAND ( step1 ) ) { emit_move_insn ( MIPS_EPILOGUE_TEMP ( Pmode ) , adjust ) ; adjust = MIPS_EPILOGUE_TEMP ( Pmode ) ; } if ( ! TARGET_MIPS16 ) target = stack_pointer_rtx ; emit_insn ( gen_add3_insn ( target , base , adjust ) ) ; } if ( target != stack_pointer_rtx ) emit_move_insn ( stack_pointer_rtx , target ) ; if ( TARGET_ABICALLS && TARGET_NEWABI && ! TARGET_EXPLICIT_RELOCS ) emit_insn ( gen_blockage ( ) ) ; mips_for_each_saved_reg ( cfun -> machine -> frame . total_size - step2 , mips_restore_reg ) ; if ( step2 > 0 ) emit_insn ( gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( step2 ) ) ) ; if ( current_function_calls_eh_return ) { if ( TARGET_MIPS16 ) { emit_move_insn ( MIPS_EPILOGUE_TEMP ( Pmode ) , stack_pointer_rtx ) ; emit_insn ( gen_add3_insn ( MIPS_EPILOGUE_TEMP ( Pmode ) , MIPS_EPILOGUE_TEMP ( Pmode ) , EH_RETURN_STACKADJ_RTX ) ) ; emit_move_insn ( stack_pointer_rtx , MIPS_EPILOGUE_TEMP ( Pmode ) ) ; } else emit_insn ( gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , EH_RETURN_STACKADJ_RTX ) ) ; } if ( ! sibcall_p ) { if ( TARGET_MIPS16 && ( cfun -> machine -> frame . mask & RA_MASK ) != 0 ) emit_jump_insn ( gen_return_internal ( gen_rtx_REG ( Pmode , GP_REG_FIRST + 7 ) ) ) ; else emit_jump_insn ( gen_return_internal ( gen_rtx_REG ( Pmode , GP_REG_FIRST + 31 ) ) ) ; } } </s>

Expand the epilogue into a bunch of separate insns . SIBCALL_P is true if this epilogue precedes a sibling call , false if it is for a normal `` epilogue '' pattern .


"stack limit expression is not supported"

Emit the correct code for allocating stack space , as insns . If COPY_R12 , make sure a copy of the old frame is left in r12 . The generated code may use hard register 0 as a temporary .


<s> bool SystemZRegisterInfo :: getRegAllocationHints ( unsigned VirtReg , ArrayRef < MCPhysReg > Order , SmallVectorImpl < MCPhysReg > & Hints , const MachineFunction & MF , const VirtRegMap * VRM , const LiveRegMatrix * Matrix ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const TargetRegisterInfo * TRI = MF . getSubtarget ( ) . getRegisterInfo ( ) ; bool BaseImplRetVal = TargetRegisterInfo :: getRegAllocationHints ( VirtReg , Order , Hints , MF , VRM , Matrix ) ; if ( MRI -> getRegClass ( VirtReg ) == & SystemZ :: GRX32BitRegClass ) { SmallVector < unsigned , 8 > Worklist ; SmallSet < unsigned , 4 > DoneRegs ; Worklist . push_back ( VirtReg ) ; while ( Worklist . size ( ) ) { unsigned Reg = Worklist . pop_back_val ( ) ; if ( ! DoneRegs . insert ( Reg ) . second ) continue ; for ( auto & Use : MRI -> use_instructions ( Reg ) ) { if ( Use . getOpcode ( ) == SystemZ :: LOCRMux ) { MachineOperand & TrueMO = Use . getOperand ( 1 ) ; MachineOperand & FalseMO = Use . getOperand ( 2 ) ; const TargetRegisterClass * RC = TRI -> getCommonSubClass ( getRC32 ( FalseMO , VRM , MRI ) , getRC32 ( TrueMO , VRM , MRI ) ) ; if ( RC && RC != & SystemZ :: GRX32BitRegClass ) { addHints ( Order , Hints , RC , MRI ) ; return true ; } unsigned OtherReg = ( TrueMO . getReg ( ) == Reg ? FalseMO . getReg ( ) : TrueMO . getReg ( ) ) ; if ( MRI -> getRegClass ( OtherReg ) == & SystemZ :: GRX32BitRegClass ) Worklist . push_back ( OtherReg ) ; } else if ( Use . getOpcode ( ) == SystemZ :: CHIMux || Use . getOpcode ( ) == SystemZ :: CFIMux ) { if ( Use . getOperand ( 1 ) . getImm ( ) == 0 ) { bool OnlyLMuxes = true ; for ( MachineInstr & DefMI : MRI -> def_instructions ( VirtReg ) ) if ( DefMI . getOpcode ( ) != SystemZ :: LMux ) OnlyLMuxes = false ; if ( OnlyLMuxes ) { addHints ( Order , Hints , & SystemZ :: GR32BitRegClass , MRI ) ; return false ; } } } } } } return BaseImplRetVal ; } </s>

Get a list of 'hint ' registers that the register allocator should try first when allocating a physical register for the virtual register VirtReg .


<s> unsigned getNumFixupKinds ( ) const override { return PPC :: NumTargetFixupKinds ; } </s>

Get the number of target specific fixup kinds .


<s> TargetTransformInfo LanaiTargetMachine :: getTargetTransformInfo ( const Function & F ) const { return TargetTransformInfo ( LanaiTTIImpl ( this , F ) ) ; } </s>

Get a TargetTransformInfo implementation for the target .


<s> static int sparc_arg_partial_bytes ( cumulative_args_t cum , const function_arg_info & arg ) { int slotno , regno , padding ; slotno = function_arg_slotno ( get_cumulative_args ( cum ) , arg . mode , arg . type , arg . named , false , & regno , & padding ) ; if ( slotno == - 1 ) return 0 ; if ( TARGET_ARCH32 ) { const int size = GET_MODE_SIZE ( arg . mode ) ; if ( size > UNITS_PER_WORD && slotno == SPARC_INT_ARG_MAX - 1 ) return UNITS_PER_WORD ; } else { if ( arg . aggregate_type_p ( ) ) { const int size = int_size_in_bytes ( arg . type ) ; if ( size > UNITS_PER_WORD && ( slotno == SPARC_INT_ARG_MAX - 1 || slotno == SPARC_FP_ARG_MAX - 1 ) ) return UNITS_PER_WORD ; } else if ( GET_MODE_CLASS ( arg . mode ) == MODE_COMPLEX_INT || ( ( GET_MODE_CLASS ( arg . mode ) == MODE_COMPLEX_FLOAT || ( arg . type && VECTOR_TYPE_P ( arg . type ) ) ) && ! ( TARGET_FPU && arg . named ) ) ) { const int size = ( arg . type && VECTOR_FLOAT_TYPE_P ( arg . type ) ) ? int_size_in_bytes ( arg . type ) : GET_MODE_SIZE ( arg . mode ) ; if ( size > UNITS_PER_WORD && slotno == SPARC_INT_ARG_MAX - 1 ) return UNITS_PER_WORD ; } else if ( GET_MODE_CLASS ( arg . mode ) == MODE_COMPLEX_FLOAT || ( arg . type && VECTOR_TYPE_P ( arg . type ) ) ) { const int size = ( arg . type && VECTOR_FLOAT_TYPE_P ( arg . type ) ) ? int_size_in_bytes ( arg . type ) : GET_MODE_SIZE ( arg . mode ) ; if ( size > UNITS_PER_WORD && slotno == SPARC_FP_ARG_MAX - 1 ) return UNITS_PER_WORD ; } } return 0 ; } </s>

For an arg passed partly in registers and partly in memory , this is the number of bytes of registers used . For args passed entirely in registers or entirely in memory , zero . Any arg that starts in the first 6 regs but wo n't entirely fit in them needs partial registers on v8 . On v9 , structures with integer values in arg slots 5,6 will be passed in % o5 and SP+176 , and complex fp values that begin in the last fp reg [ where `` last fp reg '' varies with the mode ] will be split between that reg and memory .


<s> void DLXTargetObjectFile :: Initialize ( MCContext & Ctx , const TargetMachine & TM ) { TargetLoweringObjectFileELF :: Initialize ( Ctx , TM ) ; InitializeELF ( TM . Options . UseInitArray ) ; SmallDataSection = getContext ( ) . getELFSection ( ".sdata" , ELF :: SHT_PROGBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC ) ; SmallBSSSection = getContext ( ) . getELFSection ( ".sbss" , ELF :: SHT_NOBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC ) ; } </s>


Select appropriate section for constants depending on where we place literal pools .


<s> bool AArch64InstrInfo :: canInsertSelect ( const MachineBasicBlock & MBB , ArrayRef < MachineOperand > Cond , unsigned DstReg , unsigned TrueReg , unsigned FalseReg , int & CondCycles , int & TrueCycles , int & FalseCycles ) const { const MachineRegisterInfo & MRI = MBB . getParent ( ) -> getRegInfo ( ) ; const TargetRegisterClass * RC = RI . getCommonSubClass ( MRI . getRegClass ( TrueReg ) , MRI . getRegClass ( FalseReg ) ) ; if ( ! RC ) return false ; if ( ! RI . getCommonSubClass ( RC , MRI . getRegClass ( DstReg ) ) ) return false ; unsigned ExtraCondLat = Cond . size ( ) != 1 ; if ( AArch64 :: GPR64allRegClass . hasSubClassEq ( RC ) || AArch64 :: GPR32allRegClass . hasSubClassEq ( RC ) ) { CondCycles = 1 + ExtraCondLat ; TrueCycles = FalseCycles = 1 ; if ( canFoldIntoCSel ( MRI , TrueReg ) ) TrueCycles = 0 ; else if ( canFoldIntoCSel ( MRI , FalseReg ) ) FalseCycles = 0 ; return true ; } if ( AArch64 :: FPR64RegClass . hasSubClassEq ( RC ) || AArch64 :: FPR32RegClass . hasSubClassEq ( RC ) ) { CondCycles = 5 + ExtraCondLat ; TrueCycles = FalseCycles = 2 ; return true ; } return false ; } </s>

Return true if it is possible to insert a select instruction that chooses between TrueReg and FalseReg based on the condition code in Cond .


<s> static void arm_function_arg_advance ( cumulative_args_t pcum_v , machine_mode mode , const_tree type , bool named ) { CUMULATIVE_ARGS * pcum = get_cumulative_args ( pcum_v ) ; if ( pcum -> pcs_variant <= ARM_PCS_AAPCS_LOCAL ) { aapcs_layout_arg ( pcum , mode , type , named ) ; if ( pcum -> aapcs_cprc_slot >= 0 ) { aapcs_cp_arg_layout [ pcum -> aapcs_cprc_slot ] . advance ( pcum , mode , type ) ; pcum -> aapcs_cprc_slot = - 1 ; } pcum -> aapcs_arg_processed = false ; pcum -> aapcs_ncrn = pcum -> aapcs_next_ncrn ; pcum -> aapcs_reg = NULL_RTX ; pcum -> aapcs_partial = 0 ; } else { pcum -> nargs += 1 ; if ( arm_vector_mode_supported_p ( mode ) && pcum -> named_count > pcum -> nargs && TARGET_IWMMXT_ABI ) pcum -> iwmmxt_nregs += 1 ; else pcum -> nregs += ARM_NUM_REGS2 ( mode , type ) ; } } </s>

Update the data in PCUM to advance over an argument of mode MODE and data type TYPE . ( TYPE is null for libcalls where that information may not be available . )


<s> bool arm_expand_vector_compare ( rtx target , rtx_code code , rtx op0 , rtx op1 , bool can_invert ) { machine_mode cmp_result_mode = GET_MODE ( target ) ; machine_mode cmp_mode = GET_MODE ( op0 ) ; bool inverted ; switch ( code ) { case UNORDERED : case UNLT : case UNLE : case UNGT : case UNGE : case UNEQ : case NE : code = reverse_condition_maybe_unordered ( code ) ; if ( ! can_invert ) { rtx tmp = gen_reg_rtx ( cmp_result_mode ) ; if ( arm_expand_vector_compare ( tmp , code , op0 , op1 , true ) ) gcc_unreachable ( ) ; emit_insn ( gen_rtx_SET ( target , gen_rtx_NOT ( cmp_result_mode , tmp ) ) ) ; return false ; } inverted = true ; break ; default : inverted = false ; break ; } switch ( code ) { case LE : case LT : if ( op1 != CONST0_RTX ( cmp_mode ) ) { code = swap_condition ( code ) ; std :: swap ( op0 , op1 ) ; } case EQ : case GE : case GT : emit_insn ( gen_neon_vc ( code , cmp_mode , target , op0 , op1 ) ) ; return inverted ; case GEU : case GTU : emit_insn ( gen_neon_vc ( code , cmp_mode , target , op0 , force_reg ( cmp_mode , op1 ) ) ) ; return inverted ; case LEU : case LTU : emit_insn ( gen_neon_vc ( swap_condition ( code ) , cmp_mode , target , force_reg ( cmp_mode , op1 ) , op0 ) ) ; return inverted ; case LTGT : case ORDERED : { rtx gt_res = gen_reg_rtx ( cmp_result_mode ) ; rtx alt_res = gen_reg_rtx ( cmp_result_mode ) ; rtx_code alt_code = ( code == LTGT ? LT : LE ) ; if ( arm_expand_vector_compare ( gt_res , GT , op0 , op1 , true ) || arm_expand_vector_compare ( alt_res , alt_code , op0 , op1 , true ) ) gcc_unreachable ( ) ; emit_insn ( gen_rtx_SET ( target , gen_rtx_IOR ( cmp_result_mode , gt_res , alt_res ) ) ) ; return inverted ; } default : gcc_unreachable ( ) ; } } </s>

Expand code to compare vectors OP0 and OP1 using condition CODE . If CAN_INVERT , store either the result or its inverse in TARGET and return true if TARGET contains the inverse . If ! CAN_INVERT , always store the result in TARGET , never its inverse . Note that the handling of floating-point comparisons is not IEEE compliant .


<s>
const
char
*
output_adjust_stack_and_probe
(
rtx
reg
)
{
static
int
labelno
=
0
;
char
loop_lab
[
32
]
,
end_lab
[
32
]
;
rtx
xops
[
2
]
;
ASM_GENERATE_INTERNAL_LABEL
(
loop_lab
,
"LPSRL"
,
labelno
)
;
ASM_GENERATE_INTERNAL_LABEL
(
end_lab
,
"LPSRE"
,
labelno
++
)
;
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
loop_lab
)
;
xops
[
0
]
=
stack_pointer_rtx
;
xops
[
1
]
=
reg
;
output_asm_insn
(
"cmp%z0\t{%1, %0|%0, %1}"
,
xops
)
;
fputs
(
"\tje\t"
,
asm_out_file
)
;
assemble_name_raw
(
asm_out_file
,
end_lab
)
;
fputc
(
'\n'
,
asm_out_file
)
;
xops
[
1
]
=
GEN_INT
(
PROBE_INTERVAL
)
;
output_asm_insn
(
"sub%z0\t{%1, %0|%0, %1}"
,
xops
)
;
xops
[
1
]
=
const0_rtx
;
output_asm_insn
(
"or%z0\t{%1, (%0)|DWORD PTR [%0], %1}"
,
xops
)
;
fprintf
(
asm_out_file
,
"\tjmp\t"
)
;
assemble_name_raw
(
asm_out_file
,
loop_lab
)
;
fputc
(
'\n'
,
asm_out_file
)
;
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
end_lab
)
;
return
""
;
}
</s>

Adjust the stack pointer up to REG while probing it .


<s> static void arm_setup_incoming_varargs ( CUMULATIVE_ARGS * cum , enum machine_mode mode ATTRIBUTE_UNUSED , tree type ATTRIBUTE_UNUSED , int * pretend_size , int second_time ATTRIBUTE_UNUSED ) { cfun -> machine -> uses_anonymous_args = 1 ; if ( cum -> nregs < NUM_ARG_REGS ) * pretend_size = ( NUM_ARG_REGS - cum -> nregs ) * UNITS_PER_WORD ; } </s>

Worker function for TARGET_SETUP_INCOMING_VARARGS . On the ARM , PRETEND_SIZE is set in order to have the prologue push the last named arg and all anonymous args onto the stack . XXX I know the prologue should n't be pushing registers , but it is faster that way .


<s> unsigned PPCFrameLowering :: determineFrameLayout ( const MachineFunction & MF , bool UseEstimate , unsigned * NewMaxCallFrameSize ) const { const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const PPCFunctionInfo * FI = MF . getInfo < PPCFunctionInfo > ( ) ; unsigned FrameSize = UseEstimate ? MFI . estimateStackSize ( MF ) : MFI . getStackSize ( ) ; Align TargetAlign = getStackAlign ( ) ; Align MaxAlign = MFI . getMaxAlign ( ) ; Align Alignment = std :: max ( TargetAlign , MaxAlign ) ; const PPCRegisterInfo * RegInfo = Subtarget . getRegisterInfo ( ) ; unsigned LR = RegInfo -> getRARegister ( ) ; bool DisableRedZone = MF . getFunction ( ) . hasFnAttribute ( Attribute :: NoRedZone ) ; bool CanUseRedZone = ! MFI . hasVarSizedObjects ( ) && ! MFI . adjustsStack ( ) && ! MustSaveLR ( MF , LR ) && ! FI -> mustSaveTOC ( ) && ! RegInfo -> hasBasePointer ( MF ) ; bool FitsInRedZone = FrameSize <= Subtarget . getRedZoneSize ( ) ; if ( ! DisableRedZone && CanUseRedZone && FitsInRedZone ) { return 0 ; } unsigned maxCallFrameSize = MFI . getMaxCallFrameSize ( ) ; unsigned minCallFrameSize = getLinkageSize ( ) ; maxCallFrameSize = std :: max ( maxCallFrameSize , minCallFrameSize ) ; if ( MFI . hasVarSizedObjects ( ) ) maxCallFrameSize = alignTo ( maxCallFrameSize , Alignment ) ; if ( NewMaxCallFrameSize ) * NewMaxCallFrameSize = maxCallFrameSize ; FrameSize += maxCallFrameSize ; FrameSize = alignTo ( FrameSize , Alignment ) ; return FrameSize ; } </s>

Determine the frame layout but do not update the machine function .


<s> static bool csky_can_change_mode_class ( machine_mode from , machine_mode to , reg_class_t rclass ) { return ( GET_MODE_SIZE ( from ) == GET_MODE_SIZE ( to ) || ! reg_classes_intersect_p ( V_REGS , rclass ) ) ; } </s>

Implement TARGET_CAN_CHANGE_MODE_CLASS . V_REG registers ca n't do subreg as all values are reformatted to internal precision .


<s> static void mt_set_memflags_1 ( rtx x , int in_struct_p , int volatile_p ) { int i ; switch ( GET_CODE ( x ) ) { case SEQUENCE : case PARALLEL : for ( i = XVECLEN ( x , 0 ) - 1 ; i >= 0 ; i -- ) mt_set_memflags_1 ( XVECEXP ( x , 0 , i ) , in_struct_p , volatile_p ) ; break ; case INSN : mt_set_memflags_1 ( PATTERN ( x ) , in_struct_p , volatile_p ) ; break ; case SET : mt_set_memflags_1 ( SET_DEST ( x ) , in_struct_p , volatile_p ) ; mt_set_memflags_1 ( SET_SRC ( x ) , in_struct_p , volatile_p ) ; break ; case MEM : MEM_IN_STRUCT_P ( x ) = in_struct_p ; MEM_VOLATILE_P ( x ) = volatile_p ; break ; default : break ; } } </s>

Subfunction of the following function . Update the flags of any MEM found in part of X .


"Wasn't expecting to be able to lower this!"

LowerOperation - Provide custom lowering hooks for some operations .


"JIT relocation model must be set to static or default!"

runOnMachineFunction - Emit the function body .


<s> static int rs6000_builtin_vectorization_cost ( enum vect_cost_for_stmt type_of_cost , tree vectype , int misalign ) { unsigned elements ; tree elem_type ; switch ( type_of_cost ) { case scalar_stmt : case scalar_load : case scalar_store : case vector_stmt : case vector_load : case vector_store : case vec_to_scalar : case scalar_to_vec : case cond_branch_not_taken : return 1 ; case vec_perm : if ( TARGET_VSX ) return 3 ; else return 1 ; case vec_promote_demote : if ( TARGET_VSX ) return 4 ; else return 1 ; case cond_branch_taken : return 3 ; case unaligned_load : if ( TARGET_P9_VECTOR ) return 3 ; if ( TARGET_EFFICIENT_UNALIGNED_VSX ) return 1 ; if ( TARGET_VSX && TARGET_ALLOW_MOVMISALIGN ) { elements = TYPE_VECTOR_SUBPARTS ( vectype ) ; if ( elements == 2 ) return 2 ; if ( elements == 4 ) { switch ( misalign ) { case 8 : return 2 ; case - 1 : case 4 : case 12 : return 22 ; default : gcc_unreachable ( ) ; } } } if ( TARGET_ALTIVEC ) gcc_unreachable ( ) ; return 2 ; case unaligned_store : if ( TARGET_EFFICIENT_UNALIGNED_VSX ) return 1 ; if ( TARGET_VSX && TARGET_ALLOW_MOVMISALIGN ) { elements = TYPE_VECTOR_SUBPARTS ( vectype ) ; if ( elements == 2 ) return 2 ; if ( elements == 4 ) { switch ( misalign ) { case 8 : return 2 ; case - 1 : case 4 : case 12 : return 23 ; default : gcc_unreachable ( ) ; } } } if ( TARGET_ALTIVEC ) gcc_unreachable ( ) ; return 2 ; case vec_construct : elem_type = TREE_TYPE ( vectype ) ; if ( SCALAR_FLOAT_TYPE_P ( elem_type ) && TYPE_PRECISION ( elem_type ) == 32 ) return 5 ; else return max ( 2 , TYPE_VECTOR_SUBPARTS ( vectype ) - 1 ) ; default : gcc_unreachable ( ) ; } } </s>


<s> SDNode * PPCDAGToDAGISel :: getGlobalBaseReg ( ) { if ( ! GlobalBaseReg ) { const TargetInstrInfo & TII = * TM . getInstrInfo ( ) ; MachineBasicBlock & FirstMBB = MF -> front ( ) ; MachineBasicBlock :: iterator MBBI = FirstMBB . begin ( ) ; DebugLoc dl ; if ( PPCLowering . getPointerTy ( ) == MVT :: i32 ) { GlobalBaseReg = RegInfo -> createVirtualRegister ( & PPC :: GPRCRegClass ) ; BuildMI ( FirstMBB , MBBI , dl , TII . get ( PPC :: MovePCtoLR ) ) ; BuildMI ( FirstMBB , MBBI , dl , TII . get ( PPC :: MFLR ) , GlobalBaseReg ) ; } else { GlobalBaseReg = RegInfo -> createVirtualRegister ( & PPC :: G8RCRegClass ) ; BuildMI ( FirstMBB , MBBI , dl , TII . get ( PPC :: MovePCtoLR8 ) ) ; BuildMI ( FirstMBB , MBBI , dl , TII . get ( PPC :: MFLR8 ) , GlobalBaseReg ) ; } } return CurDAG -> getRegister ( GlobalBaseReg , PPCLowering . getPointerTy ( ) ) . getNode ( ) ; } </s>

getGlobalBaseReg - Return a virtual register initialized with the the global base register value .


<s> static MachineInstr * storeRegToStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , Register SrcReg , unsigned BitSize , int FrameIdx , int Offset , const TargetInstrInfo * TII , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) { unsigned SubIdx = ( BitSize == 8 ) ? X86 :: sub_8bit : X86 :: sub_16bit ; unsigned Opc = ( BitSize == 8 ) ? X86 :: MOV8mr : X86 :: MOV16mr ; if ( BitSize == TRI -> getRegSizeInBits ( * RC ) ) SubIdx = 0 ; MachineInstr * NewMI = addFrameReference ( BuildMI ( MBB , MI , DebugLoc ( ) , TII -> get ( Opc ) ) , FrameIdx , Offset ) . addReg ( SrcReg , 0 , SubIdx ) ; return NewMI ; } </s>

Store the specified register of the given register class to the specified stack frame index .


<s> static bool classof ( const VEMCExpr * ) { return true ; } </s>

Methods for support type inquiry through isa , cast , and dyn_cast :


<s> TargetLoweringObjectFile * getObjFileLowering ( ) const override { return TLOF . get ( ) ; } </s>

Return information about object file lowering .


<s> TargetLoweringBase :: AtomicRMWExpansionKind ARMTargetLowering :: shouldExpandAtomicRMWInIR ( AtomicRMWInst * AI ) const { unsigned Size = AI -> getType ( ) -> getPrimitiveSizeInBits ( ) ; return ( Size <= ( Subtarget -> isMClass ( ) ? 32U : 64U ) ) ? AtomicRMWExpansionKind :: LLSC : AtomicRMWExpansionKind :: None ; } </s>

Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW , if at all .


<s> unsigned getNumFixupKinds ( ) const override { return Lanai :: NumTargetFixupKinds ; } </s>

Get the number of target specific fixup kinds .


<s>
const
MCPhysReg
*
AArch64RegisterInfo
::
getCalleeSavedRegs
(
const
MachineFunction
*
MF
)
const
{
assert
(
MF
&&
"Invalid MachineFunction pointer."
)
;
if
(
MF
->
getFunction
(
)
->
getCallingConv
(
)
==
CallingConv
::
GHC
)
return
CSR_AArch64_NoRegs_SaveList
;
if
(
MF
->
getFunction
(
)
->
getCallingConv
(
)
==
CallingConv
::
AnyReg
)
return
CSR_AArch64_AllRegs_SaveList
;
if
(
MF
->
getFunction
(
)
->
getCallingConv
(
)
==
CallingConv
::
CXX_FAST_TLS
)
return
MF
->
getInfo
<
AArch64FunctionInfo
>
(
)
->
isSplitCSR
(
)
CSR_AArch64_CXX_TLS_Darwin_PE_SaveList
:
CSR_AArch64_CXX_TLS_Darwin_SaveList
;
else
return
CSR_AArch64_AAPCS_SaveList
;
}
</s>


<s>
void
X86IntelInstPrinter
::
printPCRelImm
(
const
MCInst
*
MI
,
unsigned
OpNo
,
raw_ostream
&
O
)
{
const
MCOperand
&
Op
=
MI
->
getOperand
(
OpNo
)
;
if
(
Op
.
isImm
(
)
)
O
<<
Op
.
getImm
(
)
;
else
{
assert
(
Op
.
isExpr
(
)
&&
"unknown pcrel immediate operand"
)
;
const
MCConstantExpr
*
BranchTarget
=
dyn_cast
<
MCConstantExpr
>
(
Op
.
getExpr
(
)
)
;
int64_t
Address
;
if
(
BranchTarget
&&
BranchTarget
->
EvaluateAsAbsolute
(
Address
)
)
{
O
<<
"0x"
;
O
.
write_hex
(
Address
)
;
}
else
{
O
<<
*
Op
.
getExpr
(
)
;
}
}
}
</s>


<s> static bool pattern_is_rotate64 ( rtx pat ) { rtx rot = SET_SRC ( pat ) ; if ( GET_CODE ( rot ) == ROTATE && CONST_INT_P ( XEXP ( rot , 1 ) ) && INTVAL ( XEXP ( rot , 1 ) ) == 64 ) return true ; return false ; } </s>

Return 1 iff PAT ( a SINGLE_SET ) is a rotate 64 bit expression ; else return 0 .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { GlobalBaseReg = 0 ; PPCLowering = TM . getTargetLowering ( ) ; PPCSubTarget = TM . getSubtargetImpl ( ) ; SelectionDAGISel :: runOnMachineFunction ( MF ) ; if ( ! PPCSubTarget -> isSVR4ABI ( ) ) InsertVRSaveCode ( MF ) ; return true ; } </s>


<s> static void mips_sim_wait_regs_1 ( rtx * x , void * data ) { for_each_rtx ( x , mips_sim_wait_regs_2 , data ) ; } </s>

Call mips_sim_wait_regs_2 ( R , DATA ) for each register R mentioned in * X .


"profiling %<-mcmodel=large%> with PIC is not supported"

Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry .


<s> bool hasFP ( const MachineFunction & ) const override { return true ; } </s>

hasFP - Return true if the specified function should have a dedicated frame pointer register .


<s>
scalar_chain
::
scalar_chain
(
enum
machine_mode
smode_
,
enum
machine_mode
vmode_
)
{
smode
=
smode_
;
vmode
=
vmode_
;
chain_id
=
++
max_id
;
if
(
dump_file
)
fprintf
(
dump_file
,
"Created a new instruction chain #%d\n"
,
chain_id
)
;
bitmap_obstack_initialize
(
)
;
insns
=
BITMAP_ALLOC
(
)
;
defs
=
BITMAP_ALLOC
(
)
;
defs_conv
=
BITMAP_ALLOC
(
)
;
queue
=
;
}
</s>


<s> static rtx rs6000_adjust_atomic_subword ( rtx orig_mem , rtx * pshift , rtx * pmask ) { rtx addr , align , shift , mask , mem ; HOST_WIDE_INT shift_mask ; machine_mode mode = GET_MODE ( orig_mem ) ; shift_mask = ( mode == QImode ? 0x18 : 0x10 ) ; addr = XEXP ( orig_mem , 0 ) ; addr = force_reg ( GET_MODE ( addr ) , addr ) ; align = expand_simple_binop ( Pmode , AND , addr , GEN_INT ( - 4 ) , NULL_RTX , 1 , OPTAB_LIB_WIDEN ) ; mem = gen_rtx_MEM ( SImode , align ) ; MEM_VOLATILE_P ( mem ) = MEM_VOLATILE_P ( orig_mem ) ; if ( MEM_ALIAS_SET ( orig_mem ) == ALIAS_SET_MEMORY_BARRIER ) set_mem_alias_set ( mem , ALIAS_SET_MEMORY_BARRIER ) ; shift = gen_reg_rtx ( SImode ) ; addr = gen_lowpart ( SImode , addr ) ; emit_insn ( gen_rlwinm ( shift , addr , GEN_INT ( 3 ) , GEN_INT ( shift_mask ) ) ) ; if ( BYTES_BIG_ENDIAN ) shift = expand_simple_binop ( SImode , XOR , shift , GEN_INT ( shift_mask ) , shift , 1 , OPTAB_LIB_WIDEN ) ; * pshift = shift ; mask = expand_simple_binop ( SImode , ASHIFT , GEN_INT ( GET_MODE_MASK ( mode ) ) , shift , NULL_RTX , 1 , OPTAB_LIB_WIDEN ) ; * pmask = mask ; return mem ; } </s>

A subroutine of the various atomic expanders . For sub-word operations , we must adjust things to operate on SImode . Given the original MEM , return a new aligned memory . Also build and return the quantities by which to shift and mask .


<s> const char * getPassName ( ) const override { return FIXUPBW_DESC ; } </s>

getPassName - Return a nice clean name for a pass .


<s> SDValue SparcTargetLowering :: LowerFormalArguments ( SDValue Chain , CallingConv :: ID CallConv , bool IsVarArg , const SmallVectorImpl < ISD :: InputArg > & Ins , SDLoc DL , SelectionDAG & DAG , SmallVectorImpl < SDValue > & InVals ) const { if ( Subtarget -> is64Bit ( ) ) return LowerFormalArguments_64 ( Chain , CallConv , IsVarArg , Ins , DL , DAG , InVals ) ; return LowerFormalArguments_32 ( Chain , CallConv , IsVarArg , Ins , DL , DAG , InVals ) ; } </s>

This hook must be implemented to lower the incoming ( formal ) arguments , described by the Ins array , into the specified DAG .


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; if ( MF . getFunction ( ) -> hasFnAttribute ( "no-realign-stack" ) ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( getFramePointerReg ( MF . getSubtarget < ARMSubtarget > ( ) ) ) ) return false ; if ( TFI -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>

True if the stack can be realigned for the target .

ARM ARM ARM ARM ARM "no-realign-stack" ARM


<s> static void ix86_live_on_entry ( bitmap regs ) { if ( cfun -> machine -> split_stack_varargs_pointer != NULL_RTX ) { gcc_assert ( flag_split_stack ) ; bitmap_set_bit ( regs , split_stack_prologue_scratch_regno ( ) ) ; } } </s>

We may have to tell the dataflow pass that the split stack prologue is initializing a scratch register .


<s> bool PPCTargetLowering :: getPreIndexedAddressParts ( SDNode * N , SDValue & Base , SDValue & Offset , ISD :: MemIndexedMode & AM , SelectionDAG & DAG ) const { if ( DisablePPCPreinc ) return false ; bool isLoad = true ; SDValue Ptr ; EVT VT ; unsigned Alignment ; if ( LoadSDNode * LD = dyn_cast < LoadSDNode > ( N ) ) { Ptr = LD -> getBasePtr ( ) ; VT = LD -> getMemoryVT ( ) ; Alignment = LD -> getAlignment ( ) ; } else if ( StoreSDNode * ST = dyn_cast < StoreSDNode > ( N ) ) { Ptr = ST -> getBasePtr ( ) ; VT = ST -> getMemoryVT ( ) ; Alignment = ST -> getAlignment ( ) ; isLoad = false ; } else return false ; if ( isLoad && usePartialVectorLoads ( N , Subtarget ) ) { return false ; } if ( VT . isVector ( ) ) { if ( ! Subtarget . hasQPX ( ) || ( VT != MVT :: v4f64 && VT != MVT :: v4f32 ) ) { return false ; } else if ( SelectAddressRegRegOnly ( Ptr , Offset , Base , DAG ) ) { AM = ISD :: PRE_INC ; return true ; } } if ( SelectAddressRegReg ( Ptr , Base , Offset , DAG ) ) { bool Swap = false ; if ( isa < FrameIndexSDNode > ( Base ) || isa < RegisterSDNode > ( Base ) ) Swap = true ; else if ( ! isLoad ) { SDValue Val = cast < StoreSDNode > ( N ) -> getValue ( ) ; if ( Val == Base || Base . getNode ( ) -> isPredecessorOf ( Val . getNode ( ) ) ) Swap = true ; } if ( Swap ) std :: swap ( Base , Offset ) ; AM = ISD :: PRE_INC ; return true ; } if ( VT != MVT :: i64 ) { if ( ! SelectAddressRegImm ( Ptr , Offset , Base , DAG , None ) ) return false ; } else { if ( Alignment < 4 ) return false ; if ( ! SelectAddressRegImm ( Ptr , Offset , Base , DAG , Align ( 4 ) ) ) return false ; } if ( LoadSDNode * LD = dyn_cast < LoadSDNode > ( N ) ) { if ( LD -> getValueType ( 0 ) == MVT :: i64 && LD -> getMemoryVT ( ) == MVT :: i32 && LD -> getExtensionType ( ) == ISD :: SEXTLOAD && isa < ConstantSDNode > ( Offset ) ) return false ; } AM = ISD :: PRE_INC ; return true ; } </s>

Returns true by value , base pointer and offset pointer and addressing mode by reference if the node 's address can be legally represented as pre-indexed load / store address .


<s> SDValue Cpu0TargetLowering :: LowerOperation ( SDValue Op , SelectionDAG & DAG ) const { switch ( Op . getOpcode ( ) ) { case ISD :: BRCOND : return lowerBRCOND ( Op , DAG ) ; case ISD :: GlobalAddress : return lowerGlobalAddress ( Op , DAG ) ; case ISD :: GlobalTLSAddress : return lowerGlobalTLSAddress ( Op , DAG ) ; case ISD :: BlockAddress : return lowerBlockAddress ( Op , DAG ) ; case ISD :: JumpTable : return lowerJumpTable ( Op , DAG ) ; case ISD :: SELECT : return lowerSELECT ( Op , DAG ) ; case ISD :: VASTART : return lowerVASTART ( Op , DAG ) ; case ISD :: FRAMEADDR : return lowerFRAMEADDR ( Op , DAG ) ; case ISD :: RETURNADDR : return lowerRETURNADDR ( Op , DAG ) ; case ISD :: EH_RETURN : return lowerEH_RETURN ( Op , DAG ) ; case ISD :: ADD : return lowerADD ( Op , DAG ) ; case ISD :: ATOMIC_FENCE : return lowerATOMIC_FENCE ( Op , DAG ) ; } return SDValue ( ) ; } </s>

LowerOperation - Provide custom lowering hooks for some operations .

Cpu0 Cpu0 ISD::BRCOND ISD::GlobalAddress ISD::GlobalTLSAddress ISD::BlockAddress ISD::JumpTable ISD::SELECT ISD::VASTART ISD::FRAMEADDR ISD::RETURNADDR ISD::EH_RETURN ISD::ADD ISD::ATOMIC_FENCE


<s> static int ix86_shift_rotate_cost ( const struct processor_costs * cost , enum rtx_code code , enum machine_mode mode , bool constant_op1 , HOST_WIDE_INT op1_val , bool speed , bool and_in_op1 , bool shift_and_truncate , bool * skip_op0 , bool * skip_op1 ) { if ( skip_op0 ) * skip_op0 = * skip_op1 = false ; if ( GET_MODE_CLASS ( mode ) == MODE_VECTOR_INT ) { if ( mode == V16QImode || mode == V32QImode ) { int count = 11 ; if ( TARGET_XOP && mode == V16QImode ) { if ( constant_op1 ) { if ( skip_op1 ) * skip_op1 = true ; return ix86_vec_cost ( mode , cost -> sse_op + ( speed ? 2 : COSTS_N_BYTES ( GET_MODE_UNIT_SIZE ( mode ) ) ) ) ; } count = 3 ; } else if ( TARGET_SSSE3 ) count = 7 ; return ix86_vec_cost ( mode , cost -> sse_op * count ) ; } else if ( code == ASHIFTRT && ( mode == V2DImode || mode == V4DImode ) && ! TARGET_XOP && ! TARGET_AVX512VL ) { int count = 4 ; if ( constant_op1 && op1_val == 63 && TARGET_SSE4_2 ) count = 2 ; else if ( constant_op1 ) count = 3 ; return ix86_vec_cost ( mode , cost -> sse_op * count ) ; } else return ix86_vec_cost ( mode , cost -> sse_op ) ; } if ( GET_MODE_SIZE ( mode ) > UNITS_PER_WORD ) { if ( constant_op1 ) { if ( op1_val > 32 ) return cost -> shift_const + COSTS_N_INSNS ( 2 ) ; else return cost -> shift_const * 2 ; } else { if ( and_in_op1 ) return cost -> shift_var * 2 ; else return cost -> shift_var * 6 + COSTS_N_INSNS ( 2 ) ; } } else { if ( constant_op1 ) return cost -> shift_const ; else if ( shift_and_truncate ) { if ( skip_op0 ) * skip_op0 = * skip_op1 = true ; return cost -> shift_var ; } else return cost -> shift_var ; } } </s>

Return cost of shift in MODE . If CONSTANT_OP1 is true , the op1 value is known and set in OP1_VAL . AND_IN_OP1 specify in op1 is result of AND and SHIFT_AND_TRUNCATE if op1 is a result of subreg . SKIP_OP0/1 is set to true if cost of OP0/1 should be ignored .


<s> void AArch64FrameLowering :: processFunctionBeforeFrameFinalized ( MachineFunction & MF , RegScavenger * RS ) const { if ( ! MF . hasEHFunclets ( ) ) return ; const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; WinEHFuncInfo & EHInfo = * MF . getWinEHFuncInfo ( ) ; MachineBasicBlock & MBB = MF . front ( ) ; auto MBBI = MBB . begin ( ) ; while ( MBBI != MBB . end ( ) && MBBI -> getFlag ( MachineInstr :: FrameSetup ) ) ++ MBBI ; if ( MBBI -> isTerminator ( ) ) return ; int UnwindHelpFI = MFI . CreateStackObject ( 8 , 16 , false ) ; EHInfo . UnwindHelpFrameIdx = UnwindHelpFI ; DebugLoc DL ; RS -> enterBasicBlock ( MBB ) ; unsigned DstReg = RS -> scavengeRegister ( & AArch64 :: GPR64RegClass , MBBI , 0 ) ; BuildMI ( MBB , MBBI , DL , TII . get ( AArch64 :: MOVi64imm ) , DstReg ) . addImm ( - 2 ) ; BuildMI ( MBB , MBBI , DL , TII . get ( AArch64 :: STURXi ) ) . addReg ( DstReg , getKillRegState ( true ) ) . addFrameIndex ( UnwindHelpFI ) . addImm ( 0 ) ; } </s>

processFunctionBeforeFrameFinalized - This method is called immediately before the specified function 's frame layout ( MF.getFrameInfo ( ) ) is finalized .


<s> MVT X86TargetLowering :: getRegisterTypeForCallingConv ( LLVMContext & Context , CallingConv :: ID CC , EVT VT ) const { if ( VT == MVT :: v32i1 && Subtarget . hasAVX512 ( ) && ! Subtarget . hasBWI ( ) ) return MVT :: v32i8 ; if ( ( VT == MVT :: v32i16 || VT == MVT :: v64i8 ) && Subtarget . hasAVX512 ( ) && ! Subtarget . hasBWI ( ) && ! EnableOldKNLABI ) return MVT :: v16i32 ; return TargetLowering :: getRegisterTypeForCallingConv ( Context , CC , VT ) ; } </s>

Certain combinations of ABIs , Targets and features require that types are legal for some operations and not for other operations .


<s> static bool ix86_save_reg ( unsigned int regno , bool maybe_eh_return , bool ignore_outlined ) { if ( cfun -> machine -> no_caller_saved_registers ) { rtx reg = crtl -> return_rtx ; if ( reg ) { unsigned int i = REGNO ( reg ) ; unsigned int nregs = REG_NREGS ( reg ) ; while ( nregs -- > 0 ) if ( ( i + nregs ) == regno ) return false ; } return ( df_regs_ever_live_p ( regno ) && ! fixed_regs [ regno ] && ! STACK_REGNO_P ( regno ) && ! MMX_REGNO_P ( regno ) && ( regno != HARD_FRAME_POINTER_REGNUM || ! frame_pointer_needed ) ) ; } if ( regno == REAL_PIC_OFFSET_TABLE_REGNUM && pic_offset_table_rtx ) { if ( ix86_use_pseudo_pic_reg ( ) ) { if ( ! TARGET_64BIT && flag_pic && crtl -> profile ) return true ; } else if ( df_regs_ever_live_p ( REAL_PIC_OFFSET_TABLE_REGNUM ) || crtl -> profile || crtl -> calls_eh_return || crtl -> uses_const_pool || cfun -> has_nonlocal_label ) return ix86_select_alt_pic_regnum ( ) == INVALID_REGNUM ; } if ( crtl -> calls_eh_return && maybe_eh_return ) { unsigned i ; for ( i = 0 ; ; i ++ ) { unsigned test = EH_RETURN_DATA_REGNO ( i ) ; if ( test == INVALID_REGNUM ) break ; if ( test == regno ) return true ; } } if ( ignore_outlined && cfun -> machine -> call_ms2sysv ) { unsigned count = cfun -> machine -> call_ms2sysv_extra_regs + xlogue_layout :: MIN_REGS ; if ( xlogue_layout :: is_stub_managed_reg ( regno , count ) ) return false ; } if ( crtl -> drap_reg && regno == REGNO ( crtl -> drap_reg ) && ! cfun -> machine -> no_drap_save_restore ) return true ; return ( df_regs_ever_live_p ( regno ) && ! call_used_regs [ regno ] && ! fixed_regs [ regno ] && ( regno != HARD_FRAME_POINTER_REGNUM || ! frame_pointer_needed ) ) ; } </s>


<s> static tree fully_fold_convert ( tree type , tree expr ) { tree result = fold_convert ( type , expr ) ; bool maybe_const = true ; if ( ! c_dialect_cxx ( ) ) result = c_fully_fold ( result , false , & maybe_const ) ; return result ; } </s>

In addition to calling fold_convert for EXPR of type TYPE , also call c_fully_fold to remove any C_MAYBE_CONST_EXPRs that could be hiding there ( PR47197 ) .


<s> bool isNoopAddrSpaceCast ( unsigned SrcAS , unsigned DestAS ) const override { return true ; } </s>

Returns true if a cast between SrcAS and DestAS is a noop .


<s> void rs6000_call_aix ( rtx value , rtx func_desc , rtx flag , rtx cookie ) { const bool direct_call_p = GET_CODE ( func_desc ) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P ( func_desc ) ; rtx toc_reg = gen_rtx_REG ( Pmode , TOC_REGNUM ) ; rtx toc_load = NULL_RTX ; rtx toc_restore = NULL_RTX ; rtx func_addr ; rtx abi_reg = NULL_RTX ; rtx call [ 4 ] ; int n_call ; rtx insn ; if ( INTVAL ( cookie ) & CALL_LONG ) func_desc = rs6000_longcall_ref ( func_desc ) ; if ( GET_CODE ( func_desc ) != SYMBOL_REF || ( DEFAULT_ABI == ABI_AIX && ! SYMBOL_REF_FUNCTION_P ( func_desc ) ) ) { rtx stack_ptr = gen_rtx_REG ( Pmode , STACK_POINTER_REGNUM ) ; rtx stack_toc_offset = GEN_INT ( RS6000_TOC_SAVE_SLOT ) ; rtx stack_toc_mem = gen_frame_mem ( Pmode , gen_rtx_PLUS ( Pmode , stack_ptr , stack_toc_offset ) ) ; rtx stack_toc_unspec = gen_rtx_UNSPEC ( Pmode , gen_rtvec ( 1 , stack_toc_offset ) , UNSPEC_TOCSLOT ) ; toc_restore = gen_rtx_SET ( toc_reg , stack_toc_unspec ) ; if ( TARGET_SAVE_TOC_INDIRECT && ! cfun -> calls_alloca ) cfun -> machine -> save_toc_in_prologue = true ; else { MEM_VOLATILE_P ( stack_toc_mem ) = 1 ; emit_move_insn ( stack_toc_mem , toc_reg ) ; } if ( DEFAULT_ABI == ABI_ELFv2 ) { func_addr = gen_rtx_REG ( Pmode , 12 ) ; emit_move_insn ( func_addr , func_desc ) ; abi_reg = func_addr ; } else { func_desc = force_reg ( Pmode , func_desc ) ; func_addr = gen_reg_rtx ( Pmode ) ; emit_move_insn ( func_addr , gen_rtx_MEM ( Pmode , func_desc ) ) ; rtx func_toc_offset = GEN_INT ( GET_MODE_SIZE ( Pmode ) ) ; rtx func_toc_mem = gen_rtx_MEM ( Pmode , gen_rtx_PLUS ( Pmode , func_desc , func_toc_offset ) ) ; toc_load = gen_rtx_USE ( VOIDmode , func_toc_mem ) ; if ( ! direct_call_p && TARGET_POINTERS_TO_NESTED_FUNCTIONS && ! chain_already_loaded ( get_current_sequence ( ) -> next -> last ) ) { rtx sc_reg = gen_rtx_REG ( Pmode , STATIC_CHAIN_REGNUM ) ; rtx func_sc_offset = GEN_INT ( 2 * GET_MODE_SIZE ( Pmode ) ) ; rtx func_sc_mem = gen_rtx_MEM ( Pmode , gen_rtx_PLUS ( Pmode , func_desc , func_sc_offset ) ) ; emit_move_insn ( sc_reg , func_sc_mem ) ; abi_reg = sc_reg ; } } } else { abi_reg = toc_reg ; func_addr = func_desc ; } call [ 0 ] = gen_rtx_CALL ( VOIDmode , gen_rtx_MEM ( SImode , func_addr ) , flag ) ; if ( value != NULL_RTX ) call [ 0 ] = gen_rtx_SET ( value , call [ 0 ] ) ; n_call = 1 ; if ( toc_load ) call [ n_call ++ ] = toc_load ; if ( toc_restore ) call [ n_call ++ ] = toc_restore ; call [ n_call ++ ] = gen_rtx_CLOBBER ( VOIDmode , gen_rtx_REG ( Pmode , LR_REGNO ) ) ; insn = gen_rtx_PARALLEL ( VOIDmode , gen_rtvec_v ( n_call , call ) ) ; insn = emit_call_insn ( insn ) ; if ( abi_reg ) use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , abi_reg ) ; } </s>

Expand code to perform a call under the AIX or ELFv2 ABI .


<s> Register getExceptionSelectorRegister ( const Constant * PersonalityFn ) const override { return ABI . IsN64 ( ) ? Mips :: A1_64 : Mips :: A1 ; } </s>

If a physical register , this returns the register that receives the exception typeid on entry to a landing pad .


<s> void PPCFrameInfo :: determineFrameLayout ( MachineFunction & MF ) const { MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; unsigned FrameSize = MFI -> getStackSize ( ) ; unsigned MaxAlign = MFI -> getMaxAlignment ( ) ; unsigned TargetAlign = MF . getTarget ( ) . getFrameInfo ( ) -> getStackAlignment ( ) ; unsigned AlignMask = TargetAlign - 1 ; bool DisableRedZone = MF . getFunction ( ) -> hasFnAttr ( Attribute :: NoRedZone ) ; if ( ! DisableRedZone && FrameSize <= 224 && ! MFI -> hasVarSizedObjects ( ) && ! MFI -> adjustsStack ( ) && ( ! ALIGN_STACK || MaxAlign <= TargetAlign ) ) { MFI -> setStackSize ( 0 ) ; return ; } unsigned maxCallFrameSize = MFI -> getMaxCallFrameSize ( ) ; unsigned minCallFrameSize = getMinCallFrameSize ( Subtarget . isPPC64 ( ) , Subtarget . isDarwinABI ( ) ) ; maxCallFrameSize = std :: max ( maxCallFrameSize , minCallFrameSize ) ; if ( MFI -> hasVarSizedObjects ( ) ) maxCallFrameSize = ( maxCallFrameSize + AlignMask ) & ~ AlignMask ; MFI -> setMaxCallFrameSize ( maxCallFrameSize ) ; FrameSize += maxCallFrameSize ; FrameSize = ( FrameSize + AlignMask ) & ~ AlignMask ; MFI -> setStackSize ( FrameSize ) ; } </s>

Determine the frame layout but do not update the machine function .


<s>
static
char
*
describe_cache
(
unsigned
l1_sizekb
,
unsigned
l1_line
,
unsigned
l1_assoc
ATTRIBUTE_UNUSED
,
unsigned
l2_sizekb
)
{
char
l1size
[
1000
]
,
line
[
1000
]
,
l2size
[
1000
]
;
sprintf
(
l1size
,
"--param l1-cache-size=%u"
,
l1_sizekb
)
;
sprintf
(
line
,
"--param l1-cache-line-size=%u"
,
l1_line
)
;
sprintf
(
l2size
,
"--param l2-cache-size=%u"
,
l2_sizekb
)
;
return
concat
(
l1size
,
" "
,
line
,
" "
,
l2size
,
" "
,
)
;
}
</s>

Returns parameters that describe L1_ASSOC associative cache of size L1_SIZEKB with lines of size L1_LINE , and L2_SIZEKB .

powerpcspe
1000
1000
1000
"--param l1-cache-size=%u"
"--param l1-cache-line-size=%u"
"--param l2-cache-size=%u"
" "
" "
" "


<s> static unsigned int mips_autovectorize_vector_sizes ( void ) { return ISA_HAS_MSA ? 16 : 0 ; } </s>


<s> static bool nds32_expand_movmemsi_loop_unknown_size ( rtx dstmem , rtx srcmem , rtx size , rtx alignment ) { rtx dst_base_reg , src_base_reg ; rtx dst_itr , src_itr ; rtx dstmem_m , srcmem_m , dst_itr_m , src_itr_m ; rtx dst_end ; rtx size_least_3_bit ; rtx double_word_end ; rtx double_word_mode_loop , byte_mode_entry , byte_mode_loop , end_label ; rtx tmp ; rtx mask_least_3_bit ; int start_regno ; bool align_to_4_bytes = ( INTVAL ( alignment ) & 3 ) == 0 ; if ( TARGET_ISA_V3M && ! align_to_4_bytes ) return 0 ; if ( TARGET_REDUCED_REGS ) start_regno = 2 ; else start_regno = 16 ; dst_itr = gen_reg_rtx ( Pmode ) ; src_itr = gen_reg_rtx ( Pmode ) ; dst_end = gen_reg_rtx ( Pmode ) ; tmp = gen_reg_rtx ( QImode ) ; mask_least_3_bit = GEN_INT ( ~ 7 ) ; double_word_mode_loop = gen_label_rtx ( ) ; byte_mode_entry = gen_label_rtx ( ) ; byte_mode_loop = gen_label_rtx ( ) ; end_label = gen_label_rtx ( ) ; dst_base_reg = copy_to_mode_reg ( Pmode , XEXP ( dstmem , 0 ) ) ; src_base_reg = copy_to_mode_reg ( Pmode , XEXP ( srcmem , 0 ) ) ; size_least_3_bit = expand_binop ( SImode , and_optab , size , mask_least_3_bit , NULL_RTX , 0 , OPTAB_WIDEN ) ; dst_end = expand_binop ( Pmode , add_optab , dst_base_reg , size , NULL_RTX , 0 , OPTAB_WIDEN ) ; emit_move_insn ( dst_itr , dst_base_reg ) ; emit_move_insn ( src_itr , src_base_reg ) ; emit_cmp_and_jump_insns ( size_least_3_bit , const0_rtx , EQ , NULL , SImode , 1 , byte_mode_entry ) ; double_word_end = expand_binop ( Pmode , add_optab , dst_base_reg , size_least_3_bit , NULL_RTX , 0 , OPTAB_WIDEN ) ; emit_label ( double_word_mode_loop ) ; src_itr_m = src_itr ; dst_itr_m = dst_itr ; srcmem_m = srcmem ; dstmem_m = dstmem ; nds32_emit_mem_move_block ( start_regno , 2 , & dst_itr_m , & dstmem_m , & src_itr_m , & srcmem_m , true ) ; emit_move_insn ( dst_itr , dst_itr_m ) ; emit_move_insn ( src_itr , src_itr_m ) ; emit_cmp_and_jump_insns ( double_word_end , dst_itr , NE , NULL , Pmode , 1 , double_word_mode_loop ) ; emit_label ( byte_mode_entry ) ; emit_cmp_and_jump_insns ( dst_itr , dst_end , EQ , NULL , Pmode , 1 , end_label ) ; emit_label ( byte_mode_loop ) ; nds32_emit_post_inc_load_store ( tmp , src_itr , QImode , true ) ; nds32_emit_post_inc_load_store ( tmp , dst_itr , QImode , false ) ; emit_cmp_and_jump_insns ( dst_itr , dst_end , NE , NULL , SImode , 1 , byte_mode_loop ) ; emit_label ( end_label ) ; return true ; } </s>

Auxiliary function for expand movmem pattern .


<s> static Mfix * create_fix_barrier ( Mfix * fix , HOST_WIDE_INT max_address ) { HOST_WIDE_INT count = 0 ; rtx_barrier * barrier ; rtx_insn * from = fix -> insn ; rtx_insn * selected = NULL ; int selected_cost ; HOST_WIDE_INT selected_address ; Mfix * new_fix ; HOST_WIDE_INT max_count = max_address - fix -> address ; rtx_code_label * label = gen_label_rtx ( ) ; selected_cost = arm_barrier_cost ( from ) ; selected_address = fix -> address ; while ( from && count < max_count ) { rtx_jump_table_data * tmp ; int new_cost ; gcc_assert ( ! BARRIER_P ( from ) ) ; if ( LABEL_P ( from ) ) count += get_label_padding ( from ) ; else count += get_attr_length ( from ) ; if ( tablejump_p ( from , NULL , & tmp ) ) { count += get_jump_table_size ( tmp ) ; new_cost = arm_barrier_cost ( from ) ; if ( count < max_count && ( ! selected || new_cost <= selected_cost ) ) { selected = tmp ; selected_cost = new_cost ; selected_address = fix -> address + count ; } from = NEXT_INSN ( tmp ) ; continue ; } new_cost = arm_barrier_cost ( from ) ; if ( count < max_count && ( ! selected || new_cost <= selected_cost ) ) { selected = from ; selected_cost = new_cost ; selected_address = fix -> address + count ; } from = NEXT_INSN ( from ) ; } gcc_assert ( selected ) ; if ( CALL_P ( selected ) ) { rtx_insn * next = NEXT_INSN ( selected ) ; if ( next && NOTE_P ( next ) && NOTE_KIND ( next ) == NOTE_INSN_CALL_ARG_LOCATION ) selected = next ; } from = emit_jump_insn_after ( gen_jump ( label ) , selected ) ; JUMP_LABEL ( from ) = label ; barrier = emit_barrier_after ( from ) ; emit_label_after ( label , barrier ) ; new_fix = ( Mfix * ) obstack_alloc ( & minipool_obstack , sizeof ( * new_fix ) ) ; new_fix -> insn = barrier ; new_fix -> address = selected_address ; new_fix -> next = fix -> next ; fix -> next = new_fix ; return new_fix ; } </s>

Find the best place in the insn stream in the range ( FIX- > address , MAX_ADDRESS ) to forcibly insert a minipool barrier . Create the barrier by inserting a jump and add a new fix entry for it .


<s>
void
X86InstrInfo
::
storeRegToStackSlot
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
unsigned
SrcReg
,
bool
isKill
,
int
FrameIdx
,
const
TargetRegisterClass
*
RC
,
const
TargetRegisterInfo
*
TRI
)
const
{
const
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
assert
(
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIdx
)
>=
TRI
->
getSpillSize
(
*
RC
)
&&
"Stack slot too small for store"
)
;
unsigned
Alignment
=
std
::
max
<
uint32_t
>
(
TRI
->
getSpillSize
(
*
RC
)
,
16
)
;
bool
isAligned
=
(
Subtarget
.
getFrameLowering
(
)
->
getStackAlignment
(
)
>=
Alignment
)
||
RI
.
canRealignStack
(
MF
)
;
unsigned
Opc
=
getStoreRegOpcode
(
SrcReg
,
RC
,
isAligned
,
Subtarget
)
;
addFrameReference
(
BuildMI
(
MBB
,
MI
,
DebugLoc
(
)
,
get
(
Opc
)
)
,
FrameIdx
)
.
addReg
(
SrcReg
,
getKillRegState
(
isKill
)
)
;
}
</s>

Store the specified register of the given register class to the specified stack frame index .


<s> bool ARM64PassConfig :: addPreRegAlloc ( ) { if ( TM -> getOptLevel ( ) != CodeGenOpt :: None && EnableAdvSIMDScalar ) addPass ( createARM64AdvSIMDScalar ( ) ) ; return true ; } </s>

This method may be implemented by targets that want to run passes immediately before register allocation .


<s> void X86RegisterInfo :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr * Old = I ; uint64_t Amount = Old -> getOperand ( 0 ) . getImm ( ) ; if ( Amount != 0 ) { Amount = ( Amount + StackAlign - 1 ) / StackAlign * StackAlign ; MachineInstr * New = 0 ; if ( Old -> getOpcode ( ) == getCallFrameSetupOpcode ( ) ) { New = BuildMI ( MF , Old -> getDebugLoc ( ) , TII . get ( getSUBriOpcode ( Is64Bit , Amount ) ) , StackPtr ) . addReg ( StackPtr ) . addImm ( Amount ) ; } else { assert ( Old -> getOpcode ( ) == getCallFrameDestroyOpcode ( ) ) ; uint64_t CalleeAmt = Old -> getOperand ( 1 ) . getImm ( ) ; Amount -= CalleeAmt ; if ( Amount ) { unsigned Opc = getADDriOpcode ( Is64Bit , Amount ) ; New = BuildMI ( MF , Old -> getDebugLoc ( ) , TII . get ( Opc ) , StackPtr ) . addReg ( StackPtr ) . addImm ( Amount ) ; } } if ( New ) { New -> getOperand ( 3 ) . setIsDead ( ) ; MBB . insert ( I , New ) ; } } } else if ( I -> getOpcode ( ) == getCallFrameDestroyOpcode ( ) ) { if ( uint64_t CalleeAmt = I -> getOperand ( 1 ) . getImm ( ) ) { unsigned Opc = getSUBriOpcode ( Is64Bit , CalleeAmt ) ; MachineInstr * Old = I ; MachineInstr * New = BuildMI ( MF , Old -> getDebugLoc ( ) , TII . get ( Opc ) , StackPtr ) . addReg ( StackPtr ) . addImm ( CalleeAmt ) ; New -> getOperand ( 3 ) . setIsDead ( ) ; MBB . insert ( I , New ) ; } } MBB . erase ( I ) ; } </s>

This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy pseudo instructions ( but only if the Target is using them ) .


<s> bool ARMTargetLowering :: shouldSinkOperands ( Instruction * I , SmallVectorImpl < Use * > & Ops ) const { if ( ! I -> getType ( ) -> isVectorTy ( ) ) return false ; if ( Subtarget -> hasNEON ( ) ) { switch ( I -> getOpcode ( ) ) { case Instruction :: Sub : case Instruction :: Add : { if ( ! areExtractExts ( I -> getOperand ( 0 ) , I -> getOperand ( 1 ) ) ) return false ; Ops . push_back ( & I -> getOperandUse ( 0 ) ) ; Ops . push_back ( & I -> getOperandUse ( 1 ) ) ; return true ; } default : return false ; } } if ( ! Subtarget -> hasMVEIntegerOps ( ) ) return false ; auto IsSinker = [ ] ( Instruction * I , int Operand ) { switch ( I -> getOpcode ( ) ) { case Instruction :: Add : case Instruction :: Mul : case Instruction :: ICmp : return true ; case Instruction :: Sub : case Instruction :: Shl : case Instruction :: LShr : case Instruction :: AShr : return Operand == 1 ; default : return false ; } } ; int Op = 0 ; if ( ! isa < ShuffleVectorInst > ( I -> getOperand ( Op ) ) ) Op = 1 ; if ( ! IsSinker ( I , Op ) ) return false ; if ( ! match ( I -> getOperand ( Op ) , m_ShuffleVector ( m_InsertElement ( m_Undef ( ) , m_Value ( ) , m_ZeroInt ( ) ) , m_Undef ( ) , m_Zero ( ) ) ) ) { return false ; } Instruction * Shuffle = cast < Instruction > ( I -> getOperand ( Op ) ) ; for ( Use & U : Shuffle -> uses ( ) ) { Instruction * Insn = cast < Instruction > ( U . getUser ( ) ) ; if ( ! IsSinker ( Insn , U . getOperandNo ( ) ) ) return false ; } Ops . push_back ( & Shuffle -> getOperandUse ( 0 ) ) ; Ops . push_back ( & I -> getOperandUse ( Op ) ) ; return true ; } </s>

Return true if sinking I 's operands to the same basic block as I is profitable , e.g .


<s> unsigned PPCTargetLowering :: getByValTypeAlignment ( const Type * Ty ) const { TargetMachine & TM = getTargetMachine ( ) ; if ( TM . getSubtarget < PPCSubtarget > ( ) . isDarwin ( ) ) return 4 ; return 4 ; } </s>

Return the desired alignment for ByVal aggregate function arguments in the caller parameter area .


Expand a builtin . These builtins are `` special '' because they do n't have symbolic constants defined per-instruction or per instruction-variant . Instead , the required info is looked up in the ARM_BUILTIN_DATA record that is passed into the function .


<s> bool arm_vector_mode_supported_p ( machine_mode mode ) { if ( TARGET_NEON && ( mode == V2SFmode || mode == V4SImode || mode == V8HImode || mode == V4HFmode || mode == V16QImode || mode == V4SFmode || mode == V2DImode || mode == V8HFmode || mode == V4BFmode || mode == V8BFmode ) ) return true ; if ( ( TARGET_NEON || TARGET_IWMMXT ) && ( ( mode == V2SImode ) || ( mode == V4HImode ) || ( mode == V8QImode ) ) ) return true ; if ( TARGET_INT_SIMD && ( mode == V4UQQmode || mode == V4QQmode || mode == V2UHQmode || mode == V2HQmode || mode == V2UHAmode || mode == V2HAmode ) ) return true ; if ( TARGET_HAVE_MVE && ( VALID_MVE_SI_MODE ( mode ) || VALID_MVE_PRED_MODE ( mode ) ) ) return true ; if ( TARGET_HAVE_MVE_FLOAT && ( mode == V2DFmode || mode == V4SFmode || mode == V8HFmode ) ) return true ; return false ; } </s>

Implements target hook vector_mode_supported_p .


<s> BitVector SparcRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( SP :: G1 ) ; Reserved . set ( SP :: G2 ) ; Reserved . set ( SP :: G3 ) ; Reserved . set ( SP :: G4 ) ; Reserved . set ( SP :: O6 ) ; Reserved . set ( SP :: I6 ) ; Reserved . set ( SP :: I7 ) ; Reserved . set ( SP :: G0 ) ; Reserved . set ( SP :: G5 ) ; Reserved . set ( SP :: G6 ) ; Reserved . set ( SP :: G7 ) ; return Reserved ; } </s>

getReservedRegs - Returns a bitset indexed by physical register number indicating if a register is a special register that has particular uses and should be considered unavailable at all times , e.g .


<s> void sh_mark_label ( rtx address , int nuses ) { if ( GOTOFF_P ( address ) ) { address = XEXP ( address , 0 ) ; if ( GET_CODE ( address ) == PLUS ) address = XEXP ( address , 0 ) ; address = XVECEXP ( address , 0 , 0 ) ; } if ( GET_CODE ( address ) == LABEL_REF && GET_CODE ( XEXP ( address , 0 ) ) == CODE_LABEL ) LABEL_NUSES ( XEXP ( address , 0 ) ) += nuses ; } </s>

If ADDRESS refers to a CODE_LABEL , add NUSES to the number of times that label is used .


<s>
SDValue
X86TargetLowering
::
LowerCallResult
(
SDValue
Chain
,
SDValue
InFlag
,
CallingConv
::
ID
CallConv
,
bool
isVarArg
,
const
SmallVectorImpl
<
ISD
::
InputArg
>
&
Ins
,
SDLoc
dl
,
SelectionDAG
&
DAG
,
SmallVectorImpl
<
SDValue
>
&
InVals
)
const
{
SmallVector
<
CCValAssign
,
16
>
RVLocs
;
bool
Is64Bit
=
Subtarget
->
is64Bit
(
)
;
CCState
CCInfo
(
CallConv
,
isVarArg
,
DAG
.
getMachineFunction
(
)
,
RVLocs
,
*
DAG
.
getContext
(
)
)
;
CCInfo
.
AnalyzeCallResult
(
Ins
,
RetCC_X86
)
;
for
(
unsigned
i
=
0
,
e
=
RVLocs
.
size
(
)
;
i
!=
e
;
++
i
)
{
CCValAssign
&
VA
=
RVLocs
[
i
]
;
EVT
CopyVT
=
VA
.
getLocVT
(
)
;
if
(
(
CopyVT
==
MVT
::
f32
||
CopyVT
==
MVT
::
f64
||
CopyVT
==
MVT
::
f128
)
&&
(
(
Is64Bit
||
Ins
[
i
]
.
Flags
.
isInReg
(
)
)
&&
!
Subtarget
->
hasSSE1
(
)
)
)
{
report_fatal_error
(
"SSE register return with SSE disabled"
)
;
}
bool
RoundAfterCopy
=
false
;
if
(
(
VA
.
getLocReg
(
)
==
X86
::
FP0
||
VA
.
getLocReg
(
)
==
X86
::
FP1
)
&&
isScalarFPTypeInSSEReg
(
VA
.
getValVT
(
)
)
)
{
CopyVT
=
MVT
::
f80
;
RoundAfterCopy
=
(
CopyVT
!=
VA
.
getLocVT
(
)
)
;
}
Chain
=
DAG
.
getCopyFromReg
(
Chain
,
dl
,
VA
.
getLocReg
(
)
,
CopyVT
,
InFlag
)
.
getValue
(
1
)
;
SDValue
Val
=
Chain
.
getValue
(
0
)
;
if
(
RoundAfterCopy
)
Val
=
DAG
.
getNode
(
ISD
::
FP_ROUND
,
dl
,
VA
.
getValVT
(
)
,
Val
,
DAG
.
getIntPtrConstant
(
1
,
dl
)
)
;
if
(
VA
.
isExtInLoc
(
)
&&
VA
.
getValVT
(
)
.
getScalarType
(
)
==
MVT
::
i1
)
Val
=
DAG
.
getNode
(
ISD
::
TRUNCATE
,
dl
,
VA
.
getValVT
(
)
,
Val
)
;
InFlag
=
Chain
.
getValue
(
2
)
;
InVals
.
push_back
(
Val
)
;
}
return
Chain
;
}
</s>

LowerCallResult - Lower the result values of an ISD : :CALL into the appropriate copies out of appropriate physical registers .


<s> void MipsPassConfig :: addPreRegAlloc ( ) { addPass ( createMipsOptimizePICCallPass ( ) ) ; if ( getMipsSubtarget ( ) . isCheri ( ) ) { addPass ( createCheriAddressingModeFolder ( ) ) ; if ( getOptLevel ( ) != CodeGenOpt :: Level :: None ) addPass ( & DeadMachineInstructionElimID ) ; addPass ( createCheri128FailHardPass ( ) ) ; } } </s>


<s> static rtx altivec_expand_st_builtin ( tree exp , rtx target ATTRIBUTE_UNUSED , bool * expandedp ) { tree fndecl = TREE_OPERAND ( CALL_EXPR_FN ( exp ) , 0 ) ; unsigned int fcode = DECL_FUNCTION_CODE ( fndecl ) ; tree arg0 , arg1 ; machine_mode mode0 , mode1 ; rtx pat , op0 , op1 ; enum insn_code icode ; switch ( fcode ) { case ALTIVEC_BUILTIN_ST_INTERNAL_16qi : icode = CODE_FOR_vector_altivec_store_v16qi ; break ; case ALTIVEC_BUILTIN_ST_INTERNAL_8hi : icode = CODE_FOR_vector_altivec_store_v8hi ; break ; case ALTIVEC_BUILTIN_ST_INTERNAL_4si : icode = CODE_FOR_vector_altivec_store_v4si ; break ; case ALTIVEC_BUILTIN_ST_INTERNAL_4sf : icode = CODE_FOR_vector_altivec_store_v4sf ; break ; case ALTIVEC_BUILTIN_ST_INTERNAL_2df : icode = CODE_FOR_vector_altivec_store_v2df ; break ; case ALTIVEC_BUILTIN_ST_INTERNAL_2di : icode = CODE_FOR_vector_altivec_store_v2di ; break ; case ALTIVEC_BUILTIN_ST_INTERNAL_1ti : icode = CODE_FOR_vector_altivec_store_v1ti ; break ; default : * expandedp = false ; return NULL_RTX ; } arg0 = CALL_EXPR_ARG ( exp , 0 ) ; arg1 = CALL_EXPR_ARG ( exp , 1 ) ; op0 = expand_normal ( arg0 ) ; op1 = expand_normal ( arg1 ) ; mode0 = insn_data [ icode ] . operand [ 0 ] . mode ; mode1 = insn_data [ icode ] . operand [ 1 ] . mode ; if ( ! ( * insn_data [ icode ] . operand [ 0 ] . predicate ) ( op0 , mode0 ) ) op0 = gen_rtx_MEM ( mode0 , copy_to_mode_reg ( Pmode , op0 ) ) ; if ( ! ( * insn_data [ icode ] . operand [ 1 ] . predicate ) ( op1 , mode1 ) ) op1 = copy_to_mode_reg ( mode1 , op1 ) ; pat = GEN_FCN ( icode ) ( op0 , op1 ) ; if ( pat ) emit_insn ( pat ) ; * expandedp = true ; return NULL_RTX ; } </s>


<s> bool doInitialization ( Module & Mod ) override { M = & Mod ; TD = std :: make_unique < DataLayout > ( M ) ; SizeTy = IntegerType :: get ( M -> getContext ( ) , TD -> getIndexSizeInBits ( 200 ) ) ; CapPtrTy = PointerType :: get ( IntegerType :: get ( M -> getContext ( ) , 8 ) , 200 ) ; return true ; } </s>

Set up the AsmPrinter when we are working on a new module .


<s> bool X86FrameLowering :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; if ( MI != MBB . end ( ) && isFuncletReturnInstr ( * MI ) && STI . isOSWindows ( ) ) { if ( STI . is32Bit ( ) ) return true ; if ( MI -> getOpcode ( ) == X86 :: CATCHRET ) { const Function & F = MBB . getParent ( ) -> getFunction ( ) ; bool IsSEH = isAsynchronousEHPersonality ( classifyEHPersonality ( F . getPersonalityFn ( ) ) ) ; if ( IsSEH ) return true ; } } DebugLoc DL = MBB . findDebugLoc ( MI ) ; for ( unsigned i = 0 , e = CSI . size ( ) ; i != e ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; if ( X86 :: GR64RegClass . contains ( Reg ) || X86 :: GR32RegClass . contains ( Reg ) ) continue ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( Reg ) ; TII . loadRegFromStackSlot ( MBB , MI , Reg , CSI [ i ] . getFrameIdx ( ) , RC , TRI ) ; } unsigned Opc = STI . is64Bit ( ) ? X86 :: POP64r : X86 :: POP32r ; for ( unsigned i = 0 , e = CSI . size ( ) ; i != e ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; if ( ! X86 :: GR64RegClass . contains ( Reg ) && ! X86 :: GR32RegClass . contains ( Reg ) ) continue ; BuildMI ( MBB , MI , DL , TII . get ( Opc ) , Reg ) . setMIFlag ( MachineInstr :: FrameDestroy ) ; } return true ; } </s>

restoreCalleeSavedRegisters - Issues instruction ( s ) to restore all callee saved registers and returns true if it is n't possible / profitable to do so by issuing a series of load instructions via loadRegToStackSlot ( ) .


<s>
bool
FPS
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
bool
FPIsUsed
=
false
;
static_assert
(
X86
::
FP6
==
X86
::
FP0
+
6
,
"Register enums aren't sorted right!"
)
;
const
MachineRegisterInfo
&
MRI
=
MF
.
getRegInfo
(
)
;
for
(
unsigned
i
=
0
;
i
<=
6
;
++
i
)
if
(
!
MRI
.
reg_nodbg_empty
(
X86
::
FP0
+
i
)
)
{
FPIsUsed
=
true
;
break
;
}
if
(
!
FPIsUsed
)
return
false
;
Bundles
=
&
getAnalysis
<
EdgeBundles
>
(
)
;
TII
=
MF
.
getSubtarget
(
)
.
getInstrInfo
(
)
;
bundleCFG
(
MF
)
;
StackTop
=
0
;
SmallPtrSet
<
MachineBasicBlock
*
,
8
>
Processed
;
MachineBasicBlock
*
Entry
=
MF
.
begin
(
)
;
bool
Changed
=
false
;
for
(
MachineBasicBlock
*
BB
:
depth_first_ext
(
Entry
,
Processed
)
)
Changed
|=
processBasicBlock
(
MF
,
*
BB
)
;
if
(
MF
.
size
(
)
!=
Processed
.
size
(
)
)
for
(
MachineFunction
::
iterator
BB
=
MF
.
begin
(
)
,
E
=
MF
.
end
(
)
;
BB
!=
E
;
++
BB
)
if
(
Processed
.
insert
(
BB
)
.
second
)
Changed
|=
processBasicBlock
(
MF
,
*
BB
)
;
LiveBundles
.
clear
(
)
;
return
Changed
;
}
</s>

runOnMachineFunction - Emit the function body .


<s> bool ARMTargetLowering :: isLegalICmpImmediate ( int64_t Imm ) const { if ( ! Subtarget -> isThumb ( ) ) return ARM_AM :: getSOImmVal ( Imm ) != - 1 ; if ( Subtarget -> isThumb2 ( ) ) return ARM_AM :: getT2SOImmVal ( Imm ) != - 1 ; return Imm >= 0 && Imm <= 255 ; } </s>

Return true if the specified immediate is legal icmp immediate , that is the target has icmp instructions which can compare a register against the immediate without having to materialize the immediate into a register .


<s> void ARMTargetLowering :: computeKnownBitsForTargetNode ( const SDValue Op , APInt & KnownZero , APInt & KnownOne , const SelectionDAG & DAG , unsigned Depth ) const { unsigned BitWidth = KnownOne . getBitWidth ( ) ; KnownZero = KnownOne = APInt ( BitWidth , 0 ) ; switch ( Op . getOpcode ( ) ) { default : break ; case ARMISD :: ADDC : case ARMISD :: ADDE : case ARMISD :: SUBC : case ARMISD :: SUBE : if ( Op . getResNo ( ) == 0 ) break ; KnownZero |= APInt :: getHighBitsSet ( BitWidth , BitWidth - 1 ) ; break ; case ARMISD :: CMOV : { DAG . computeKnownBits ( Op . getOperand ( 0 ) , KnownZero , KnownOne , Depth + 1 ) ; if ( KnownZero == 0 && KnownOne == 0 ) return ; APInt KnownZeroRHS , KnownOneRHS ; DAG . computeKnownBits ( Op . getOperand ( 1 ) , KnownZeroRHS , KnownOneRHS , Depth + 1 ) ; KnownZero &= KnownZeroRHS ; KnownOne &= KnownOneRHS ; return ; } case ISD :: INTRINSIC_W_CHAIN : { ConstantSDNode * CN = cast < ConstantSDNode > ( Op -> getOperand ( 1 ) ) ; Intrinsic :: ID IntID = static_cast < Intrinsic :: ID > ( CN -> getZExtValue ( ) ) ; switch ( IntID ) { default : return ; case Intrinsic :: arm_ldaex : case Intrinsic :: arm_ldrex : { EVT VT = cast < MemIntrinsicSDNode > ( Op ) -> getMemoryVT ( ) ; unsigned MemBits = VT . getScalarSizeInBits ( ) ; KnownZero |= APInt :: getHighBitsSet ( BitWidth , BitWidth - MemBits ) ; return ; } } } } } </s>

Determine which of the bits specified in Mask are known to be either zero or one and return them in the KnownZero/KnownOne bitsets .


<s> static int rs6000_hard_regno_mode_ok ( int regno , machine_mode mode ) { int last_regno = regno + rs6000_hard_regno_nregs [ mode ] [ regno ] - 1 ; if ( mode == PTImode ) return ( IN_RANGE ( regno , FIRST_GPR_REGNO , LAST_GPR_REGNO ) && IN_RANGE ( last_regno , FIRST_GPR_REGNO , LAST_GPR_REGNO ) && ( ( regno & 1 ) == 0 ) ) ; if ( TARGET_VSX && VSX_REGNO_P ( regno ) && ( VECTOR_MEM_VSX_P ( mode ) || reg_addr [ mode ] . scalar_in_vmx_p || ( TARGET_VSX_TIMODE && mode == TImode ) || ( TARGET_VADDUQM && mode == V1TImode ) ) ) { if ( FP_REGNO_P ( regno ) ) return FP_REGNO_P ( last_regno ) ; if ( ALTIVEC_REGNO_P ( regno ) ) { if ( GET_MODE_SIZE ( mode ) != 16 && ! reg_addr [ mode ] . scalar_in_vmx_p ) return 0 ; return ALTIVEC_REGNO_P ( last_regno ) ; } } if ( INT_REGNO_P ( regno ) ) return INT_REGNO_P ( last_regno ) ; if ( FP_REGNO_P ( regno ) ) { if ( SCALAR_FLOAT_MODE_P ( mode ) && ( mode != TDmode || ( regno % 2 ) == 0 ) && FP_REGNO_P ( last_regno ) ) return 1 ; if ( GET_MODE_CLASS ( mode ) == MODE_INT && GET_MODE_SIZE ( mode ) == UNITS_PER_FP_WORD ) return 1 ; if ( PAIRED_SIMD_REGNO_P ( regno ) && TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE ( mode ) ) return 1 ; return 0 ; } if ( CR_REGNO_P ( regno ) ) return GET_MODE_CLASS ( mode ) == MODE_CC ; if ( CA_REGNO_P ( regno ) ) return mode == Pmode || mode == SImode ; if ( ALTIVEC_REGNO_P ( regno ) ) return ( VECTOR_MEM_ALTIVEC_OR_VSX_P ( mode ) || mode == V1TImode ) ; if ( SPE_SIMD_REGNO_P ( regno ) && TARGET_SPE && SPE_VECTOR_MODE ( mode ) ) return 1 ; return GET_MODE_SIZE ( mode ) <= UNITS_PER_WORD ; } </s>

Value is 1 if hard register REGNO can hold a value of machine-mode MODE .


<s> bool toc_relative_expr_p ( const_rtx op , bool strict , const_rtx * tocrel_base_ret , const_rtx * tocrel_offset_ret ) { if ( ! TARGET_TOC ) return false ; if ( TARGET_CMODEL != CMODEL_SMALL ) { if ( strict && ! ( GET_CODE ( op ) == LO_SUM && REG_P ( XEXP ( op , 0 ) ) && INT_REG_OK_FOR_BASE_P ( XEXP ( op , 0 ) , strict ) ) ) return false ; if ( GET_CODE ( op ) == LO_SUM ) op = XEXP ( op , 1 ) ; } const_rtx tocrel_base = op ; const_rtx tocrel_offset = const0_rtx ; if ( GET_CODE ( op ) == PLUS && add_cint_operand ( XEXP ( op , 1 ) , GET_MODE ( op ) ) ) { tocrel_base = XEXP ( op , 0 ) ; tocrel_offset = XEXP ( op , 1 ) ; } if ( tocrel_base_ret ) * tocrel_base_ret = tocrel_base ; if ( tocrel_offset_ret ) * tocrel_offset_ret = tocrel_offset ; return ( GET_CODE ( tocrel_base ) == UNSPEC && XINT ( tocrel_base , 1 ) == UNSPEC_TOCREL ) ; } </s>

Return true if OP is a toc pointer relative address ( the output of create_TOC_reference ) . If STRICT , do not match high part or non-split -mcmodel=large/medium toc pointer relative addresses .


<s> Optional < MCFixupKind > getFixupKind ( StringRef Name ) const override { return StringSwitch < Optional < MCFixupKind >> ( Name ) . Case ( "dir32" , FK_Data_4 ) . Case ( "secrel32" , FK_SecRel_4 ) . Case ( "secidx" , FK_SecRel_2 ) . Default ( MCAsmBackend :: getFixupKind ( Name ) ) ; } </s>

getFixupKind - Get the fixup kind of this expression .


<s> static int ix86_function_regparm ( const_tree type , const_tree decl ) { tree attr ; int regparm ; unsigned int ccvt ; if ( TARGET_64BIT ) return ( ix86_function_type_abi ( type ) == SYSV_ABI ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX ) ; ccvt = ix86_get_callcvt ( type ) ; regparm = ix86_regparm ; if ( ( ccvt & IX86_CALLCVT_REGPARM ) != 0 ) { attr = lookup_attribute ( "regparm" , TYPE_ATTRIBUTES ( type ) ) ; if ( attr ) { regparm = TREE_INT_CST_LOW ( TREE_VALUE ( TREE_VALUE ( attr ) ) ) ; return regparm ; } } else if ( ( ccvt & IX86_CALLCVT_FASTCALL ) != 0 ) return 2 ; else if ( ( ccvt & IX86_CALLCVT_THISCALL ) != 0 ) return 1 ; if ( decl && TREE_CODE ( decl ) == FUNCTION_DECL ) { cgraph_node * target = cgraph_node :: get ( decl ) ; if ( target ) target = target -> function_symbol ( ) ; if ( target && opt_for_fn ( target -> decl , optimize ) && ! ( profile_flag && ! flag_fentry ) ) { cgraph_local_info * i = & target -> local ; if ( i && i -> local && i -> can_change_signature ) { int local_regparm , globals = 0 , regno ; for ( local_regparm = 0 ; local_regparm < REGPARM_MAX ; local_regparm ++ ) if ( fixed_regs [ local_regparm ] ) break ; if ( local_regparm == 3 && DECL_STATIC_CHAIN ( target -> decl ) ) local_regparm = 2 ; if ( local_regparm == 3 && flag_split_stack ) local_regparm = 2 ; for ( regno = AX_REG ; regno <= DI_REG ; regno ++ ) if ( fixed_regs [ regno ] ) globals ++ ; local_regparm = globals < local_regparm ? local_regparm - globals : 0 ; if ( local_regparm > regparm ) regparm = local_regparm ; } } } return regparm ; } </s>

Return the regparm value for a function with the indicated TYPE and DECL . DECL may be NULL when calling function indirectly or considering a libcall .


<s> bool csky_valid_fpuv2_mem_operand ( rtx op ) { struct csky_address addr ; if ( GET_CODE ( op ) != MEM ) return false ; if ( ! decompose_csky_address ( XEXP ( op , 0 ) , & addr ) ) return false ; if ( ! is_csky_address_register_rtx_p ( addr . base , 0 ) ) return false ; if ( addr . index ) { if ( ! is_csky_address_register_rtx_p ( addr . index , 0 ) ) return false ; if ( addr . scale == 1 || addr . scale == 2 || addr . scale == 4 || addr . scale == 8 ) return true ; return false ; } else if ( addr . disp ) { rtx disp = addr . disp ; if ( ! CONST_INT_P ( disp ) ) return false ; if ( ( ( unsigned ) INTVAL ( disp ) % 4 ) == 0 && ( unsigned ) INTVAL ( disp ) <= ( unsigned ) 1020 ) return true ; return false ; } return true ; } </s>

Support for the Q memory constraint . Returns true if OP is a MEM RTX with an address consisting of base + index or base + displacement .


<s>
bool
processBlock
(
MachineBasicBlock
&
MBB
)
{
bool
Changed
=
false
;
MachineRegisterInfo
&
MRI
=
MBB
.
getParent
(
)
->
getRegInfo
(
)
;
for
(
MachineInstr
&
MI
:
MBB
)
{
if
(
!
MI
.
isFullCopy
(
)
)
continue
;
MachineOperand
&
DstMO
=
MI
.
getOperand
(
0
)
;
MachineOperand
&
SrcMO
=
MI
.
getOperand
(
1
)
;
if
(
IsVSReg
(
DstMO
.
getReg
(
)
,
MRI
)
&&
!
IsVSReg
(
SrcMO
.
getReg
(
)
,
MRI
)
)
{
Changed
=
true
;
const
TargetRegisterClass
*
SrcRC
=
IsVRReg
(
SrcMO
.
getReg
(
)
,
MRI
)
&
PPC
::
VSHRCRegClass
:
&
PPC
::
VSLRCRegClass
;
assert
(
(
IsF8Reg
(
SrcMO
.
getReg
(
)
,
MRI
)
||
IsVRReg
(
SrcMO
.
getReg
(
)
,
MRI
)
||
IsVSSReg
(
SrcMO
.
getReg
(
)
,
MRI
)
||
IsVSFReg
(
SrcMO
.
getReg
(
)
,
MRI
)
)
&&
"Unknown source for a VSX copy"
)
;
unsigned
NewVReg
=
MRI
.
createVirtualRegister
(
SrcRC
)
;
BuildMI
(
MBB
,
MI
,
MI
.
getDebugLoc
(
)
,
TII
->
get
(
TargetOpcode
::
SUBREG_TO_REG
)
,
NewVReg
)
.
addImm
(
1
)
.
addOperand
(
SrcMO
)
.
addImm
(
IsVRReg
(
SrcMO
.
getReg
(
)
,
MRI
)
PPC
::
sub_128
:
PPC
::
sub_64
)
;
SrcMO
.
setReg
(
NewVReg
)
;
}
else
if
(
!
IsVSReg
(
DstMO
.
getReg
(
)
,
MRI
)
&&
IsVSReg
(
SrcMO
.
getReg
(
)
,
MRI
)
)
{
Changed
=
true
;
const
TargetRegisterClass
*
DstRC
=
IsVRReg
(
DstMO
.
getReg
(
)
,
MRI
)
&
PPC
::
VSHRCRegClass
:
&
PPC
::
VSLRCRegClass
;
assert
(
(
IsF8Reg
(
DstMO
.
getReg
(
)
,
MRI
)
||
IsVSFReg
(
DstMO
.
getReg
(
)
,
MRI
)
||
IsVSSReg
(
DstMO
.
getReg
(
)
,
MRI
)
||
IsVRReg
(
DstMO
.
getReg
(
)
,
MRI
)
)
&&
"Unknown destination for a VSX copy"
)
;
unsigned
NewVReg
=
MRI
.
createVirtualRegister
(
DstRC
)
;
BuildMI
(
MBB
,
MI
,
MI
.
getDebugLoc
(
)
,
TII
->
get
(
TargetOpcode
::
COPY
)
,
NewVReg
)
.
addOperand
(
SrcMO
)
;
SrcMO
.
setReg
(
NewVReg
)
;
SrcMO
.
setSubReg
(
IsVRReg
(
DstMO
.
getReg
(
)
,
MRI
)
PPC
::
sub_128
:
PPC
::
sub_64
)
;
}
}
return
Changed
;
}
</s>

processBlock - If there are any predecessors whose control can be threaded through to a successor , transform them now .


<s> static rtx mark_constant_pool_use ( rtx x ) { if ( x == NULL_RTX ) return x ; switch ( GET_CODE ( x ) ) { case LABEL_REF : x = XEXP ( x , 0 ) ; case CODE_LABEL : break ; default : return x ; } rtx_insn * lab = as_a < rtx_insn * > ( x ) ; for ( rtx_insn * insn = PREV_INSN ( lab ) ; insn ; insn = PREV_INSN ( insn ) ) { if ( ! LABEL_P ( insn ) || LABEL_REFS ( insn ) != NEXT_INSN ( insn ) ) break ; lab = insn ; } for ( rtx insn = LABEL_REFS ( lab ) ; insn ; insn = LABEL_REFS ( insn ) ) as_a < rtx_insn * > ( insn ) -> set_deleted ( ) ; for ( rtx_insn * insn = NEXT_INSN ( as_a < rtx_insn * > ( x ) ) ; insn ; insn = NEXT_INSN ( insn ) ) { if ( ! NONJUMP_INSN_P ( insn ) ) continue ; rtx pattern = PATTERN ( insn ) ; if ( GET_CODE ( pattern ) != UNSPEC_VOLATILE ) continue ; switch ( XINT ( pattern , 1 ) ) { case UNSPECV_CONST2 : case UNSPECV_CONST4 : case UNSPECV_CONST8 : XVECEXP ( pattern , 0 , 1 ) = const1_rtx ; break ; case UNSPECV_WINDOW_END : if ( XVECEXP ( pattern , 0 , 0 ) == x ) return lab ; break ; case UNSPECV_CONST_END : return lab ; default : break ; } } return lab ; } </s>

Mark the use of a constant in the literal table . If the constant has multiple labels , make it unique .


<s> static tree ix86_veclibabi_acml ( combined_fn fn , tree type_out , tree type_in ) { char name [ 20 ] = "__vr.._" ; tree fntype , new_fndecl , args ; unsigned arity ; const char * bname ; machine_mode el_mode , in_mode ; int n , in_n ; if ( ! TARGET_64BIT || ! flag_unsafe_math_optimizations ) return NULL_TREE ; el_mode = TYPE_MODE ( TREE_TYPE ( type_out ) ) ; n = TYPE_VECTOR_SUBPARTS ( type_out ) ; in_mode = TYPE_MODE ( TREE_TYPE ( type_in ) ) ; in_n = TYPE_VECTOR_SUBPARTS ( type_in ) ; if ( el_mode != in_mode || n != in_n ) return NULL_TREE ; switch ( fn ) { CASE_CFN_SIN : CASE_CFN_COS : CASE_CFN_EXP : CASE_CFN_LOG : CASE_CFN_LOG2 : CASE_CFN_LOG10 : if ( el_mode == DFmode && n == 2 ) { name [ 4 ] = 'd' ; name [ 5 ] = '2' ; } else if ( el_mode == SFmode && n == 4 ) { name [ 4 ] = 's' ; name [ 5 ] = '4' ; } else return NULL_TREE ; break ; default : return NULL_TREE ; } tree fndecl = mathfn_built_in ( TREE_TYPE ( type_in ) , fn ) ; bname = IDENTIFIER_POINTER ( DECL_NAME ( fndecl ) ) ; sprintf ( name + 7 , "%s" , bname + 10 ) ; arity = 0 ; for ( args = DECL_ARGUMENTS ( fndecl ) ; args ; args = TREE_CHAIN ( args ) ) arity ++ ; if ( arity == 1 ) fntype = build_function_type_list ( type_out , type_in , NULL ) ; else fntype = build_function_type_list ( type_out , type_in , type_in , NULL ) ; new_fndecl = build_decl ( BUILTINS_LOCATION , FUNCTION_DECL , get_identifier ( name ) , fntype ) ; TREE_PUBLIC ( new_fndecl ) = 1 ; DECL_EXTERNAL ( new_fndecl ) = 1 ; DECL_IS_NOVOPS ( new_fndecl ) = 1 ; TREE_READONLY ( new_fndecl ) = 1 ; return new_fndecl ; } </s>

Handler for an ACML-style interface to a library with vectorized intrinsics .


<s> void pa_output_addr_vec ( rtx lab , rtx body ) { int idx , vlen = XVECLEN ( body , 0 ) ; targetm . asm_out . internal_label ( asm_out_file , "L" , CODE_LABEL_NUMBER ( lab ) ) ; if ( TARGET_GAS ) fputs ( "\t.begin_brtab\n" , asm_out_file ) ; for ( idx = 0 ; idx < vlen ; idx ++ ) { ASM_OUTPUT_ADDR_VEC_ELT ( asm_out_file , CODE_LABEL_NUMBER ( XEXP ( XVECEXP ( body , 0 , idx ) , 0 ) ) ) ; } if ( TARGET_GAS ) fputs ( "\t.end_brtab\n" , asm_out_file ) ; } </s>


<s> bool AArch64TargetLowering :: isLegalAddImmediate ( int64_t Immed ) const { return ( ( Immed >> 12 ) == 0 || ( ( Immed & 0xfff ) == 0 && Immed >> 24 == 0 ) ) ; } </s>

Return true if the specified immediate is legal add immediate , that is the target has add instructions which can add a register and the immediate without having to materialize the immediate into a register .


<s> bool SystemZInstrInfo :: isPredicable ( MachineInstr * MI ) const { unsigned Opcode = MI -> getOpcode ( ) ; return STI . hasLoadStoreOnCond ( ) && getConditionalMove ( Opcode ) ; } </s>

Return true if the specified instruction can be predicated .