<s> MCSection * X86ELFMCAsmInfo :: getNonexecutableStackSection ( MCContext & Ctx ) const { return MCSectionELF :: Create ( ".note.GNU-stack" , MCSectionELF :: SHT_PROGBITS , 0 , SectionKind :: getMetadata ( ) , false , Ctx ) ; } </s>

Targets can implement this method to specify a section to switch to if the translation unit does n't have any trampolines that require an executable stack .


<s> bool aarch64_float_const_representable_p ( rtx x ) { int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1 ; int exponent ; unsigned HOST_WIDE_INT mantissa , mask ; REAL_VALUE_TYPE r , m ; bool fail ; if ( ! CONST_DOUBLE_P ( x ) ) return false ; if ( GET_MODE ( x ) == VOIDmode || ( GET_MODE ( x ) == HFmode && ! TARGET_FP_F16INST ) ) return false ; r = * CONST_DOUBLE_REAL_VALUE ( x ) ; if ( REAL_VALUE_ISINF ( r ) || REAL_VALUE_ISNAN ( r ) || REAL_VALUE_MINUS_ZERO ( r ) ) return false ; r = real_value_abs ( & r ) ; exponent = REAL_EXP ( & r ) ; real_ldexp ( & m , & r , point_pos - exponent ) ; wide_int w = real_to_integer ( & m , & fail , HOST_BITS_PER_WIDE_INT * 2 ) ; if ( w . ulow ( ) != 0 ) return false ; mantissa = w . elt ( 1 ) ; point_pos -= HOST_BITS_PER_WIDE_INT ; mask = ( ( unsigned HOST_WIDE_INT ) 1 << ( point_pos - 5 ) ) - 1 ; if ( ( mantissa & mask ) != 0 ) return false ; mantissa >>= point_pos - 5 ; if ( mantissa == 0 ) return false ; mantissa &= ~ ( 1 << 4 ) ; gcc_assert ( mantissa <= 15 ) ; exponent = 5 - exponent ; return ( exponent >= 0 && exponent <= 7 ) ; } </s>

Return true iff X can be represented by a quarter-precision floating point immediate operand X . Note , we can not represent 0.0 .


<s> bool ARMRegisterInfo :: hasReservedCallFrame ( MachineFunction & MF ) const { const MachineFrameInfo * FFI = MF . getFrameInfo ( ) ; unsigned CFSize = FFI -> getMaxCallFrameSize ( ) ; ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( AFI -> isThumbFunction ( ) ) { if ( CFSize >= ( ( 1 << 8 ) - 1 ) * 4 / 2 ) return false ; } else { if ( CFSize >= ( ( 1 << 12 ) - 1 ) / 2 ) return false ; } return ! MF . getFrameInfo ( ) -> hasVarSizedObjects ( ) ; } </s>

hasReservedCallFrame - Under normal circumstances , when a frame pointer is not required , we reserve argument space for call sites in the function immediately on entry to the current function .


<s> bool AArch64TargetLowering :: isExtFreeImpl ( const Instruction * Ext ) const { if ( isa < FPExtInst > ( Ext ) ) return false ; if ( Ext -> getType ( ) -> isVectorTy ( ) ) return false ; for ( const Use & U : Ext -> uses ( ) ) { const Instruction * Instr = cast < Instruction > ( U . getUser ( ) ) ; switch ( Instr -> getOpcode ( ) ) { case Instruction :: Shl : if ( ! isa < ConstantInt > ( Instr -> getOperand ( 1 ) ) ) return false ; break ; case Instruction :: GetElementPtr : { gep_type_iterator GTI = gep_type_begin ( Instr ) ; auto & DL = Ext -> getModule ( ) -> getDataLayout ( ) ; std :: advance ( GTI , U . getOperandNo ( ) ) ; Type * IdxTy = * GTI ; uint64_t ShiftAmt = countTrailingZeros ( DL . getTypeStoreSizeInBits ( IdxTy ) ) - 3 ; if ( ShiftAmt == 0 || ShiftAmt > 4 ) return false ; break ; } case Instruction :: Trunc : if ( Instr -> getType ( ) == Ext -> getOperand ( 0 ) -> getType ( ) ) continue ; LLVM_FALLTHROUGH ; default : return false ; } } return true ; } </s>

Return true if the extension represented by I is free .


<s> static rtx sparc_function_arg_1 ( cumulative_args_t cum_v , machine_mode mode , const_tree type , bool named , bool incoming ) { const CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; int regbase = ( incoming ? SPARC_INCOMING_INT_ARG_FIRST : SPARC_OUTGOING_INT_ARG_FIRST ) ; int slotno , regno , padding ; enum mode_class mclass = GET_MODE_CLASS ( mode ) ; slotno = function_arg_slotno ( cum , mode , type , named , incoming , & regno , & padding ) ; if ( slotno == - 1 ) return 0 ; if ( type && TREE_CODE ( type ) == VECTOR_TYPE ) { HOST_WIDE_INT size = int_size_in_bytes ( type ) ; gcc_assert ( ( TARGET_ARCH32 && size <= 8 ) || ( TARGET_ARCH64 && size <= 16 ) ) ; if ( mode == BLKmode ) return function_arg_vector_value ( size , SPARC_FP_ARG_FIRST + 2 * slotno ) ; mclass = MODE_FLOAT ; } if ( TARGET_ARCH32 ) return gen_rtx_REG ( mode , regno ) ; if ( type && TREE_CODE ( type ) == RECORD_TYPE ) { HOST_WIDE_INT size = int_size_in_bytes ( type ) ; gcc_assert ( size <= 16 ) ; return function_arg_record_value ( type , mode , slotno , named , regbase ) ; } else if ( type && TREE_CODE ( type ) == UNION_TYPE ) { HOST_WIDE_INT size = int_size_in_bytes ( type ) ; gcc_assert ( size <= 16 ) ; return function_arg_union_value ( size , mode , slotno , regno ) ; } else if ( ( mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT ) && SPARC_FP_REG_P ( regno ) ) { rtx reg = gen_rtx_REG ( mode , regno ) ; if ( cum -> prototype_p || cum -> libcall_p ) return reg ; else { rtx v0 , v1 ; if ( ( regno - SPARC_FP_ARG_FIRST ) < SPARC_INT_ARG_MAX * 2 ) { int intreg ; if ( incoming ) return reg ; intreg = ( SPARC_OUTGOING_INT_ARG_FIRST + ( regno - SPARC_FP_ARG_FIRST ) / 2 ) ; v0 = gen_rtx_EXPR_LIST ( VOIDmode , reg , const0_rtx ) ; v1 = gen_rtx_EXPR_LIST ( VOIDmode , gen_rtx_REG ( mode , intreg ) , const0_rtx ) ; return gen_rtx_PARALLEL ( mode , gen_rtvec ( 2 , v0 , v1 ) ) ; } else { v0 = gen_rtx_EXPR_LIST ( VOIDmode , NULL_RTX , const0_rtx ) ; v1 = gen_rtx_EXPR_LIST ( VOIDmode , reg , const0_rtx ) ; return gen_rtx_PARALLEL ( mode , gen_rtvec ( 2 , v0 , v1 ) ) ; } } } else if ( type && AGGREGATE_TYPE_P ( type ) ) { HOST_WIDE_INT size = int_size_in_bytes ( type ) ; gcc_assert ( size <= 16 ) ; mode = int_mode_for_size ( size * BITS_PER_UNIT , 0 ) . else_blk ( ) ; } return gen_rtx_REG ( mode , regno ) ; } </s>

Determine where to put an argument to a function . Value is zero to push the argument on the stack , or a hard register in which to store the argument . CUM is a variable of type CUMULATIVE_ARGS which gives info about the preceding args and about the function being called . MODE is the argument 's machine mode . TYPE is the data type of the argument ( as a tree ) . This is null for libcalls where that information may not be available . NAMED is true if this argument is a named parameter ( otherwise it is an extra parameter matching an ellipsis ) . INCOMING_P is false for TARGET_FUNCTION_ARG , true for TARGET_FUNCTION_INCOMING_ARG .


<s> static void set_reg_plus_d ( int reg , int base , HOST_WIDE_INT disp , int note ) { rtx_insn * insn ; if ( VAL_14_BITS_P ( disp ) ) { insn = emit_move_insn ( gen_rtx_REG ( Pmode , reg ) , plus_constant ( Pmode , gen_rtx_REG ( Pmode , base ) , disp ) ) ; } else if ( TARGET_64BIT && ! VAL_32_BITS_P ( disp ) ) { rtx basereg = gen_rtx_REG ( Pmode , base ) ; rtx delta = GEN_INT ( disp ) ; rtx tmpreg = gen_rtx_REG ( Pmode , 1 ) ; emit_move_insn ( tmpreg , delta ) ; insn = emit_move_insn ( gen_rtx_REG ( Pmode , reg ) , gen_rtx_PLUS ( Pmode , tmpreg , basereg ) ) ; if ( DO_FRAME_NOTES ) add_reg_note ( insn , REG_FRAME_RELATED_EXPR , gen_rtx_SET ( tmpreg , gen_rtx_PLUS ( Pmode , basereg , delta ) ) ) ; } else { rtx basereg = gen_rtx_REG ( Pmode , base ) ; rtx delta = GEN_INT ( disp ) ; rtx tmpreg = gen_rtx_REG ( Pmode , 1 ) ; emit_move_insn ( tmpreg , gen_rtx_PLUS ( Pmode , basereg , gen_rtx_HIGH ( Pmode , delta ) ) ) ; insn = emit_move_insn ( gen_rtx_REG ( Pmode , reg ) , gen_rtx_LO_SUM ( Pmode , tmpreg , delta ) ) ; } if ( DO_FRAME_NOTES && note ) RTX_FRAME_RELATED_P ( insn ) = 1 ; } </s>

Emit RTL to set REG to the value specified by BASE+DISP . Handle case where DISP > 8k by using the add_high_const patterns . Note in DISP > 8k case , we will leave the high part of the address in % r1 . There is code in expand_hppa_ { prologue , epilogue } that knows this .


<s> static bool div_sqrt_insn_p ( rtx_insn * insn ) { if ( GET_CODE ( PATTERN ( insn ) ) != SET ) return false ; switch ( get_attr_type ( insn ) ) { case TYPE_FPDIVS : case TYPE_FPSQRTS : case TYPE_FPDIVD : case TYPE_FPSQRTD : return true ; default : return false ; } } </s>

True if INSN is a floating-point division or square-root .


<s> static void mips_output_mi_thunk ( FILE * file , tree thunk_fndecl ATTRIBUTE_UNUSED , HOST_WIDE_INT delta , HOST_WIDE_INT vcall_offset , tree function ) { rtx this , temp1 , temp2 , insn , fnaddr ; no_new_pseudos = 1 ; reload_completed = 1 ; reset_block_changes ( ) ; if ( TARGET_ABICALLS ) cfun -> machine -> global_pointer = REGNO ( pic_offset_table_rtx ) = TARGET_NEWABI ? 15 : GLOBAL_POINTER_REGNUM ; mips_emit_loadgp ( ) ; temp1 = gen_rtx_REG ( Pmode , 2 ) ; temp2 = gen_rtx_REG ( Pmode , 3 ) ; if ( aggregate_value_p ( TREE_TYPE ( TREE_TYPE ( function ) ) , function ) ) this = gen_rtx_REG ( Pmode , GP_ARG_FIRST + 1 ) ; else this = gen_rtx_REG ( Pmode , GP_ARG_FIRST ) ; if ( delta != 0 ) { rtx offset = GEN_INT ( delta ) ; if ( ! SMALL_OPERAND ( delta ) ) { emit_move_insn ( temp1 , offset ) ; offset = temp1 ; } emit_insn ( gen_add3_insn ( this , this , offset ) ) ; } if ( vcall_offset != 0 ) { rtx addr ; emit_move_insn ( temp1 , gen_rtx_MEM ( Pmode , this ) ) ; addr = mips_add_offset ( temp2 , temp1 , vcall_offset ) ; emit_move_insn ( temp1 , gen_rtx_MEM ( Pmode , addr ) ) ; emit_insn ( gen_add3_insn ( this , this , temp1 ) ) ; } fnaddr = XEXP ( DECL_RTL ( function ) , 0 ) ; if ( TARGET_MIPS16 || TARGET_ABICALLS || TARGET_LONG_CALLS ) { if ( TARGET_ABICALLS && ! mips_dangerous_for_la25_p ( fnaddr ) ) temp1 = gen_rtx_REG ( Pmode , PIC_FUNCTION_ADDR_REGNUM ) ; mips_load_call_address ( temp1 , fnaddr , true ) ; if ( TARGET_ABICALLS && REGNO ( temp1 ) != PIC_FUNCTION_ADDR_REGNUM ) emit_move_insn ( gen_rtx_REG ( Pmode , PIC_FUNCTION_ADDR_REGNUM ) , temp1 ) ; emit_jump_insn ( gen_indirect_jump ( temp1 ) ) ; } else { insn = emit_call_insn ( gen_sibcall_internal ( fnaddr , const0_rtx ) ) ; SIBLING_CALL_P ( insn ) = 1 ; } insn = get_insns ( ) ; insn_locators_initialize ( ) ; split_all_insns_noflow ( ) ; if ( TARGET_MIPS16 ) mips16_lay_out_constants ( ) ; shorten_branches ( insn ) ; final_start_function ( insn , file , 1 ) ; final ( insn , file , 1 ) ; final_end_function ( ) ; reload_completed = 0 ; no_new_pseudos = 0 ; } </s>

Implement TARGET_ASM_OUTPUT_MI_THUNK . Generate rtl rather than asm text in order to avoid duplicating too much logic from elsewhere .


<s> bool ARMTargetLowering :: isVectorLoadExtDesirable ( SDValue ExtVal ) const { EVT VT = ExtVal . getValueType ( ) ; if ( ! isTypeLegal ( VT ) ) return false ; if ( auto * Ld = dyn_cast < MaskedLoadSDNode > ( ExtVal . getOperand ( 0 ) ) ) { if ( Ld -> isExpandingLoad ( ) ) return false ; } if ( Subtarget -> hasMVEIntegerOps ( ) ) return true ; if ( ExtVal -> use_empty ( ) || ! ExtVal -> use_begin ( ) -> isOnlyUserOf ( ExtVal . getNode ( ) ) ) return true ; SDNode * U = * ExtVal -> use_begin ( ) ; if ( ( U -> getOpcode ( ) == ISD :: ADD || U -> getOpcode ( ) == ISD :: SUB || U -> getOpcode ( ) == ISD :: SHL || U -> getOpcode ( ) == ARMISD :: VSHLIMM ) ) return false ; return true ; } </s>

Return true if folding a vector load into ExtVal ( a sign , zero , or any extend node ) is profitable .

ARM ARM 0 ISD::ADD ISD::SUB ISD::SHL ARMISD::VSHLIMM


<s> SDValue PPCTargetLowering :: LowerFormalArguments ( SDValue Chain , CallingConv :: ID CallConv , bool isVarArg , const SmallVectorImpl < ISD :: InputArg > & Ins , const SDLoc & dl , SelectionDAG & DAG , SmallVectorImpl < SDValue > & InVals ) const { if ( Subtarget . is64BitELFABI ( ) ) return LowerFormalArguments_64SVR4 ( Chain , CallConv , isVarArg , Ins , dl , DAG , InVals ) ; else if ( Subtarget . is32BitELFABI ( ) ) return LowerFormalArguments_32SVR4 ( Chain , CallConv , isVarArg , Ins , dl , DAG , InVals ) ; return LowerFormalArguments_Darwin ( 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> char * aarch64_output_sve_cnt_pat_immediate ( const char * prefix , const char * operands , rtx * cnt_pat ) { aarch64_svpattern pattern = ( aarch64_svpattern ) INTVAL ( cnt_pat [ 0 ] ) ; unsigned int nelts_per_vq = INTVAL ( cnt_pat [ 1 ] ) ; unsigned int factor = INTVAL ( cnt_pat [ 2 ] ) * nelts_per_vq ; return aarch64_output_sve_cnt_immediate ( prefix , operands , pattern , factor , nelts_per_vq ) ; } </s>

Return the asm string for an instruction with a CNT-like vector size operand ( a vector pattern followed by a multiplier in the range [ 1 , 16 ] ) . PREFIX is the mnemonic without the size suffix and OPERANDS is the first part of the operands template ( the part that comes before the vector size itself ) . CNT_PAT [ 0 .. 2 ] are the operands of the UNSPEC_SVE_CNT_PAT ; see aarch64_sve_cnt_pat for details .


<s> static rtx aarch64_expand_sve_const_pred_eor ( rtx target , rtx_vector_builder & builder , unsigned int elt_size ) { rtx_vector_builder inv_builder ( VNx16BImode , builder . npatterns ( ) , builder . nelts_per_pattern ( ) ) ; for ( unsigned int i = 0 ; i < builder . encoded_nelts ( ) ; ++ i ) if ( ( i & ( elt_size - 1 ) ) == 0 && INTVAL ( builder . elt ( i ) ) == 0 ) inv_builder . quick_push ( const1_rtx ) ; else inv_builder . quick_push ( const0_rtx ) ; inv_builder . finalize ( ) ; rtx inv = aarch64_expand_sve_const_pred_1 ( NULL_RTX , inv_builder , false ) ; if ( ! inv ) return NULL_RTX ; rtx mask = aarch64_ptrue_all ( elt_size ) ; mask = force_reg ( VNx16BImode , mask ) ; inv = gen_lowpart ( VNx16BImode , inv ) ; target = aarch64_target_reg ( target , VNx16BImode ) ; emit_insn ( gen_aarch64_pred_z ( XOR , VNx16BImode , target , mask , inv , mask ) ) ; return target ; } </s>

BUILDER is a constant predicate in which the index of every set bit is a multiple of ELT_SIZE ( which is < = 8 ) . Try to load the constant by inverting every element at a multiple of ELT_SIZE and EORing the result with an ELT_SIZE PTRUE . Return a register that contains the constant on success , otherwise return null . Use TARGET as the register if it is nonnull and convenient .


<s> unsigned int rs6000_debugger_regno ( unsigned int regno , unsigned int format ) { if ( ( format == 0 && dwarf_debuginfo_p ( ) ) || format == 1 ) { if ( regno <= 31 ) return regno ; if ( FP_REGNO_P ( regno ) ) return regno - FIRST_FPR_REGNO + 32 ; if ( ALTIVEC_REGNO_P ( regno ) ) return regno - FIRST_ALTIVEC_REGNO + 1124 ; if ( regno == LR_REGNO ) return 108 ; if ( regno == CTR_REGNO ) return 109 ; if ( regno == CA_REGNO ) return 101 ; if ( format == 1 && regno == CR2_REGNO ) return 64 ; if ( CR_REGNO_P ( regno ) ) return regno - CR0_REGNO + 86 ; if ( regno == VRSAVE_REGNO ) return 356 ; if ( regno == VSCR_REGNO ) return 67 ; if ( regno == FRAME_POINTER_REGNUM ) return 111 ; if ( regno == ARG_POINTER_REGNUM ) return 67 ; if ( regno == 64 ) return 100 ; gcc_unreachable ( ) ; } if ( regno <= 31 ) return regno ; if ( FP_REGNO_P ( regno ) ) return regno - FIRST_FPR_REGNO + 32 ; if ( ALTIVEC_REGNO_P ( regno ) ) return regno - FIRST_ALTIVEC_REGNO + 77 ; if ( regno == LR_REGNO ) return 65 ; if ( regno == CTR_REGNO ) return 66 ; if ( regno == CA_REGNO ) return 76 ; if ( CR_REGNO_P ( regno ) ) return regno - CR0_REGNO + 68 ; if ( regno == VRSAVE_REGNO ) return 109 ; if ( regno == VSCR_REGNO ) return 110 ; if ( regno == FRAME_POINTER_REGNUM ) return 111 ; if ( regno == ARG_POINTER_REGNUM ) return 67 ; if ( regno == 64 ) return 64 ; gcc_unreachable ( ) ; } </s>

Map internal gcc register numbers to debug format register numbers . FORMAT specifies the type of debug register number to use : 0 -- debug information , except for frame-related sections 1 -- DWARF .debug_frame section 2 -- DWARF .eh_frame section


<s>
bool
processBlock
(
MachineBasicBlock
&
MBB
)
{
bool
Changed
=
false
;
bool
Is64Bit
=
MBB
.
getParent
(
)
->
getSubtarget
<
PPCSubtarget
>
(
)
.
isPPC64
(
)
;
for
(
MachineBasicBlock
::
iterator
I
=
MBB
.
begin
(
)
,
IE
=
MBB
.
end
(
)
;
I
!=
IE
;
++
I
)
{
MachineInstr
*
MI
=
I
;
if
(
MI
->
getOpcode
(
)
!=
PPC
::
ADDItlsgdLADDR
&&
MI
->
getOpcode
(
)
!=
PPC
::
ADDItlsldLADDR
&&
MI
->
getOpcode
(
)
!=
PPC
::
ADDItlsgdLADDR32
&&
MI
->
getOpcode
(
)
!=
PPC
::
ADDItlsldLADDR32
)
continue
;
DEBUG
(
dbgs
(
)
<<
"TLS Dynamic Call Fixup:\n    "
<<
*
MI
;
)
;
unsigned
OutReg
=
MI
->
getOperand
(
0
)
.
getReg
(
)
;
unsigned
InReg
=
MI
->
getOperand
(
1
)
.
getReg
(
)
;
DebugLoc
DL
=
MI
->
getDebugLoc
(
)
;
unsigned
GPR3
=
Is64Bit
PPC
::
X3
:
PPC
::
R3
;
unsigned
Opc1
,
Opc2
;
SmallVector
<
unsigned
,
4
>
OrigRegs
;
OrigRegs
.
push_back
(
OutReg
)
;
OrigRegs
.
push_back
(
InReg
)
;
OrigRegs
.
push_back
(
GPR3
)
;
switch
(
MI
->
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Opcode inconsistency error"
)
;
case
PPC
::
ADDItlsgdLADDR
:
Opc1
=
PPC
::
ADDItlsgdL
;
Opc2
=
PPC
::
GETtlsADDR
;
break
;
case
PPC
::
ADDItlsldLADDR
:
Opc1
=
PPC
::
ADDItlsldL
;
Opc2
=
PPC
::
GETtlsldADDR
;
break
;
case
PPC
::
ADDItlsgdLADDR32
:
Opc1
=
PPC
::
ADDItlsgdL32
;
Opc2
=
PPC
::
GETtlsADDR32
;
break
;
case
PPC
::
ADDItlsldLADDR32
:
Opc1
=
PPC
::
ADDItlsldL32
;
Opc2
=
PPC
::
GETtlsldADDR32
;
break
;
}
MachineInstr
*
Addi
=
BuildMI
(
MBB
,
I
,
DL
,
TII
->
get
(
Opc1
)
,
GPR3
)
.
addReg
(
InReg
)
;
Addi
->
addOperand
(
MI
->
getOperand
(
2
)
)
;
MachineBasicBlock
::
iterator
First
=
I
;
First
;
MachineInstr
*
Call
=
(
BuildMI
(
MBB
,
I
,
DL
,
TII
->
get
(
Opc2
)
,
GPR3
)
.
addReg
(
GPR3
)
)
;
Call
->
addOperand
(
MI
->
getOperand
(
3
)
)
;
BuildMI
(
MBB
,
I
,
DL
,
TII
->
get
(
TargetOpcode
::
COPY
)
,
OutReg
)
.
addReg
(
GPR3
)
;
MachineBasicBlock
::
iterator
Last
=
I
;
Last
;
++
I
;
MI
->
removeFromParent
(
)
;
LIS
->
repairIntervalsInRange
(
&
MBB
,
First
,
Last
,
OrigRegs
)
;
Changed
=
true
;
}
return
Changed
;
}
</s>

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


<s> static void register_svpattern ( ) { auto_vec < string_int_pair , 32 > values ; values . quick_push ( string_int_pair ( "SV_" # UPPER , VALUE ) ) ; AARCH64_FOR_SVPATTERN ( PUSH ) acle_svpattern = lang_hooks . types . simulate_enum_decl ( input_location , "svpattern" , & values ) ; } </s>


<s> bool ARMTargetLowering :: isUsedByReturnOnly ( SDNode * N , SDValue & Chain ) const { if ( N -> getNumValues ( ) != 1 ) return false ; if ( ! N -> hasNUsesOfValue ( 1 , 0 ) ) return false ; SDValue TCChain = Chain ; SDNode * Copy = * N -> use_begin ( ) ; if ( Copy -> getOpcode ( ) == ISD :: CopyToReg ) { if ( Copy -> getOperand ( Copy -> getNumOperands ( ) - 1 ) . getValueType ( ) == MVT :: Glue ) return false ; TCChain = Copy -> getOperand ( 0 ) ; } else if ( Copy -> getOpcode ( ) == ARMISD :: VMOVRRD ) { SDNode * VMov = Copy ; SmallPtrSet < SDNode * , 2 > Copies ; for ( SDNode :: use_iterator UI = VMov -> use_begin ( ) , UE = VMov -> use_end ( ) ; UI != UE ; ++ UI ) { if ( UI -> getOpcode ( ) != ISD :: CopyToReg ) return false ; Copies . insert ( * UI ) ; } if ( Copies . size ( ) > 2 ) return false ; for ( SDNode :: use_iterator UI = VMov -> use_begin ( ) , UE = VMov -> use_end ( ) ; UI != UE ; ++ UI ) { SDValue UseChain = UI -> getOperand ( 0 ) ; if ( Copies . count ( UseChain . getNode ( ) ) ) Copy = * UI ; else { if ( UI -> getOperand ( UI -> getNumOperands ( ) - 1 ) . getValueType ( ) == MVT :: Glue ) return false ; TCChain = UseChain ; } } } else if ( Copy -> getOpcode ( ) == ISD :: BITCAST ) { if ( ! Copy -> hasOneUse ( ) ) return false ; Copy = * Copy -> use_begin ( ) ; if ( Copy -> getOpcode ( ) != ISD :: CopyToReg || ! Copy -> hasNUsesOfValue ( 1 , 0 ) ) return false ; if ( Copy -> getOperand ( Copy -> getNumOperands ( ) - 1 ) . getValueType ( ) == MVT :: Glue ) return false ; TCChain = Copy -> getOperand ( 0 ) ; } else { return false ; } bool HasRet = false ; for ( SDNode :: use_iterator UI = Copy -> use_begin ( ) , UE = Copy -> use_end ( ) ; UI != UE ; ++ UI ) { if ( UI -> getOpcode ( ) != ARMISD :: RET_FLAG && UI -> getOpcode ( ) != ARMISD :: INTRET_FLAG ) return false ; HasRet = true ; } if ( ! HasRet ) return false ; Chain = TCChain ; return true ; } </s>

Return true if result of the specified node is used by a return node only .


<s> static void mips_reorg_process_insns ( void ) { rtx_insn * insn , * last_insn , * subinsn , * next_insn ; rtx lo_reg , delayed_reg ; int hilo_delay ; split_all_insns_noflow ( ) ; cfun -> machine -> ignore_hazard_length_p = true ; shorten_branches ( get_insns ( ) ) ; cfun -> machine -> all_noreorder_p = true ; if ( TARGET_MIPS16 ) cfun -> machine -> all_noreorder_p = false ; if ( ! TARGET_EXPLICIT_RELOCS ) cfun -> machine -> all_noreorder_p = false ; if ( crtl -> profile ) cfun -> machine -> all_noreorder_p = false ; if ( TARGET_FIX_VR4120 || TARGET_FIX_RM7000 || TARGET_FIX_24K || TARGET_MIPS5900 ) cfun -> machine -> all_noreorder_p = false ; if ( TARGET_FIX_VR4130 && ! ISA_HAS_MACCHI ) cfun -> machine -> all_noreorder_p = false ; mips_offset_table htab ( 37 ) ; for ( insn = get_insns ( ) ; insn != 0 ; insn = NEXT_INSN ( insn ) ) FOR_EACH_SUBINSN ( subinsn , insn ) if ( USEFUL_INSN_P ( subinsn ) ) { rtx body = PATTERN ( insn ) ; int noperands = asm_noperands ( body ) ; if ( noperands >= 0 ) { rtx * ops = XALLOCAVEC ( rtx , noperands ) ; bool * used = XALLOCAVEC ( bool , noperands ) ; const char * string = decode_asm_operands ( body , ops , NULL , NULL , NULL , NULL ) ; get_referenced_operands ( string , used , noperands ) ; for ( int i = 0 ; i < noperands ; ++ i ) if ( used [ i ] ) mips_record_lo_sums ( ops [ i ] , & htab ) ; } else mips_record_lo_sums ( PATTERN ( subinsn ) , & htab ) ; } last_insn = 0 ; hilo_delay = 2 ; delayed_reg = 0 ; lo_reg = gen_rtx_REG ( SImode , LO_REGNUM ) ; for ( insn = get_insns ( ) ; insn != 0 ; insn = next_insn ) { next_insn = NEXT_INSN ( insn ) ; if ( USEFUL_INSN_P ( insn ) ) { if ( GET_CODE ( PATTERN ( insn ) ) == SEQUENCE ) { FOR_EACH_SUBINSN ( subinsn , insn ) if ( INSN_P ( subinsn ) ) { if ( mips_orphaned_high_part_p ( & htab , subinsn ) ) { PATTERN ( subinsn ) = gen_nop ( ) ; INSN_CODE ( subinsn ) = CODE_FOR_nop ; } mips_avoid_hazard ( last_insn , subinsn , & hilo_delay , & delayed_reg , lo_reg ) ; } last_insn = insn ; } else { if ( mips_orphaned_high_part_p ( & htab , insn ) ) delete_insn ( insn ) ; else if ( recog_memoized ( insn ) == CODE_FOR_r10k_cache_barrier && last_insn && JUMP_P ( SEQ_BEGIN ( last_insn ) ) && INSN_ANNULLED_BRANCH_P ( SEQ_BEGIN ( last_insn ) ) ) delete_insn ( insn ) ; else { mips_avoid_hazard ( last_insn , insn , & hilo_delay , & delayed_reg , lo_reg ) ; last_insn = insn ; } } } } } </s>

Go through the instruction stream and insert nops where necessary . Also delete any high-part relocations whose partnering low parts are now all dead . See if the whole function can then be put into .set noreorder and .set nomacro .


<s> bool canMergeStoresTo ( unsigned AddressSpace , EVT MemVT , const MachineFunction & MF ) const override { bool NoFloat = MF . getFunction ( ) . hasFnAttribute ( Attribute :: NoImplicitFloat ) ; if ( NoFloat ) return ( MemVT . getSizeInBits ( ) <= 64 ) ; return true ; } </s>

Returns if it 's reasonable to merge stores to MemVT size .


<s> tree d30v_build_va_list ( ) { tree f_arg_ptr , f_arg_num , record , type_decl ; tree int_type_node ; record = make_lang_type ( RECORD_TYPE ) ; type_decl = build_decl ( TYPE_DECL , get_identifier ( "__va_list_tag" ) , record ) ; int_type_node = make_signed_type ( INT_TYPE_SIZE ) ; f_arg_ptr = build_decl ( FIELD_DECL , get_identifier ( "__va_arg_ptr" ) , ptr_type_node ) ; f_arg_num = build_decl ( FIELD_DECL , get_identifier ( "__va_arg_num" ) , int_type_node ) ; DECL_FIELD_CONTEXT ( f_arg_ptr ) = record ; DECL_FIELD_CONTEXT ( f_arg_num ) = record ; TREE_CHAIN ( record ) = type_decl ; TYPE_NAME ( record ) = type_decl ; TYPE_FIELDS ( record ) = f_arg_ptr ; TREE_CHAIN ( f_arg_ptr ) = f_arg_num ; layout_type ( record ) ; return build_array_type ( record , build_index_type ( size_zero_node ) ) ; } </s>


<s> void ARMPassConfig :: addIRPasses ( ) { if ( getARMSubtarget ( ) . isTargetNaCl ( ) ) addPass ( createInsertDivideCheckPass ( ) ) ; addPass ( createAtomicExpandLoadLinkedPass ( TM ) ) ; const ARMSubtarget * Subtarget = & getARMSubtarget ( ) ; if ( Subtarget -> hasAnyDataBarrier ( ) && ! Subtarget -> isThumb1Only ( ) ) if ( TM -> getOptLevel ( ) != CodeGenOpt :: None && EnableAtomicTidy ) addPass ( createCFGSimplificationPass ( ) ) ; TargetPassConfig :: addIRPasses ( ) ; } </s>

Add common target configurable passes that perform LLVM IR to IR transforms following machine independent optimization .


"The function works only with LEA instructions"


This method may be implemented by targets that want to run passes after register allocation pass pipeline but before prolog-epilog insertion .


<s>
bool
ARMAsmBackend
::
shouldForceRelocation
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
)
{
const
MCSymbolRefExpr
*
A
=
Target
.
getSymA
(
)
;
const
MCSymbol
*
Sym
=
A
&
A
->
getSymbol
(
)
:
nullptr
;
const
unsigned
FixupKind
=
Fixup
.
getKind
(
)
;
if
(
FixupKind
==
FK_NONE
)
return
true
;
if
(
FixupKind
==
ARM
::
fixup_arm_thumb_bl
)
{
assert
(
Sym
&&
"How did we resolve this?"
)
;
if
(
Sym
->
isExternal
(
)
)
return
true
;
}
if
(
Sym
&&
Sym
->
isELF
(
)
)
{
unsigned
Type
=
cast
<
MCSymbolELF
>
(
Sym
)
->
getType
(
)
;
if
(
(
Type
==
ELF
::
STT_FUNC
||
Type
==
ELF
::
STT_GNU_IFUNC
)
)
{
if
(
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_uncondbranch
)
)
return
true
;
if
(
!
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_br
||
FixupKind
==
ARM
::
fixup_arm_thumb_bl
||
FixupKind
==
ARM
::
fixup_t2_condbranch
||
FixupKind
==
ARM
::
fixup_t2_uncondbranch
)
)
return
true
;
}
}
if
(
A
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_blx
||
FixupKind
==
ARM
::
fixup_arm_blx
||
FixupKind
==
ARM
::
fixup_arm_uncondbl
||
FixupKind
==
ARM
::
fixup_arm_condbl
)
)
return
true
;
return
false
;
}
</s>

Hook to check if a relocation is needed for some target specific reason .


<s> bool MVEGatherScatterLowering :: runOnFunction ( Function & F ) { if ( ! EnableMaskedGatherScatters ) return false ; auto & TPC = getAnalysis < TargetPassConfig > ( ) ; auto & TM = TPC . getTM < TargetMachine > ( ) ; auto * ST = & TM . getSubtarget < ARMSubtarget > ( F ) ; if ( ! ST -> hasMVEIntegerOps ( ) ) return false ; SmallVector < IntrinsicInst * , 4 > Gathers ; SmallVector < IntrinsicInst * , 4 > Scatters ; LoopInfo & LI = getAnalysis < LoopInfoWrapperPass > ( ) . getLoopInfo ( ) ; for ( BasicBlock & BB : F ) { for ( Instruction & I : BB ) { IntrinsicInst * II = dyn_cast < IntrinsicInst > ( & I ) ; if ( II && II -> getIntrinsicID ( ) == Intrinsic :: masked_gather ) Gathers . push_back ( II ) ; else if ( II && II -> getIntrinsicID ( ) == Intrinsic :: masked_scatter ) Scatters . push_back ( II ) ; } } bool Changed = false ; for ( unsigned i = 0 ; i < Gathers . size ( ) ; i ++ ) { IntrinsicInst * I = Gathers [ i ] ; if ( isa < GetElementPtrInst > ( I -> getArgOperand ( 0 ) ) ) optimiseOffsets ( cast < Instruction > ( I -> getArgOperand ( 0 ) ) -> getOperand ( 1 ) , I -> getParent ( ) , & LI ) ; Value * L = lowerGather ( I ) ; if ( L == nullptr ) continue ; SimplifyInstructionsInBlock ( cast < Instruction > ( L ) -> getParent ( ) ) ; Changed = true ; } for ( unsigned i = 0 ; i < Scatters . size ( ) ; i ++ ) { IntrinsicInst * I = Scatters [ i ] ; if ( isa < GetElementPtrInst > ( I -> getArgOperand ( 1 ) ) ) optimiseOffsets ( cast < Instruction > ( I -> getArgOperand ( 1 ) ) -> getOperand ( 1 ) , I -> getParent ( ) , & LI ) ; Value * S = lowerScatter ( I ) ; if ( S == nullptr ) continue ; SimplifyInstructionsInBlock ( cast < Instruction > ( S ) -> getParent ( ) ) ; Changed = true ; } return Changed ; } </s>

runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass .


<s> void AArch64PassConfig :: addCodeGenPrepare ( ) { if ( getOptLevel ( ) != CodeGenOpt :: None ) addPass ( createTypePromotionPass ( ) ) ; TargetPassConfig :: addCodeGenPrepare ( ) ; } </s>

Add pass to prepare the LLVM IR for code generation .


<s>
void
CSKYRegisterInfo
::
eliminateFrameIndex
(
MachineBasicBlock
::
iterator
II
,
int
SPAdj
,
unsigned
FIOperandNum
,
RegScavenger
*
RS
)
const
{
assert
(
SPAdj
==
0
&&
"Unexpected non-zero SPAdj value"
)
;
}
</s>

This method must be overriden to eliminate abstract frame indices from instructions which may use them .

CSKY
CSKY
0
"Unexpected non-zero SPAdj value"


<s>
TargetTransformInfo
MipsTargetMachine
::
getTargetTransformInfo
(
const
Function
&
F
)
{
if
(
Subtarget
->
allowMixed16_32
(
)
)
{
LLVM_DEBUG
(
errs
(
)
<<
"No Target Transform Info Pass Added\n"
)
;
return
TargetTransformInfo
(
F
.
getParent
(
)
->
getDataLayout
(
)
)
;
}
LLVM_DEBUG
(
errs
(
)
<<
"Target Transform Info Pass Added\n"
)
;
return
TargetTransformInfo
(
BasicTTIImpl
(
this
,
F
)
)
;
}
</s>

Get a TargetTransformInfo implementation for the target .

Mips
Mips
"No Target Transform Info Pass Added\n"
"Target Transform Info Pass Added\n"


<s>
unsigned
LanaiTargetLowering
::
getRegisterByName
(
const
char
*
RegName
,
EVT
,
SelectionDAG
&
)
const
{
unsigned
Reg
=
StringSwitch
<
unsigned
>
(
RegName
)
.
Case
(
"pc"
,
Lanai
::
PC
)
.
Case
(
"sp"
,
Lanai
::
SP
)
.
Case
(
"fp"
,
Lanai
::
FP
)
.
Case
(
"rr1"
,
Lanai
::
RR1
)
.
Case
(
"r10"
,
Lanai
::
R10
)
.
Case
(
"rr2"
,
Lanai
::
RR2
)
.
Case
(
"r11"
,
Lanai
::
R11
)
.
Case
(
"rca"
,
Lanai
::
RCA
)
.
Default
(
0
)
;
if
(
Reg
)
return
Reg
;
report_fatal_error
(
"Invalid register name global variable"
)
;
}
</s>

Return the register ID of the name passed in .


<s>
static
void
segv_crash_handler
(
int
sig
ATTRIBUTE_UNUSED
)
{
internal_error
(
"segmentation fault (code)"
)
;
}
</s>

On Darwin/powerpc , hitting the stack limit turns into a SIGSEGV . This code detects the difference between hitting the stack limit and a true wild pointer dereference by looking at the instruction that faulted ; only a few kinds of instruction are used to access below the previous bottom of the stack .


<s> static rtx arm_find_sub_rtx_with_code ( rtx pattern , rtx_code code , bool find_any_shift ) { subrtx_var_iterator :: array_type array ; FOR_EACH_SUBRTX_VAR ( iter , array , pattern , NONCONST ) { rtx x = * iter ; if ( find_any_shift ) { if ( arm_rtx_shift_left_p ( x ) ) return x ; else for ( unsigned int i = 0 ; i < ARRAY_SIZE ( shift_rtx_codes ) ; i ++ ) if ( GET_CODE ( x ) == shift_rtx_codes [ i ] ) return x ; } if ( GET_CODE ( x ) == code ) return x ; } return NULL_RTX ; } </s>

Traverse PATTERN looking for a sub-rtx with RTX_CODE CODE . If FIND_ANY_SHIFT then we are interested in anything which can reasonably be described as a SHIFT RTX .


<s> static inline int choose_baseaddr_len ( unsigned int regno , HOST_WIDE_INT offset ) { int len = 4 ; if ( offset == 0 ) { len = ( regno == BP_REG || regno == R13_REG ) ; } else if ( IN_RANGE ( offset , - 128 , 127 ) ) len = 1 ; if ( regno == SP_REG || regno == R12_REG ) len ++ ; return len ; } </s>

This is semi-inlined memory_address_length , but simplified since we know that we 're always dealing with reg+offset , and to avoid having to create and discard all that rtl .


<s> MCSection * X86WindowsTargetObjectFile :: getSectionForConstant ( SectionKind Kind , const Constant * C ) const { if ( Kind . isReadOnly ( ) ) { if ( C ) { Type * Ty = C -> getType ( ) ; SmallString < 32 > COMDATSymName ; if ( Ty -> isFloatTy ( ) || Ty -> isDoubleTy ( ) ) { COMDATSymName = "__real@" ; COMDATSymName += scalarConstantToHexString ( C ) ; } else if ( const auto * VTy = dyn_cast < VectorType > ( Ty ) ) { uint64_t NumBits = VTy -> getBitWidth ( ) ; if ( NumBits == 128 || NumBits == 256 ) { COMDATSymName = NumBits == 128 ? "__xmm@" : "__ymm@" ; for ( int I = VTy -> getNumElements ( ) - 1 , E = - 1 ; I != E ; -- I ) COMDATSymName += scalarConstantToHexString ( C -> getAggregateElement ( I ) ) ; } } if ( ! COMDATSymName . empty ( ) ) { unsigned Characteristics = COFF :: IMAGE_SCN_CNT_INITIALIZED_DATA | COFF :: IMAGE_SCN_MEM_READ | COFF :: IMAGE_SCN_LNK_COMDAT ; return getContext ( ) . getCOFFSection ( ".rdata" , Characteristics , Kind , COMDATSymName , COFF :: IMAGE_COMDAT_SELECT_ANY ) ; } } } return TargetLoweringObjectFile :: getSectionForConstant ( Kind , C ) ; } </s>

Given a constant with the SectionKind , return a section that it should be placed in .


<s> bool SystemZLDCleanup :: runOnMachineFunction ( MachineFunction & F ) { TII = static_cast < const SystemZInstrInfo * > ( F . getSubtarget ( ) . getInstrInfo ( ) ) ; MF = & F ; SystemZMachineFunctionInfo * MFI = F . getInfo < SystemZMachineFunctionInfo > ( ) ; if ( MFI -> getNumLocalDynamicTLSAccesses ( ) < 2 ) { return false ; } MachineDominatorTree * DT = & getAnalysis < MachineDominatorTree > ( ) ; return VisitNode ( DT -> getRootNode ( ) , 0 ) ; } </s>

runOnMachineFunction - Emit the function body .

SystemZ SystemZ SystemZ SystemZ SystemZ 2 0


"No DAG nodes should be reachable from ExitSU"

Apply the profile inference algorithm for a given function .


<s> static bool vax_mode_dependent_address_p ( const_rtx x , addr_space_t as ATTRIBUTE_UNUSED ) { rtx xfoo0 , xfoo1 ; if ( GET_CODE ( x ) != PLUS ) return false ; xfoo0 = XEXP ( x , 0 ) ; xfoo1 = XEXP ( x , 1 ) ; if ( CONST_INT_P ( xfoo0 ) && REG_P ( xfoo1 ) ) return false ; if ( CONST_INT_P ( xfoo1 ) && REG_P ( xfoo0 ) ) return false ; if ( ! flag_pic && CONSTANT_ADDRESS_P ( xfoo0 ) && REG_P ( xfoo1 ) ) return false ; if ( ! flag_pic && CONSTANT_ADDRESS_P ( xfoo1 ) && REG_P ( xfoo0 ) ) return false ; return true ; } </s>

Return 1 if x ( a legitimate address expression ) has an effect that depends on the machine mode it is used for . On the VAX , the predecrement and postincrement address depend thus ( the amount of decrement or increment being the length of the operand ) and all indexed address depend thus ( because the index scale factor is the length of the operand ) .


<s> void pa_output_global_address ( FILE * file , rtx x , int round_constant ) { if ( GET_CODE ( x ) == HIGH ) x = XEXP ( x , 0 ) ; if ( GET_CODE ( x ) == SYMBOL_REF && read_only_operand ( x , VOIDmode ) ) output_addr_const ( file , x ) ; else if ( GET_CODE ( x ) == SYMBOL_REF && ! flag_pic ) { output_addr_const ( file , x ) ; fputs ( "-$global$" , file ) ; } else if ( GET_CODE ( x ) == CONST ) { const char * sep = "" ; int offset = 0 ; rtx base = NULL_RTX ; switch ( GET_CODE ( XEXP ( XEXP ( x , 0 ) , 0 ) ) ) { case SYMBOL_REF : base = XEXP ( XEXP ( x , 0 ) , 0 ) ; output_addr_const ( file , base ) ; break ; case CONST_INT : offset = INTVAL ( XEXP ( XEXP ( x , 0 ) , 0 ) ) ; break ; default : gcc_unreachable ( ) ; } switch ( GET_CODE ( XEXP ( XEXP ( x , 0 ) , 1 ) ) ) { case SYMBOL_REF : base = XEXP ( XEXP ( x , 0 ) , 1 ) ; output_addr_const ( file , base ) ; break ; case CONST_INT : offset = INTVAL ( XEXP ( XEXP ( x , 0 ) , 1 ) ) ; break ; default : gcc_unreachable ( ) ; } if ( round_constant ) offset = ( ( offset + 0x1000 ) & ~ 0x1fff ) ; switch ( GET_CODE ( XEXP ( x , 0 ) ) ) { case PLUS : if ( offset < 0 ) { offset = - offset ; sep = "-" ; } else sep = "+" ; break ; case MINUS : gcc_assert ( GET_CODE ( XEXP ( XEXP ( x , 0 ) , 0 ) ) == SYMBOL_REF ) ; sep = "-" ; break ; default : gcc_unreachable ( ) ; } if ( ! read_only_operand ( base , VOIDmode ) && ! flag_pic ) fputs ( "-$global$" , file ) ; if ( offset ) fprintf ( file , "%s%d" , sep , offset ) ; } else output_addr_const ( file , x ) ; } </s>

output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF .


<s>
unsigned
char
X86Subtarget
::
ClassifyGlobalReference
(
const
GlobalValue
*
GV
,
const
TargetMachine
&
TM
)
const
{
if
(
GV
->
hasDLLImportStorageClass
(
)
)
return
X86II
::
MO_DLLIMPORT
;
bool
isDecl
=
GV
->
hasAvailableExternallyLinkage
(
)
;
if
(
GV
->
isDeclaration
(
)
&&
!
GV
->
isMaterializable
(
)
)
isDecl
=
true
;
if
(
isPICStyleRIPRel
(
)
)
{
if
(
TM
.
getCodeModel
(
)
==
CodeModel
::
Large
)
return
X86II
::
MO_NO_FLAG
;
if
(
isTargetDarwin
(
)
)
{
if
(
GV
->
hasDefaultVisibility
(
)
&&
(
isDecl
||
GV
->
isWeakForLinker
(
)
)
)
return
X86II
::
MO_GOTPCREL
;
}
else
if
(
!
isTargetWin64
(
)
)
{
assert
(
isTargetELF
(
)
&&
"Unknown rip-relative target"
)
;
if
(
!
GV
->
hasLocalLinkage
(
)
&&
GV
->
hasDefaultVisibility
(
)
)
return
X86II
::
MO_GOTPCREL
;
}
return
X86II
::
MO_NO_FLAG
;
}
if
(
isPICStyleGOT
(
)
)
{
if
(
GV
->
hasLocalLinkage
(
)
||
GV
->
hasHiddenVisibility
(
)
)
return
X86II
::
MO_GOTOFF
;
return
X86II
::
MO_GOT
;
}
if
(
isPICStyleStubPIC
(
)
)
{
if
(
!
isDecl
&&
!
GV
->
isWeakForLinker
(
)
)
return
X86II
::
MO_PIC_BASE_OFFSET
;
if
(
!
GV
->
hasHiddenVisibility
(
)
)
return
X86II
::
MO_DARWIN_NONLAZY_PIC_BASE
;
if
(
isDecl
||
GV
->
hasCommonLinkage
(
)
)
{
return
X86II
::
MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE
;
}
return
X86II
::
MO_PIC_BASE_OFFSET
;
}
if
(
isPICStyleStubNoDynamic
(
)
)
{
if
(
!
isDecl
&&
!
GV
->
isWeakForLinker
(
)
)
return
X86II
::
MO_NO_FLAG
;
if
(
!
GV
->
hasHiddenVisibility
(
)
)
return
X86II
::
MO_DARWIN_NONLAZY
;
return
X86II
::
MO_NO_FLAG
;
}
return
X86II
::
MO_NO_FLAG
;
}
</s>

ClassifyGlobalReference - Find the target operand flags that describe how a global value should be referenced for the current subtarget .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; AArch64FunctionInfo * AFI = MF . getInfo < AArch64FunctionInfo > ( ) ; if ( AFI -> getNumLocalDynamicTLSAccesses ( ) < 2 ) { return false ; } MachineDominatorTree * DT = & getAnalysis < MachineDominatorTree > ( ) ; return VisitNode ( DT -> getRootNode ( ) , 0 ) ; } </s>


<s> void rs6000_emit_swdivsf ( rtx res , rtx n , rtx d ) { rtx x0 , e0 , e1 , y1 , u0 , v0 , one ; x0 = gen_reg_rtx ( SFmode ) ; e0 = gen_reg_rtx ( SFmode ) ; e1 = gen_reg_rtx ( SFmode ) ; y1 = gen_reg_rtx ( SFmode ) ; u0 = gen_reg_rtx ( SFmode ) ; v0 = gen_reg_rtx ( SFmode ) ; one = force_reg ( SFmode , CONST_DOUBLE_FROM_REAL_VALUE ( dconst1 , SFmode ) ) ; emit_insn ( gen_rtx_SET ( VOIDmode , x0 , gen_rtx_UNSPEC ( SFmode , gen_rtvec ( 1 , d ) , UNSPEC_FRES ) ) ) ; emit_insn ( gen_rtx_SET ( VOIDmode , e0 , gen_rtx_MINUS ( SFmode , one , gen_rtx_MULT ( SFmode , d , x0 ) ) ) ) ; emit_insn ( gen_rtx_SET ( VOIDmode , e1 , gen_rtx_PLUS ( SFmode , gen_rtx_MULT ( SFmode , e0 , e0 ) , e0 ) ) ) ; emit_insn ( gen_rtx_SET ( VOIDmode , y1 , gen_rtx_PLUS ( SFmode , gen_rtx_MULT ( SFmode , e1 , x0 ) , x0 ) ) ) ; emit_insn ( gen_rtx_SET ( VOIDmode , u0 , gen_rtx_MULT ( SFmode , n , y1 ) ) ) ; emit_insn ( gen_rtx_SET ( VOIDmode , v0 , gen_rtx_MINUS ( SFmode , n , gen_rtx_MULT ( SFmode , d , u0 ) ) ) ) ; emit_insn ( gen_rtx_SET ( VOIDmode , res , gen_rtx_PLUS ( SFmode , gen_rtx_MULT ( SFmode , v0 , y1 ) , u0 ) ) ) ; } </s>

Newton-Raphson approximation of single-precision floating point divide n/d . Assumes no trapping math and finite arguments .


<s> void LanaiAsmBackend :: applyFixup ( const MCAssembler & Asm , const MCFixup & Fixup , const MCValue & Target , MutableArrayRef < char > Data , uint64_t Value , bool , const MCSubtargetInfo * ) const { MCFixupKind Kind = Fixup . getKind ( ) ; Value = adjustFixupValue ( static_cast < unsigned > ( Kind ) , Value ) ; if ( ! Value ) return ; unsigned Offset = Fixup . getOffset ( ) ; unsigned NumBytes = ( getFixupKindInfo ( Kind ) . TargetSize + 7 ) / 8 ; unsigned FullSize = 4 ; uint64_t CurVal = 0 ; for ( unsigned i = 0 ; i != NumBytes ; ++ i ) { unsigned Idx = ( FullSize - 1 - i ) ; CurVal |= static_cast < uint64_t > ( static_cast < uint8_t > ( Data [ Offset + Idx ] ) ) << ( i * 8 ) ; } uint64_t Mask = ( static_cast < uint64_t > ( - 1 ) >> ( 64 - getFixupKindInfo ( Kind ) . TargetSize ) ) ; CurVal |= Value & Mask ; for ( unsigned i = 0 ; i != NumBytes ; ++ i ) { unsigned Idx = ( FullSize - 1 - i ) ; Data [ Offset + Idx ] = static_cast < uint8_t > ( ( CurVal >> ( i * 8 ) ) & 0xff ) ; } } </s>

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>
const
char
*
getPassName
(
)
const
override
{
return
"AArch64 Redundant Copy Elimination"
;
}
</s>

getPassName - Return a nice clean name for a pass .


getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned ' is on an i32 first argument if the calling convention is one that can ( partially ) model this attribute with a preserved mask ( i.e .


<s> void Cpu0InstPrinter :: printInst ( const MCInst * MI , raw_ostream & O , StringRef Annot ) { printInstruction ( MI , O ) ; O << ";" ; printAnnotation ( O , Annot ) ; } </s>

Print the specified MCInst to the specified raw_ostream .


<s> bool rs6000_emit_set_const ( rtx dest , rtx source ) { machine_mode mode = GET_MODE ( dest ) ; rtx temp , set ; rtx_insn * insn ; HOST_WIDE_INT c ; gcc_checking_assert ( CONST_INT_P ( source ) ) ; c = INTVAL ( source ) ; switch ( mode ) { case E_QImode : case E_HImode : emit_insn ( gen_rtx_SET ( dest , source ) ) ; return true ; case E_SImode : temp = ! can_create_pseudo_p ( ) ? dest : gen_reg_rtx ( SImode ) ; emit_insn ( gen_rtx_SET ( copy_rtx ( temp ) , GEN_INT ( c & ~ ( HOST_WIDE_INT ) 0xffff ) ) ) ; emit_insn ( gen_rtx_SET ( dest , gen_rtx_IOR ( SImode , copy_rtx ( temp ) , GEN_INT ( c & 0xffff ) ) ) ) ; break ; case E_DImode : if ( ! TARGET_POWERPC64 ) { rtx hi , lo ; hi = operand_subword_force ( copy_rtx ( dest ) , WORDS_BIG_ENDIAN == 0 , DImode ) ; lo = operand_subword_force ( dest , WORDS_BIG_ENDIAN != 0 , DImode ) ; emit_move_insn ( hi , GEN_INT ( c >> 32 ) ) ; c = ( ( c & 0xffffffff ) ^ 0x80000000 ) - 0x80000000 ; emit_move_insn ( lo , GEN_INT ( c ) ) ; } else rs6000_emit_set_long_const ( dest , c ) ; break ; default : gcc_unreachable ( ) ; } insn = get_last_insn ( ) ; set = single_set ( insn ) ; if ( ! CONSTANT_P ( SET_SRC ( set ) ) ) set_unique_reg_note ( insn , REG_EQUAL , GEN_INT ( c ) ) ; return true ; } </s>

Try to output insns to set TARGET equal to the constant C if it can be done in less than N insns . Do all computations in MODE . Returns the place where the output has been placed if it can be done and the insns have been emitted . If it would take more than N insns , zero is returned and no insns and emitted .


<s> bool SystemZAsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , unsigned AsmVariant , const char * ExtraCode , raw_ostream & OS ) { if ( ExtraCode && * ExtraCode == 'n' ) { if ( ! MI -> getOperand ( OpNo ) . isImm ( ) ) return true ; OS << - int64_t ( MI -> getOperand ( OpNo ) . getImm ( ) ) ; } else { SystemZMCInstLower Lower ( Mang , MF -> getContext ( ) , * this ) ; MCOperand MO ( Lower . lowerOperand ( MI -> getOperand ( OpNo ) ) ) ; SystemZInstPrinter :: printOperand ( MO , OS ) ; } return false ; } </s>

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


Define the offset between two registers , one to be eliminated , and the other its replacement , at the start of a routine .


<s>
void
emitInst
(
uint32_t
Inst
,
char
Suffix
)
{
unsigned
Size
;
char
Buffer
[
4
]
;
const
bool
LittleEndian
=
getContext
(
)
.
getAsmInfo
(
)
->
isLittleEndian
(
)
;
switch
(
Suffix
)
{
case
'\0'
:
Size
=
4
;
assert
(
!
IsThumb
)
;
EmitARMMappingSymbol
(
)
;
for
(
unsigned
II
=
0
,
IE
=
Size
;
II
!=
IE
;
II
++
)
{
const
unsigned
I
=
LittleEndian
(
Size
II
1
)
:
II
;
Buffer
[
Size
II
1
]
=
uint8_t
(
Inst
>>
I
*
CHAR_BIT
)
;
}
break
;
case
'n'
:
case
'w'
:
Size
=
(
Suffix
==
'n'
2
:
4
)
;
assert
(
IsThumb
)
;
EmitThumbMappingSymbol
(
)
;
for
(
unsigned
II
=
0
,
IE
=
Size
;
II
!=
IE
;
II
=
II
+
2
)
{
const
unsigned
I0
=
LittleEndian
II
+
0
:
II
+
1
;
const
unsigned
I1
=
LittleEndian
II
+
1
:
II
+
0
;
Buffer
[
Size
II
2
]
=
uint8_t
(
Inst
>>
I0
*
CHAR_BIT
)
;
Buffer
[
Size
II
1
]
=
uint8_t
(
Inst
>>
I1
*
CHAR_BIT
)
;
}
break
;
default
:
llvm_unreachable
(
"Invalid Suffix"
)
;
}
MCELFStreamer
::
emitBytes
(
StringRef
(
Buffer
,
Size
)
)
;
}
</s>

Callback used to implement the .inst directive .


<s> MCSymbol * ARMAsmPrinter :: GetCPISymbol ( unsigned CPID ) const { const DataLayout & DL = getDataLayout ( ) ; return OutContext . getOrCreateSymbol ( Twine ( DL . getPrivateGlobalPrefix ( ) ) + "CPI" + Twine ( getFunctionNumber ( ) ) + "_" + Twine ( CPID ) ) ; } </s>

Return the symbol for the specified constant pool entry .


<s> bool X86AsmPrinter :: PrintAsmMemoryOperand ( const MachineInstr * MI , unsigned OpNo , const char * ExtraCode , raw_ostream & O ) { 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 'H' : if ( MI -> getInlineAsmDialect ( ) == InlineAsm :: AD_Intel ) { return true ; } else { PrintMemReference ( MI , OpNo , O , "H" ) ; } return false ; case 'P' : if ( MI -> getInlineAsmDialect ( ) == InlineAsm :: AD_Intel ) { PrintIntelMemReference ( MI , OpNo , O , "no-rip" ) ; } else { PrintMemReference ( MI , OpNo , O , "no-rip" ) ; } return false ; } } if ( MI -> getInlineAsmDialect ( ) == InlineAsm :: AD_Intel ) { PrintIntelMemReference ( MI , OpNo , O , nullptr ) ; } else { PrintMemReference ( MI , OpNo , O , nullptr ) ; } return false ; } </s>

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


<s> int X86TTIImpl :: getIntImmCost ( const APInt & Imm , Type * Ty , TTI :: TargetCostKind CostKind ) { assert ( Ty -> isIntegerTy ( ) ) ; unsigned BitSize = Ty -> getPrimitiveSizeInBits ( ) ; if ( BitSize == 0 ) return ~ 0U ; if ( BitSize > 128 ) return TTI :: TCC_Free ; if ( Imm == 0 ) return TTI :: TCC_Free ; APInt ImmVal = Imm ; if ( BitSize % 64 != 0 ) ImmVal = Imm . sext ( alignTo ( BitSize , 64 ) ) ; int Cost = 0 ; for ( unsigned ShiftVal = 0 ; ShiftVal < BitSize ; ShiftVal += 64 ) { APInt Tmp = ImmVal . ashr ( ShiftVal ) . sextOrTrunc ( 64 ) ; int64_t Val = Tmp . getSExtValue ( ) ; Cost += getIntImmCost ( Val ) ; } return std :: max ( 1 , Cost ) ; } </s>

Calculate the cost of materializing a 64-bit value .


<s> const char * mips16_set_fcsr_one_only_stub :: get_name ( ) { return "__mips16_set_fcsr" ; } </s>

Return the overloaded or full function name for INSTANCE ; OVERLOADED_P selects which . Allocate the string on m_string_obstack ; the caller must use obstack_free to free it after use .


<s>
static
void
rs6000_xcoff_file_start
(
void
)
{
rs6000_gen_section_name
(
&
xcoff_bss_section_name
,
main_input_filename
,
".bss_"
)
;
rs6000_gen_section_name
(
&
xcoff_private_data_section_name
,
main_input_filename
,
".rw_"
)
;
rs6000_gen_section_name
(
&
xcoff_read_only_section_name
,
main_input_filename
,
".ro_"
)
;
rs6000_gen_section_name
(
&
xcoff_tls_data_section_name
,
main_input_filename
,
".tls_"
)
;
rs6000_gen_section_name
(
&
xcoff_tbss_section_name
,
main_input_filename
,
".tbss_[UL]"
)
;
fputs
(
"\t.file\t"
,
asm_out_file
)
;
output_quoted_string
(
asm_out_file
,
main_input_filename
)
;
fputc
(
'\n'
,
asm_out_file
)
;
if
(
write_symbols
!=
NO_DEBUG
)
switch_to_section
(
private_data_section
)
;
switch_to_section
(
toc_section
)
;
switch_to_section
(
text_section
)
;
if
(
profile_flag
)
fprintf
(
asm_out_file
,
"\t.extern %s\n"
,
RS6000_MCOUNT
)
;
rs6000_file_start
(
)
;
}
</s>

Output at beginning of assembler file . Initialize the section names for the RS/6000 at this point . Specify filename , including full path , to assembler . We want to go into the TOC section so at least one .toc will be emitted . Also , in order to output proper .bs/.es pairs , we need at least one static [ RW ] section emitted . Finally , declare mcount when profiling to make the assembler happy .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { const TargetMachine & TM = MF . getTarget ( ) ; if ( MF . getFunction ( ) -> hasFnAttribute ( Attribute :: Naked ) ) return false ; if ( TM . getRelocationModel ( ) != Reloc :: PIC_ ) return false ; OR1KMachineFunctionInfo * OR1KFI = MF . getInfo < OR1KMachineFunctionInfo > ( ) ; unsigned GlobalBaseReg = OR1KFI -> getGlobalBaseReg ( ) ; if ( GlobalBaseReg == 0 ) return false ; MachineBasicBlock & FirstMBB = MF . front ( ) ; MachineBasicBlock :: iterator MBBI = FirstMBB . begin ( ) ; DebugLoc DL = FirstMBB . findDebugLoc ( MBBI ) ; MachineRegisterInfo & RegInfo = MF . getRegInfo ( ) ; const TargetInstrInfo * TII = MF . getSubtarget ( ) . getInstrInfo ( ) ; unsigned Scratch1 = RegInfo . createVirtualRegister ( & OR1K :: GPRRegClass ) ; unsigned Scratch2 = RegInfo . createVirtualRegister ( & OR1K :: GPRRegClass ) ; BuildMI ( FirstMBB , MBBI , DL , TII -> get ( OR1K :: GETPC ) ) . addImm ( 0 ) ; BuildMI ( FirstMBB , MBBI , DL , TII -> get ( OR1K :: MOVHI ) , Scratch1 ) . addExternalSymbol ( "_GLOBAL_OFFSET_TABLE_" , OR1KII :: MO_GOTPCHI ) ; BuildMI ( FirstMBB , MBBI , DL , TII -> get ( OR1K :: ORI ) , Scratch2 ) . addReg ( Scratch1 ) . addExternalSymbol ( "_GLOBAL_OFFSET_TABLE_" , OR1KII :: MO_GOTPCLO ) ; BuildMI ( FirstMBB , MBBI , DL , TII -> get ( OR1K :: ADD ) , GlobalBaseReg ) . addReg ( OR1K :: R9 ) . addReg ( Scratch2 ) ; return true ; } </s>

runOnMachineFunction - Emit the function body .


<s> void X86FrameLowering :: orderFrameObjects ( const MachineFunction & MF , SmallVectorImpl < int > & ObjectsToAllocate ) const { const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; if ( ObjectsToAllocate . empty ( ) ) return ; std :: vector < X86FrameSortingObject > SortingObjects ( MFI . getObjectIndexEnd ( ) ) ; for ( auto & Obj : ObjectsToAllocate ) { SortingObjects [ Obj ] . IsValid = true ; SortingObjects [ Obj ] . ObjectIndex = Obj ; SortingObjects [ Obj ] . ObjectAlignment = MFI . getObjectAlignment ( Obj ) ; int ObjectSize = MFI . getObjectSize ( Obj ) ; if ( ObjectSize == 0 ) SortingObjects [ Obj ] . ObjectSize = 4 ; else SortingObjects [ Obj ] . ObjectSize = ObjectSize ; } for ( auto & MBB : MF ) { for ( auto & MI : MBB ) { if ( MI . isDebugInstr ( ) ) continue ; for ( const MachineOperand & MO : MI . operands ( ) ) { if ( ! MO . isFI ( ) ) continue ; int Index = MO . getIndex ( ) ; if ( Index >= 0 && Index < MFI . getObjectIndexEnd ( ) && SortingObjects [ Index ] . IsValid ) SortingObjects [ Index ] . ObjectNumUses ++ ; } } } llvm :: stable_sort ( SortingObjects , X86FrameSortingComparator ( ) ) ; int i = 0 ; for ( auto & Obj : SortingObjects ) { if ( ! Obj . IsValid ) break ; ObjectsToAllocate [ i ++ ] = Obj . ObjectIndex ; } if ( ! TRI -> needsStackRealignment ( MF ) && hasFP ( MF ) ) std :: reverse ( ObjectsToAllocate . begin ( ) , ObjectsToAllocate . end ( ) ) ; } </s>


<s> int SystemZTTIImpl :: getIntrinsicInstrCost ( const IntrinsicCostAttributes & ICA , TTI :: TargetCostKind CostKind ) { int Cost = getVectorIntrinsicInstrCost ( ICA . getID ( ) , ICA . getReturnType ( ) ) ; if ( Cost != - 1 ) return Cost ; return BaseT :: getIntrinsicInstrCost ( ICA , CostKind ) ; } </s>


<s> bool X86AsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getIdentifier ( ) ; if ( IDVal == ".word" ) return ParseDirectiveWord ( 2 , DirectiveID . getLoc ( ) ) ; else if ( IDVal . startswith ( ".code" ) ) return ParseDirectiveCode ( IDVal , DirectiveID . getLoc ( ) ) ; else if ( IDVal . startswith ( ".att_syntax" ) ) { getParser ( ) . setAssemblerDialect ( 0 ) ; return false ; } else if ( IDVal . startswith ( ".intel_syntax" ) ) { getParser ( ) . setAssemblerDialect ( 1 ) ; if ( getLexer ( ) . isNot ( AsmToken :: EndOfStatement ) ) { if ( Parser . getTok ( ) . getString ( ) == "noprefix" ) Parser . Lex ( ) ; } return false ; } return true ; } </s>

ParseDirective - Parse a target specific assembler directive This method is deprecated , use 'parseDirective ' instead .


<s> bool MipsSEDAGToDAGISel :: runOnMachineFunction ( MachineFunction & MF ) { Subtarget = & static_cast < const MipsSubtarget & > ( MF . getSubtarget ( ) ) ; if ( Subtarget -> inMips16Mode ( ) ) return false ; return MipsDAGToDAGISel :: runOnMachineFunction ( MF ) ; } </s>


<s> bool AArch64TargetLowering :: shouldReduceLoadWidth ( SDNode * Load , ISD :: LoadExtType ExtTy , EVT NewVT ) const { if ( ! TargetLoweringBase :: shouldReduceLoadWidth ( Load , ExtTy , NewVT ) ) return false ; if ( ExtTy != ISD :: NON_EXTLOAD ) return true ; MemSDNode * Mem = dyn_cast < MemSDNode > ( Load ) ; assert ( Mem ) ; const SDValue & Base = Mem -> getBasePtr ( ) ; if ( Base . getOpcode ( ) == ISD :: ADD && Base . getOperand ( 1 ) . getOpcode ( ) == ISD :: SHL && Base . getOperand ( 1 ) . hasOneUse ( ) && Base . getOperand ( 1 ) . getOperand ( 1 ) . getOpcode ( ) == ISD :: Constant ) { uint64_t ShiftAmount = Base . getOperand ( 1 ) . getConstantOperandVal ( 1 ) ; uint64_t LoadBytes = Mem -> getMemoryVT ( ) . getSizeInBits ( ) / 8 ; if ( ShiftAmount == Log2_32 ( LoadBytes ) ) return false ; } return true ; } </s>

Return true if we believe it is correct and profitable to reduce the load node to a smaller type .


<s> int ix86_issue_rate ( void ) { switch ( ix86_tune ) { case PROCESSOR_PENTIUM : case PROCESSOR_LAKEMONT : case PROCESSOR_BONNELL : case PROCESSOR_SILVERMONT : case PROCESSOR_KNL : case PROCESSOR_KNM : case PROCESSOR_INTEL : case PROCESSOR_K6 : case PROCESSOR_BTVER2 : case PROCESSOR_PENTIUM4 : case PROCESSOR_NOCONA : return 2 ; case PROCESSOR_PENTIUMPRO : case PROCESSOR_ATHLON : case PROCESSOR_K8 : case PROCESSOR_AMDFAM10 : case PROCESSOR_BTVER1 : case PROCESSOR_LUJIAZUI : return 3 ; case PROCESSOR_BDVER1 : case PROCESSOR_BDVER2 : case PROCESSOR_BDVER3 : case PROCESSOR_BDVER4 : case PROCESSOR_ZNVER1 : case PROCESSOR_ZNVER2 : case PROCESSOR_ZNVER3 : case PROCESSOR_ZNVER4 : case PROCESSOR_CORE2 : case PROCESSOR_NEHALEM : case PROCESSOR_SANDYBRIDGE : case PROCESSOR_HASWELL : case PROCESSOR_TREMONT : case PROCESSOR_SKYLAKE : case PROCESSOR_SKYLAKE_AVX512 : case PROCESSOR_CASCADELAKE : case PROCESSOR_CANNONLAKE : case PROCESSOR_ALDERLAKE : case PROCESSOR_GENERIC : return 4 ; case PROCESSOR_ICELAKE_CLIENT : case PROCESSOR_ICELAKE_SERVER : case PROCESSOR_TIGERLAKE : case PROCESSOR_COOPERLAKE : case PROCESSOR_ROCKETLAKE : return 5 ; case PROCESSOR_SAPPHIRERAPIDS : return 6 ; default : return 1 ; } } </s>

Return the maximum number of instructions a cpu can issue .


<s> bool mips_signed_immediate_p ( unsigned HOST_WIDE_INT x , int bits , int shift = 0 ) { x += 1 << ( bits + shift - 1 ) ; return mips_unsigned_immediate_p ( x , bits , shift ) ; } </s>

Return true if X fits within a signed field of BITS bits that is shifted left SHIFT bits before being used .


<s> StringRef getPassName ( ) const override { return ARM_EXPAND_PSEUDO_NAME ; } </s>

getPassName - Return a nice clean name for a pass .


<s> void gen_ashift_hi ( int type , int n , rtx reg ) { if ( n < 0 ) { if ( type == ASHIFT ) type = LSHIFTRT ; else type = ASHIFT ; n = - n ; } switch ( type ) { case ASHIFTRT : case LSHIFTRT : { int offset = 0 ; if ( GET_CODE ( reg ) == SUBREG ) { offset = SUBREG_BYTE ( reg ) ; reg = SUBREG_REG ( reg ) ; } gen_ashift ( type , n , gen_rtx_SUBREG ( SImode , reg , offset ) ) ; break ; } case ASHIFT : emit_insn ( gen_ashlhi3_k ( reg , reg , GEN_INT ( n ) ) ) ; break ; } } </s>


<s> int ccr_bit ( rtx op , int scc_p ) { enum rtx_code code = GET_CODE ( op ) ; enum machine_mode cc_mode ; int cc_regnum ; int base_bit ; rtx reg ; if ( ! COMPARISON_P ( op ) ) return - 1 ; reg = XEXP ( op , 0 ) ; gcc_assert ( GET_CODE ( reg ) == REG && CR_REGNO_P ( REGNO ( reg ) ) ) ; cc_mode = GET_MODE ( reg ) ; cc_regnum = REGNO ( reg ) ; base_bit = 4 * ( cc_regnum - CR0_REGNO ) ; validate_condition_mode ( code , cc_mode ) ; gcc_assert ( ! scc_p || code == EQ || code == GT || code == LT || code == UNORDERED || code == GTU || code == LTU ) ; switch ( code ) { case NE : return scc_p ? base_bit + 3 : base_bit + 2 ; case EQ : return base_bit + 2 ; case GT : case GTU : case UNLE : return base_bit + 1 ; case LT : case LTU : case UNGE : return base_bit ; case ORDERED : case UNORDERED : return base_bit + 3 ; case GE : case GEU : return scc_p ? base_bit + 3 : base_bit ; case LE : case LEU : return scc_p ? base_bit + 3 : base_bit + 1 ; default : gcc_unreachable ( ) ; } } </s>

Given a comparison operation , return the bit number in CCR to test . We know this is a valid comparison . SCC_P is 1 if this is for an scc . That means that % D will have been used instead of % C , so the bits will be in different places . Return -1 if OP is n't a valid comparison for some reason .


<s> static enum machine_mode ix86_cc_modes_compatible ( enum machine_mode m1 , enum machine_mode m2 ) { if ( m1 == m2 ) return m1 ; if ( GET_MODE_CLASS ( m1 ) != MODE_CC || GET_MODE_CLASS ( m2 ) != MODE_CC ) return VOIDmode ; if ( ( m1 == CCGCmode && m2 == CCGOCmode ) || ( m1 == CCGOCmode && m2 == CCGCmode ) ) return CCGCmode ; switch ( m1 ) { default : gcc_unreachable ( ) ; case CCmode : case CCGCmode : case CCGOCmode : case CCNOmode : case CCZmode : switch ( m2 ) { default : return VOIDmode ; case CCmode : case CCGCmode : case CCGOCmode : case CCNOmode : case CCZmode : return CCmode ; } case CCFPmode : case CCFPUmode : return VOIDmode ; } } </s>

If two condition code modes are compatible , return a condition code mode which is compatible with both . Otherwise , return VOIDmode .


<s> bool isToken ( ) const { return Kind == Token ; } </s>


<s> static unsigned int aarch64_call_properties ( unsigned int flags , machine_mode mode ) { if ( ! ( flags & FLAG_AUTO_FP ) && FLOAT_MODE_P ( mode ) ) flags |= FLAG_FP ; if ( ! flag_trapping_math ) flags &= ~ FLAG_RAISE_FP_EXCEPTIONS ; return flags ; } </s>

Return a set of FLAG_ * flags that describe what the function could do , taking the command-line flags into account .


<s> const MCSection * SystemZMCAsmInfo :: getNonexecutableStackSection ( MCContext & Ctx ) const { return Ctx . getELFSection ( ".note.GNU-stack" , ELF :: SHT_PROGBITS , 0 , SectionKind :: getMetadata ( ) ) ; } </s>

Targets can implement this method to specify a section to switch to if the translation unit does n't have any trampolines that require an executable stack .


<s> static void ix86_simd_clone_adjust ( struct cgraph_node * node ) { const char * str = NULL ; if ( ! node -> definition ) return ; gcc_assert ( node -> decl == cfun -> decl ) ; switch ( node -> simdclone -> vecsize_mangle ) { case 'b' : if ( ! TARGET_SSE2 ) str = "sse2" ; break ; case 'c' : if ( ! TARGET_AVX ) str = "avx" ; break ; case 'd' : if ( ! TARGET_AVX2 ) str = "avx2" ; break ; case 'e' : if ( ! TARGET_AVX512F ) str = "avx512f" ; break ; default : gcc_unreachable ( ) ; } if ( str == NULL ) return ; push_cfun ( NULL ) ; tree args = build_tree_list ( NULL_TREE , build_string ( strlen ( str ) , str ) ) ; bool ok = ix86_valid_target_attribute_p ( node -> decl , NULL , args , 0 ) ; gcc_assert ( ok ) ; pop_cfun ( ) ; ix86_reset_previous_fndecl ( ) ; ix86_set_current_function ( node -> decl ) ; } </s>

Add target attribute to SIMD clone NODE if needed .


<s> bool PPCTTIImpl :: shouldBuildRelLookupTables ( ) const { const PPCTargetMachine & TM = ST -> getTargetMachine ( ) ; if ( ! TM . isELFv2ABI ( ) ) return false ; return BaseT :: shouldBuildRelLookupTables ( ) ; } </s>

Return true if lookup tables should be turned into relative lookup tables .


<s> void F2003fPassConfig :: addPreEmitPass ( ) { addPass ( createF2003fFiMalkrzPass ( ) ) ; } </s>

This pass may be implemented by targets that want to run passes immediately before machine code is emitted .


<s> static void ix86_emit_save_reg_using_mov ( machine_mode mode , unsigned int regno , HOST_WIDE_INT cfa_offset ) { struct machine_function * m = cfun -> machine ; rtx reg = gen_rtx_REG ( mode , regno ) ; rtx mem , addr , base , insn ; unsigned int align = GET_MODE_ALIGNMENT ( mode ) ; addr = choose_baseaddr ( cfa_offset , & align ) ; mem = gen_frame_mem ( mode , addr ) ; align = MIN ( GET_MODE_ALIGNMENT ( mode ) , align ) ; gcc_assert ( ! ( cfa_offset & ( align / BITS_PER_UNIT - 1 ) ) ) ; set_mem_align ( mem , align ) ; insn = emit_insn ( gen_rtx_SET ( mem , reg ) ) ; RTX_FRAME_RELATED_P ( insn ) = 1 ; base = addr ; if ( GET_CODE ( base ) == PLUS ) base = XEXP ( base , 0 ) ; gcc_checking_assert ( REG_P ( base ) ) ; if ( m -> fs . realigned ) { gcc_checking_assert ( stack_realign_drap ) ; if ( regno == REGNO ( crtl -> drap_reg ) ) { gcc_checking_assert ( cfun -> machine -> fs . fp_valid ) ; addr = plus_constant ( Pmode , hard_frame_pointer_rtx , cfun -> machine -> fs . fp_offset - cfa_offset ) ; mem = gen_rtx_MEM ( mode , addr ) ; add_reg_note ( insn , REG_CFA_DEF_CFA , mem ) ; } else { gcc_checking_assert ( cfun -> machine -> fs . fp_valid ) ; addr = plus_constant ( Pmode , hard_frame_pointer_rtx , cfun -> machine -> fs . fp_offset - cfa_offset ) ; mem = gen_rtx_MEM ( mode , addr ) ; add_reg_note ( insn , REG_CFA_EXPRESSION , gen_rtx_SET ( mem , reg ) ) ; } } else if ( base == stack_pointer_rtx && m -> fs . sp_realigned && cfa_offset >= m -> fs . sp_realigned_offset ) { gcc_checking_assert ( stack_realign_fp ) ; add_reg_note ( insn , REG_CFA_EXPRESSION , gen_rtx_SET ( mem , reg ) ) ; } else if ( base != m -> fs . cfa_reg ) { addr = plus_constant ( Pmode , m -> fs . cfa_reg , m -> fs . cfa_offset - cfa_offset ) ; mem = gen_rtx_MEM ( mode , addr ) ; add_reg_note ( insn , REG_CFA_OFFSET , gen_rtx_SET ( mem , reg ) ) ; } } </s>

Emit a single register save at CFA - CFA_OFFSET .


<s> bool Thumb2InstrInfo :: isLegalToSplitMBBAt ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI ) const { while ( MBBI -> isDebugValue ( ) ) { ++ MBBI ; if ( MBBI == MBB . end ( ) ) return false ; } unsigned PredReg = 0 ; return getITInstrPredicate ( MBBI , PredReg ) == ARMCC :: AL ; } </s>

Return true if it 's legal to split the given basic block at the specified instruction ( i.e .


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
Mips
::
NumTargetFixupKinds
]
=
{
{
"fixup_Mips_16"
,
0
,
16
,
0
}
,
{
"fixup_Mips_32"
,
0
,
32
,
0
}
,
{
"fixup_Mips_REL32"
,
0
,
32
,
0
}
,
{
"fixup_Mips_26"
,
0
,
26
,
0
}
,
{
"fixup_Mips_HI16"
,
0
,
16
,
0
}
,
{
"fixup_Mips_LO16"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GPREL16"
,
0
,
16
,
0
}
,
{
"fixup_Mips_LITERAL"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GOT_Global"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GOT_Local"
,
0
,
16
,
0
}
,
{
"fixup_Mips_PC16"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_Mips_CALL16"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GPREL32"
,
0
,
32
,
0
}
,
{
"fixup_Mips_SHIFT5"
,
6
,
5
,
0
}
,
{
"fixup_Mips_SHIFT6"
,
6
,
5
,
0
}
,
{
"fixup_Mips_64"
,
0
,
64
,
0
}
,
{
"fixup_Mips_TLSGD"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GOTTPREL"
,
0
,
16
,
0
}
,
{
"fixup_Mips_TPREL_HI"
,
0
,
16
,
0
}
,
{
"fixup_Mips_TPREL_LO"
,
0
,
16
,
0
}
,
{
"fixup_Mips_TLSLDM"
,
0
,
16
,
0
}
,
{
"fixup_Mips_DTPREL_HI"
,
0
,
16
,
0
}
,
{
"fixup_Mips_DTPREL_LO"
,
0
,
16
,
0
}
,
{
"fixup_Mips_Branch_PCRel"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_Mips_GPOFF_HI"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GPOFF_LO"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GOT_PAGE"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GOT_OFST"
,
0
,
16
,
0
}
,
{
"fixup_Mips_GOT_DISP"
,
0
,
16
,
0
}
,
{
"fixup_Mips_HIGHER"
,
0
,
16
,
0
}
,
{
"fixup_Mips_HIGHEST"
,
0
,
16
,
0
}
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s>
const
char
*
pa_output_parallel_addb
(
rtx
*
operands
,
rtx_insn
*
insn
)
{
int
length
=
get_attr_length
(
insn
)
;
if
(
operands
[
0
]
==
operands
[
1
]
)
operands
[
1
]
=
operands
[
2
]
;
if
(
length
==
4
)
return
"add%I1b,tr %1,%0,%3"
;
if
(
length
==
8
)
{
if
(
dbr_sequence_length
(
)
==
0
)
return
"b %3\n\tadd%I1 %1,%0,%0"
;
else
return
"add%I1 %1,%0,%0\n\tb %3"
;
}
output_asm_insn
(
"add%I1 %1,%0,%0"
,
operands
)
;
return
pa_output_lbranch
(
operands
[
3
]
,
insn
,
1
)
;
}
</s>

Output an unconditional add and branch insn .


<s> rtx rs6000_emit_eqne ( machine_mode mode , rtx op1 , rtx op2 , rtx scratch ) { if ( op2 == const0_rtx ) return op1 ; if ( GET_CODE ( scratch ) == SCRATCH ) scratch = gen_reg_rtx ( mode ) ; if ( logical_operand ( op2 , mode ) ) emit_insn ( gen_rtx_SET ( VOIDmode , scratch , gen_rtx_XOR ( mode , op1 , op2 ) ) ) ; else emit_insn ( gen_rtx_SET ( VOIDmode , scratch , gen_rtx_PLUS ( mode , op1 , negate_rtx ( mode , op2 ) ) ) ) ; return scratch ; } </s>

Emit RTL that sets a register to zero if OP1 and OP2 are equal . SCRATCH can be used as that dest register . Return the dest register .


<s>
int
scalar_chain
::
convert
(
)
{
bitmap_iterator
bi
;
unsigned
id
;
int
converted_insns
=
0
;
if
(
!
dbg_cnt
(
stv_conversion
)
)
return
0
;
if
(
dump_file
)
fprintf
(
dump_file
,
"Converting chain #%d...\n"
,
chain_id
)
;
convert_registers
(
)
;
EXECUTE_IF_SET_IN_BITMAP
(
insns
,
0
,
id
,
bi
)
{
convert_insn
(
DF_INSN_UID_GET
(
id
)
->
insn
)
;
converted_insns
++
;
}
return
converted_insns
;
}
</s>

Convert whole chain creating required register conversions and copies .


<s> int arm_max_const_double_inline_cost ( ) { if ( arm_disable_literal_pool ) return 99 ; return ( ( optimize_size || arm_ld_sched ) ? 3 : 4 ) ; } </s>

Return maximum allowed cost of synthesizing a 64-bit constant VAL inline . Returns the number of insns needed , or 99 if we always want to synthesize the value .


<s> const TargetRegisterClass * Thumb1RegisterInfo :: getLargestLegalSuperClass ( const TargetRegisterClass * RC ) const { if ( ARM :: tGPRRegClass . hasSubClassEq ( RC ) ) return & ARM :: tGPRRegClass ; return ARMBaseRegisterInfo :: getLargestLegalSuperClass ( RC ) ; } </s>

Returns the largest super class of RC that is legal to use in the current sub-target and has the same spill size .

ARM ARM::tGPRRegClass ARM::tGPRRegClass ARM


<s> bool SystemZLongBranch :: runOnMachineFunction ( MachineFunction & F ) { TII = static_cast < const SystemZInstrInfo * > ( F . getSubtarget ( ) . getInstrInfo ( ) ) ; MF = & F ; uint64_t Size = initMBBInfo ( ) ; if ( Size <= MaxForwardRange || ! mustRelaxABranch ( ) ) return false ; setWorstCaseAddresses ( ) ; relaxBranches ( ) ; return true ; } </s>

runOnMachineFunction - Emit the function body .


"stack frame not a multiple of octabyte: %wd"

Expands the function epilogue into RTX .


<s> inline void count_registers ( const_tree field , HOST_WIDE_INT bitpos , bool fp , assign_data_t * data ) { if ( fp ) { int nregs ; machine_mode mode ; if ( compute_int_layout ( bitpos , data , & nregs ) ) data -> nregs += nregs ; if ( compute_fp_layout ( field , bitpos , data , & nregs , & mode ) ) data -> nregs += nregs ; } else { if ( data -> intoffset < 0 ) data -> intoffset = bitpos ; } } </s>

A subroutine of function_arg_record_value . Count the number of registers to be assigned for FIELD and between PARMS- > intoffset and BITPOS .


<s> static void ix86_emit_save_regs ( void ) { unsigned int regno ; rtx insn ; for ( regno = FIRST_PSEUDO_REGISTER - 1 ; regno -- > 0 ; ) if ( ! SSE_REGNO_P ( regno ) && ix86_save_reg ( regno , true ) ) { insn = emit_insn ( gen_push ( gen_rtx_REG ( word_mode , regno ) ) ) ; RTX_FRAME_RELATED_P ( insn ) = 1 ; } } </s>

Emit code to save registers in the prologue .


<s> std :: pair < SDValue , SDValue > SystemZSelectionDAGInfo :: EmitTargetCodeForMemchr ( SelectionDAG & DAG , SDLoc DL , SDValue Chain , SDValue Src , SDValue Char , SDValue Length , MachinePointerInfo SrcPtrInfo ) const { EVT PtrVT = Src . getValueType ( ) ; SDVTList VTs = DAG . getVTList ( PtrVT , MVT :: Other , MVT :: Glue ) ; Length = DAG . getZExtOrTrunc ( Length , DL , PtrVT ) ; Char = DAG . getZExtOrTrunc ( Char , DL , MVT :: i32 ) ; Char = DAG . getNode ( ISD :: AND , DL , MVT :: i32 , Char , DAG . getConstant ( 255 , MVT :: i32 ) ) ; SDValue Limit = DAG . getNode ( ISD :: ADD , DL , PtrVT , Src , Length ) ; SDValue End = DAG . getNode ( SystemZISD :: SEARCH_STRING , DL , VTs , Chain , Limit , Src , Char ) ; Chain = End . getValue ( 1 ) ; SDValue Glue = End . getValue ( 2 ) ; SmallVector < SDValue , 5 > Ops ; Ops . push_back ( End ) ; Ops . push_back ( DAG . getConstant ( 0 , PtrVT ) ) ; Ops . push_back ( DAG . getConstant ( SystemZ :: CCMASK_SRST , MVT :: i32 ) ) ; Ops . push_back ( DAG . getConstant ( SystemZ :: CCMASK_SRST_FOUND , MVT :: i32 ) ) ; Ops . push_back ( Glue ) ; VTs = DAG . getVTList ( PtrVT , MVT :: Glue ) ; End = DAG . getNode ( SystemZISD :: SELECT_CCMASK , DL , VTs , & Ops [ 0 ] , Ops . size ( ) ) ; return std :: make_pair ( End , Chain ) ; } </s>

Emit target-specific code that performs a memchr , in cases where that is faster than a libcall .


Return TRUE if the type , as described by TYPE and MODE , is a short vector type as described in AAPCS64 \S 4.1.2 . See the comment above aarch64_composite_type_p for the notes on MODE .


<s> std :: pair < unsigned , const TargetRegisterClass * > MipsTargetLowering :: getRegForInlineAsmConstraint ( const std :: string & Constraint , MVT VT ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { case 'r' : return std :: make_pair ( 0U , Mips :: CPURegsRegisterClass ) ; case 'f' : if ( VT == MVT :: f32 ) return std :: make_pair ( 0U , Mips :: FGR32RegisterClass ) ; if ( VT == MVT :: f64 ) if ( ( ! Subtarget -> isSingleFloat ( ) ) && ( ! Subtarget -> isFP64bit ( ) ) ) return std :: make_pair ( 0U , Mips :: AFGR64RegisterClass ) ; } } return TargetLowering :: getRegForInlineAsmConstraint ( Constraint , VT ) ; } </s>

Given a physical register constraint ( e.g .


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

Returns true if the target requires ( and can make use of ) the register scavenger .


<s> static enum machine_mode hfa_element_mode ( tree type , bool nested ) { enum machine_mode element_mode = VOIDmode ; enum machine_mode mode ; enum tree_code code = TREE_CODE ( type ) ; int know_element_mode = 0 ; tree t ; if ( ! nested && ( ! TYPE_SIZE ( type ) || integer_zerop ( TYPE_SIZE ( type ) ) ) ) return VOIDmode ; switch ( code ) { case VOID_TYPE : case INTEGER_TYPE : case ENUMERAL_TYPE : case BOOLEAN_TYPE : case CHAR_TYPE : case POINTER_TYPE : case OFFSET_TYPE : case REFERENCE_TYPE : case METHOD_TYPE : case LANG_TYPE : case FUNCTION_TYPE : return VOIDmode ; case COMPLEX_TYPE : if ( GET_MODE_CLASS ( TYPE_MODE ( type ) ) == MODE_COMPLEX_FLOAT && TYPE_MODE ( type ) != TCmode ) return GET_MODE_INNER ( TYPE_MODE ( type ) ) ; else return VOIDmode ; case REAL_TYPE : if ( nested && TYPE_MODE ( type ) != TFmode ) return TYPE_MODE ( type ) ; else return VOIDmode ; case ARRAY_TYPE : return hfa_element_mode ( TREE_TYPE ( type ) , 1 ) ; case RECORD_TYPE : case UNION_TYPE : case QUAL_UNION_TYPE : for ( t = TYPE_FIELDS ( type ) ; t ; t = TREE_CHAIN ( t ) ) { if ( TREE_CODE ( t ) != FIELD_DECL ) continue ; mode = hfa_element_mode ( TREE_TYPE ( t ) , 1 ) ; if ( know_element_mode ) { if ( mode != element_mode ) return VOIDmode ; } else if ( GET_MODE_CLASS ( mode ) != MODE_FLOAT ) return VOIDmode ; else { know_element_mode = 1 ; element_mode = mode ; } } return element_mode ; default : return VOIDmode ; } return VOIDmode ; } </s>

Check whether TYPE is a homogeneous floating point aggregate . If it is , return the mode of the floating point type that appears in all leafs . If it is not , return VOIDmode . An aggregate is a homogeneous floating point aggregate is if all fields/elements in it have the same floating point type ( e.g , SFmode ) . 128-bit quad-precision floats are excluded .


<s>
static
MCSymbol
*
GetSymbolFromOperand
(
const
MachineOperand
&
MO
,
AsmPrinter
&
AP
)
{
MCContext
&
Ctx
=
AP
.
OutContext
;
SmallString
<
128
>
Name
;
if
(
!
MO
.
isGlobal
(
)
)
{
assert
(
MO
.
isSymbol
(
)
&&
"Isn't a symbol reference"
)
;
Name
+=
AP
.
MAI
->
getGlobalPrefix
(
)
;
Name
+=
MO
.
getSymbolName
(
)
;
}
else
{
const
GlobalValue
*
GV
=
MO
.
getGlobal
(
)
;
bool
isImplicitlyPrivate
=
false
;
if
(
MO
.
getTargetFlags
(
)
==
PPCII
::
MO_DARWIN_STUB
||
(
MO
.
getTargetFlags
(
)
&
PPCII
::
MO_NLP_FLAG
)
)
isImplicitlyPrivate
=
true
;
AP
.
Mang
->
getNameWithPrefix
(
Name
,
GV
,
isImplicitlyPrivate
)
;
}
if
(
MO
.
getTargetFlags
(
)
==
PPCII
::
MO_DARWIN_STUB
)
{
Name
+=
"$stub"
;
const
char
*
PGP
=
AP
.
MAI
->
getPrivateGlobalPrefix
(
)
;
const
char
*
Prefix
=
""
;
if
(
!
Name
.
startswith
(
PGP
)
)
{
Prefix
=
PGP
;
}
MCSymbol
*
Sym
=
Ctx
.
GetOrCreateSymbol
(
Twine
(
Prefix
)
+
Twine
(
Name
)
)
;
MachineModuleInfoImpl
::
StubValueTy
&
StubSym
=
getMachOMMI
(
AP
)
.
getFnStubEntry
(
Sym
)
;
if
(
StubSym
.
getPointer
(
)
)
return
Sym
;
if
(
MO
.
isGlobal
(
)
)
{
StubSym
=
MachineModuleInfoImpl
::
StubValueTy
(
AP
.
Mang
->
getSymbol
(
MO
.
getGlobal
(
)
)
,
!
MO
.
getGlobal
(
)
->
hasInternalLinkage
(
)
)
;
}
else
{
Name
.
erase
(
Name
.
end
(
)
5
,
Name
.
end
(
)
)
;
StubSym
=
MachineModuleInfoImpl
::
StubValueTy
(
Ctx
.
GetOrCreateSymbol
(
Name
.
str
(
)
)
,
false
)
;
}
return
Sym
;
}
if
(
MO
.
getTargetFlags
(
)
&
PPCII
::
MO_NLP_FLAG
)
{
Name
+=
"$non_lazy_ptr"
;
MCSymbol
*
Sym
=
Ctx
.
GetOrCreateSymbol
(
Name
.
str
(
)
)
;
MachineModuleInfoMachO
&
MachO
=
getMachOMMI
(
AP
)
;
MachineModuleInfoImpl
::
StubValueTy
&
StubSym
=
(
MO
.
getTargetFlags
(
)
&
PPCII
::
MO_NLP_HIDDEN_FLAG
)
MachO
.
getHiddenGVStubEntry
(
Sym
)
:
MachO
.
getGVStubEntry
(
Sym
)
;
if
(
StubSym
.
getPointer
(
)
==
0
)
{
assert
(
MO
.
isGlobal
(
)
&&
"Extern symbol not handled yet"
)
;
StubSym
=
MachineModuleInfoImpl
::
StubValueTy
(
AP
.
Mang
->
getSymbol
(
MO
.
getGlobal
(
)
)
,
!
MO
.
getGlobal
(
)
->
hasInternalLinkage
(
)
)
;
}
return
Sym
;
}
return
Ctx
.
GetOrCreateSymbol
(
Name
.
str
(
)
)
;
}
</s>

Lower an MO_GlobalAddress or MO_ExternalSymbol operand to an MCSymbol .


<s>
SDValue
SystemZTargetLowering
::
LowerReturn
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
IsVarArg
,
const
SmallVectorImpl
<
ISD
::
OutputArg
>
&
Outs
,
const
SmallVectorImpl
<
SDValue
>
&
OutVals
,
SDLoc
DL
,
SelectionDAG
&
DAG
)
const
{
MachineFunction
&
MF
=
DAG
.
getMachineFunction
(
)
;
SmallVector
<
CCValAssign
,
16
>
RetLocs
;
CCState
RetCCInfo
(
CallConv
,
IsVarArg
,
MF
,
TM
,
RetLocs
,
*
DAG
.
getContext
(
)
)
;
RetCCInfo
.
AnalyzeReturn
(
Outs
,
RetCC_SystemZ
)
;
if
(
RetLocs
.
empty
(
)
)
return
DAG
.
getNode
(
SystemZISD
::
RET_FLAG
,
DL
,
MVT
::
Other
,
Chain
)
;
SDValue
Glue
;
SmallVector
<
SDValue
,
4
>
RetOps
;
RetOps
.
push_back
(
Chain
)
;
for
(
unsigned
I
=
0
,
E
=
RetLocs
.
size
(
)
;
I
!=
E
;
++
I
)
{
CCValAssign
&
VA
=
RetLocs
[
I
]
;
SDValue
RetValue
=
OutVals
[
I
]
;
assert
(
VA
.
isRegLoc
(
)
&&
"Can only return in registers!"
)
;
RetValue
=
convertValVTToLocVT
(
DAG
,
DL
,
VA
,
RetValue
)
;
unsigned
Reg
=
VA
.
getLocReg
(
)
;
Chain
=
DAG
.
getCopyToReg
(
Chain
,
DL
,
Reg
,
RetValue
,
Glue
)
;
Glue
=
Chain
.
getValue
(
1
)
;
RetOps
.
push_back
(
DAG
.
getRegister
(
Reg
,
VA
.
getLocVT
(
)
)
)
;
}
RetOps
[
0
]
=
Chain
;
if
(
Glue
.
getNode
(
)
)
RetOps
.
push_back
(
Glue
)
;
return
DAG
.
getNode
(
SystemZISD
::
RET_FLAG
,
DL
,
MVT
::
Other
,
RetOps
.
data
(
)
,
RetOps
.
size
(
)
)
;
}
</s>

This hook must be implemented to lower outgoing return values , described by the Outs array , into the specified DAG .


<s> bool ARMBaseInstrInfo :: areLoadsFromSameBasePtr ( SDNode * Load1 , SDNode * Load2 , int64_t & Offset1 , int64_t & Offset2 ) const { if ( Subtarget . isThumb1Only ( ) ) return false ; if ( ! Load1 -> isMachineOpcode ( ) || ! Load2 -> isMachineOpcode ( ) ) return false ; switch ( Load1 -> getMachineOpcode ( ) ) { default : return false ; case ARM :: LDR : case ARM :: LDRB : case ARM :: LDRD : case ARM :: LDRH : case ARM :: LDRSB : case ARM :: LDRSH : case ARM :: VLDRD : case ARM :: VLDRS : case ARM :: t2LDRi8 : case ARM :: t2LDRDi8 : case ARM :: t2LDRSHi8 : case ARM :: t2LDRi12 : case ARM :: t2LDRSHi12 : break ; } switch ( Load2 -> getMachineOpcode ( ) ) { default : return false ; case ARM :: LDR : case ARM :: LDRB : case ARM :: LDRD : case ARM :: LDRH : case ARM :: LDRSB : case ARM :: LDRSH : case ARM :: VLDRD : case ARM :: VLDRS : case ARM :: t2LDRi8 : case ARM :: t2LDRDi8 : case ARM :: t2LDRSHi8 : case ARM :: t2LDRi12 : case ARM :: t2LDRSHi12 : break ; } if ( Load1 -> getOperand ( 0 ) != Load2 -> getOperand ( 0 ) || Load1 -> getOperand ( 4 ) != Load2 -> getOperand ( 4 ) ) return false ; if ( Load1 -> getOperand ( 3 ) != Load2 -> getOperand ( 3 ) ) return false ; if ( isa < ConstantSDNode > ( Load1 -> getOperand ( 1 ) ) && isa < ConstantSDNode > ( Load2 -> getOperand ( 1 ) ) ) { Offset1 = cast < ConstantSDNode > ( Load1 -> getOperand ( 1 ) ) -> getSExtValue ( ) ; Offset2 = cast < ConstantSDNode > ( Load2 -> getOperand ( 1 ) ) -> getSExtValue ( ) ; return true ; } return false ; } </s>

areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to determine if two loads are loading from the same base address .


<s> static void mips_output_mi_thunk ( FILE * file , tree thunk_fndecl ATTRIBUTE_UNUSED , HOST_WIDE_INT delta , HOST_WIDE_INT vcall_offset , tree function ) { rtx this_rtx , temp1 , temp2 , fnaddr ; rtx_insn * insn ; bool use_sibcall_p ; reload_completed = 1 ; emit_note ( NOTE_INSN_PROLOGUE_END ) ; fnaddr = XEXP ( DECL_RTL ( function ) , 0 ) ; use_sibcall_p = ( mips_function_ok_for_sibcall ( function , NULL ) && const_call_insn_operand ( fnaddr , Pmode ) ) ; if ( ! use_sibcall_p && ( mips_got_symbol_type_p ( mips_classify_symbol ( fnaddr , SYMBOL_CONTEXT_LEA ) ) ) ) { cfun -> machine -> global_pointer = TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM ; cfun -> machine -> must_initialize_gp_p = true ; SET_REGNO ( pic_offset_table_rtx , cfun -> machine -> global_pointer ) ; mips_emit_loadgp ( ) ; } temp1 = gen_rtx_REG ( Pmode , 2 ) ; temp2 = gen_rtx_REG ( Pmode , 3 ) ; if ( aggregate_value_p ( TREE_TYPE ( TREE_TYPE ( function ) ) , function ) ) this_rtx = gen_rtx_REG ( Pmode , GP_ARG_FIRST + 1 ) ; else this_rtx = gen_rtx_REG ( Pmode , GP_ARG_FIRST ) ; if ( delta != 0 ) { rtx offset = GEN_INT ( delta ) ; if ( ! SMALL_OPERAND ( delta ) ) { mips_emit_move ( temp1 , offset ) ; offset = temp1 ; } emit_insn ( gen_add3_insn ( this_rtx , this_rtx , offset ) ) ; } if ( vcall_offset != 0 ) { rtx addr ; mips_emit_move ( temp1 , gen_rtx_MEM ( Pmode , this_rtx ) ) ; addr = mips_add_offset ( temp2 , temp1 , vcall_offset ) ; mips_emit_move ( temp1 , gen_rtx_MEM ( Pmode , addr ) ) ; emit_insn ( gen_add3_insn ( this_rtx , this_rtx , temp1 ) ) ; } if ( use_sibcall_p ) { insn = emit_call_insn ( gen_sibcall_internal ( fnaddr , const0_rtx ) ) ; SIBLING_CALL_P ( insn ) = 1 ; } else { if ( TARGET_USE_PIC_FN_ADDR_REG && ! TARGET_MIPS16 && ! mips_dangerous_for_la25_p ( fnaddr ) ) temp1 = gen_rtx_REG ( Pmode , PIC_FUNCTION_ADDR_REGNUM ) ; mips_load_call_address ( MIPS_CALL_SIBCALL , temp1 , fnaddr ) ; if ( TARGET_USE_PIC_FN_ADDR_REG && REGNO ( temp1 ) != PIC_FUNCTION_ADDR_REGNUM ) mips_emit_move ( gen_rtx_REG ( Pmode , PIC_FUNCTION_ADDR_REGNUM ) , temp1 ) ; emit_jump_insn ( gen_indirect_jump ( temp1 ) ) ; } insn = get_insns ( ) ; split_all_insns_noflow ( ) ; mips16_lay_out_constants ( true ) ; shorten_branches ( insn ) ; final_start_function ( insn , file , 1 ) ; final ( insn , file , 1 ) ; final_end_function ( ) ; reload_completed = 0 ; } </s>

Implement TARGET_ASM_OUTPUT_MI_THUNK . Generate rtl rather than asm text in order to avoid duplicating too much logic from elsewhere .


<s> bool LanaiAsmParser :: ParseDirective ( AsmToken ) { return true ; } </s>

ParseDirective - Parse a target specific assembler directive This method is deprecated , use 'parseDirective ' instead .


<s>
void
LanaiDAGToDAGISel
::
Select
(
SDNode
*
Node
)
{
unsigned
Opcode
=
Node
->
getOpcode
(
)
;
DEBUG
(
errs
(
)
<<
"Selecting: "
;
Node
->
dump
(
CurDAG
)
;
errs
(
)
<<
"\n"
)
;
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> static void emitSPUpdate ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , int64_t NumBytes , const TargetInstrInfo & TII ) { unsigned Opc ; uint64_t Chunk ; bool isSub = NumBytes < 0 ; uint64_t Offset = isSub ? - NumBytes : NumBytes ; if ( Offset >= ( 1LL << 15 ) - 1 ) { Opc = SystemZ :: ADD64ri32 ; Chunk = ( 1LL << 31 ) - 1 ; } else { Opc = SystemZ :: ADD64ri16 ; Chunk = ( 1LL << 15 ) - 1 ; } DebugLoc DL = ( MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc :: getUnknownLoc ( ) ) ; while ( Offset ) { uint64_t ThisVal = ( Offset > Chunk ) ? Chunk : Offset ; MachineInstr * MI = BuildMI ( MBB , MBBI , DL , TII . get ( Opc ) , SystemZ :: R15D ) . addReg ( SystemZ :: R15D ) . addImm ( ( isSub ? - ( int64_t ) ThisVal : ThisVal ) ) ; MI -> getOperand ( 3 ) . setIsDead ( ) ; Offset -= ThisVal ; } } </s>

Emit a series of instructions to increment / decrement the stack pointer by a constant value .


<s>
MachineBasicBlock
::
iterator
ARMBaseInstrInfo
::
insertOutlinedCall
(
Module
&
M
,
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
&
It
,
MachineFunction
&
MF
,
const
outliner
::
Candidate
&
C
)
const
{
MachineInstrBuilder
MIB
;
MachineBasicBlock
::
iterator
CallPt
;
unsigned
Opc
;
bool
isThumb
=
Subtarget
.
isThumb
(
)
;
if
(
C
.
CallConstructionID
==
MachineOutlinerTailCall
)
{
Opc
=
isThumb
Subtarget
.
isTargetMachO
(
)
ARM
::
tTAILJMPd
:
ARM
::
tTAILJMPdND
:
ARM
::
TAILJMPd
;
MIB
=
BuildMI
(
MF
,
DebugLoc
(
)
,
get
(
Opc
)
)
.
addGlobalAddress
(
M
.
getNamedValue
(
MF
.
getName
(
)
)
)
;
if
(
isThumb
)
MIB
.
add
(
predOps
(
ARMCC
::
AL
)
)
;
It
=
MBB
.
insert
(
It
,
MIB
)
;
return
It
;
}
Opc
=
isThumb
ARM
::
tBL
:
ARM
::
BL
;
MachineInstrBuilder
CallMIB
=
BuildMI
(
MF
,
DebugLoc
(
)
,
get
(
Opc
)
)
;
if
(
isThumb
)
CallMIB
.
add
(
predOps
(
ARMCC
::
AL
)
)
;
CallMIB
.
addGlobalAddress
(
M
.
getNamedValue
(
MF
.
getName
(
)
)
)
;
if
(
C
.
CallConstructionID
==
MachineOutlinerNoLRSave
||
C
.
CallConstructionID
==
MachineOutlinerThunk
)
{
It
=
MBB
.
insert
(
It
,
CallMIB
)
;
return
It
;
}
const
ARMFunctionInfo
&
AFI
=
*
C
.
getMF
(
)
->
getInfo
<
ARMFunctionInfo
>
(
)
;
if
(
C
.
CallConstructionID
==
MachineOutlinerRegSave
)
{
unsigned
Reg
=
findRegisterToSaveLRTo
(
C
)
;
assert
(
Reg
!=
0
&&
"No callee-saved register available?"
)
;
copyPhysReg
(
MBB
,
It
,
DebugLoc
(
)
,
Reg
,
ARM
::
LR
,
true
)
;
if
(
!
AFI
.
isLRSpilled
(
)
)
emitCFIForLRSaveToReg
(
MBB
,
It
,
Reg
)
;
CallPt
=
MBB
.
insert
(
It
,
CallMIB
)
;
copyPhysReg
(
MBB
,
It
,
DebugLoc
(
)
,
ARM
::
LR
,
Reg
,
true
)
;
if
(
!
AFI
.
isLRSpilled
(
)
)
emitCFIForLRRestoreFromReg
(
MBB
,
It
)
;
It
;
return
CallPt
;
}
saveLROnStack
(
MBB
,
It
)
;
if
(
!
AFI
.
isLRSpilled
(
)
)
emitCFIForLRSaveOnStack
(
MBB
,
It
)
;
CallPt
=
MBB
.
insert
(
It
,
CallMIB
)
;
restoreLRFromStack
(
MBB
,
It
)
;
if
(
!
AFI
.
isLRSpilled
(
)
)
emitCFIForLRRestoreFromStack
(
MBB
,
It
)
;
It
;
return
CallPt
;
}
</s>

Insert a call to an outlined function into the program .

ARM
ARM
ARM::tTAILJMPd
ARM::tTAILJMPdND
ARM::TAILJMPd
ARMCC::AL
ARM::tBL
ARM::BL
ARMCC::AL
ARM
ARM
0
"No callee-saved register available?"
ARM::LR
ARM::LR


<s> bool LanaiPassConfig :: addInstSelector ( ) { addPass ( createLanaiISelDag ( getLanaiTargetMachine ( ) ) ) ; return false ; } </s>

addInstSelector - This method should install an instruction selector pass , which converts from LLVM code to machine instructions .


<s> BitVector PPCRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; const TargetFrameInfo * TFI = MF . getTarget ( ) . getFrameInfo ( ) ; Reserved . set ( PPC :: R0 ) ; Reserved . set ( PPC :: R1 ) ; Reserved . set ( PPC :: LR ) ; Reserved . set ( PPC :: LR8 ) ; Reserved . set ( PPC :: RM ) ; if ( Subtarget . isSVR4ABI ( ) ) { Reserved . set ( PPC :: R2 ) ; Reserved . set ( PPC :: R13 ) ; } if ( Subtarget . isDarwinABI ( ) ) { Reserved . set ( PPC :: R2 ) ; } if ( Subtarget . isPPC64 ( ) ) { Reserved . set ( PPC :: R13 ) ; Reserved . set ( PPC :: R31 ) ; if ( ! requiresRegisterScavenging ( MF ) ) Reserved . set ( PPC :: R0 ) ; Reserved . set ( PPC :: X0 ) ; Reserved . set ( PPC :: X1 ) ; Reserved . set ( PPC :: X13 ) ; Reserved . set ( PPC :: X31 ) ; if ( Subtarget . isSVR4ABI ( ) ) { Reserved . set ( PPC :: X2 ) ; } if ( Subtarget . isDarwinABI ( ) ) { Reserved . set ( PPC :: X2 ) ; } } if ( TFI -> hasFP ( MF ) ) Reserved . set ( PPC :: R31 ) ; 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> MachineInstrBuilder buildLoad ( const DstOp & Res , Register Addr , uint64_t Size , MachinePointerInfo & MPO ) { MachineFunction & MF = MIRBuilder . getMF ( ) ; auto MMO = MF . getMachineMemOperand ( MPO , MachineMemOperand :: MOLoad , Size , inferAlignFromPtrInfo ( MF , MPO ) ) ; return MIRBuilder . buildLoad ( Res , Addr , * MMO ) ; } </s>

Build and insert a G_LOAD instruction , while constructing the MachineMemOperand .


"MMIX Internal: This is not a constant:"

Return the bit-value for a const_int or const_double .


<s> static bool rs6000_vector_mode_supported_p ( machine_mode mode ) { if ( TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE ( mode ) ) return true ; else if ( VECTOR_MEM_ALTIVEC_OR_VSX_P ( mode ) && ! FLOAT128_IEEE_P ( mode ) ) return true ; else return false ; } </s>

Target hook for vector_mode_supported_p .


<s> void MipsSEFrameLowering :: emitEpilogue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { MachineBasicBlock :: iterator MBBI = MBB . getFirstTerminator ( ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; MipsFunctionInfo * MipsFI = MF . getInfo < MipsFunctionInfo > ( ) ; const MipsSEInstrInfo & TII = * static_cast < const MipsSEInstrInfo * > ( STI . getInstrInfo ( ) ) ; const MipsRegisterInfo & RegInfo = * static_cast < const MipsRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; DebugLoc DL = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; MipsABIInfo ABI = STI . getABI ( ) ; unsigned SP = ABI . GetStackPtr ( ) ; unsigned FP = ABI . GetFramePtr ( ) ; unsigned ZERO = ABI . GetNullPtr ( ) ; unsigned MOVE = ABI . GetGPRMoveOp ( ) ; if ( hasFP ( MF ) ) { MachineBasicBlock :: iterator I = MBBI ; for ( unsigned i = 0 ; i < MFI . getCalleeSavedInfo ( ) . size ( ) ; ++ i ) -- I ; BuildMI ( MBB , I , DL , TII . get ( MOVE ) , SP ) . addReg ( FP ) . addReg ( ZERO ) ; } if ( MipsFI -> callsEhReturn ( ) ) { const TargetRegisterClass * RC = ABI . ArePtrs64bit ( ) ? & Mips :: GPR64RegClass : & Mips :: GPR32RegClass ; MachineBasicBlock :: iterator I = MBBI ; for ( unsigned i = 0 ; i < MFI . getCalleeSavedInfo ( ) . size ( ) ; ++ i ) -- I ; for ( int J = 0 ; J < 4 ; ++ J ) { TII . loadRegFromStackSlot ( MBB , I , ABI . GetEhDataReg ( J ) , MipsFI -> getEhDataRegFI ( J ) , RC , & RegInfo ) ; } } if ( MF . getFunction ( ) . hasFnAttribute ( "interrupt" ) ) emitInterruptEpilogueStub ( MF , MBB ) ; uint64_t StackSize = MFI . getStackSize ( ) ; if ( ! StackSize ) return ; TII . adjustStackPtr ( SP , StackSize , MBB , MBBI ) ; } </s>

Mips Mips Mips Mips Mips Mips Mips Mips Mips Mips 0 Mips Mips::GPR64RegClass Mips::GPR32RegClass 0 0 4 Mips "interrupt"


<s> EVT AArch64TargetLowering :: getOptimalMemOpType ( const MemOp & Op , const AttributeList & FuncAttributes ) const { bool CanImplicitFloat = ! FuncAttributes . hasFnAttr ( Attribute :: NoImplicitFloat ) ; bool CanUseNEON = Subtarget -> hasNEON ( ) && CanImplicitFloat ; bool CanUseFP = Subtarget -> hasFPARMv8 ( ) && CanImplicitFloat ; bool IsSmallMemset = Op . isMemset ( ) && Op . size ( ) < 32 ; auto AlignmentIsAcceptable = [ & ] ( EVT VT , Align AlignCheck ) { if ( Op . isAligned ( AlignCheck ) ) return true ; bool Fast ; return allowsMisalignedMemoryAccesses ( VT , 0 , Align ( 1 ) , MachineMemOperand :: MONone , & Fast ) && Fast ; } ; if ( CanUseNEON && Op . isMemset ( ) && ! IsSmallMemset && AlignmentIsAcceptable ( MVT :: v16i8 , Align ( 16 ) ) ) return MVT :: v16i8 ; if ( CanUseFP && ! IsSmallMemset && AlignmentIsAcceptable ( MVT :: f128 , Align ( 16 ) ) ) return MVT :: f128 ; if ( Op . size ( ) >= 8 && AlignmentIsAcceptable ( MVT :: i64 , Align ( 8 ) ) ) return MVT :: i64 ; if ( Op . size ( ) >= 4 && AlignmentIsAcceptable ( MVT :: i32 , Align ( 4 ) ) ) return MVT :: i32 ; return MVT :: Other ; } </s>

It returns EVT : :Other if the type should be determined using generic target-independent logic .


<s> bool aarch64_legitimate_address_p ( machine_mode mode , rtx x , bool strict_p , aarch64_addr_query_type type ) { struct aarch64_address_info addr ; return aarch64_classify_address ( & addr , x , mode , strict_p , type ) ; } </s>

Return TRUE if X is a legitimate address for accessing memory in mode MODE . OUTER_CODE will be PARALLEL if this is a load/store pair operation .


<s> rtx extract_mac_non_acc_rtx ( rtx_insn * insn ) { rtx exp = SET_SRC ( PATTERN ( insn ) ) ; switch ( get_attr_type ( insn ) ) { case TYPE_MAC : if ( REG_P ( XEXP ( exp , 0 ) ) ) return XEXP ( exp , 1 ) ; else return XEXP ( exp , 0 ) ; default : gcc_unreachable ( ) ; } } </s>

Extract the rtx representing non-accumulation operands of a MAC insn .


<s> const uint32_t * PPCRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { const PPCSubtarget & Subtarget = MF . getSubtarget < PPCSubtarget > ( ) ; if ( CC == CallingConv :: AnyReg ) { if ( Subtarget . hasVSX ( ) ) { if ( Subtarget . pairedVectorMemops ( ) ) return CSR_64_AllRegs_VSRP_RegMask ; if ( Subtarget . isAIXABI ( ) && ! TM . getAIXExtendedAltivecABI ( ) ) return CSR_64_AllRegs_AIX_Dflt_VSX_RegMask ; return CSR_64_AllRegs_VSX_RegMask ; } if ( Subtarget . hasAltivec ( ) ) { if ( Subtarget . isAIXABI ( ) && ! TM . getAIXExtendedAltivecABI ( ) ) return CSR_64_AllRegs_AIX_Dflt_Altivec_RegMask ; return CSR_64_AllRegs_Altivec_RegMask ; } return CSR_64_AllRegs_RegMask ; } if ( Subtarget . isAIXABI ( ) ) { return TM . isPPC64 ( ) ? ( ( Subtarget . hasAltivec ( ) && TM . getAIXExtendedAltivecABI ( ) ) ? CSR_PPC64_Altivec_RegMask : CSR_PPC64_RegMask ) : ( ( Subtarget . hasAltivec ( ) && TM . getAIXExtendedAltivecABI ( ) ) ? CSR_AIX32_Altivec_RegMask : CSR_AIX32_RegMask ) ; } if ( CC == CallingConv :: Cold ) { if ( TM . isPPC64 ( ) ) return Subtarget . pairedVectorMemops ( ) ? CSR_SVR64_ColdCC_VSRP_RegMask : ( Subtarget . hasAltivec ( ) ? CSR_SVR64_ColdCC_Altivec_RegMask : CSR_SVR64_ColdCC_RegMask ) ; else return Subtarget . pairedVectorMemops ( ) ? CSR_SVR32_ColdCC_VSRP_RegMask : ( Subtarget . hasAltivec ( ) ? CSR_SVR32_ColdCC_Altivec_RegMask : ( Subtarget . hasSPE ( ) ? CSR_SVR32_ColdCC_SPE_RegMask : CSR_SVR32_ColdCC_RegMask ) ) ; } if ( TM . isPPC64 ( ) ) return Subtarget . pairedVectorMemops ( ) ? CSR_SVR464_VSRP_RegMask : ( Subtarget . hasAltivec ( ) ? CSR_PPC64_Altivec_RegMask : CSR_PPC64_RegMask ) ; else return Subtarget . pairedVectorMemops ( ) ? CSR_SVR432_VSRP_RegMask : ( Subtarget . hasAltivec ( ) ? CSR_SVR432_Altivec_RegMask : ( Subtarget . hasSPE ( ) ? CSR_SVR432_SPE_RegMask : CSR_SVR432_RegMask ) ) ; } </s>

Return a mask of call-preserved registers for the given calling convention on the current function .

PowerPC PPC PPC PPC PPC PPC PPC PPC PPC PPC PPC


<s> static void assign_fp_registers ( const_tree field , int bitpos , assign_data_t * data ) { int nregs ; machine_mode mode ; if ( ! compute_fp_layout ( field , bitpos , data , & nregs , & mode ) ) return ; const int this_slotno = data -> slotno + bitpos / BITS_PER_WORD ; int regno = SPARC_FP_ARG_FIRST + this_slotno * 2 ; if ( GET_MODE_SIZE ( mode ) <= 4 && ( bitpos & 32 ) != 0 ) regno ++ ; int pos = bitpos / BITS_PER_UNIT ; do { rtx reg = gen_rtx_REG ( mode , regno ) ; XVECEXP ( data -> ret , 0 , data -> stack + data -> nregs ) = gen_rtx_EXPR_LIST ( VOIDmode , reg , GEN_INT ( pos ) ) ; data -> nregs += 1 ; regno += GET_MODE_SIZE ( mode ) / 4 ; pos += GET_MODE_SIZE ( mode ) ; } while ( -- nregs > 0 ) ; } </s>

A subroutine of function_arg_record_value . Assign FIELD at position BITPOS to FP registers .


<s> TargetLoweringBase :: LegalizeTypeAction X86TargetLowering :: getPreferredVectorAction ( MVT VT ) const { if ( ( VT == MVT :: v32i1 || VT == MVT :: v64i1 ) && Subtarget . hasAVX512 ( ) && ! Subtarget . hasBWI ( ) ) return TypeSplitVector ; if ( ! VT . isScalableVector ( ) && VT . getVectorNumElements ( ) != 1 && VT . getVectorElementType ( ) != MVT :: i1 ) return TypeWidenVector ; return TargetLoweringBase :: getPreferredVectorAction ( VT ) ; } </s>

Customize the preferred legalization strategy for certain types .


<s> static unsigned int mips_autovectorize_vector_modes ( vector_modes * modes , bool ) { if ( ISA_HAS_MSA ) modes -> safe_push ( V16QImode ) ; return 0 ; } </s>


<s> static bool rs6000_discover_homogeneous_aggregate ( machine_mode mode , const_tree type , machine_mode * elt_mode , int * n_elts ) { if ( TARGET_HARD_FLOAT && DEFAULT_ABI == ABI_ELFv2 && type && AGGREGATE_TYPE_P ( type ) ) { machine_mode field_mode = VOIDmode ; int field_count = rs6000_aggregate_candidate ( type , & field_mode ) ; if ( field_count > 0 ) { int reg_size = ALTIVEC_OR_VSX_VECTOR_MODE ( field_mode ) ? 16 : 8 ; int field_size = ROUND_UP ( GET_MODE_SIZE ( field_mode ) , reg_size ) ; if ( field_count * field_size <= AGGR_ARG_NUM_REG * reg_size ) { if ( elt_mode ) * elt_mode = field_mode ; if ( n_elts ) * n_elts = field_count ; return true ; } } } if ( elt_mode ) * elt_mode = mode ; if ( n_elts ) * n_elts = 1 ; return false ; } </s>

If an argument , whose type is described by TYPE and MODE , is a homogeneous float or vector aggregate that shall be passed in FP/vector registers according to the ELFv2 ABI , return the homogeneous element mode in * ELT_MODE and the number of elements in * N_ELTS , and return TRUE . Otherwise , set * ELT_MODE to MODE and * N_ELTS to 1 , and return FALSE .


<s> static bool ix86_dep_by_shift_count_body ( const_rtx set_body , const_rtx use_body ) { rtx set_dest ; rtx shift_rtx ; int i ; switch ( GET_CODE ( set_body ) ) { case SET : set_dest = SET_DEST ( set_body ) ; if ( ! set_dest || ! REG_P ( set_dest ) ) return false ; break ; case PARALLEL : for ( i = XVECLEN ( set_body , 0 ) - 1 ; i >= 0 ; i -- ) if ( ix86_dep_by_shift_count_body ( XVECEXP ( set_body , 0 , i ) , use_body ) ) return true ; default : return false ; } switch ( GET_CODE ( use_body ) ) { case SET : shift_rtx = XEXP ( use_body , 1 ) ; break ; case PARALLEL : for ( i = XVECLEN ( use_body , 0 ) - 1 ; i >= 0 ; i -- ) if ( ix86_dep_by_shift_count_body ( set_body , XVECEXP ( use_body , 0 , i ) ) ) return true ; default : return false ; } if ( shift_rtx && ( GET_CODE ( shift_rtx ) == ASHIFT || GET_CODE ( shift_rtx ) == LSHIFTRT || GET_CODE ( shift_rtx ) == ASHIFTRT || GET_CODE ( shift_rtx ) == ROTATE || GET_CODE ( shift_rtx ) == ROTATERT ) ) { rtx shift_count = XEXP ( shift_rtx , 1 ) ; if ( REG_P ( shift_count ) ) { if ( reload_completed && true_regnum ( set_dest ) == true_regnum ( shift_count ) ) return true ; else if ( REGNO ( set_dest ) == REGNO ( shift_count ) ) return true ; } } return false ; } </s>

Return true if destination reg of SET_BODY is shift count of USE_BODY .


<s> static void store_reg ( int reg , HOST_WIDE_INT disp , int base ) { rtx dest , src , basereg ; rtx_insn * insn ; src = gen_rtx_REG ( word_mode , reg ) ; basereg = gen_rtx_REG ( Pmode , base ) ; if ( VAL_14_BITS_P ( disp ) ) { dest = gen_rtx_MEM ( word_mode , plus_constant ( Pmode , basereg , disp ) ) ; insn = emit_move_insn ( dest , src ) ; } else if ( TARGET_64BIT && ! VAL_32_BITS_P ( disp ) ) { rtx delta = GEN_INT ( disp ) ; rtx tmpreg = gen_rtx_REG ( Pmode , 1 ) ; emit_move_insn ( tmpreg , delta ) ; insn = emit_move_insn ( tmpreg , gen_rtx_PLUS ( Pmode , tmpreg , basereg ) ) ; if ( DO_FRAME_NOTES ) { add_reg_note ( insn , REG_FRAME_RELATED_EXPR , gen_rtx_SET ( tmpreg , gen_rtx_PLUS ( Pmode , basereg , delta ) ) ) ; RTX_FRAME_RELATED_P ( insn ) = 1 ; } dest = gen_rtx_MEM ( word_mode , tmpreg ) ; insn = emit_move_insn ( dest , src ) ; } else { rtx delta = GEN_INT ( disp ) ; rtx high = gen_rtx_PLUS ( Pmode , basereg , gen_rtx_HIGH ( Pmode , delta ) ) ; rtx tmpreg = gen_rtx_REG ( Pmode , 1 ) ; emit_move_insn ( tmpreg , high ) ; dest = gen_rtx_MEM ( word_mode , gen_rtx_LO_SUM ( Pmode , tmpreg , delta ) ) ; insn = emit_move_insn ( dest , src ) ; if ( DO_FRAME_NOTES ) add_reg_note ( insn , REG_FRAME_RELATED_EXPR , gen_rtx_SET ( gen_rtx_MEM ( word_mode , gen_rtx_PLUS ( word_mode , basereg , delta ) ) , src ) ) ; } if ( DO_FRAME_NOTES ) RTX_FRAME_RELATED_P ( insn ) = 1 ; } </s>

Emit RTL to store REG at the memory location specified by BASE+DISP . Handle case where DISP > 8k by using the add_high_const patterns . Note in DISP > 8k case , we will leave the high part of the address in % r1 . There is code in expand_hppa_ { prologue , epilogue } that knows this .


<s> unsigned ARMBaseInstrInfo :: getInstrLatency ( const InstrItineraryData * ItinData , const MachineInstr & MI , unsigned * PredCost ) const { if ( MI . isCopyLike ( ) || MI . isInsertSubreg ( ) || MI . isRegSequence ( ) || MI . isImplicitDef ( ) ) return 1 ; if ( MI . isBundle ( ) ) { unsigned Latency = 0 ; MachineBasicBlock :: const_instr_iterator I = MI . getIterator ( ) ; MachineBasicBlock :: const_instr_iterator E = MI . getParent ( ) -> instr_end ( ) ; while ( ++ I != E && I -> isInsideBundle ( ) ) { if ( I -> getOpcode ( ) != ARM :: t2IT ) Latency += getInstrLatency ( ItinData , * I , PredCost ) ; } return Latency ; } const MCInstrDesc & MCID = MI . getDesc ( ) ; if ( PredCost && ( MCID . isCall ( ) || ( MCID . hasImplicitDefOfPhysReg ( ARM :: CPSR ) && ! Subtarget . cheapPredicableCPSRDef ( ) ) ) ) { * PredCost = 1 ; } if ( ! ItinData ) return MI . mayLoad ( ) ? 3 : 1 ; unsigned Class = MCID . getSchedClass ( ) ; if ( ! ItinData -> isEmpty ( ) && ItinData -> getNumMicroOps ( Class ) < 0 ) return getNumMicroOps ( ItinData , MI ) ; unsigned Latency = ItinData -> getStageLatency ( Class ) ; unsigned DefAlign = MI . hasOneMemOperand ( ) ? ( * MI . memoperands_begin ( ) ) -> getAlignment ( ) : 0 ; int Adj = adjustDefLatency ( Subtarget , MI , MCID , DefAlign ) ; if ( Adj >= 0 || ( int ) Latency > - Adj ) { return Latency + Adj ; } return Latency ; } </s>

Compute the instruction latency of a given instruction .


<s> unsigned getNumberOfRegisters ( bool Vector ) const override { if ( Vector ) { if ( ST -> hasNEON ( ) ) return 32 ; return 0 ; } return 31 ; } </s>


<s> std :: pair < unsigned , const TargetRegisterClass * > ARMTargetLowering :: getRegForInlineAsmConstraint ( const std :: string & Constraint , EVT VT ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { case 'l' : if ( Subtarget -> isThumb ( ) ) return std :: make_pair ( 0U , ARM :: tGPRRegisterClass ) ; else return std :: make_pair ( 0U , ARM :: GPRRegisterClass ) ; case 'r' : return std :: make_pair ( 0U , ARM :: GPRRegisterClass ) ; case 'w' : if ( VT == MVT :: f32 ) return std :: make_pair ( 0U , ARM :: SPRRegisterClass ) ; if ( VT . getSizeInBits ( ) == 64 ) return std :: make_pair ( 0U , ARM :: DPRRegisterClass ) ; if ( VT . getSizeInBits ( ) == 128 ) return std :: make_pair ( 0U , ARM :: QPRRegisterClass ) ; break ; } } return TargetLowering :: getRegForInlineAsmConstraint ( Constraint , VT ) ; } </s>

Given a physical register constraint ( e.g .