<s>
bool
AArch64InstrInfo
::
getMemOperandWithOffsetWidth
(
const
MachineInstr
&
LdSt
,
const
MachineOperand
*
&
BaseOp
,
int64_t
&
Offset
,
unsigned
&
Width
,
const
TargetRegisterInfo
*
TRI
)
const
{
assert
(
LdSt
.
mayLoadOrStore
(
)
&&
"Expected a memory operation."
)
;
if
(
LdSt
.
getNumExplicitOperands
(
)
==
3
)
{
if
(
(
!
LdSt
.
getOperand
(
1
)
.
isReg
(
)
&&
!
LdSt
.
getOperand
(
1
)
.
isFI
(
)
)
||
!
LdSt
.
getOperand
(
2
)
.
isImm
(
)
)
return
false
;
}
else
if
(
LdSt
.
getNumExplicitOperands
(
)
==
4
)
{
if
(
!
LdSt
.
getOperand
(
1
)
.
isReg
(
)
||
(
!
LdSt
.
getOperand
(
2
)
.
isReg
(
)
&&
!
LdSt
.
getOperand
(
2
)
.
isFI
(
)
)
||
!
LdSt
.
getOperand
(
3
)
.
isImm
(
)
)
return
false
;
}
else
return
false
;
unsigned
Scale
=
0
;
int64_t
Dummy1
,
Dummy2
;
if
(
!
getMemOpInfo
(
LdSt
.
getOpcode
(
)
,
Scale
,
Width
,
Dummy1
,
Dummy2
)
)
return
false
;
if
(
LdSt
.
getNumExplicitOperands
(
)
==
3
)
{
BaseOp
=
&
LdSt
.
getOperand
(
1
)
;
Offset
=
LdSt
.
getOperand
(
2
)
.
getImm
(
)
*
Scale
;
}
else
{
assert
(
LdSt
.
getNumExplicitOperands
(
)
==
4
&&
"invalid number of operands"
)
;
BaseOp
=
&
LdSt
.
getOperand
(
2
)
;
Offset
=
LdSt
.
getOperand
(
3
)
.
getImm
(
)
*
Scale
;
}
if
(
!
BaseOp
->
isReg
(
)
&&
!
BaseOp
->
isFI
(
)
)
return
false
;
return
true
;
}
</s>

Return true if get the base operand , byte offset of an instruction and the memory width .


<s> static bool ck860_rtx_costs ( rtx x , int code , machine_mode mode , int outer_code ATTRIBUTE_UNUSED , int * total , bool speed ATTRIBUTE_UNUSED ) { switch ( code ) { case PLUS : if ( GET_CODE ( XEXP ( x , 0 ) ) == MULT && REG_P ( XEXP ( x , 1 ) ) && speed ) { rtx mul_op0 = XEXP ( XEXP ( x , 0 ) , 0 ) ; rtx mul_op1 = XEXP ( XEXP ( x , 0 ) , 1 ) ; if ( REG_P ( mul_op0 ) && REG_P ( mul_op1 ) ) { * total = COSTS_N_INSNS ( 1 ) ; * total += rtx_cost ( XEXP ( x , 0 ) , mode , ( enum rtx_code ) code , 0 , speed ) ; return true ; } } return false ; case MULT : if ( REG_P ( XEXP ( x , 0 ) ) && CONST_INT_P ( XEXP ( x , 1 ) ) ) { HOST_WIDE_INT val = INTVAL ( XEXP ( x , 1 ) ) ; if ( val % 2 == 0 && val < 0xffffffff && val > 0 ) { * total = COSTS_N_INSNS ( 1 ) ; return true ; } } return false ; case CONST : case LABEL_REF : case SYMBOL_REF : * total = COSTS_N_INSNS ( 3 ) ; return true ; default : return false ; } } </s>

TARGET_RTX_COSTS helper for ck860 arches .


<s> static bool pa_scalar_mode_supported_p ( enum machine_mode mode ) { int precision = GET_MODE_PRECISION ( mode ) ; switch ( GET_MODE_CLASS ( mode ) ) { case MODE_PARTIAL_INT : case MODE_INT : if ( precision == CHAR_TYPE_SIZE ) return true ; if ( precision == SHORT_TYPE_SIZE ) return true ; if ( precision == INT_TYPE_SIZE ) return true ; if ( precision == LONG_TYPE_SIZE ) return true ; if ( precision == LONG_LONG_TYPE_SIZE ) return true ; return false ; case MODE_FLOAT : if ( precision == FLOAT_TYPE_SIZE ) return true ; if ( precision == DOUBLE_TYPE_SIZE ) return true ; if ( precision == LONG_DOUBLE_TYPE_SIZE ) return true ; return false ; default : gcc_unreachable ( ) ; } } </s>

True if MODE is valid for the target . By `` valid '' , we mean able to be manipulated in non-trivial ways . In particular , this means all the arithmetic is supported .


<s> unsigned X86RegisterInfo :: findDeadCallerSavedReg ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI ) const { const MachineFunction * MF = MBB . getParent ( ) ; if ( MF -> callsEHReturn ( ) ) return 0 ; const TargetRegisterClass & AvailableRegs = * getGPRsForTailCall ( * MF ) ; if ( MBBI == MBB . end ( ) ) return 0 ; switch ( MBBI -> getOpcode ( ) ) { default : return 0 ; case TargetOpcode :: PATCHABLE_RET : case X86 :: RET : case X86 :: RET32 : case X86 :: RET64 : case X86 :: RETI32 : case X86 :: RETI64 : case X86 :: TCRETURNdi : case X86 :: TCRETURNri : case X86 :: TCRETURNmi : case X86 :: TCRETURNdi64 : case X86 :: TCRETURNri64 : case X86 :: TCRETURNmi64 : case X86 :: EH_RETURN : case X86 :: EH_RETURN64 : { SmallSet < uint16_t , 8 > Uses ; for ( unsigned I = 0 , E = MBBI -> getNumOperands ( ) ; I != E ; ++ I ) { MachineOperand & MO = MBBI -> getOperand ( I ) ; if ( ! MO . isReg ( ) || MO . isDef ( ) ) continue ; Register Reg = MO . getReg ( ) ; if ( ! Reg ) continue ; for ( MCRegAliasIterator AI ( Reg , this , true ) ; AI . isValid ( ) ; ++ AI ) Uses . insert ( * AI ) ; } for ( auto CS : AvailableRegs ) if ( ! Uses . count ( CS ) && CS != X86 :: RIP && CS != X86 :: RSP && CS != X86 :: ESP ) return CS ; } } return 0 ; } </s>

findDeadCallerSavedReg - Return a caller-saved register that is n't live when it reaches the `` return '' instruction .


<s> static int ia64_spec_check_p ( rtx x ) { x = PATTERN ( x ) ; if ( GET_CODE ( x ) == COND_EXEC ) x = COND_EXEC_CODE ( x ) ; if ( GET_CODE ( x ) == SET ) return ia64_spec_check_src_p ( SET_SRC ( x ) ) ; return 0 ; } </s>

Return nonzero , if X is branchy recovery check .


<s> void sparc_flat_expand_epilogue ( bool for_eh ) { HOST_WIDE_INT size = sparc_frame_size ; if ( sparc_n_global_fp_regs > 0 ) emit_save_or_restore_global_fp_regs ( sparc_frame_base_reg , sparc_frame_base_offset - sparc_apparent_frame_size , SORR_RESTORE ) ; if ( frame_pointer_needed && ! for_eh ) emit_move_insn ( gen_rtx_REG ( Pmode , 1 ) , hard_frame_pointer_rtx ) ; if ( return_addr_reg_needed_p ( sparc_leaf_function_p ) ) emit_move_insn ( gen_rtx_REG ( Pmode , INCOMING_RETURN_ADDR_REGNUM ) , gen_rtx_REG ( Pmode , RETURN_ADDR_REGNUM ) ) ; if ( sparc_save_local_in_regs_p ) emit_save_or_restore_local_in_regs ( sparc_frame_base_reg , sparc_frame_base_offset , SORR_RESTORE ) ; if ( size == 0 || for_eh ) ; else if ( frame_pointer_needed ) { emit_insn ( gen_blockage ( ) ) ; emit_move_insn ( stack_pointer_rtx , gen_rtx_REG ( Pmode , 1 ) ) ; } else { emit_insn ( gen_blockage ( ) ) ; if ( size <= 4096 ) emit_insn ( gen_stack_pointer_inc ( GEN_INT ( size ) ) ) ; else if ( size <= 8192 ) { emit_insn ( gen_stack_pointer_inc ( GEN_INT ( 4096 ) ) ) ; emit_insn ( gen_stack_pointer_inc ( GEN_INT ( size - 4096 ) ) ) ; } else { rtx reg = gen_rtx_REG ( Pmode , 1 ) ; emit_move_insn ( reg , GEN_INT ( size ) ) ; emit_insn ( gen_stack_pointer_inc ( reg ) ) ; } } } </s>

Expand the function epilogue , either normal or part of a sibcall . We emit all the instructions except the return or the call .


<s> bool AArch64FrameLowering :: canUseRedZone ( const MachineFunction & MF ) const { if ( ! EnableRedZone ) return false ; if ( MF . getFunction ( ) -> hasFnAttribute ( Attribute :: NoRedZone ) ) return false ; const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; const AArch64FunctionInfo * AFI = MF . getInfo < AArch64FunctionInfo > ( ) ; unsigned NumBytes = AFI -> getLocalStackSize ( ) ; if ( MFI -> hasCalls ( ) || hasFP ( MF ) || NumBytes > 128 ) return false ; return true ; } </s>

Can this function use the red zone for local allocations .


<s> unsigned X86TargetLowering :: getNumRegistersForCallingConv ( LLVMContext & Context , EVT VT ) const { if ( VT == MVT :: v32i1 && Subtarget . hasAVX512 ( ) && ! Subtarget . hasBWI ( ) ) return 1 ; return TargetLowering :: getNumRegistersForCallingConv ( Context , VT ) ; } </s>

Certain targets require unusual breakdowns of certain types .


<s> unsigned X86TTI :: getIntImmCost ( unsigned Opcode , unsigned Idx , const APInt & Imm , Type * Ty ) const { assert ( Ty -> isIntegerTy ( ) ) ; unsigned BitSize = Ty -> getPrimitiveSizeInBits ( ) ; if ( BitSize == 0 ) return ~ 0U ; unsigned ImmIdx = ~ 0U ; switch ( Opcode ) { default : return TCC_Free ; case Instruction :: GetElementPtr : if ( Idx == 0 ) return 2 * TCC_Basic ; return TCC_Free ; case Instruction :: Store : ImmIdx = 0 ; break ; case Instruction :: Add : case Instruction :: Sub : case Instruction :: Mul : case Instruction :: UDiv : case Instruction :: SDiv : case Instruction :: URem : case Instruction :: SRem : case Instruction :: And : case Instruction :: Or : case Instruction :: Xor : case Instruction :: ICmp : ImmIdx = 1 ; break ; case Instruction :: Shl : case Instruction :: LShr : case Instruction :: AShr : if ( Idx == 1 ) return TCC_Free ; break ; case Instruction :: Trunc : case Instruction :: ZExt : case Instruction :: SExt : case Instruction :: IntToPtr : case Instruction :: PtrToInt : case Instruction :: BitCast : case Instruction :: PHI : case Instruction :: Call : case Instruction :: Select : case Instruction :: Ret : case Instruction :: Load : break ; } if ( ( Idx == ImmIdx ) && Imm . getBitWidth ( ) <= 64 && isInt < 32 > ( Imm . getSExtValue ( ) ) ) return TCC_Free ; return X86TTI :: getIntImmCost ( Imm , Ty ) ; } </s>

Calculate the cost of materializing a 64-bit value .


<s> ARMBaseTargetMachine :: ARMBaseTargetMachine ( const Target & T , const Triple & TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Optional < Reloc :: Model > RM , Optional < CodeModel :: Model > CM , CodeGenOpt :: Level OL , bool isLittle ) : LLVMTargetMachine ( T , computeDataLayout ( TT , CPU , Options , isLittle ) , TT , CPU , FS , Options , getEffectiveRelocModel ( TT , RM ) , getEffectiveCodeModel ( CM , CodeModel :: Small ) , OL ) , TargetABI ( computeTargetABI ( TT , CPU , Options ) ) , TLOF ( createTLOF ( getTargetTriple ( ) ) ) , isLittle ( isLittle ) { if ( Options . FloatABIType == FloatABI :: Default ) { if ( isTargetHardFloat ( ) ) this -> Options . FloatABIType = FloatABI :: Hard ; else this -> Options . FloatABIType = FloatABI :: Soft ; } if ( Options . EABIVersion == EABI :: Default || Options . EABIVersion == EABI :: Unknown ) { if ( ( TargetTriple . getEnvironment ( ) == Triple :: GNUEABI || TargetTriple . getEnvironment ( ) == Triple :: GNUEABIHF || TargetTriple . getEnvironment ( ) == Triple :: MuslEABI || TargetTriple . getEnvironment ( ) == Triple :: MuslEABIHF ) && ! ( TargetTriple . isOSWindows ( ) || TargetTriple . isOSDarwin ( ) ) ) this -> Options . EABIVersion = EABI :: GNU ; else this -> Options . EABIVersion = EABI :: EABI5 ; } if ( TT . isOSBinFormatMachO ( ) ) { this -> Options . TrapUnreachable = true ; this -> Options . NoTrapAfterNoreturn = true ; } setSupportsDebugEntryValues ( true ) ; initAsmInfo ( ) ; setMachineOutliner ( true ) ; setSupportsDefaultOutlining ( false ) ; } </s>


<s> void arm_init_expanders ( void ) { init_machine_status = arm_init_machine_status ; if ( cfun ) mark_reg_pointer ( arg_pointer_rtx , PARM_BOUNDARY ) ; } </s>

Do anything needed before RTL is emitted for each function .


<s> bool FPGATTIImpl :: isLegalMaskedLoad ( Type * DataType ) { return true ; } </s>

Return true if the target supports masked load .


<s> bool AArch64PassConfig :: addILPOpts ( ) { if ( EnableCondOpt ) addPass ( createAArch64ConditionOptimizerPass ( ) ) ; if ( EnableCCMP ) addPass ( createAArch64ConditionalCompares ( ) ) ; if ( EnableMCR ) addPass ( & MachineCombinerID ) ; if ( EnableCondBrTuning ) addPass ( createAArch64CondBrTuning ( ) ) ; if ( EnableEarlyIfConversion ) addPass ( & EarlyIfConverterID ) ; if ( EnableStPairSuppress ) addPass ( createAArch64StorePairSuppressPass ( ) ) ; addPass ( createAArch64VectorByElementOptPass ( ) ) ; return true ; } </s>

Add passes that optimize instruction level parallelism for out-of-order targets .


<s> bool ARMTargetLowering :: shouldConvertConstantLoadToIntImm ( const APInt & Imm , Type * Ty ) const { assert ( Ty -> isIntegerTy ( ) ) ; unsigned Bits = Ty -> getPrimitiveSizeInBits ( ) ; if ( Bits == 0 || Bits > 32 ) return false ; return true ; } </s>

Returns true if it is beneficial to convert a load of a constant to just the constant itself .


<s> bool sparc_modes_tieable_p ( machine_mode mode1 , machine_mode mode2 ) { enum mode_class mclass1 , mclass2 ; unsigned short size1 , size2 ; if ( mode1 == mode2 ) return true ; mclass1 = GET_MODE_CLASS ( mode1 ) ; mclass2 = GET_MODE_CLASS ( mode2 ) ; if ( mclass1 != mclass2 ) return false ; if ( ! TARGET_V9 ) return true ; if ( mclass1 != MODE_FLOAT && mclass1 != MODE_VECTOR_INT ) return true ; size1 = GET_MODE_SIZE ( mode1 ) ; size2 = GET_MODE_SIZE ( mode2 ) ; if ( ( size1 > 4 && size2 == 4 ) || ( size2 > 4 && size1 == 4 ) ) return false ; return true ; } </s>

Return TRUE if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2 . If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2 , for any hard reg , then this must be FALSE for correct output . For V9 we have to deal with the fact that only the lower 32 floating point registers are 32-bit addressable .


<s> bool X86ATTAsmPrinter :: PrintAsmMemoryOperand ( const MachineInstr * MI , unsigned OpNo , unsigned AsmVariant , const char * ExtraCode ) { if ( ExtraCode && ExtraCode [ 0 ] ) { if ( ExtraCode [ 1 ] != 0 ) return true ; switch ( ExtraCode [ 0 ] ) { default : return true ; case 'b' : case 'h' : case 'w' : case 'k' : case 'q' : break ; case 'P' : printMemReference ( MI , OpNo , "mem" , true ) ; return false ; } } printMemReference ( MI , OpNo ) ; return false ; } </s>

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


<s>
bool
X86FrameLowering
::
canUseAsEpilogue
(
const
MachineBasicBlock
&
MBB
)
const
{
assert
(
MBB
.
getParent
(
)
&&
"Block is not attached to a function!"
)
;
if
(
canUseLEAForSPInEpilogue
(
*
MBB
.
getParent
(
)
)
)
return
true
;
return
!
terminatorsNeedFlagsAsInput
(
MBB
)
;
}
</s>

Check whether or not the given MBB can be used as a epilogue for the target .


<s> inline static bool isMem ( const MachineInstr & MI , unsigned Op ) { if ( MI . getOperand ( Op ) . isFI ( ) ) return true ; return Op + X86 :: AddrNumOperands <= MI . getNumOperands ( ) && MI . getOperand ( Op + X86 :: AddrSegmentReg ) . isReg ( ) && isLeaMem ( MI , Op ) ; } </s>


<s>
static
void
rs6000_file_start
(
void
)
{
char
buffer
[
80
]
;
const
char
*
start
=
buffer
;
FILE
*
file
=
asm_out_file
;
rs6000_default_cpu
=
TARGET_CPU_DEFAULT
;
default_file_start
(
)
;
if
(
flag_verbose_asm
)
{
sprintf
(
buffer
,
"\n%s rs6000/powerpc options:"
,
ASM_COMMENT_START
)
;
if
(
rs6000_default_cpu
!=
0
&&
rs6000_default_cpu
[
0
]
!=
'\0'
)
{
fprintf
(
file
,
"%s --with-cpu=%s"
,
start
,
rs6000_default_cpu
)
;
start
=
""
;
}
if
(
global_options_set
.
x_rs6000_cpu_index
)
{
fprintf
(
file
,
"%s -mcpu=%s"
,
start
,
processor_target_table
[
rs6000_cpu_index
]
.
name
)
;
start
=
""
;
}
if
(
global_options_set
.
x_rs6000_tune_index
)
{
fprintf
(
file
,
"%s -mtune=%s"
,
start
,
processor_target_table
[
rs6000_tune_index
]
.
name
)
;
start
=
""
;
}
if
(
PPC405_ERRATUM77
)
{
fprintf
(
file
,
"%s PPC405CR_ERRATUM77"
,
start
)
;
start
=
""
;
}
switch
(
rs6000_sdata
)
{
case
SDATA_NONE
:
fprintf
(
file
,
"%s -msdata=none"
,
start
)
;
start
=
""
;
break
;
case
SDATA_DATA
:
fprintf
(
file
,
"%s -msdata=data"
,
start
)
;
start
=
""
;
break
;
case
SDATA_SYSV
:
fprintf
(
file
,
"%s -msdata=sysv"
,
start
)
;
start
=
""
;
break
;
case
SDATA_EABI
:
fprintf
(
file
,
"%s -msdata=eabi"
,
start
)
;
start
=
""
;
break
;
}
if
(
rs6000_sdata
&&
g_switch_value
)
{
fprintf
(
file
,
"%s -G %d"
,
start
,
g_switch_value
)
;
start
=
""
;
}
if
(
*
start
==
'\0'
)
putc
(
'\n'
,
file
)
;
}
if
(
!
(
rs6000_default_cpu
&&
rs6000_default_cpu
[
0
]
)
&&
!
global_options_set
.
x_rs6000_cpu_index
)
{
fputs
(
"\t.machine "
,
asm_out_file
)
;
if
(
(
rs6000_isa_flags
&
OPTION_MASK_MODULO
)
!=
0
)
fputs
(
"power9\n"
,
asm_out_file
)
;
else
if
(
(
rs6000_isa_flags
&
OPTION_MASK_DIRECT_MOVE
)
!=
0
)
fputs
(
"power8\n"
,
asm_out_file
)
;
else
if
(
(
rs6000_isa_flags
&
OPTION_MASK_POPCNTD
)
!=
0
)
fputs
(
"power7\n"
,
asm_out_file
)
;
else
if
(
(
rs6000_isa_flags
&
OPTION_MASK_CMPB
)
!=
0
)
fputs
(
"power6\n"
,
asm_out_file
)
;
else
if
(
(
rs6000_isa_flags
&
OPTION_MASK_POPCNTB
)
!=
0
)
fputs
(
"power5\n"
,
asm_out_file
)
;
else
if
(
(
rs6000_isa_flags
&
OPTION_MASK_MFCRF
)
!=
0
)
fputs
(
"power4\n"
,
asm_out_file
)
;
else
if
(
(
rs6000_isa_flags
&
OPTION_MASK_POWERPC64
)
!=
0
)
fputs
(
"ppc64\n"
,
asm_out_file
)
;
else
fputs
(
"ppc\n"
,
asm_out_file
)
;
}
if
(
DEFAULT_ABI
==
ABI_ELFv2
)
fprintf
(
file
,
"\t.abiversion 2\n"
)
;
}
</s>

Do anything needed at the start of the asm file .