<s> static void arm_init_neon_builtins ( void ) { unsigned int i , fcode = ARM_BUILTIN_NEON_PATTERN_START ; arm_init_simd_builtin_types ( ) ; arm_init_simd_builtin_scalar_types ( ) ; tree lane_check_fpr = build_function_type_list ( void_type_node , intSI_type_node , intSI_type_node , NULL ) ; arm_builtin_decls [ ARM_BUILTIN_NEON_LANE_CHECK ] = add_builtin_function ( "__builtin_arm_lane_check" , lane_check_fpr , ARM_BUILTIN_NEON_LANE_CHECK , BUILT_IN_MD , NULL , NULL_TREE ) ; for ( i = 0 ; i < ARRAY_SIZE ( neon_builtin_data ) ; i ++ , fcode ++ ) { bool print_type_signature_p = false ; char type_signature [ SIMD_MAX_BUILTIN_ARGS ] = { 0 } ; neon_builtin_datum * d = & neon_builtin_data [ i ] ; char namebuf [ 60 ] ; tree ftype = NULL ; tree fndecl = NULL ; d -> fcode = fcode ; int op_num = insn_data [ d -> code ] . n_operands - 1 ; int arg_num = d -> qualifiers [ 0 ] & qualifier_void ? op_num + 1 : op_num ; tree return_type = void_type_node , args = void_list_node ; tree eltype ; for ( ; op_num >= 0 ; arg_num -- , op_num -- ) { machine_mode op_mode = insn_data [ d -> code ] . operand [ op_num ] . mode ; enum arm_type_qualifiers qualifiers = d -> qualifiers [ arg_num ] ; if ( qualifiers & qualifier_unsigned ) { type_signature [ arg_num ] = 'u' ; print_type_signature_p = true ; } else if ( qualifiers & qualifier_poly ) { type_signature [ arg_num ] = 'p' ; print_type_signature_p = true ; } else type_signature [ arg_num ] = 's' ; if ( qualifiers & qualifier_internal ) continue ; if ( qualifiers & qualifier_map_mode ) op_mode = d -> mode ; if ( qualifiers & qualifier_pointer && VECTOR_MODE_P ( op_mode ) ) op_mode = GET_MODE_INNER ( op_mode ) ; eltype = arm_simd_builtin_type ( op_mode , ( qualifiers & qualifier_unsigned ) != 0 , ( qualifiers & qualifier_poly ) != 0 ) ; gcc_assert ( eltype != NULL ) ; if ( qualifiers & qualifier_const ) eltype = build_qualified_type ( eltype , TYPE_QUAL_CONST ) ; if ( qualifiers & qualifier_pointer ) eltype = build_pointer_type ( eltype ) ; if ( arg_num == 0 ) return_type = eltype ; else args = tree_cons ( NULL_TREE , eltype , args ) ; } ftype = build_function_type ( return_type , args ) ; gcc_assert ( ftype != NULL ) ; if ( print_type_signature_p ) snprintf ( namebuf , sizeof ( namebuf ) , "__builtin_neon_%s_%s" , d -> name , type_signature ) ; else snprintf ( namebuf , sizeof ( namebuf ) , "__builtin_neon_%s" , d -> name ) ; fndecl = add_builtin_function ( namebuf , ftype , fcode , BUILT_IN_MD , NULL , NULL_TREE ) ; arm_builtin_decls [ fcode ] = fndecl ; } } </s>

Set up all the NEON builtins , even builtins for instructions that are not in the current target ISA to allow the user to compile particular modules with different target specific options that differ from the command line options . Such builtins will be rejected in arm_expand_builtin .


<s> rtx function_symbol ( rtx target , const char * name , enum sh_function_kind kind ) { rtx sym ; if ( kind != FUNCTION_ORDINARY ) name = IDENTIFIER_POINTER ( get_identifier ( name ) ) ; sym = gen_rtx_SYMBOL_REF ( Pmode , name ) ; SYMBOL_REF_FLAGS ( sym ) = SYMBOL_FLAG_FUNCTION ; if ( flag_pic ) switch ( kind ) { case FUNCTION_ORDINARY : break ; case SFUNC_GOT : { rtx reg = target ? target : gen_reg_rtx ( Pmode ) ; emit_insn ( gen_symGOT2reg ( reg , sym ) ) ; sym = reg ; break ; } case SFUNC_STATIC : { rtx reg = target ? target : gen_reg_rtx ( Pmode ) ; emit_insn ( gen_symGOTOFF2reg ( reg , sym ) ) ; sym = reg ; break ; } } if ( target && sym != target ) { emit_move_insn ( target , sym ) ; return target ; } return sym ; } </s>

Return an RTX pair for the address and call site label of a function NAME of kind KIND , placing the result in TARGET if not NULL . For SFUNC_STATIC , if FDPIC , the LAB member of result will be set to ( const_int 0 ) if jsr should be used , or a label_ref if bsrf should be used . For FDPIC , both SFUNC_GOT and SFUNC_STATIC will return the address of the function itself , not a function descriptor , so they can only be used with functions not using the FDPIC register that are known to be called directory without a PLT entry .


<s>
SDValue
RISCVTargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
default
:
report_fatal_error
(
"unimplemented operand"
)
;
case
ISD
::
GlobalAddress
:
return
lowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
BlockAddress
:
return
lowerBlockAddress
(
Op
,
DAG
)
;
case
ISD
::
ConstantPool
:
return
lowerConstantPool
(
Op
,
DAG
)
;
case
ISD
::
SELECT
:
return
lowerSELECT
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
lowerVASTART
(
Op
,
DAG
)
;
case
ISD
::
FRAMEADDR
:
return
lowerFRAMEADDR
(
Op
,
DAG
)
;
case
ISD
::
RETURNADDR
:
return
lowerRETURNADDR
(
Op
,
DAG
)
;
case
ISD
::
INTRINSIC_WO_CHAIN
:
return
lowerINTRINSIC_WO_CHAIN
(
Op
,
DAG
)
;
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .

RISCV
RISCV
"unimplemented operand"
ISD::GlobalAddress
ISD::BlockAddress
ISD::ConstantPool
ISD::SELECT
ISD::VASTART
ISD::FRAMEADDR
ISD::RETURNADDR
ISD::INTRINSIC_WO_CHAIN


<s> const MCPhysReg * MSP430RegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const TargetFrameLowering * TFI = MF -> getSubtarget ( ) . getFrameLowering ( ) ; const Function * F = MF -> getFunction ( ) ; static const MCPhysReg CalleeSavedRegs [ ] = { MSP430 :: FPW , MSP430 :: R5W , MSP430 :: R6W , MSP430 :: R7W , MSP430 :: R8W , MSP430 :: R9W , MSP430 :: R10W , MSP430 :: R11W , 0 } ; static const MCPhysReg CalleeSavedRegsFP [ ] = { MSP430 :: R5W , MSP430 :: R6W , MSP430 :: R7W , MSP430 :: R8W , MSP430 :: R9W , MSP430 :: R10W , MSP430 :: R11W , 0 } ; static const MCPhysReg CalleeSavedRegsIntr [ ] = { MSP430 :: FPW , MSP430 :: R5W , MSP430 :: R6W , MSP430 :: R7W , MSP430 :: R8W , MSP430 :: R9W , MSP430 :: R10W , MSP430 :: R11W , MSP430 :: R12W , MSP430 :: R13W , MSP430 :: R14W , MSP430 :: R15W , 0 } ; static const MCPhysReg CalleeSavedRegsIntrFP [ ] = { MSP430 :: R5W , MSP430 :: R6W , MSP430 :: R7W , MSP430 :: R8W , MSP430 :: R9W , MSP430 :: R10W , MSP430 :: R11W , MSP430 :: R12W , MSP430 :: R13W , MSP430 :: R14W , MSP430 :: R15W , 0 } ; if ( TFI -> hasFP ( * MF ) ) return ( F -> getCallingConv ( ) == CallingConv :: MSP430_INTR ? CalleeSavedRegsIntrFP : CalleeSavedRegsFP ) ; else return ( F -> getCallingConv ( ) == CallingConv :: MSP430_INTR ? CalleeSavedRegsIntr : CalleeSavedRegs ) ; } </s>


<s> static int arm_address_register_rtx_p ( rtx x , int strict_p ) { int regno ; if ( GET_CODE ( x ) != REG ) return 0 ; regno = REGNO ( x ) ; if ( strict_p ) return ARM_REGNO_OK_FOR_BASE_P ( regno ) ; return ( regno <= LAST_ARM_REGNUM || regno >= FIRST_PSEUDO_REGISTER || regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM ) ; } </s>

Return nonzero if X is valid as an ARM state addressing register .


<s> unsigned AMDGPURegisterBankInfo :: getBreakDownCost ( const ValueMapping & ValMapping , const RegisterBank * CurBank ) const { assert ( ValMapping . NumBreakDowns == 2 && ValMapping . BreakDown [ 0 ] . Length == 32 && ValMapping . BreakDown [ 0 ] . StartIdx == 0 && ValMapping . BreakDown [ 1 ] . Length == 32 && ValMapping . BreakDown [ 1 ] . StartIdx == 32 && ValMapping . BreakDown [ 0 ] . RegBank == ValMapping . BreakDown [ 1 ] . RegBank ) ; return 1 ; } </s>

Get the cost of using ValMapping to decompose a register .


<s> int direct_return ( void ) { return ( reload_completed && xstormy16_compute_stack_layout ( ) . frame_size == 0 ) ; } </s>

Return non-zero if this function is known to have a null epilogue .


<s> static unsigned aarch64_next_callee_save ( unsigned regno , unsigned limit ) { while ( regno <= limit && ! aarch64_register_saved_on_entry ( regno ) ) regno ++ ; return regno ; } </s>

Return the next register up from REGNO up to LIMIT for the callee to save .


<s> BTFTypeDerived :: BTFTypeDerived ( unsigned NextTypeId , unsigned Tag , StringRef Name ) : DTy ( nullptr ) , NeedsFixup ( false ) , Name ( Name ) { Kind = BTF :: BTF_KIND_PTR ; BTFType . Info = Kind << 24 ; BTFType . Type = NextTypeId ; } </s>


<s>
const
char
*
getPassName
(
)
const
override
{
return
"AArch64 branch fixup pass"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> void ia64_function_arg_advance ( CUMULATIVE_ARGS * cum , enum machine_mode mode , tree type , int named ) { int words = ia64_function_arg_words ( type , mode ) ; int offset = ia64_function_arg_offset ( cum , type , words ) ; enum machine_mode hfa_mode = VOIDmode ; if ( cum -> words >= MAX_ARGUMENT_SLOTS ) return ; cum -> words += words + offset ; if ( type ) hfa_mode = hfa_element_mode ( type , 0 ) ; if ( hfa_mode != VOIDmode && ( ! cum -> prototype || named ) ) { int fp_regs = cum -> fp_regs ; int int_regs = cum -> words - words ; int hfa_size = GET_MODE_SIZE ( hfa_mode ) ; int byte_size ; int args_byte_size ; byte_size = ( ( mode == BLKmode ) ? int_size_in_bytes ( type ) : GET_MODE_SIZE ( mode ) ) ; args_byte_size = int_regs * UNITS_PER_WORD ; offset = 0 ; for ( ; ( offset < byte_size && fp_regs < MAX_ARGUMENT_SLOTS && args_byte_size < ( MAX_ARGUMENT_SLOTS * UNITS_PER_WORD ) ) ; ) { offset += hfa_size ; args_byte_size += hfa_size ; fp_regs ++ ; } cum -> fp_regs = fp_regs ; } else if ( mode == TFmode || mode == TCmode || ( ! FLOAT_MODE_P ( mode ) || cum -> fp_regs == MAX_ARGUMENT_SLOTS ) ) cum -> int_regs = cum -> words ; else if ( cum -> prototype ) { if ( ! named ) cum -> int_regs = cum -> words ; else cum -> fp_regs += ( GET_MODE_CLASS ( mode ) == MODE_COMPLEX_FLOAT ? 2 : 1 ) ; } else { cum -> fp_regs += ( GET_MODE_CLASS ( mode ) == MODE_COMPLEX_FLOAT ? 2 : 1 ) ; cum -> int_regs = cum -> words ; } } </s>

Update CUM to point after this argument . This is patterned after ia64_function_arg .


<s> static rtx push ( int rn , bool in_prologue ) { rtx reg = gen_rtx_REG ( word_mode , rn ) ; rtx x ; if ( ! TARGET_NORMAL_MODE ) x = gen_push_h8300hs_advanced ( reg ) ; else x = gen_push_h8300hs_normal ( reg ) ; x = F ( emit_insn ( x ) , 0 ) ; add_reg_note ( x , REG_INC , stack_pointer_rtx ) ; return x ; } </s>

Output RTL to push register RN onto the stack .


<s> bool AMDGPUTargetLowering :: isLoadBitCastBeneficial ( EVT LoadTy , EVT CastTy ) const { assert ( LoadTy . getSizeInBits ( ) == CastTy . getSizeInBits ( ) ) ; if ( LoadTy . getScalarType ( ) == MVT :: i32 ) return false ; unsigned LScalarSize = LoadTy . getScalarSizeInBits ( ) ; unsigned CastScalarSize = CastTy . getScalarSizeInBits ( ) ; return ( LScalarSize < CastScalarSize ) || ( CastScalarSize >= 32 ) ; } </s>

Return true if the following transform is beneficial : fold ( conv ( load x ) ) - > ( load ( conv * ) x ) On architectures that do n't natively support some vector loads efficiently , casting the load to a smaller vector of larger types and loading is more efficient , however , this can be undone by optimizations in dag combiner .


<s> bool isConstantSplat ( SDValue Op , APInt & SplatVal ) { APInt UndefElts ; SmallVector < APInt , 16 > EltBits ; if ( getTargetConstantBitsFromNode ( Op , Op . getScalarValueSizeInBits ( ) , UndefElts , EltBits , true , false ) ) { int SplatIndex = - 1 ; for ( int i = 0 , e = EltBits . size ( ) ; i != e ; ++ i ) { if ( UndefElts [ i ] ) continue ; if ( 0 <= SplatIndex && EltBits [ i ] != EltBits [ SplatIndex ] ) { SplatIndex = - 1 ; break ; } SplatIndex = i ; } if ( 0 <= SplatIndex ) { SplatVal = EltBits [ SplatIndex ] ; return true ; } } return false ; } </s>

Check if this is a constant splat , and if so , find the smallest element size that splats the vector .


<s> void rl78_expand_prologue ( void ) { int i , fs ; rtx sp = gen_rtx_REG ( HImode , STACK_POINTER_REGNUM ) ; rtx ax = gen_rtx_REG ( HImode , AX_REG ) ; int rb = 0 ; if ( rl78_is_naked_func ( ) ) return ; rl78_compute_frame_info ( ) ; if ( flag_stack_usage_info ) current_function_static_stack_size = cfun -> machine -> framesize ; if ( is_interrupt_func ( cfun -> decl ) && ! TARGET_G10 ) for ( i = 0 ; i < 4 ; i ++ ) if ( cfun -> machine -> need_to_push [ i ] ) { emit_insn ( gen_sel_rb ( GEN_INT ( 0 ) ) ) ; break ; } for ( i = 0 ; i < 16 ; i ++ ) if ( cfun -> machine -> need_to_push [ i ] ) { int reg = i * 2 ; if ( TARGET_G10 ) { if ( reg >= 8 ) { emit_move_insn ( ax , gen_rtx_REG ( HImode , reg ) ) ; reg = AX_REG ; } } else { int need_bank = i / 4 ; if ( need_bank != rb ) { emit_insn ( gen_sel_rb ( GEN_INT ( need_bank ) ) ) ; rb = need_bank ; } } F ( emit_insn ( gen_push ( gen_rtx_REG ( HImode , reg ) ) ) ) ; } if ( rb != 0 ) emit_insn ( gen_sel_rb ( GEN_INT ( 0 ) ) ) ; if ( is_interrupt_func ( cfun -> decl ) && cfun -> machine -> uses_es ) { emit_insn ( gen_movqi_from_es ( gen_rtx_REG ( QImode , A_REG ) ) ) ; F ( emit_insn ( gen_push ( ax ) ) ) ; } if ( frame_pointer_needed ) { F ( emit_move_insn ( ax , sp ) ) ; F ( emit_move_insn ( gen_rtx_REG ( HImode , FRAME_POINTER_REGNUM ) , ax ) ) ; } fs = cfun -> machine -> framesize_locals + cfun -> machine -> framesize_outgoing ; if ( fs > 0 ) { if ( fs > 254 * 3 ) { rtx insn ; emit_move_insn ( ax , sp ) ; emit_insn ( gen_subhi3 ( ax , ax , GEN_INT ( fs ) ) ) ; insn = emit_move_insn ( sp , ax ) ; add_reg_note ( insn , REG_FRAME_RELATED_EXPR , gen_rtx_SET ( SImode , sp , gen_rtx_PLUS ( HImode , sp , GEN_INT ( - fs ) ) ) ) ; } else { while ( fs > 0 ) { int fs_byte = ( fs > 254 ) ? 254 : fs ; F ( emit_insn ( gen_subhi3 ( sp , sp , GEN_INT ( fs_byte ) ) ) ) ; fs -= fs_byte ; } } } } </s>

Expand the function prologue ( from the prologue pattern ) .


<s> static rtx_insn * mips_emit_call_insn ( rtx pattern , rtx orig_addr , rtx addr , bool lazy_p ) { rtx_insn * insn ; rtx reg ; insn = emit_call_insn ( pattern ) ; if ( TARGET_MIPS16 && mips_use_pic_fn_addr_reg_p ( orig_addr ) ) { reg = gen_rtx_REG ( Pmode , PIC_FUNCTION_ADDR_REGNUM ) ; emit_insn_before ( gen_move_insn ( reg , addr ) , insn ) ; use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , reg ) ; } if ( lazy_p ) use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , pic_offset_table_rtx ) ; if ( TARGET_USE_GOT ) { use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , gen_rtx_REG ( Pmode , GOT_VERSION_REGNUM ) ) ; emit_insn ( gen_update_got_version ( ) ) ; } if ( TARGET_MIPS16 && TARGET_EXPLICIT_RELOCS && TARGET_CALL_CLOBBERED_GP ) { rtx post_call_tmp_reg = gen_rtx_REG ( word_mode , POST_CALL_TMP_REG ) ; clobber_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , post_call_tmp_reg ) ; } return insn ; } </s>

Emit a call sequence with call pattern PATTERN and return the call instruction itself ( which is not necessarily the last instruction emitted ) . ORIG_ADDR is the original , unlegitimized address , ADDR is the legitimized form , and LAZY_P is true if the call address is lazily-bound .


<s> rtx function_expander :: use_pred_x_insn ( insn_code icode ) { gcc_assert ( pred == PRED_x ) ; unsigned int nops = args . length ( ) - 1 ; bool has_float_operand_p = FLOAT_MODE_P ( insn_data [ icode ] . operand [ 0 ] . mode ) ; add_output_operand ( icode ) ; add_input_operand ( icode , args [ 0 ] ) ; for ( unsigned int i = 0 ; i < nops ; ++ i ) { add_input_operand ( icode , args [ i + 1 ] ) ; if ( FLOAT_MODE_P ( GET_MODE ( args [ i + 1 ] ) ) ) has_float_operand_p = true ; } if ( has_float_operand_p ) { rtx pred = m_ops [ 1 ] . value ; if ( flag_trapping_math && pred != CONST1_RTX ( GET_MODE ( pred ) ) ) add_integer_operand ( SVE_STRICT_GP ) ; else add_integer_operand ( SVE_RELAXED_GP ) ; } return generate_insn ( icode ) ; } </s>

Implement the call using instruction ICODE , which is a predicated operation that returns arbitrary values for inactive lanes .


<s> void s390_expand_vcond ( rtx target , rtx then , rtx els , enum rtx_code cond , rtx cmp_op1 , rtx cmp_op2 ) { rtx tmp ; machine_mode result_mode ; rtx result_target ; machine_mode target_mode = GET_MODE ( target ) ; machine_mode cmp_mode = GET_MODE ( cmp_op1 ) ; rtx op = ( cond == LT ) ? els : then ; if ( ( cond == LT || cond == GE ) && target_mode == cmp_mode && cmp_op2 == CONST0_RTX ( cmp_mode ) && op == CONST0_RTX ( target_mode ) && s390_vector_mode_supported_p ( target_mode ) && GET_MODE_CLASS ( target_mode ) == MODE_VECTOR_INT ) { rtx negop = ( cond == LT ) ? then : els ; int shift = GET_MODE_BITSIZE ( GET_MODE_INNER ( target_mode ) ) - 1 ; if ( negop == CONST1_RTX ( target_mode ) ) { rtx res = expand_simple_binop ( cmp_mode , LSHIFTRT , cmp_op1 , GEN_INT ( shift ) , target , 1 , OPTAB_DIRECT ) ; if ( res != target ) emit_move_insn ( target , res ) ; return ; } else if ( all_ones_operand ( negop , target_mode ) ) { rtx res = expand_simple_binop ( cmp_mode , ASHIFTRT , cmp_op1 , GEN_INT ( shift ) , target , 0 , OPTAB_DIRECT ) ; if ( res != target ) emit_move_insn ( target , res ) ; return ; } } result_mode = cmp_mode == V2DFmode ? V2DImode : cmp_mode ; result_target = gen_reg_rtx ( result_mode ) ; if ( ! REG_P ( cmp_op1 ) ) cmp_op1 = force_reg ( GET_MODE ( cmp_op1 ) , cmp_op1 ) ; if ( ! REG_P ( cmp_op2 ) ) cmp_op2 = force_reg ( GET_MODE ( cmp_op2 ) , cmp_op2 ) ; s390_expand_vec_compare ( result_target , cond , cmp_op1 , cmp_op2 ) ; if ( all_ones_operand ( then , GET_MODE ( then ) ) && const0_operand ( els , GET_MODE ( els ) ) ) { emit_move_insn ( target , gen_rtx_SUBREG ( target_mode , result_target , 0 ) ) ; return ; } if ( ! REG_P ( then ) ) then = force_reg ( target_mode , then ) ; if ( ! REG_P ( els ) ) els = force_reg ( target_mode , els ) ; tmp = gen_rtx_fmt_ee ( EQ , VOIDmode , result_target , CONST0_RTX ( result_mode ) ) ; tmp = gen_rtx_IF_THEN_ELSE ( target_mode , tmp , els , then ) ; gcc_assert ( target_mode == GET_MODE ( then ) ) ; emit_insn ( gen_rtx_SET ( target , tmp ) ) ; } </s>

Generate a vector comparison expression loading either elements of THEN or ELS into TARGET depending on the comparison COND of CMP_OP1 and CMP_OP2 .


<s> bool MOSSchedStrategy :: tryCandidate ( SchedCandidate & Cand , SchedCandidate & TryCand , SchedBoundary * Zone ) const { if ( ! Cand . isValid ( ) ) { TryCand . Reason = NodeOrder ; return true ; } if ( tryLess ( registerClassPressureDiff ( MOS :: AcRegClass , TryCand . SU , TryCand . AtTop ) , registerClassPressureDiff ( MOS :: AcRegClass , Cand . SU , Cand . AtTop ) , TryCand , Cand , PhysReg ) ) return TryCand . Reason != NoCand ; if ( tryLess ( registerClassPressureDiff ( MOS :: XYRegClass , TryCand . SU , TryCand . AtTop ) , registerClassPressureDiff ( MOS :: XYRegClass , Cand . SU , Cand . AtTop ) , TryCand , Cand , PhysReg ) ) return TryCand . Reason != NoCand ; if ( tryLess ( registerClassPressureDiff ( MOS :: Imag8RegClass , TryCand . SU , TryCand . AtTop ) , registerClassPressureDiff ( MOS :: Imag8RegClass , Cand . SU , Cand . AtTop ) , TryCand , Cand , PhysReg ) ) return TryCand . Reason != NoCand ; if ( DAG -> isTrackingPressure ( ) && tryPressure ( TryCand . RPDelta . Excess , Cand . RPDelta . Excess , TryCand , Cand , RegExcess , TRI , DAG -> MF ) ) return TryCand . Reason != NoCand ; if ( DAG -> isTrackingPressure ( ) && tryPressure ( TryCand . RPDelta . CriticalMax , Cand . RPDelta . CriticalMax , TryCand , Cand , RegCritical , TRI , DAG -> MF ) ) return TryCand . Reason != NoCand ; if ( DAG -> isTrackingPressure ( ) && tryPressure ( TryCand . RPDelta . CurrentMax , Cand . RPDelta . CurrentMax , TryCand , Cand , RegMax , TRI , DAG -> MF ) ) return TryCand . Reason != NoCand ; bool SameBoundary = Zone != nullptr ; if ( SameBoundary ) { if ( ( Zone -> isTop ( ) && TryCand . SU -> NodeNum < Cand . SU -> NodeNum ) || ( ! Zone -> isTop ( ) && TryCand . SU -> NodeNum > Cand . SU -> NodeNum ) ) { TryCand . Reason = NodeOrder ; return true ; } } return false ; } </s>

Apply a set of heuristics to a new candidate .

MOS MOS MOS::AcRegClass MOS::AcRegClass MOS::XYRegClass MOS::XYRegClass MOS::Imag8RegClass MOS::Imag8RegClass


<s> const MCExpr * X86TargetLowering :: getPICJumpTableRelocBaseExpr ( const MachineFunction * MF , unsigned JTI , MCContext & Ctx ) const { if ( Subtarget -> isPICStyleRIPRel ( ) ) return TargetLowering :: getPICJumpTableRelocBaseExpr ( MF , JTI , Ctx ) ; return MCSymbolRefExpr :: Create ( getPICBaseSymbol ( MF , Ctx ) , Ctx ) ; } </s>

This returns the relocation base for the given PIC jumptable , the same as getPICJumpTableRelocBase , but as an MCExpr .


<s>
SDValue
PPCTargetLowering
::
LowerReturn
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
isVarArg
,
const
SmallVectorImpl
<
ISD
::
OutputArg
>
&
Outs
,
const
SmallVectorImpl
<
SDValue
>
&
OutVals
,
DebugLoc
dl
,
SelectionDAG
&
DAG
)
const
{
SmallVector
<
CCValAssign
,
16
>
RVLocs
;
CCState
CCInfo
(
CallConv
,
isVarArg
,
DAG
.
getMachineFunction
(
)
,
getTargetMachine
(
)
,
RVLocs
,
*
DAG
.
getContext
(
)
)
;
CCInfo
.
AnalyzeReturn
(
Outs
,
RetCC_PPC
)
;
SDValue
Flag
;
SmallVector
<
SDValue
,
4
>
RetOps
(
1
,
Chain
)
;
for
(
unsigned
i
=
0
;
i
!=
RVLocs
.
size
(
)
;
++
i
)
{
CCValAssign
&
VA
=
RVLocs
[
i
]
;
assert
(
VA
.
isRegLoc
(
)
&&
"Can only return in registers!"
)
;
SDValue
Arg
=
OutVals
[
i
]
;
switch
(
VA
.
getLocInfo
(
)
)
{
default
:
llvm_unreachable
(
"Unknown loc info!"
)
;
case
CCValAssign
::
Full
:
break
;
case
CCValAssign
::
AExt
:
Arg
=
DAG
.
getNode
(
ISD
::
ANY_EXTEND
,
dl
,
VA
.
getLocVT
(
)
,
Arg
)
;
break
;
case
CCValAssign
::
ZExt
:
Arg
=
DAG
.
getNode
(
ISD
::
ZERO_EXTEND
,
dl
,
VA
.
getLocVT
(
)
,
Arg
)
;
break
;
case
CCValAssign
::
SExt
:
Arg
=
DAG
.
getNode
(
ISD
::
SIGN_EXTEND
,
dl
,
VA
.
getLocVT
(
)
,
Arg
)
;
break
;
}
Chain
=
DAG
.
getCopyToReg
(
Chain
,
dl
,
VA
.
getLocReg
(
)
,
Arg
,
Flag
)
;
Flag
=
Chain
.
getValue
(
1
)
;
RetOps
.
push_back
(
DAG
.
getRegister
(
VA
.
getLocReg
(
)
,
VA
.
getLocVT
(
)
)
)
;
}
RetOps
[
0
]
=
Chain
;
if
(
Flag
.
getNode
(
)
)
RetOps
.
push_back
(
Flag
)
;
return
DAG
.
getNode
(
PPCISD
::
RET_FLAG
,
dl
,
MVT
::
Other
,
&
RetOps
[
0
]
,
RetOps
.
size
(
)
)
;
}
</s>

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


<s> bool HexagonInstrInfo :: canExecuteInBundle ( const MachineInstr * First , const MachineInstr * Second ) const { if ( DisableNVSchedule ) return false ; if ( mayBeNewStore ( Second ) ) { const MachineOperand & Stored = Second -> getOperand ( Second -> getNumOperands ( ) - 1 ) ; if ( ! Stored . isReg ( ) ) return false ; for ( unsigned i = 0 , e = First -> getNumOperands ( ) ; i < e ; ++ i ) { const MachineOperand & Op = First -> getOperand ( i ) ; if ( Op . isReg ( ) && Op . isDef ( ) && Op . getReg ( ) == Stored . getReg ( ) ) return true ; } } return false ; } </s>

Can these instructions execute at the same time in a bundle .


<s> const RISCVSubtarget & getSubtarget ( ) const { return Subtarget ; } </s>

getSubtarget - Return the subtarget for which this machine code is being compiled .


<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> bool TL45AsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , const char * ExtraCode , raw_ostream & OS ) { if ( ! AsmPrinter :: PrintAsmOperand ( MI , OpNo , ExtraCode , OS ) ) return false ; const MachineOperand & MO = MI -> getOperand ( OpNo ) ; if ( ExtraCode && ExtraCode [ 0 ] ) { if ( ExtraCode [ 1 ] != 0 ) return true ; switch ( ExtraCode [ 0 ] ) { default : return true ; case 'z' : if ( MO . isImm ( ) && MO . getImm ( ) == 0 ) { OS << TL45InstPrinter :: getRegisterName ( TL45 :: r0 ) ; return false ; } break ; case 'i' : if ( ! MO . isReg ( ) ) OS << 'i' ; return false ; } } switch ( MO . getType ( ) ) { case MachineOperand :: MO_Immediate : OS << MO . getImm ( ) ; return false ; case MachineOperand :: MO_Register : OS << TL45InstPrinter :: getRegisterName ( MO . getReg ( ) ) ; return false ; default : break ; } return true ; } </s>

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


<s> void Thumb2InstrInfo :: storeRegToStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , unsigned SrcReg , bool isKill , int FI , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { if ( RC == ARM :: GPRRegisterClass || RC == ARM :: tGPRRegisterClass || RC == ARM :: tcGPRRegisterClass || RC == ARM :: rGPRRegisterClass ) { DebugLoc DL ; if ( I != MBB . end ( ) ) DL = I -> getDebugLoc ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; MachineFrameInfo & MFI = * MF . getFrameInfo ( ) ; MachineMemOperand * MMO = MF . getMachineMemOperand ( MachinePointerInfo ( PseudoSourceValue :: getFixedStack ( FI ) ) , MachineMemOperand :: MOStore , MFI . getObjectSize ( FI ) , MFI . getObjectAlignment ( FI ) ) ; AddDefaultPred ( BuildMI ( MBB , I , DL , get ( ARM :: t2STRi12 ) ) . addReg ( SrcReg , getKillRegState ( isKill ) ) . addFrameIndex ( FI ) . addImm ( 0 ) . addMemOperand ( MMO ) ) ; return ; } ARMBaseInstrInfo :: storeRegToStackSlot ( MBB , I , SrcReg , isKill , FI , RC , TRI ) ; } </s>

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

ARM ARM::GPRRegisterClass ARM::tGPRRegisterClass ARM::tcGPRRegisterClass ARM::rGPRRegisterClass ARM::t2STRi12 0 ARM


<s>
static
std
::
unique_ptr
<
X86Operand
>
CreateMem
(
unsigned
ModeSize
,
unsigned
SegReg
,
const
MCExpr
*
Disp
,
unsigned
BaseReg
,
unsigned
IndexReg
,
unsigned
Scale
,
SMLoc
StartLoc
,
SMLoc
EndLoc
,
unsigned
Size
=
0
,
StringRef
SymName
=
StringRef
(
)
,
void
*
OpDecl
=
nullptr
,
unsigned
FrontendSize
=
0
)
{
assert
(
(
SegReg
||
BaseReg
||
IndexReg
)
&&
"Invalid memory operand!"
)
;
assert
(
(
(
Scale
==
1
||
Scale
==
2
||
Scale
==
4
||
Scale
==
8
)
)
&&
"Invalid scale!"
)
;
auto
Res
=
llvm
::
make_unique
<
X86Operand
>
(
Memory
,
StartLoc
,
EndLoc
)
;
Res
->
Mem
.
SegReg
=
SegReg
;
Res
->
Mem
.
Disp
=
Disp
;
Res
->
Mem
.
BaseReg
=
BaseReg
;
Res
->
Mem
.
IndexReg
=
IndexReg
;
Res
->
Mem
.
Scale
=
Scale
;
Res
->
Mem
.
Size
=
Size
;
Res
->
Mem
.
ModeSize
=
ModeSize
;
Res
->
Mem
.
FrontendSize
=
FrontendSize
;
Res
->
SymName
=
SymName
;
Res
->
OpDecl
=
OpDecl
;
Res
->
AddressOf
=
false
;
return
Res
;
}
</s>


<s> static tree char_to_type ( char c ) { static tree volatile_ptr_type_node = NULL ; static tree volatile_const_ptr_type_node = NULL ; if ( volatile_ptr_type_node == NULL ) { volatile_ptr_type_node = build_pointer_type ( build_qualified_type ( void_type_node , TYPE_QUAL_VOLATILE ) ) ; volatile_const_ptr_type_node = build_pointer_type ( build_qualified_type ( void_type_node , TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE ) ) ; } switch ( c ) { case 'v' : return void_type_node ; case 'i' : return unsigned_type_node ; case 'l' : return long_long_unsigned_type_node ; case 'p' : return volatile_ptr_type_node ; case 'k' : return volatile_const_ptr_type_node ; default : gcc_unreachable ( ) ; } } </s>

Convert a character in a builtin type string to a tree type .


<s>
SDNode
*
BPFDAGToDAGISel
::
Select
(
SDNode
*
Node
)
{
unsigned
Opcode
=
Node
->
getOpcode
(
)
;
DEBUG
(
dbgs
(
)
<<
"Selecting: "
;
Node
->
dump
(
CurDAG
)
;
dbgs
(
)
<<
'\n'
)
;
if
(
Node
->
isMachineOpcode
(
)
)
{
DEBUG
(
dbgs
(
)
<<
"== "
;
Node
->
dump
(
CurDAG
)
;
dbgs
(
)
<<
'\n'
)
;
return
;
}
switch
(
Opcode
)
{
default
:
break
;
case
ISD
::
UNDEF
:
{
errs
(
)
<<
"BUG: "
;
Node
->
dump
(
CurDAG
)
;
errs
(
)
<<
'\n'
;
report_fatal_error
(
"shouldn't see UNDEF during Select"
)
;
break
;
}
case
ISD
::
INTRINSIC_W_CHAIN
:
{
unsigned
IntNo
=
cast
<
ConstantSDNode
>
(
Node
->
getOperand
(
1
)
)
->
getZExtValue
(
)
;
switch
(
IntNo
)
{
case
Intrinsic
::
bpf_load_byte
:
case
Intrinsic
::
bpf_load_half
:
case
Intrinsic
::
bpf_load_word
:
{
SDLoc
DL
(
Node
)
;
SDValue
Chain
=
Node
->
getOperand
(
0
)
;
SDValue
N1
=
Node
->
getOperand
(
1
)
;
SDValue
Skb
=
Node
->
getOperand
(
2
)
;
SDValue
N3
=
Node
->
getOperand
(
3
)
;
SDValue
R6Reg
=
CurDAG
->
getRegister
(
BPF
::
R6
,
MVT
::
i64
)
;
Chain
=
CurDAG
->
getCopyToReg
(
Chain
,
DL
,
R6Reg
,
Skb
,
SDValue
(
)
)
;
Node
=
CurDAG
->
UpdateNodeOperands
(
Node
,
Chain
,
N1
,
R6Reg
,
N3
)
;
break
;
}
}
break
;
}
case
ISD
::
FrameIndex
:
{
int
FI
=
dyn_cast
<
FrameIndexSDNode
>
(
Node
)
->
getIndex
(
)
;
EVT
VT
=
Node
->
getValueType
(
0
)
;
SDValue
TFI
=
CurDAG
->
getTargetFrameIndex
(
FI
,
VT
)
;
unsigned
Opc
=
BPF
::
MOV_rr
;
if
(
Node
->
hasOneUse
(
)
)
return
CurDAG
->
SelectNodeTo
(
Node
,
Opc
,
VT
,
TFI
)
;
return
CurDAG
->
getMachineNode
(
Opc
,
SDLoc
(
Node
)
,
VT
,
TFI
)
;
}
}
SDNode
*
ResNode
=
SelectCode
(
Node
)
;
DEBUG
(
dbgs
(
)
<<
"=> "
;
if
(
ResNode
==
nullptr
||
ResNode
==
Node
)
Node
->
dump
(
CurDAG
)
;
else
ResNode
->
dump
(
CurDAG
)
;
dbgs
(
)
<<
'\n'
)
;
return
ResNode
;
}
</s>

Main hook for targets to transform nodes into machine nodes .


<s> static void rs6000_setup_reg_addr_masks ( void ) { ssize_t rc , reg , m , nregs ; addr_mask_type any_addr_mask , addr_mask ; for ( m = 0 ; m < NUM_MACHINE_MODES ; ++ m ) { machine_mode m2 = ( machine_mode ) m ; bool complex_p = false ; bool small_int_p = ( m2 == QImode || m2 == HImode || m2 == SImode ) ; size_t msize ; if ( COMPLEX_MODE_P ( m2 ) ) { complex_p = true ; m2 = GET_MODE_INNER ( m2 ) ; } msize = GET_MODE_SIZE ( m2 ) ; bool indexed_only_p = ( m == SDmode && TARGET_NO_SDMODE_STACK ) ; any_addr_mask = 0 ; for ( rc = FIRST_RELOAD_REG_CLASS ; rc <= LAST_RELOAD_REG_CLASS ; rc ++ ) { addr_mask = 0 ; reg = reload_reg_map [ rc ] . reg ; if ( reg >= 0 && rs6000_hard_regno_mode_ok_p [ m ] [ reg ] ) { bool small_int_vsx_p = ( small_int_p && ( rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX ) ) ; nregs = rs6000_hard_regno_nregs [ m ] [ reg ] ; addr_mask |= RELOAD_REG_VALID ; if ( small_int_vsx_p ) addr_mask |= RELOAD_REG_INDEXED ; else if ( nregs > 1 || m == BLKmode || complex_p ) addr_mask |= RELOAD_REG_MULTIPLE ; else addr_mask |= RELOAD_REG_INDEXED ; if ( TARGET_UPDATE && ( rc == RELOAD_REG_GPR || rc == RELOAD_REG_FPR ) && msize <= 8 && ! VECTOR_MODE_P ( m2 ) && ! FLOAT128_VECTOR_P ( m2 ) && ! complex_p && ! small_int_vsx_p && ( m2 != DFmode || ! TARGET_UPPER_REGS_DF ) && ( m2 != SFmode || ! TARGET_UPPER_REGS_SF ) && ! ( TARGET_E500_DOUBLE && msize == 8 ) ) { addr_mask |= RELOAD_REG_PRE_INCDEC ; switch ( m ) { default : addr_mask |= RELOAD_REG_PRE_MODIFY ; break ; case DImode : if ( TARGET_POWERPC64 ) addr_mask |= RELOAD_REG_PRE_MODIFY ; break ; case DFmode : case DDmode : if ( TARGET_DF_INSN ) addr_mask |= RELOAD_REG_PRE_MODIFY ; break ; } } } if ( ( addr_mask != 0 ) && ! indexed_only_p && msize <= 8 && ( rc == RELOAD_REG_GPR || ( ( msize == 8 || m2 == SFmode ) && ( rc == RELOAD_REG_FPR || ( rc == RELOAD_REG_VMX && TARGET_P9_DFORM_SCALAR ) ) ) ) ) addr_mask |= RELOAD_REG_OFFSET ; else if ( ( addr_mask != 0 ) && ! indexed_only_p && msize == 16 && TARGET_P9_DFORM_VECTOR && ( ALTIVEC_OR_VSX_VECTOR_MODE ( m2 ) || ( m2 == TImode && TARGET_VSX_TIMODE ) ) ) { addr_mask |= RELOAD_REG_OFFSET ; if ( rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX ) addr_mask |= RELOAD_REG_QUAD_OFFSET ; } if ( rc == RELOAD_REG_VMX && msize == 16 && ( addr_mask & RELOAD_REG_VALID ) != 0 ) addr_mask |= RELOAD_REG_AND_M16 ; reg_addr [ m ] . addr_mask [ rc ] = addr_mask ; any_addr_mask |= addr_mask ; } reg_addr [ m ] . addr_mask [ RELOAD_REG_ANY ] = any_addr_mask ; } } </s>

Update the addr mask bits in reg_addr to help secondary reload and go if legitimate address support to figure out the appropriate addressing to use .


<s> TargetPassConfig * LanaiTargetMachine :: createPassConfig ( PassManagerBase & PassManager ) { return new LanaiPassConfig ( * this , & PassManager ) ; } </s>

Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of CodeGen passes .


<s> std :: pair < const TargetRegisterClass * , uint8_t > HexagonTargetLowering :: findRepresentativeClass ( const TargetRegisterInfo * TRI , MVT VT ) const { const TargetRegisterClass * RRC = nullptr ; uint8_t Cost = 1 ; switch ( VT . SimpleTy ) { default : return TargetLowering :: findRepresentativeClass ( TRI , VT ) ; case MVT :: v64i8 : case MVT :: v32i16 : case MVT :: v16i32 : case MVT :: v8i64 : RRC = & Hexagon :: HvxVRRegClass ; break ; case MVT :: v128i8 : case MVT :: v64i16 : case MVT :: v32i32 : case MVT :: v16i64 : if ( Subtarget . hasV60TOps ( ) && Subtarget . useHVXOps ( ) && Subtarget . useHVX128BOps ( ) ) RRC = & Hexagon :: HvxVRRegClass ; else RRC = & Hexagon :: HvxWRRegClass ; break ; case MVT :: v256i8 : case MVT :: v128i16 : case MVT :: v64i32 : case MVT :: v32i64 : RRC = & Hexagon :: HvxWRRegClass ; break ; } return std :: make_pair ( RRC , Cost ) ; } </s>

Return the largest legal super-reg register class of the register class for the specified type and its associated `` cost '' .


<s> void paired_expand_vector_init ( rtx target , rtx vals ) { machine_mode mode = GET_MODE ( target ) ; int n_elts = GET_MODE_NUNITS ( mode ) ; int n_var = 0 ; rtx x , new_rtx , tmp , constant_op , op1 , op2 ; int i ; for ( i = 0 ; i < n_elts ; ++ i ) { x = XVECEXP ( vals , 0 , i ) ; if ( ! ( CONST_SCALAR_INT_P ( x ) || CONST_DOUBLE_P ( x ) || CONST_FIXED_P ( x ) ) ) ++ n_var ; } if ( n_var == 0 ) { emit_move_insn ( target , gen_rtx_CONST_VECTOR ( mode , XVEC ( vals , 0 ) ) ) ; return ; } if ( n_var == 2 ) { new_rtx = gen_rtx_VEC_CONCAT ( V2SFmode , XVECEXP ( vals , 0 , 0 ) , XVECEXP ( vals , 0 , 1 ) ) ; emit_move_insn ( target , new_rtx ) ; return ; } op1 = XVECEXP ( vals , 0 , 0 ) ; op2 = XVECEXP ( vals , 0 , 1 ) ; constant_op = ( CONSTANT_P ( op1 ) ) ? op1 : op2 ; tmp = gen_reg_rtx ( GET_MODE ( constant_op ) ) ; emit_move_insn ( tmp , constant_op ) ; if ( CONSTANT_P ( op1 ) ) new_rtx = gen_rtx_VEC_CONCAT ( V2SFmode , tmp , op2 ) ; else new_rtx = gen_rtx_VEC_CONCAT ( V2SFmode , op1 , tmp ) ; emit_move_insn ( target , new_rtx ) ; } </s>

Initialize TARGET of vector PAIRED to VALS .


<s>
static
tree
rs6000_handle_struct_attribute
(
tree
*
node
,
tree
name
,
tree
args
ATTRIBUTE_UNUSED
,
int
flags
ATTRIBUTE_UNUSED
,
bool
*
no_add_attrs
)
{
tree
*
type
=
;
if
(
DECL_P
(
*
node
)
)
{
if
(
TREE_CODE
(
*
node
)
==
TYPE_DECL
)
type
=
&
TREE_TYPE
(
*
node
)
;
}
else
type
=
node
;
if
(
!
(
type
&&
(
TREE_CODE
(
*
type
)
==
RECORD_TYPE
||
TREE_CODE
(
*
type
)
==
UNION_TYPE
)
)
)
{
warning
(
OPT_Wattributes
,
"%qE attribute ignored"
,
name
)
;
*
no_add_attrs
=
true
;
}
else
if
(
(
is_attribute_p
(
"ms_struct"
,
name
)
&&
lookup_attribute
(
"gcc_struct"
,
TYPE_ATTRIBUTES
(
*
type
)
)
)
||
(
(
is_attribute_p
(
"gcc_struct"
,
name
)
&&
lookup_attribute
(
"ms_struct"
,
TYPE_ATTRIBUTES
(
*
type
)
)
)
)
)
{
warning
(
OPT_Wattributes
,
"%qE incompatible attribute ignored"
,
name
)
;
*
no_add_attrs
=
true
;
}
return
NULL_TREE
;
}
</s>

Handle a `` ms_struct '' or `` gcc_struct '' attribute ; arguments as in struct attribute_spec.handler .


<s> void AArch64_MachoTargetObjectFile :: getNameWithPrefix ( SmallVectorImpl < char > & OutName , const GlobalValue * GV , const TargetMachine & TM ) const { getMangler ( ) . getNameWithPrefix ( OutName , GV , true ) ; } </s>

Print the appropriate prefix and the specified name as the global variable name .


<s> void create_regs_rtx ( ) { ix_reg = gen_rtx ( REG , HImode , HARD_X_REGNUM ) ; iy_reg = gen_rtx ( REG , HImode , HARD_Y_REGNUM ) ; d_reg = gen_rtx ( REG , HImode , HARD_D_REGNUM ) ; da_reg = gen_rtx ( REG , QImode , HARD_A_REGNUM ) ; m68hc11_soft_tmp_reg = gen_rtx ( REG , HImode , SOFT_TMP_REGNUM ) ; stack_push_word = gen_rtx ( MEM , HImode , gen_rtx ( PRE_DEC , HImode , gen_rtx ( REG , HImode , HARD_SP_REGNUM ) ) ) ; stack_pop_word = gen_rtx ( MEM , HImode , gen_rtx ( POST_INC , HImode , gen_rtx ( REG , HImode , HARD_SP_REGNUM ) ) ) ; } </s>


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

Return information about object file lowering .


<s>
SDValue
J2TargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
ConstantPool
:
return
LowerConstantPool
(
Op
,
DAG
)
;
case
ISD
::
SHL
:
return
LowerShift
<
J2ISD
::
SHL
>
(
Op
,
DAG
)
;
case
ISD
::
SRL
:
return
LowerShift
<
J2ISD
::
SRL
>
(
Op
,
DAG
)
;
default
:
llvm_unreachable
(
"unimplemented operation"
)
;
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .


<s> bool Mips16InstrInfo :: expandPostRAPseudo ( MachineBasicBlock :: iterator MI ) const { MachineBasicBlock & MBB = * MI -> getParent ( ) ; switch ( MI -> getDesc ( ) . getOpcode ( ) ) { default : return false ; case Mips :: BteqzT8CmpX16 : ExpandFEXT_T8I816_ins ( MBB , MI , Mips :: BteqzX16 , Mips :: CmpRxRy16 ) ; break ; case Mips :: BteqzT8CmpiX16 : ExpandFEXT_T8I8I16_ins ( MBB , MI , Mips :: BteqzX16 , Mips :: CmpiRxImm16 , Mips :: CmpiRxImmX16 ) ; break ; case Mips :: BteqzT8SltX16 : ExpandFEXT_T8I816_ins ( MBB , MI , Mips :: BteqzX16 , Mips :: SltRxRy16 ) ; break ; case Mips :: BteqzT8SltiX16 : ExpandFEXT_T8I8I16_ins ( MBB , MI , Mips :: BteqzX16 , Mips :: SltiRxImm16 , Mips :: SltiRxImmX16 ) ; break ; case Mips :: BteqzT8SltuX16 : ExpandFEXT_T8I816_ins ( MBB , MI , Mips :: BteqzX16 , Mips :: SltuRxRy16 ) ; break ; case Mips :: BteqzT8SltiuX16 : ExpandFEXT_T8I8I16_ins ( MBB , MI , Mips :: BteqzX16 , Mips :: SltiuRxImm16 , Mips :: SltiuRxImmX16 ) ; break ; case Mips :: BtnezT8CmpX16 : ExpandFEXT_T8I816_ins ( MBB , MI , Mips :: BtnezX16 , Mips :: CmpRxRy16 ) ; break ; case Mips :: BtnezT8CmpiX16 : ExpandFEXT_T8I8I16_ins ( MBB , MI , Mips :: BtnezX16 , Mips :: CmpiRxImm16 , Mips :: CmpiRxImmX16 ) ; break ; case Mips :: BtnezT8SltX16 : ExpandFEXT_T8I816_ins ( MBB , MI , Mips :: BtnezX16 , Mips :: SltRxRy16 ) ; break ; case Mips :: BtnezT8SltiX16 : ExpandFEXT_T8I8I16_ins ( MBB , MI , Mips :: BtnezX16 , Mips :: SltiRxImm16 , Mips :: SltiRxImmX16 ) ; break ; case Mips :: BtnezT8SltuX16 : ExpandFEXT_T8I816_ins ( MBB , MI , Mips :: BtnezX16 , Mips :: SltuRxRy16 ) ; break ; case Mips :: BtnezT8SltiuX16 : ExpandFEXT_T8I8I16_ins ( MBB , MI , Mips :: BtnezX16 , Mips :: SltiuRxImm16 , Mips :: SltiuRxImmX16 ) ; break ; case Mips :: RetRA16 : ExpandRetRA16 ( MBB , MI , Mips :: JrcRa16 ) ; break ; case Mips :: SltCCRxRy16 : ExpandFEXT_CCRX16_ins ( MBB , MI , Mips :: SltRxRy16 ) ; break ; case Mips :: SltiCCRxImmX16 : ExpandFEXT_CCRXI16_ins ( MBB , MI , Mips :: SltiRxImm16 , Mips :: SltiRxImmX16 ) ; break ; case Mips :: SltiuCCRxImmX16 : ExpandFEXT_CCRXI16_ins ( MBB , MI , Mips :: SltiuRxImm16 , Mips :: SltiuRxImmX16 ) ; break ; case Mips :: SltuCCRxRy16 : ExpandFEXT_CCRX16_ins ( MBB , MI , Mips :: SltuRxRy16 ) ; break ; } MBB . erase ( MI ) ; return true ; } </s>

This function is called for all pseudo instructions that remain after register allocation .


<s>
SDValue
RV16KTargetLowering
::
LowerReturn
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
IsVarArg
,
const
SmallVectorImpl
<
ISD
::
OutputArg
>
&
Outs
,
const
SmallVectorImpl
<
SDValue
>
&
OutVals
,
const
SDLoc
&
DL
,
SelectionDAG
&
DAG
)
const
{
if
(
IsVarArg
)
{
report_fatal_error
(
"VarArg not supported"
)
;
}
SmallVector
<
CCValAssign
,
16
>
RVLocs
;
CCState
CCInfo
(
CallConv
,
IsVarArg
,
DAG
.
getMachineFunction
(
)
,
RVLocs
,
*
DAG
.
getContext
(
)
)
;
CCInfo
.
AnalyzeReturn
(
Outs
,
RetCC_RV16K
)
;
SDValue
Flag
;
SmallVector
<
SDValue
,
4
>
RetOps
(
1
,
Chain
)
;
for
(
unsigned
i
=
0
,
e
=
RVLocs
.
size
(
)
;
i
<
e
;
++
i
)
{
CCValAssign
&
VA
=
RVLocs
[
i
]
;
assert
(
VA
.
isRegLoc
(
)
&&
"Can only return in registers!"
)
;
Chain
=
DAG
.
getCopyToReg
(
Chain
,
DL
,
VA
.
getLocReg
(
)
,
OutVals
[
i
]
,
Flag
)
;
Flag
=
Chain
.
getValue
(
1
)
;
RetOps
.
push_back
(
DAG
.
getRegister
(
VA
.
getLocReg
(
)
,
VA
.
getLocVT
(
)
)
)
;
}
RetOps
[
0
]
=
Chain
;
if
(
Flag
.
getNode
(
)
)
{
RetOps
.
push_back
(
Flag
)
;
}
return
DAG
.
getNode
(
RV16KISD
::
RET_FLAG
,
DL
,
MVT
::
Other
,
RetOps
)
;
}
</s>

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


<s> static void sparc_solaris_elf_asm_named_section ( const char * name , unsigned int flags , tree decl ATTRIBUTE_UNUSED ) { if ( HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE ) { solaris_elf_asm_comdat_section ( name , flags , decl ) ; return ; } fprintf ( asm_out_file , "\t.section\t\"%s\"" , name ) ; if ( ! ( flags & SECTION_DEBUG ) ) fputs ( ",#alloc" , asm_out_file ) ; if ( flags & SECTION_EXCLUDE ) fputs ( ",#exclude" , asm_out_file ) ; if ( flags & SECTION_WRITE ) fputs ( ",#write" , asm_out_file ) ; if ( flags & SECTION_TLS ) fputs ( ",#tls" , asm_out_file ) ; if ( flags & SECTION_CODE ) fputs ( ",#execinstr" , asm_out_file ) ; if ( flags & SECTION_NOTYPE ) ; else if ( flags & SECTION_BSS ) fputs ( ",#nobits" , asm_out_file ) ; else fputs ( ",#progbits" , asm_out_file ) ; fputc ( '\n' , asm_out_file ) ; } </s>

Solaris implementation of TARGET_ASM_NAMED_SECTION .

sparc "\t.section\t\"%s\"" ",#alloc" ",#exclude" ",#write" ",#tls" ",#execinstr" ",#nobits" ",#progbits"


<s> static void mcore_print_operand_address ( FILE * stream , rtx x ) { switch ( GET_CODE ( x ) ) { case REG : fprintf ( stream , "(%s)" , reg_names [ REGNO ( x ) ] ) ; break ; case PLUS : { rtx base = XEXP ( x , 0 ) ; rtx index = XEXP ( x , 1 ) ; if ( GET_CODE ( base ) != REG ) { rtx temp = base ; base = index ; index = temp ; } switch ( GET_CODE ( index ) ) { case CONST_INT : fprintf ( stream , "(%s," HOST_WIDE_INT_PRINT_DEC ")" , reg_names [ REGNO ( base ) ] , INTVAL ( index ) ) ; break ; default : gcc_unreachable ( ) ; } } break ; default : output_addr_const ( stream , x ) ; break ; } } </s>

Print the operand address in x to the stream .


<s> Bucket ( const SCEV * B , Instruction * I ) : BaseSCEV ( B ) , Elements ( 1 , BucketElement ( I ) ) { ChainSize = 0 ; } </s>

The bucket assigned by balanced partitioning .


<s> static unsigned int aarch64_function_arg_boundary ( machine_mode mode , const_tree type ) { unsigned int alignment = aarch64_function_arg_alignment ( mode , type ) ; if ( alignment < PARM_BOUNDARY ) alignment = PARM_BOUNDARY ; if ( alignment > STACK_BOUNDARY ) alignment = STACK_BOUNDARY ; return alignment ; } </s>

Implement FUNCTION_ARG_BOUNDARY . Every parameter gets at least PARM_BOUNDARY bits of alignment , but will be given anything up to STACK_BOUNDARY bits if the type requires it . This makes sure that both before and after the layout of each argument , the Next Stacked Argument Address ( NSAA ) will have a minimum alignment of 8 bytes .


"va_start: n_gpr = %d, n_fpr = %d off %d\n"

Implement va_start by filling the va_list structure VALIST . STDARG_P is always true , and ignored . NEXTARG points to the first anonymous stack argument . The following global variables are used to initialize the va_list structure : current_function_args_info : holds number of gprs and fprs used for named arguments . current_function_arg_offset_rtx : holds the offset of the first anonymous stack argument ( relative to the virtual arg pointer ) .


<s>
void
Finish
(
)
{
const
size_t
VendorHeaderSize
=
4
+
CurrentVendor
.
size
(
)
+
1
;
const
size_t
TagHeaderSize
=
1
+
4
;
Streamer
.
EmitIntValue
(
VendorHeaderSize
+
TagHeaderSize
+
ContentsSize
,
4
)
;
Streamer
.
EmitBytes
(
CurrentVendor
,
0
)
;
Streamer
.
EmitIntValue
(
0
,
1
)
;
Streamer
.
EmitIntValue
(
ARMBuildAttrs
::
File
,
1
)
;
Streamer
.
EmitIntValue
(
TagHeaderSize
+
ContentsSize
,
4
)
;
for
(
unsigned
int
i
=
0
;
i
<
Contents
.
size
(
)
;
++
i
)
{
AttributeItemType
item
=
Contents
[
i
]
;
Streamer
.
EmitULEB128IntValue
(
item
.
Tag
,
0
)
;
switch
(
item
.
Type
)
{
case
AttributeItemType
::
NumericAttribute
:
Streamer
.
EmitULEB128IntValue
(
item
.
IntValue
,
0
)
;
break
;
case
AttributeItemType
::
TextAttribute
:
Streamer
.
EmitBytes
(
item
.
StringValue
.
upper
(
)
,
0
)
;
Streamer
.
EmitIntValue
(
0
,
1
)
;
break
;
default
:
assert
(
0
&&
"Invalid attribute type"
)
;
}
}
Contents
.
clear
(
)
;
}
</s>

Finish - Do final processing and write the object to the output stream .


<s>
bool
PPCInstrInfo
::
areMemAccessesTriviallyDisjoint
(
const
MachineInstr
&
MIa
,
const
MachineInstr
&
MIb
)
const
{
assert
(
MIa
.
mayLoadOrStore
(
)
&&
"MIa must be a load or store."
)
;
assert
(
MIb
.
mayLoadOrStore
(
)
&&
"MIb must be a load or store."
)
;
if
(
MIa
.
hasUnmodeledSideEffects
(
)
||
MIb
.
hasUnmodeledSideEffects
(
)
||
MIa
.
hasOrderedMemoryRef
(
)
||
MIb
.
hasOrderedMemoryRef
(
)
)
return
false
;
const
TargetRegisterInfo
*
TRI
=
&
getRegisterInfo
(
)
;
const
MachineOperand
*
BaseOpA
=
nullptr
,
*
BaseOpB
=
nullptr
;
int64_t
OffsetA
=
0
,
OffsetB
=
0
;
unsigned
int
WidthA
=
0
,
WidthB
=
0
;
if
(
getMemOperandWithOffsetWidth
(
MIa
,
BaseOpA
,
OffsetA
,
WidthA
,
TRI
)
&&
getMemOperandWithOffsetWidth
(
MIb
,
BaseOpB
,
OffsetB
,
WidthB
,
TRI
)
)
{
if
(
BaseOpA
->
isIdenticalTo
(
*
BaseOpB
)
)
{
int
LowOffset
=
std
::
min
(
OffsetA
,
OffsetB
)
;
int
HighOffset
=
std
::
max
(
OffsetA
,
OffsetB
)
;
int
LowWidth
=
(
LowOffset
==
OffsetA
)
WidthA
:
WidthB
;
if
(
LowOffset
+
LowWidth
<=
HighOffset
)
return
true
;
}
}
return
false
;
}
</s>

Sometimes , it is possible for the target to tell , even without aliasing information , that two MIs access different memory addresses .


<s> bool ARMTargetLowering :: alignLoopsWithOptSize ( ) const { return Subtarget -> isMClass ( ) ; } </s>

Should loops be aligned even when the function is marked OptSize ( but not MinSize ) .


<s> void X86DAGToDAGISel :: PostprocessISelDAG ( ) { if ( TM . getOptLevel ( ) == CodeGenOpt :: None ) return ; SelectionDAG :: allnodes_iterator Position ( CurDAG -> getRoot ( ) . getNode ( ) ) ; ++ Position ; while ( Position != CurDAG -> allnodes_begin ( ) ) { SDNode * N = & * -- Position ; if ( N -> use_empty ( ) || ! N -> isMachineOpcode ( ) ) continue ; if ( N -> getMachineOpcode ( ) != TargetOpcode :: SUBREG_TO_REG ) continue ; unsigned SubRegIdx = N -> getConstantOperandVal ( 2 ) ; if ( SubRegIdx != X86 :: sub_xmm && SubRegIdx != X86 :: sub_ymm ) continue ; SDValue Move = N -> getOperand ( 1 ) ; if ( ! Move . isMachineOpcode ( ) ) continue ; switch ( Move . getMachineOpcode ( ) ) { default : continue ; case X86 :: VMOVAPDrr : case X86 :: VMOVUPDrr : case X86 :: VMOVAPSrr : case X86 :: VMOVUPSrr : case X86 :: VMOVDQArr : case X86 :: VMOVDQUrr : case X86 :: VMOVAPDYrr : case X86 :: VMOVUPDYrr : case X86 :: VMOVAPSYrr : case X86 :: VMOVUPSYrr : case X86 :: VMOVDQAYrr : case X86 :: VMOVDQUYrr : case X86 :: VMOVAPDZ128rr : case X86 :: VMOVUPDZ128rr : case X86 :: VMOVAPSZ128rr : case X86 :: VMOVUPSZ128rr : case X86 :: VMOVDQA32Z128rr : case X86 :: VMOVDQU32Z128rr : case X86 :: VMOVDQA64Z128rr : case X86 :: VMOVDQU64Z128rr : case X86 :: VMOVAPDZ256rr : case X86 :: VMOVUPDZ256rr : case X86 :: VMOVAPSZ256rr : case X86 :: VMOVUPSZ256rr : case X86 :: VMOVDQA32Z256rr : case X86 :: VMOVDQU32Z256rr : case X86 :: VMOVDQA64Z256rr : case X86 :: VMOVDQU64Z256rr : break ; } SDValue In = Move . getOperand ( 0 ) ; if ( ! In . isMachineOpcode ( ) || In . getMachineOpcode ( ) <= TargetOpcode :: GENERIC_OP_END ) continue ; CurDAG -> UpdateNodeOperands ( N , N -> getOperand ( 0 ) , In , N -> getOperand ( 2 ) ) ; if ( Move . getNode ( ) -> use_empty ( ) ) CurDAG -> RemoveDeadNode ( Move . getNode ( ) ) ; } } </s>

PostprocessISelDAG ( ) - This hook allows the target to hack on the graph right after selection .


<s> bool HexagonFrameLowering :: hasFP ( const MachineFunction & MF ) const { if ( MF . getFunction ( ) -> hasFnAttribute ( Attribute :: Naked ) ) return false ; auto & MFI = MF . getFrameInfo ( ) ; auto & HRI = * MF . getSubtarget < HexagonSubtarget > ( ) . getRegisterInfo ( ) ; bool HasExtraAlign = HRI . needsStackRealignment ( MF ) ; bool HasAlloca = MFI . hasVarSizedObjects ( ) ; if ( MF . getTarget ( ) . getOptLevel ( ) == CodeGenOpt :: None ) return true ; if ( HasAlloca || HasExtraAlign ) return true ; if ( MFI . getStackSize ( ) > 0 ) { const TargetMachine & TM = MF . getTarget ( ) ; if ( TM . Options . DisableFramePointerElim ( MF ) || ! EliminateFramePointer ) return true ; if ( EnableStackOVFSanitizer ) return true ; } const auto & HMFI = * MF . getInfo < HexagonMachineFunctionInfo > ( ) ; if ( MFI . hasCalls ( ) || HMFI . hasClobberLR ( ) ) return true ; return false ; } </s>

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


<s> static tree spu_builtin_decl ( unsigned code , bool initialize_p ATTRIBUTE_UNUSED ) { if ( code >= NUM_SPU_BUILTINS ) return error_mark_node ; return spu_builtin_decls [ code ] ; } </s>


<s> static tree sparc_gimplify_va_arg ( tree valist , tree type , gimple_seq * pre_p , gimple_seq * post_p ) { HOST_WIDE_INT size , rsize , align ; tree addr , incr ; bool indirect ; tree ptrtype = build_pointer_type ( type ) ; if ( pass_va_arg_by_reference ( type ) ) { indirect = true ; size = rsize = UNITS_PER_WORD ; align = 0 ; } else { indirect = false ; size = int_size_in_bytes ( type ) ; rsize = ROUND_UP ( size , UNITS_PER_WORD ) ; align = 0 ; if ( TARGET_ARCH64 ) { if ( TYPE_ALIGN ( type ) >= 2 * ( unsigned ) BITS_PER_WORD ) align = 2 * UNITS_PER_WORD ; if ( AGGREGATE_TYPE_P ( type ) ) { if ( size == 0 ) size = rsize = UNITS_PER_WORD ; else size = rsize ; } } } incr = valist ; if ( align ) { incr = fold_build_pointer_plus_hwi ( incr , align - 1 ) ; incr = fold_convert ( sizetype , incr ) ; incr = fold_build2 ( BIT_AND_EXPR , sizetype , incr , size_int ( - align ) ) ; incr = fold_convert ( ptr_type_node , incr ) ; } gimplify_expr ( & incr , pre_p , post_p , is_gimple_val , fb_rvalue ) ; addr = incr ; if ( BYTES_BIG_ENDIAN && size < rsize ) addr = fold_build_pointer_plus_hwi ( incr , rsize - size ) ; if ( indirect ) { addr = fold_convert ( build_pointer_type ( ptrtype ) , addr ) ; addr = build_va_arg_indirect_ref ( addr ) ; } else if ( align == 0 && TYPE_ALIGN ( type ) > BITS_PER_WORD ) { tree tmp = create_tmp_var ( type , "va_arg_tmp" ) ; tree dest_addr = build_fold_addr_expr ( tmp ) ; tree copy = build_call_expr ( builtin_decl_implicit ( BUILT_IN_MEMCPY ) , 3 , dest_addr , addr , size_int ( rsize ) ) ; TREE_ADDRESSABLE ( tmp ) = 1 ; gimplify_and_add ( copy , pre_p ) ; addr = dest_addr ; } else addr = fold_convert ( ptrtype , addr ) ; incr = fold_build_pointer_plus_hwi ( incr , rsize ) ; gimplify_assign ( valist , incr , post_p ) ; return build_va_arg_indirect_ref ( addr ) ; } </s>


<s> int spu_emit_vector_cond_expr ( rtx dest , rtx op1 , rtx op2 , rtx cond , rtx cc_op0 , rtx cc_op1 ) { machine_mode dest_mode = GET_MODE ( dest ) ; enum rtx_code rcode = GET_CODE ( cond ) ; rtx mask ; mask = spu_emit_vector_compare ( rcode , cc_op0 , cc_op1 , dest_mode ) ; emit_insn ( gen_selb ( dest , op2 , op1 , mask ) ) ; return 1 ; } </s>

Emit vector conditional expression . DEST is destination . OP1 and OP2 are two VEC_COND_EXPR operands . CC_OP0 and CC_OP1 are the two operands for the relation operation COND .


<s> void ARMConstantPoolValue :: print ( raw_ostream & O ) const { if ( GV ) O << GV -> getName ( ) ; else O << S ; if ( isNonLazyPointer ( ) ) O << "$non_lazy_ptr" ; else if ( isStub ( ) ) O << "$stub" ; if ( Modifier ) O << "(" << Modifier << ")" ; if ( PCAdjust != 0 ) { O << "-(LPC" << LabelId << "+" << ( unsigned ) PCAdjust ; if ( AddCurrentAddress ) O << "-." ; O << ")" ; } } </s>

print - Print a debug representation of the operand to the given stream .


<s> void AArch64TargetStreamer :: emitInst ( uint32_t Inst ) { char Buffer [ 4 ] ; for ( unsigned I = 0 ; I < 4 ; ++ I ) { Buffer [ I ] = uint8_t ( Inst ) ; Inst >>= 8 ; } getStreamer ( ) . EmitBytes ( StringRef ( Buffer , 4 ) ) ; } </s>

Callback used to implement the .inst directive .


<s> static reg_class_t z8k_secondary_reload ( bool in_p ATTRIBUTE_UNUSED , rtx in , reg_class_t rclass , enum machine_mode mode , secondary_reload_info * sri ATTRIBUTE_UNUSED ) { int regno = - 1 ; enum rtx_code code = GET_CODE ( in ) ; if ( mode != QImode ) return NO_REGS ; if ( rclass == QI_REGS ) return NO_REGS ; if ( ! CONSTANT_P ( in ) ) { regno = true_regnum ( in ) ; if ( regno == - 1 || regno >= FIRST_PSEUDO_REGISTER ) code = MEM ; } if ( code == MEM ) return SQI_REGS ; return NO_REGS ; } </s>

Return the register class of a scratch register needed to copy IN into or out of a register in CLASS in MODE . If it can be done directly , NO_REGS is returned .


<s> static void cr16_compute_save_regs ( void ) { unsigned int regno ; current_frame_info . last_reg_to_save = - 1 ; current_frame_info . reg_size = 0 ; if ( FUNC_IS_NORETURN_P ( current_function_decl ) && ! MUST_SAVE_REGS_P ( ) ) return ; for ( regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno ++ ) { if ( fixed_regs [ regno ] ) { current_frame_info . save_regs [ regno ] = 0 ; continue ; } if ( cr16_interrupt_function_p ( ) ) { if ( ! crtl -> is_leaf && call_used_regs [ regno ] ) current_frame_info . save_regs [ regno ] = 1 ; else if ( df_regs_ever_live_p ( regno ) ) current_frame_info . save_regs [ regno ] = 1 ; else current_frame_info . save_regs [ regno ] = 0 ; } else { if ( df_regs_ever_live_p ( regno ) && ( ! call_used_regs [ regno ] || regno == RETURN_ADDRESS_REGNUM ) ) current_frame_info . save_regs [ regno ] = 1 ; else current_frame_info . save_regs [ regno ] = 0 ; } } if ( crtl -> calls_eh_return ) { unsigned int i ; for ( i = 0 ; ; ++ i ) { regno = EH_RETURN_DATA_REGNO ( i ) ; if ( INVALID_REGNUM == regno ) break ; current_frame_info . save_regs [ regno ] = 1 ; } } for ( regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno ++ ) if ( current_frame_info . save_regs [ regno ] == 1 ) { current_frame_info . last_reg_to_save = regno ; if ( regno >= CR16_FIRST_DWORD_REGISTER ) current_frame_info . reg_size += CR16_UNITS_PER_DWORD ; else current_frame_info . reg_size += UNITS_PER_WORD ; } } </s>

Compute values for the array current_frame_info.save_regs and the variable current_frame_info.reg_size . The index of current_frame_info.save_regs is numbers of register , each will get 1 if we need to save it in the current function , 0 if not . current_frame_info.reg_size is the total sum of the registers being saved .


<s> static rtx rs6000_darwin64_record_arg ( CUMULATIVE_ARGS * orig_cum , const_tree type , bool named , bool retval ) { rtx rvec [ FIRST_PSEUDO_REGISTER ] ; int k = 1 , kbase = 1 ; HOST_WIDE_INT typesize = int_size_in_bytes ( type ) ; CUMULATIVE_ARGS copy_cum = * orig_cum ; CUMULATIVE_ARGS * cum = & copy_cum ; if ( ! retval && TYPE_ALIGN ( type ) >= 2 * BITS_PER_WORD && ( cum -> words % 2 ) != 0 ) cum -> words ++ ; cum -> intoffset = 0 ; cum -> use_stack = 0 ; cum -> named = named ; rs6000_darwin64_record_arg_recurse ( cum , type , 0 , rvec , & k ) ; rs6000_darwin64_record_arg_flush ( cum , typesize * BITS_PER_UNIT , rvec , & k ) ; if ( cum -> use_stack ) { if ( retval ) return NULL_RTX ; kbase = 0 ; rvec [ 0 ] = gen_rtx_EXPR_LIST ( VOIDmode , NULL_RTX , const0_rtx ) ; } if ( k > 1 || cum -> use_stack ) return gen_rtx_PARALLEL ( BLKmode , gen_rtvec_v ( k - kbase , & rvec [ kbase ] ) ) ; else return NULL_RTX ; } </s>

For the darwin64 ABI , we want to construct a PARALLEL consisting of the register ( s ) to be used for each field and subfield of a struct being passed by value , along with the offset of where the register 's value may be found in the block . FP fields go in FP register , vector fields go in vector registers , and everything else goes in int registers , packed as in memory . This code is also used for function return values . RETVAL indicates whether this is the case . Much of this is taken from the SPARC V9 port , which has a similar calling convention .


<s> const MCPhysReg * MSP430RegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const MSP430FrameLowering * TFI = getFrameLowering ( * MF ) ; const Function * F = MF -> getFunction ( ) ; static const MCPhysReg CalleeSavedRegs [ ] = { MSP430 :: FP , MSP430 :: R5 , MSP430 :: R6 , MSP430 :: R7 , MSP430 :: R8 , MSP430 :: R9 , MSP430 :: R10 , MSP430 :: R11 , 0 } ; static const MCPhysReg CalleeSavedRegsFP [ ] = { MSP430 :: R5 , MSP430 :: R6 , MSP430 :: R7 , MSP430 :: R8 , MSP430 :: R9 , MSP430 :: R10 , MSP430 :: R11 , 0 } ; static const MCPhysReg CalleeSavedRegsIntr [ ] = { MSP430 :: FP , MSP430 :: R5 , MSP430 :: R6 , MSP430 :: R7 , MSP430 :: R8 , MSP430 :: R9 , MSP430 :: R10 , MSP430 :: R11 , MSP430 :: R12 , MSP430 :: R13 , MSP430 :: R14 , MSP430 :: R15 , 0 } ; static const MCPhysReg CalleeSavedRegsIntrFP [ ] = { MSP430 :: R5 , MSP430 :: R6 , MSP430 :: R7 , MSP430 :: R8 , MSP430 :: R9 , MSP430 :: R10 , MSP430 :: R11 , MSP430 :: R12 , MSP430 :: R13 , MSP430 :: R14 , MSP430 :: R15 , 0 } ; if ( TFI -> hasFP ( * MF ) ) return ( F -> getCallingConv ( ) == CallingConv :: MSP430_INTR ? CalleeSavedRegsIntrFP : CalleeSavedRegsFP ) ; else return ( F -> getCallingConv ( ) == CallingConv :: MSP430_INTR ? CalleeSavedRegsIntr : CalleeSavedRegs ) ; } </s>


"Stack offset for byval regs doesn't introduced anymore?"

Target-specific cleanup for formal ByVal parameters .


<s>
static
const
char
*
arc_invalid_within_doloop
(
const
rtx_insn
*
insn
)
{
if
(
CALL_P
(
insn
)
)
return
"Function call in the loop."
;
return
;
}
</s>

NULL if INSN insn is valid within a low-overhead loop . Otherwise return why doloop can not be applied .


<s> inline tree rvv_arg_type_info :: get_vector_type ( vector_type_index type_idx ) const { return get_function_type_index ( type_idx ) == VECTOR_TYPE_INVALID ? NULL_TREE : builtin_types [ get_function_type_index ( type_idx ) ] . vector ; } </s>

Return the vector type associated with type suffix TYPE .


<s> bool GCNSubtarget :: zeroesHigh16BitsOfDest ( unsigned Opcode ) const { switch ( Opcode ) { case AMDGPU :: V_CVT_F16_F32_e32 : case AMDGPU :: V_CVT_F16_F32_e64 : case AMDGPU :: V_CVT_F16_U16_e32 : case AMDGPU :: V_CVT_F16_U16_e64 : case AMDGPU :: V_CVT_F16_I16_e32 : case AMDGPU :: V_CVT_F16_I16_e64 : case AMDGPU :: V_RCP_F16_e64 : case AMDGPU :: V_RCP_F16_e32 : case AMDGPU :: V_RSQ_F16_e64 : case AMDGPU :: V_RSQ_F16_e32 : case AMDGPU :: V_SQRT_F16_e64 : case AMDGPU :: V_SQRT_F16_e32 : case AMDGPU :: V_LOG_F16_e64 : case AMDGPU :: V_LOG_F16_e32 : case AMDGPU :: V_EXP_F16_e64 : case AMDGPU :: V_EXP_F16_e32 : case AMDGPU :: V_SIN_F16_e64 : case AMDGPU :: V_SIN_F16_e32 : case AMDGPU :: V_COS_F16_e64 : case AMDGPU :: V_COS_F16_e32 : case AMDGPU :: V_FLOOR_F16_e64 : case AMDGPU :: V_FLOOR_F16_e32 : case AMDGPU :: V_CEIL_F16_e64 : case AMDGPU :: V_CEIL_F16_e32 : case AMDGPU :: V_TRUNC_F16_e64 : case AMDGPU :: V_TRUNC_F16_e32 : case AMDGPU :: V_RNDNE_F16_e64 : case AMDGPU :: V_RNDNE_F16_e32 : case AMDGPU :: V_FRACT_F16_e64 : case AMDGPU :: V_FRACT_F16_e32 : case AMDGPU :: V_FREXP_MANT_F16_e64 : case AMDGPU :: V_FREXP_MANT_F16_e32 : case AMDGPU :: V_FREXP_EXP_I16_F16_e64 : case AMDGPU :: V_FREXP_EXP_I16_F16_e32 : case AMDGPU :: V_LDEXP_F16_e64 : case AMDGPU :: V_LDEXP_F16_e32 : case AMDGPU :: V_LSHLREV_B16_e64 : case AMDGPU :: V_LSHLREV_B16_e32 : case AMDGPU :: V_LSHRREV_B16_e64 : case AMDGPU :: V_LSHRREV_B16_e32 : case AMDGPU :: V_ASHRREV_I16_e64 : case AMDGPU :: V_ASHRREV_I16_e32 : case AMDGPU :: V_ADD_U16_e64 : case AMDGPU :: V_ADD_U16_e32 : case AMDGPU :: V_SUB_U16_e64 : case AMDGPU :: V_SUB_U16_e32 : case AMDGPU :: V_SUBREV_U16_e64 : case AMDGPU :: V_SUBREV_U16_e32 : case AMDGPU :: V_MUL_LO_U16_e64 : case AMDGPU :: V_MUL_LO_U16_e32 : case AMDGPU :: V_ADD_F16_e64 : case AMDGPU :: V_ADD_F16_e32 : case AMDGPU :: V_SUB_F16_e64 : case AMDGPU :: V_SUB_F16_e32 : case AMDGPU :: V_SUBREV_F16_e64 : case AMDGPU :: V_SUBREV_F16_e32 : case AMDGPU :: V_MUL_F16_e64 : case AMDGPU :: V_MUL_F16_e32 : case AMDGPU :: V_MAX_F16_e64 : case AMDGPU :: V_MAX_F16_e32 : case AMDGPU :: V_MIN_F16_e64 : case AMDGPU :: V_MIN_F16_e32 : case AMDGPU :: V_MAX_U16_e64 : case AMDGPU :: V_MAX_U16_e32 : case AMDGPU :: V_MIN_U16_e64 : case AMDGPU :: V_MIN_U16_e32 : case AMDGPU :: V_MAX_I16_e64 : case AMDGPU :: V_MAX_I16_e32 : case AMDGPU :: V_MIN_I16_e64 : case AMDGPU :: V_MIN_I16_e32 : return getGeneration ( ) <= AMDGPUSubtarget :: GFX9 ; case AMDGPU :: V_MAD_F16_e64 : case AMDGPU :: V_MADAK_F16 : case AMDGPU :: V_MADMK_F16 : case AMDGPU :: V_MAC_F16_e64 : case AMDGPU :: V_MAC_F16_e32 : case AMDGPU :: V_FMAMK_F16 : case AMDGPU :: V_FMAAK_F16 : case AMDGPU :: V_MAD_U16_e64 : case AMDGPU :: V_MAD_I16_e64 : case AMDGPU :: V_FMA_F16_e64 : case AMDGPU :: V_FMAC_F16_e64 : case AMDGPU :: V_FMAC_F16_e32 : case AMDGPU :: V_DIV_FIXUP_F16_e64 : return getGeneration ( ) == AMDGPUSubtarget :: VOLCANIC_ISLANDS ; case AMDGPU :: V_MAD_MIXLO_F16 : case AMDGPU :: V_MAD_MIXHI_F16 : default : return false ; } } </s>

Returns if the result of this instruction with a 16-bit result returned in a 32-bit register implicitly zeroes the high 16-bits , rather than preserve the original value .


<s>
virtual
const
char
*
getPassName
(
)
const
{
return
"TLCS900 Assembly Printer"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> static void rs6000_option_override ( void ) { ( void ) rs6000_option_override_internal ( true ) ; } </s>

Implement TARGET_OPTION_OVERRIDE . On the RS/6000 this is used to define the target cpu type .


<s> void GCNPassConfig :: addPreSched2 ( ) { addPass ( & SIPostRABundlerID ) ; } </s>

This method may be implemented by targets that want to run passes after prolog-epilog insertion and before the second instruction scheduling pass .


<s> void MipsTargetStreamer :: emitStoreWithImmOffset ( unsigned Opcode , unsigned SrcReg , unsigned BaseReg , int64_t Offset , std :: function < unsigned ( ) > GetATReg , SMLoc IDLoc , const MCSubtargetInfo * STI ) { if ( isInt < 16 > ( Offset ) ) { emitRRI ( Opcode , SrcReg , BaseReg , Offset , IDLoc , STI ) ; return ; } unsigned ATReg = GetATReg ( ) ; if ( ! ATReg ) return ; unsigned LoOffset = Offset & 0x0000ffff ; unsigned HiOffset = ( Offset & 0xffff0000 ) >> 16 ; if ( LoOffset & 0x8000 ) HiOffset ++ ; emitRI ( Mips :: LUi , ATReg , HiOffset , IDLoc , STI ) ; if ( BaseReg != Mips :: ZERO ) emitRRR ( Mips :: ADDu , ATReg , ATReg , BaseReg , IDLoc , STI ) ; emitRRI ( Opcode , SrcReg , ATReg , LoOffset , IDLoc , STI ) ; } </s>

Emit a store instruction with an offset .


"Encoding of this operand type is not supported yet."

getMachineOpValue - Return binary encoding of operand .


<s> static machine_mode aarch64_simd_container_mode ( scalar_mode mode , poly_int64 width ) { if ( TARGET_SVE && maybe_ne ( width , 128 ) && known_eq ( width , BITS_PER_SVE_VECTOR ) ) return aarch64_full_sve_mode ( mode ) . else_mode ( word_mode ) ; gcc_assert ( known_eq ( width , 64 ) || known_eq ( width , 128 ) ) ; if ( TARGET_SIMD ) { if ( known_eq ( width , 128 ) ) return aarch64_vq_mode ( mode ) . else_mode ( word_mode ) ; else switch ( mode ) { case E_SFmode : return V2SFmode ; case E_HFmode : return V4HFmode ; case E_BFmode : return V4BFmode ; case E_SImode : return V2SImode ; case E_HImode : return V4HImode ; case E_QImode : return V8QImode ; default : break ; } } return word_mode ; } </s>

Return appropriate SIMD container for MODE within a vector of WIDTH bits .


<s> Value * X86TargetLowering :: getIRStackGuard ( IRBuilder < > & IRB ) const { if ( hasStackGuardSlotTLS ( Subtarget . getTargetTriple ( ) ) ) { if ( Subtarget . isTargetFuchsia ( ) ) { return SegmentOffset ( IRB , 0x10 , getAddressSpace ( ) ) ; } else { unsigned Offset = ( Subtarget . is64Bit ( ) ) ? 0x28 : 0x14 ; return SegmentOffset ( IRB , Offset , getAddressSpace ( ) ) ; } } return TargetLowering :: getIRStackGuard ( IRB ) ; } </s>

If the target has a standard location for the stack protector cookie , returns the address of that location .


<s> int microblaze_expand_shift ( rtx operands [ ] ) { gcc_assert ( ( GET_CODE ( operands [ 2 ] ) == CONST_INT ) || ( GET_CODE ( operands [ 2 ] ) == REG ) || ( GET_CODE ( operands [ 2 ] ) == SUBREG ) ) ; if ( ( GET_CODE ( operands [ 2 ] ) == CONST_INT ) && ( INTVAL ( operands [ 2 ] ) == 1 ) ) return 0 ; if ( TARGET_BARREL_SHIFT ) return 0 ; gcc_assert ( ( GET_CODE ( operands [ 0 ] ) == REG ) || ( GET_CODE ( operands [ 0 ] ) == SUBREG ) || ( GET_CODE ( operands [ 1 ] ) == REG ) || ( GET_CODE ( operands [ 1 ] ) == SUBREG ) ) ; if ( ( GET_CODE ( operands [ 2 ] ) == CONST_INT ) && ( INTVAL ( operands [ 2 ] ) == 0 ) ) { if ( REGNO ( operands [ 0 ] ) != REGNO ( operands [ 1 ] ) ) emit_insn ( gen_movsi ( operands [ 0 ] , operands [ 1 ] ) ) ; return 1 ; } return 0 ; } </s>


<s> bool runOnMachineFunction ( MachineFunction & F ) { if ( SkipDelaySlotFiller ) return false ; bool Changed = false ; for ( MachineFunction :: iterator FI = F . begin ( ) , FE = F . end ( ) ; FI != FE ; ++ FI ) Changed |= runOnMachineBasicBlock ( * FI ) ; return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s> std :: pair < unsigned , const TargetRegisterClass * > AArch64TargetLowering :: getRegForInlineAsmConstraint ( const TargetRegisterInfo * TRI , StringRef Constraint , MVT VT ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { case 'r' : if ( VT . getSizeInBits ( ) == 64 ) return std :: make_pair ( 0U , & AArch64 :: GPR64commonRegClass ) ; return std :: make_pair ( 0U , & AArch64 :: GPR32commonRegClass ) ; case 'w' : if ( VT == MVT :: f32 ) return std :: make_pair ( 0U , & AArch64 :: FPR32RegClass ) ; if ( VT . getSizeInBits ( ) == 64 ) return std :: make_pair ( 0U , & AArch64 :: FPR64RegClass ) ; if ( VT . getSizeInBits ( ) == 128 ) return std :: make_pair ( 0U , & AArch64 :: FPR128RegClass ) ; break ; case 'x' : if ( VT . getSizeInBits ( ) == 128 ) return std :: make_pair ( 0U , & AArch64 :: FPR128_loRegClass ) ; break ; } } if ( StringRef ( "{cc}" ) . equals_lower ( Constraint ) ) return std :: make_pair ( unsigned ( AArch64 :: NZCV ) , & AArch64 :: CCRRegClass ) ; std :: pair < unsigned , const TargetRegisterClass * > Res ; Res = TargetLowering :: getRegForInlineAsmConstraint ( TRI , Constraint , VT ) ; if ( ! Res . second ) { unsigned Size = Constraint . size ( ) ; if ( ( Size == 4 || Size == 5 ) && Constraint [ 0 ] == '{' && tolower ( Constraint [ 1 ] ) == 'v' && Constraint [ Size - 1 ] == '}' ) { int RegNo ; bool Failed = Constraint . slice ( 2 , Size - 1 ) . getAsInteger ( 10 , RegNo ) ; if ( ! Failed && RegNo >= 0 && RegNo <= 31 ) { Res . first = AArch64 :: FPR128RegClass . getRegister ( RegNo ) ; Res . second = & AArch64 :: FPR128RegClass ; } } } return Res ; } </s>

Given a physical register constraint ( e.g .


<s> static int rs6000_variable_issue_1 ( rtx_insn * insn , int more ) { last_scheduled_insn = insn ; if ( GET_CODE ( PATTERN ( insn ) ) == USE || GET_CODE ( PATTERN ( insn ) ) == CLOBBER ) { cached_can_issue_more = more ; return cached_can_issue_more ; } if ( insn_terminates_group_p ( insn , current_group ) ) { cached_can_issue_more = 0 ; return cached_can_issue_more ; } if ( recog_memoized ( insn ) < 0 ) return more ; if ( rs6000_sched_groups ) { if ( is_microcoded_insn ( insn ) ) cached_can_issue_more = 0 ; else if ( is_cracked_insn ( insn ) ) cached_can_issue_more = more > 2 ? more - 2 : 0 ; else cached_can_issue_more = more - 1 ; return cached_can_issue_more ; } if ( rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn ( insn ) ) return 0 ; cached_can_issue_more = more - 1 ; return cached_can_issue_more ; } </s>

Power4 load update and store update instructions are cracked into a load or store and an integer insn which are executed in the same cycle . Branches have their own dispatch slot which does not count against the GCC issue rate , but it changes the program flow so there are no other instructions to issue in this cycle .


<s> virtual const TMS320C64XInstrInfo * getInstrInfo ( ) const { return & InstrInfo ; } </s>


<s> unsigned X86InstrInfo :: getPartialRegUpdateClearance ( const MachineInstr & MI , unsigned OpNum , const TargetRegisterInfo * TRI ) const { if ( OpNum != 0 || ! hasPartialRegUpdate ( MI . getOpcode ( ) , Subtarget ) ) return 0 ; const MachineOperand & MO = MI . getOperand ( 0 ) ; unsigned Reg = MO . getReg ( ) ; if ( TargetRegisterInfo :: isVirtualRegister ( Reg ) ) { if ( MO . readsReg ( ) || MI . readsVirtualRegister ( Reg ) ) return 0 ; } else { if ( MI . readsRegister ( Reg , TRI ) ) return 0 ; } return PartialRegUpdateClearance ; } </s>

Inform the BreakFalseDeps pass how many idle instructions we would like before a partial register update .


<s>
X86TargetMachine
::
X86TargetMachine
(
const
Target
&
T
,
const
std
::
string
&
TT
,
const
std
::
string
&
FS
,
bool
is64Bit
)
:
LLVMTargetMachine
(
T
,
TT
)
,
Subtarget
(
TT
,
FS
,
is64Bit
)
,
DataLayout
(
Subtarget
.
getDataLayout
(
)
)
,
FrameInfo
(
TargetFrameInfo
::
StackGrowsDown
,
Subtarget
.
getStackAlignment
(
)
,
(
Subtarget
.
isTargetWin64
(
)
40
:
(
Subtarget
.
is64Bit
(
)
8
:
4
)
)
)
,
InstrInfo
(
*
this
)
,
JITInfo
(
*
this
)
,
TLInfo
(
*
this
)
,
ELFWriterInfo
(
*
this
)
{
DefRelocModel
=
getRelocationModel
(
)
;
if
(
getRelocationModel
(
)
==
Reloc
::
Default
)
{
if
(
!
Subtarget
.
isTargetDarwin
(
)
)
setRelocationModel
(
Reloc
::
Static
)
;
else
if
(
Subtarget
.
is64Bit
(
)
)
setRelocationModel
(
Reloc
::
PIC_
)
;
else
setRelocationModel
(
Reloc
::
DynamicNoPIC
)
;
}
assert
(
getRelocationModel
(
)
!=
Reloc
::
Default
&&
"Relocation mode not picked"
)
;
if
(
getCodeModel
(
)
==
CodeModel
::
Default
)
setCodeModel
(
CodeModel
::
Small
)
;
if
(
getRelocationModel
(
)
==
Reloc
::
DynamicNoPIC
)
{
if
(
is64Bit
)
setRelocationModel
(
Reloc
::
PIC_
)
;
else
if
(
!
Subtarget
.
isTargetDarwin
(
)
)
setRelocationModel
(
Reloc
::
Static
)
;
}
if
(
getRelocationModel
(
)
==
Reloc
::
Static
&&
Subtarget
.
isTargetDarwin
(
)
&&
is64Bit
)
setRelocationModel
(
Reloc
::
PIC_
)
;
if
(
getRelocationModel
(
)
==
Reloc
::
Static
)
{
Subtarget
.
setPICStyle
(
PICStyles
::
)
;
}
else
if
(
Subtarget
.
isTargetCygMing
(
)
)
{
Subtarget
.
setPICStyle
(
PICStyles
::
)
;
}
else
if
(
Subtarget
.
isTargetDarwin
(
)
)
{
if
(
Subtarget
.
is64Bit
(
)
)
Subtarget
.
setPICStyle
(
PICStyles
::
RIPRel
)
;
else
if
(
getRelocationModel
(
)
==
Reloc
::
PIC_
)
Subtarget
.
setPICStyle
(
PICStyles
::
StubPIC
)
;
else
{
assert
(
getRelocationModel
(
)
==
Reloc
::
DynamicNoPIC
)
;
Subtarget
.
setPICStyle
(
PICStyles
::
StubDynamicNoPIC
)
;
}
}
else
if
(
Subtarget
.
isTargetELF
(
)
)
{
if
(
Subtarget
.
is64Bit
(
)
)
Subtarget
.
setPICStyle
(
PICStyles
::
RIPRel
)
;
else
Subtarget
.
setPICStyle
(
PICStyles
::
GOT
)
;
}
if
(
Subtarget
.
getPICStyle
(
)
==
PICStyles
::
)
setRelocationModel
(
Reloc
::
Static
)
;
}
</s>


<s> static void aarch64_option_save ( struct cl_target_option * ptr , struct gcc_options * opts , struct gcc_options * ) { ptr -> x_aarch64_override_tune_string = opts -> x_aarch64_override_tune_string ; ptr -> x_aarch64_branch_protection_string = opts -> x_aarch64_branch_protection_string ; } </s>


<s> static void spu_destroy_cost_data ( void * data ) { free ( data ) ; } </s>


<s> static bool csky_function_value_regno_p ( const unsigned int regno ) { if ( regno == CSKY_FIRST_RET_REGNUM || ( TARGET_HARD_FLOAT_ABI && regno == CSKY_FIRST_VFP_REGNUM ) ) return true ; return false ; } </s>

Implement TARGET_FUNCTION_VALUE_REGNO_P . On C-SKY , only r0 can return results .


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


<s> void x86_initialize_trampoline ( rtx tramp , rtx fnaddr , rtx cxt ) { if ( ! TARGET_64BIT ) { rtx disp = expand_binop ( SImode , sub_optab , fnaddr , plus_constant ( tramp , 10 ) , NULL_RTX , 1 , OPTAB_DIRECT ) ; emit_move_insn ( gen_rtx_MEM ( QImode , tramp ) , gen_int_mode ( 0xb9 , QImode ) ) ; emit_move_insn ( gen_rtx_MEM ( SImode , plus_constant ( tramp , 1 ) ) , cxt ) ; emit_move_insn ( gen_rtx_MEM ( QImode , plus_constant ( tramp , 5 ) ) , gen_int_mode ( 0xe9 , QImode ) ) ; emit_move_insn ( gen_rtx_MEM ( SImode , plus_constant ( tramp , 6 ) ) , disp ) ; } else { int offset = 0 ; if ( x86_64_zext_immediate_operand ( fnaddr , VOIDmode ) ) { fnaddr = copy_to_mode_reg ( DImode , fnaddr ) ; emit_move_insn ( gen_rtx_MEM ( HImode , plus_constant ( tramp , offset ) ) , gen_int_mode ( 0xbb41 , HImode ) ) ; emit_move_insn ( gen_rtx_MEM ( SImode , plus_constant ( tramp , offset + 2 ) ) , gen_lowpart ( SImode , fnaddr ) ) ; offset += 6 ; } else { emit_move_insn ( gen_rtx_MEM ( HImode , plus_constant ( tramp , offset ) ) , gen_int_mode ( 0xbb49 , HImode ) ) ; emit_move_insn ( gen_rtx_MEM ( DImode , plus_constant ( tramp , offset + 2 ) ) , fnaddr ) ; offset += 10 ; } emit_move_insn ( gen_rtx_MEM ( HImode , plus_constant ( tramp , offset ) ) , gen_int_mode ( 0xba49 , HImode ) ) ; emit_move_insn ( gen_rtx_MEM ( DImode , plus_constant ( tramp , offset + 2 ) ) , cxt ) ; offset += 10 ; emit_move_insn ( gen_rtx_MEM ( HImode , plus_constant ( tramp , offset ) ) , gen_int_mode ( 0xff49 , HImode ) ) ; emit_move_insn ( gen_rtx_MEM ( QImode , plus_constant ( tramp , offset + 2 ) ) , gen_int_mode ( 0xe3 , QImode ) ) ; offset += 3 ; gcc_assert ( offset <= TRAMPOLINE_SIZE ) ; } emit_library_call ( gen_rtx_SYMBOL_REF ( Pmode , "__enable_execute_stack" ) , LCT_NORMAL , VOIDmode , 1 , tramp , Pmode ) ; } </s>

Emit RTL insns to initialize the variable parts of a trampoline . FNADDR is an RTX for the address of the function 's pure code . CXT is an RTX for the static chain value for the function .


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


<s> std :: unique_ptr < SICacheControl > SICacheControl :: create ( const GCNSubtarget & ST ) { GCNSubtarget :: Generation Generation = ST . getGeneration ( ) ; if ( ST . hasGFX90AInsts ( ) ) return std :: make_unique < SIGfx90ACacheControl > ( ST ) ; if ( Generation <= AMDGPUSubtarget :: SOUTHERN_ISLANDS ) return std :: make_unique < SIGfx6CacheControl > ( ST ) ; if ( Generation < AMDGPUSubtarget :: GFX10 ) return std :: make_unique < SIGfx7CacheControl > ( ST ) ; return std :: make_unique < SIGfx10CacheControl > ( ST ) ; } </s>


<s> void MipsTargetELFStreamer :: finish ( ) { MCAssembler & MCA = getStreamer ( ) . getAssembler ( ) ; MCContext & Context = MCA . getContext ( ) ; MCStreamer & OS = getStreamer ( ) ; Triple T ( STI . getTargetTriple ( ) ) ; uint64_t Features = STI . getFeatureBits ( ) ; if ( T . isArch64Bit ( ) && ( Features & Mips :: FeatureN64 ) ) { const MCSectionELF * Sec = Context . getELFSection ( ".MIPS.options" , ELF :: SHT_MIPS_OPTIONS , ELF :: SHF_ALLOC | ELF :: SHF_MIPS_NOSTRIP , SectionKind :: getMetadata ( ) ) ; OS . SwitchSection ( Sec ) ; OS . EmitIntValue ( 1 , 1 ) ; OS . EmitIntValue ( 40 , 1 ) ; OS . EmitIntValue ( 0 , 2 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 8 ) ; } else { const MCSectionELF * Sec = Context . getELFSection ( ".reginfo" , ELF :: SHT_MIPS_REGINFO , ELF :: SHF_ALLOC , SectionKind :: getMetadata ( ) ) ; OS . SwitchSection ( Sec ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; OS . EmitIntValue ( 0 , 4 ) ; } } </s>

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


<s>
void
print_operand_address
(
FILE
*
file
,
rtx
addr
)
{
struct
s390_address
ad
;
if
(
s390_loadrelative_operand_p
(
addr
,
,
)
)
{
if
(
!
TARGET_Z10
)
{
output_operand_lossage
(
"symbolic memory references are "
"only supported on z10 or later"
)
;
return
;
}
output_addr_const
(
file
,
addr
)
;
return
;
}
if
(
!
s390_decompose_address
(
addr
,
&
ad
)
||
(
ad
.
base
&&
!
REGNO_OK_FOR_BASE_P
(
REGNO
(
ad
.
base
)
)
)
||
(
ad
.
indx
&&
!
REGNO_OK_FOR_INDEX_P
(
REGNO
(
ad
.
indx
)
)
)
)
output_operand_lossage
(
"cannot decompose address"
)
;
if
(
ad
.
disp
)
output_addr_const
(
file
,
ad
.
disp
)
;
else
fprintf
(
file
,
"0"
)
;
if
(
ad
.
base
&&
ad
.
indx
)
fprintf
(
file
,
"(%s,%s)"
,
reg_names
[
REGNO
(
ad
.
indx
)
]
,
reg_names
[
REGNO
(
ad
.
base
)
]
)
;
else
if
(
ad
.
base
)
fprintf
(
file
,
"(%s)"
,
reg_names
[
REGNO
(
ad
.
base
)
]
)
;
}
</s>

Print the operand address represented by the rtx addr

s390
"symbolic memory references are "
"only supported on z10 or later"
"cannot decompose address"
"0"
"(%s,%s)"
"(%s)"


"`%s' attribute only applies to functions"

"can't apply both longcall and shortcall attributes to the same function"

Handle a `` longcall '' or `` shortcall '' attribute ; arguments as in struct attribute_spec.handler .


<s> bool isDead ( ) const { return IsDead ; } </s>

isDead - Returns true if this is a dead def kill slot .


<s> bool MipsAsmPrinter :: runOnMachineFunction ( MachineFunction & MF ) { Subtarget = & MF . getSubtarget < MipsSubtarget > ( ) ; MipsFI = MF . getInfo < MipsFunctionInfo > ( ) ; if ( Subtarget -> inMips16Mode ( ) ) for ( const auto & I : MipsFI -> StubsNeeded ) { const char * Symbol = I . first ; const Mips16HardFloatInfo :: FuncSignature * Signature = I . second ; if ( StubsNeeded . find ( Symbol ) == StubsNeeded . end ( ) ) StubsNeeded [ Symbol ] = Signature ; } MCP = MF . getConstantPool ( ) ; if ( Subtarget -> isTargetNaCl ( ) ) NaClAlignIndirectJumpTargets ( MF ) ; AsmPrinter :: runOnMachineFunction ( MF ) ; emitXRayTable ( ) ; return true ; } </s>

Mips Mips Mips Mips Mips Mips Mips Mips16HardFloatInfo::FuncSignature


<s>
StringRef
getPassName
(
)
const
override
{
return
"Patmos Single-Path Clone (bitcode)"
;
}
</s>

getPassName - Return a nice clean name for a pass .

Patmos
"Patmos Single-Path Clone (bitcode)"


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getSubtarget ( ) . getFrameLowering ( ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; Reserved . set ( ARM :: APSR_NZCV ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( FramePtr ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; if ( ! STI . hasVFP3 ( ) || STI . hasD16 ( ) ) { assert ( ARM :: D31 == ARM :: D16 + 15 ) ; for ( unsigned i = 0 ; i != 16 ; ++ i ) Reserved . set ( ARM :: D16 + i ) ; } const TargetRegisterClass * RC = & ARM :: GPRPairRegClass ; for ( TargetRegisterClass :: iterator I = RC -> begin ( ) , E = RC -> end ( ) ; I != E ; ++ I ) for ( MCSubRegIterator SI ( * I , this ) ; SI . isValid ( ) ; ++ SI ) if ( Reserved . test ( * SI ) ) Reserved . set ( * I ) ; 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> bool AArch64TargetLowering :: isReassocProfitable ( SelectionDAG & DAG , SDValue N0 , SDValue N1 ) const { if ( ! N0 . hasOneUse ( ) ) return false ; unsigned IID = getIntrinsicID ( N1 . getNode ( ) ) ; if ( IID == Intrinsic :: aarch64_neon_umull || N1 . getOpcode ( ) == AArch64ISD :: UMULL || IID == Intrinsic :: aarch64_neon_smull || N1 . getOpcode ( ) == AArch64ISD :: SMULL ) return N0 . getOpcode ( ) != ISD :: ADD ; return true ; } </s>

Control the following reassociation of operands : ( op ( op x , c1 ) , y ) - > ( op ( op x , y ) , c1 ) where N0 is ( op x , c1 ) and N1 is y .


<s> SMLoc getEndLoc ( ) const { return EndLoc ; } </s>

getEndLoc - Get the location of the last token of this operand .


<s> int insvdi_rshift_rlwimi_p ( rtx sizeop , rtx startop , rtx shiftop ) { if ( INTVAL ( startop ) < 64 && INTVAL ( startop ) > 32 && ( INTVAL ( sizeop ) + INTVAL ( startop ) < 64 ) && ( INTVAL ( sizeop ) + INTVAL ( startop ) > 33 ) && ( INTVAL ( sizeop ) + INTVAL ( startop ) + INTVAL ( shiftop ) < 96 ) && ( INTVAL ( sizeop ) + INTVAL ( startop ) + INTVAL ( shiftop ) >= 64 ) && ( 64 - ( INTVAL ( shiftop ) & 63 ) ) >= INTVAL ( sizeop ) ) return 1 ; return 0 ; } </s>

Return 1 if operands will generate a valid arguments to rlwimiinstruction for insert with right shift in 64-bit mode . The mask maynot start on the first bit or stop on the last bit because wrap-aroundeffects of instruction do not correspond to semantics of RTL insn .


<s> virtual MVT getShiftAmountTy ( EVT LHSTy ) const { return MVT :: i8 ; } </s>

Returns the type for the shift amount of a shift opcode .


<s> bool msp430_use_f5_series_hwmult ( void ) { static const char * cached_match = NULL ; static bool cached_result ; if ( msp430_hwmult_type == F5SERIES ) return true ; if ( target_mcu == NULL || msp430_hwmult_type != AUTO ) return false ; if ( target_mcu == cached_match ) return cached_result ; cached_match = target_mcu ; if ( strncasecmp ( target_mcu , "msp430f5" , 8 ) == 0 ) return cached_result = true ; if ( strncasecmp ( target_mcu , "msp430fr5" , 9 ) == 0 ) return cached_result = true ; if ( strncasecmp ( target_mcu , "msp430f6" , 8 ) == 0 ) return cached_result = true ; int i ; for ( i = ARRAY_SIZE ( msp430_mcu_data ) ; i -- ; ) if ( strcasecmp ( target_mcu , msp430_mcu_data [ i ] . name ) == 0 ) return cached_result = msp430_mcu_data [ i ] . hwmpy == 8 ; return cached_result = false ; } </s>

Returns true if the current MCU supports an F5xxx series hardware multiper .


Returns the number of bytes offset between FROM_REG and TO_REG for the current function . As a side effect it fills in the current_frame_info structure , if the data is available .


<s> MachineBasicBlock * SITargetLowering :: EmitInstrWithCustomInserter ( MachineInstr * MI , MachineBasicBlock * BB ) const { MachineBasicBlock :: iterator I = * MI ; const SIInstrInfo * TII = static_cast < const SIInstrInfo * > ( getTargetMachine ( ) . getSubtargetImpl ( ) -> getInstrInfo ( ) ) ; switch ( MI -> getOpcode ( ) ) { default : return AMDGPUTargetLowering :: EmitInstrWithCustomInserter ( MI , BB ) ; case AMDGPU :: BRANCH : return BB ; case AMDGPU :: V_SUB_F64 : { unsigned DestReg = MI -> getOperand ( 0 ) . getReg ( ) ; BuildMI ( * BB , I , MI -> getDebugLoc ( ) , TII -> get ( AMDGPU :: V_ADD_F64 ) , DestReg ) . addImm ( 0 ) . addReg ( MI -> getOperand ( 1 ) . getReg ( ) ) . addImm ( 1 ) . addReg ( MI -> getOperand ( 2 ) . getReg ( ) ) . addImm ( 0 ) . addImm ( 0 ) ; MI -> eraseFromParent ( ) ; break ; } case AMDGPU :: SI_RegisterStorePseudo : { MachineRegisterInfo & MRI = BB -> getParent ( ) -> getRegInfo ( ) ; unsigned Reg = MRI . createVirtualRegister ( & AMDGPU :: SReg_64RegClass ) ; MachineInstrBuilder MIB = BuildMI ( * BB , I , MI -> getDebugLoc ( ) , TII -> get ( AMDGPU :: SI_RegisterStore ) , Reg ) ; for ( unsigned i = 0 , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) MIB . addOperand ( MI -> getOperand ( i ) ) ; MI -> eraseFromParent ( ) ; break ; } } return BB ; } </s>

This method should be implemented by targets that mark instructions with the 'usesCustomInserter ' flag .


<s> bool runOnFunction ( Function & F ) override { if ( ! X86ScalarizeAMX ) return false ; TargetMachine * TM = & getAnalysis < TargetPassConfig > ( ) . getTM < TargetMachine > ( ) ; if ( ! F . hasFnAttribute ( Attribute :: OptimizeNone ) && TM -> getOptLevel ( ) != CodeGenOpt :: None ) return false ; auto * DTWP = getAnalysisIfAvailable < DominatorTreeWrapperPass > ( ) ; auto * DT = DTWP ? & DTWP -> getDomTree ( ) : nullptr ; auto * LIWP = getAnalysisIfAvailable < LoopInfoWrapperPass > ( ) ; auto * LI = LIWP ? & LIWP -> getLoopInfo ( ) : nullptr ; DomTreeUpdater DTU ( DT , DomTreeUpdater :: UpdateStrategy :: Lazy ) ; X86LowerAMXIntrinsics LAT ( F , DTU , LI ) ; return LAT . visit ( ) ; } </s>

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


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

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


<s>
SDNode
*
MBlazeDAGToDAGISel
::
Select
(
SDNode
*
Node
)
{
unsigned
Opcode
=
Node
->
getOpcode
(
)
;
DebugLoc
dl
=
Node
->
getDebugLoc
(
)
;
if
(
Node
->
isMachineOpcode
(
)
)
return
;
switch
(
Opcode
)
{
default
:
break
;
case
ISD
::
GLOBAL_OFFSET_TABLE
:
return
getGlobalBaseReg
(
)
;
case
ISD
::
FrameIndex
:
{
SDValue
imm
=
CurDAG
->
getTargetConstant
(
0
,
MVT
::
i32
)
;
int
FI
=
dyn_cast
<
FrameIndexSDNode
>
(
Node
)
->
getIndex
(
)
;
EVT
VT
=
Node
->
getValueType
(
0
)
;
SDValue
TFI
=
CurDAG
->
getTargetFrameIndex
(
FI
,
VT
)
;
unsigned
Opc
=
MBlaze
::
ADDIK
;
if
(
Node
->
hasOneUse
(
)
)
return
CurDAG
->
SelectNodeTo
(
Node
,
Opc
,
VT
,
TFI
,
imm
)
;
return
CurDAG
->
getMachineNode
(
Opc
,
dl
,
VT
,
TFI
,
imm
)
;
}
case
MBlazeISD
::
JmpLink
:
{
if
(
TM
.
getRelocationModel
(
)
==
Reloc
::
PIC_
)
{
SDValue
Chain
=
Node
->
getOperand
(
0
)
;
SDValue
Callee
=
Node
->
getOperand
(
1
)
;
SDValue
R20Reg
=
CurDAG
->
getRegister
(
MBlaze
::
R20
,
MVT
::
i32
)
;
SDValue
InFlag
(
0
,
0
)
;
if
(
(
isa
<
GlobalAddressSDNode
>
(
Callee
)
)
||
(
isa
<
ExternalSymbolSDNode
>
(
Callee
)
)
)
{
SDValue
GPReg
=
CurDAG
->
getRegister
(
MBlaze
::
R15
,
MVT
::
i32
)
;
SDValue
Ops
[
]
=
{
Callee
,
GPReg
,
Chain
}
;
SDValue
Load
=
SDValue
(
CurDAG
->
getMachineNode
(
MBlaze
::
LW
,
dl
,
MVT
::
i32
,
MVT
::
Other
,
Ops
,
3
)
,
0
)
;
Chain
=
Load
.
getValue
(
1
)
;
Chain
=
CurDAG
->
getCopyToReg
(
Chain
,
dl
,
R20Reg
,
Load
,
InFlag
)
;
}
else
Chain
=
CurDAG
->
getCopyToReg
(
Chain
,
dl
,
R20Reg
,
Callee
,
InFlag
)
;
SDNode
*
ResNode
=
CurDAG
->
getMachineNode
(
MBlaze
::
BRLID
,
dl
,
MVT
::
Other
,
MVT
::
Glue
,
R20Reg
,
Chain
)
;
Chain
=
SDValue
(
ResNode
,
0
)
;
InFlag
=
SDValue
(
ResNode
,
1
)
;
ReplaceUses
(
SDValue
(
Node
,
0
)
,
Chain
)
;
ReplaceUses
(
SDValue
(
Node
,
1
)
,
InFlag
)
;
return
ResNode
;
}
}
}
SDNode
*
ResNode
=
SelectCode
(
Node
)
;
DEBUG
(
errs
(
)
<<
"=> "
)
;
if
(
ResNode
==
||
ResNode
==
Node
)
DEBUG
(
Node
->
dump
(
CurDAG
)
)
;
else
DEBUG
(
ResNode
->
dump
(
CurDAG
)
)
;
DEBUG
(
errs
(
)
<<
"\n"
)
;
return
ResNode
;
}
</s>

Main hook for targets to transform nodes into machine nodes .


<s> const DataLayout * getDataLayout ( ) const override { return & DL ; } </s>

Return the DataLayout associated with the module this SCEV instance is operating on .


Return true iff x is a uniform vector of floating-point constants , and the constant can be represented in quarter-precision form . Note , as aarch64_float_const_representable rejects both +0.0 and -0.0 , we will also reject +0.0 and -0.0 .


<s>
bool
SystemZAsmParser
::
MatchAndEmitInstruction
(
SMLoc
IDLoc
,
unsigned
&
Opcode
,
SmallVectorImpl
<
MCParsedAsmOperand
*
>
&
Operands
,
MCStreamer
&
Out
,
unsigned
&
ErrorInfo
,
bool
MatchingInlineAsm
)
{
MCInst
Inst
;
unsigned
MatchResult
;
MatchResult
=
MatchInstructionImpl
(
Operands
,
Inst
,
ErrorInfo
,
MatchingInlineAsm
)
;
switch
(
MatchResult
)
{
default
:
break
;
case
Match_Success
:
Inst
.
setLoc
(
IDLoc
)
;
Out
.
EmitInstruction
(
Inst
)
;
return
false
;
case
Match_MissingFeature
:
{
assert
(
ErrorInfo
&&
"Unknown missing feature!"
)
;
std
::
string
Msg
=
"instruction requires:"
;
unsigned
Mask
=
1
;
for
(
unsigned
I
=
0
;
I
<
sizeof
(
ErrorInfo
)
*
8
1
;
++
I
)
{
if
(
ErrorInfo
&
Mask
)
{
Msg
+=
" "
;
Msg
+=
getSubtargetFeatureName
(
ErrorInfo
&
Mask
)
;
}
Mask
<<=
1
;
}
return
Error
(
IDLoc
,
Msg
)
;
}
case
Match_InvalidOperand
:
{
SMLoc
ErrorLoc
=
IDLoc
;
if
(
ErrorInfo
!=
~
0U
)
{
if
(
ErrorInfo
>=
Operands
.
size
(
)
)
return
Error
(
IDLoc
,
"too few operands for instruction"
)
;
ErrorLoc
=
(
(
SystemZOperand
*
)
Operands
[
ErrorInfo
]
)
->
getStartLoc
(
)
;
if
(
ErrorLoc
==
SMLoc
(
)
)
ErrorLoc
=
IDLoc
;
}
return
Error
(
ErrorLoc
,
"invalid operand for instruction"
)
;
}
case
Match_MnemonicFail
:
return
Error
(
IDLoc
,
"invalid instruction"
)
;
}
llvm_unreachable
(
"Unexpected match type"
)
;
}
</s>

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


<s> static int ix86_mode_entry ( int entity ) { switch ( entity ) { case X86_DIRFLAG : return ix86_dirflag_mode_entry ( ) ; case AVX_U128 : return ix86_avx_u128_mode_entry ( ) ; case I387_TRUNC : case I387_FLOOR : case I387_CEIL : return I387_CW_ANY ; default : gcc_unreachable ( ) ; } } </s>

Return a mode that ENTITY is assumed to be switched to at function entry .


<s> static unsigned parse_field ( const std :: string & field ) { const char * rest = strchr ( field . c_str ( ) , ':' ) ; if ( rest == NULL ) return - 1 ; char * after ; unsigned fint = strtol ( rest + 1 , & after , 16 ) ; if ( after == rest + 1 ) return - 1 ; return fint ; } </s>

Returns the hex integer that is after ' : ' for the FIELD . Returns -1 is returned if there was problem parsing the integer .


<s> void print_operand_address ( FILE * file , rtx x ) { if ( REG_P ( x ) ) fprintf ( file , "0(%s)" , reg_names [ REGNO ( x ) ] ) ; else if ( GET_CODE ( x ) == SYMBOL_REF || GET_CODE ( x ) == CONST || GET_CODE ( x ) == LABEL_REF ) { output_addr_const ( file , x ) ; if ( small_data_operand ( x , GET_MODE ( x ) ) ) fprintf ( file , "@%s(%s)" , SMALL_DATA_RELOC , reg_names [ SMALL_DATA_REG ] ) ; else gcc_assert ( ! TARGET_TOC ) ; } else if ( GET_CODE ( x ) == PLUS && REG_P ( XEXP ( x , 0 ) ) && REG_P ( XEXP ( x , 1 ) ) ) { if ( REGNO ( XEXP ( x , 0 ) ) == 0 ) fprintf ( file , "%s,%s" , reg_names [ REGNO ( XEXP ( x , 1 ) ) ] , reg_names [ REGNO ( XEXP ( x , 0 ) ) ] ) ; else fprintf ( file , "%s,%s" , reg_names [ REGNO ( XEXP ( x , 0 ) ) ] , reg_names [ REGNO ( XEXP ( x , 1 ) ) ] ) ; } else if ( GET_CODE ( x ) == PLUS && REG_P ( XEXP ( x , 0 ) ) && GET_CODE ( XEXP ( x , 1 ) ) == CONST_INT ) fprintf ( file , HOST_WIDE_INT_PRINT_DEC "(%s)" , INTVAL ( XEXP ( x , 1 ) ) , reg_names [ REGNO ( XEXP ( x , 0 ) ) ] ) ; else if ( GET_CODE ( x ) == LO_SUM && REG_P ( XEXP ( x , 0 ) ) && CONSTANT_P ( XEXP ( x , 1 ) ) ) { fprintf ( file , "lo16(" ) ; output_addr_const ( file , XEXP ( x , 1 ) ) ; fprintf ( file , ")(%s)" , reg_names [ REGNO ( XEXP ( x , 0 ) ) ] ) ; } else if ( GET_CODE ( x ) == LO_SUM && REG_P ( XEXP ( x , 0 ) ) && CONSTANT_P ( XEXP ( x , 1 ) ) ) { output_addr_const ( file , XEXP ( x , 1 ) ) ; fprintf ( file , "@l(%s)" , reg_names [ REGNO ( XEXP ( x , 0 ) ) ] ) ; } else if ( toc_relative_expr_p ( x , false , & tocrel_base_oac , & tocrel_offset_oac ) ) { output_addr_const ( file , CONST_CAST_RTX ( tocrel_base_oac ) ) ; if ( GET_CODE ( x ) == LO_SUM ) fprintf ( file , "@l(%s)" , reg_names [ REGNO ( XEXP ( x , 0 ) ) ] ) ; else fprintf ( file , "(%s)" , reg_names [ REGNO ( XVECEXP ( tocrel_base_oac , 0 , 1 ) ) ] ) ; } else gcc_unreachable ( ) ; } </s>

Print the operand address represented by the rtx addr


<s> static inline void aarch64_add_sp ( rtx temp1 , rtx temp2 , poly_int64 delta , bool emit_move_imm ) { aarch64_add_offset ( Pmode , stack_pointer_rtx , stack_pointer_rtx , delta , temp1 , temp2 , true , emit_move_imm ) ; } </s>

Add DELTA to the stack pointer , marking the instructions frame-related . TEMP1 is available as a temporary if nonnull . EMIT_MOVE_IMM is false if TEMP1 already contains abs ( DELTA ) .


<s> bool SITargetLowering :: requiresUniformRegister ( MachineFunction & MF , const Value * V ) const { if ( const IntrinsicInst * Intrinsic = dyn_cast < IntrinsicInst > ( V ) ) { switch ( Intrinsic -> getIntrinsicID ( ) ) { default : return false ; case Intrinsic :: amdgcn_if_break : return true ; } } if ( const ExtractValueInst * ExtValue = dyn_cast < ExtractValueInst > ( V ) ) { if ( const IntrinsicInst * Intrinsic = dyn_cast < IntrinsicInst > ( ExtValue -> getOperand ( 0 ) ) ) { switch ( Intrinsic -> getIntrinsicID ( ) ) { default : return false ; case Intrinsic :: amdgcn_if : case Intrinsic :: amdgcn_else : { ArrayRef < unsigned > Indices = ExtValue -> getIndices ( ) ; if ( Indices . size ( ) == 1 && Indices [ 0 ] == 1 ) { return true ; } } } } } if ( const CallInst * CI = dyn_cast < CallInst > ( V ) ) { if ( isa < InlineAsm > ( CI -> getCalledValue ( ) ) ) { const SIRegisterInfo * SIRI = Subtarget -> getRegisterInfo ( ) ; ImmutableCallSite CS ( CI ) ; TargetLowering :: AsmOperandInfoVector TargetConstraints = ParseConstraints ( MF . getDataLayout ( ) , Subtarget -> getRegisterInfo ( ) , CS ) ; for ( auto & TC : TargetConstraints ) { if ( TC . Type == InlineAsm :: isOutput ) { ComputeConstraintToUse ( TC , SDValue ( ) ) ; unsigned AssignedReg ; const TargetRegisterClass * RC ; std :: tie ( AssignedReg , RC ) = getRegForInlineAsmConstraint ( SIRI , TC . ConstraintCode , TC . ConstraintVT ) ; if ( RC ) { MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; if ( AssignedReg != 0 && SIRI -> isSGPRReg ( MRI , AssignedReg ) ) return true ; else if ( SIRI -> isSGPRClass ( RC ) ) return true ; } } } } } SetVector < const Value * > Visited ; return hasIfBreakUser ( V , Visited ) ; } </s>

Allows target to decide about the register class of the specific value that is live outside the defining block .


<s>
std
::
pair
<
unsigned
,
const
TargetRegisterClass
*
>
Z80TargetLowering
::
getRegForInlineAsmConstraint
(
const
std
::
string
&
Constraint
,
MVT
VT
)
const
{
if
(
Constraint
.
size
(
)
==
1
)
{
switch
(
Constraint
[
0
]
)
{
case
'r'
:
if
(
VT
==
MVT
::
i8
)
return
std
::
make_pair
(
0U
,
&
Z80
::
GR8RegClass
)
;
if
(
VT
==
MVT
::
i16
)
return
std
::
make_pair
(
0U
,
&
Z80
::
GR16RegClass
)
;
return
std
::
make_pair
(
0u
,
static_cast
<
const
TargetRegisterClass
*
>
(
0
)
)
;
case
'c'
:
if
(
VT
==
MVT
::
i16
)
return
std
::
make_pair
(
(
unsigned
)
Z80
::
BC
,
&
Z80
::
GR16RegClass
)
;
assert
(
"Unexpected type."
)
;
}
}
std
::
pair
<
unsigned
,
const
TargetRegisterClass
*
>
R
;
R
=
parseRegForInlineAsmConstraint
(
Constraint
,
VT
)
;
if
(
R
.
second
)
return
R
;
return
TargetLowering
::
getRegForInlineAsmConstraint
(
Constraint
,
VT
)
;
}
</s>

Given a physical register constraint ( e.g .


<s> static void visium_add_queued_cfa_restore_notes ( rtx insn ) { rtx last ; if ( ! cfa_restores ) return ; for ( last = cfa_restores ; XEXP ( last , 1 ) ; last = XEXP ( last , 1 ) ) ; XEXP ( last , 1 ) = REG_NOTES ( insn ) ; REG_NOTES ( insn ) = cfa_restores ; cfa_restores = NULL_RTX ; } </s>

Add queued REG_CFA_RESTORE notes to INSN , if any .


<s> static enum aarch64_parse_opt_result aarch64_parse_arch ( const char * to_parse , const struct processor * * res , unsigned long * isa_flags ) { char * ext ; const struct processor * arch ; char * str = ( char * ) alloca ( strlen ( to_parse ) + 1 ) ; size_t len ; strcpy ( str , to_parse ) ; ext = strchr ( str , '+' ) ; if ( ext != NULL ) len = ext - str ; else len = strlen ( str ) ; if ( len == 0 ) return AARCH64_PARSE_MISSING_ARG ; for ( arch = all_architectures ; arch -> name != NULL ; arch ++ ) { if ( strlen ( arch -> name ) == len && strncmp ( arch -> name , str , len ) == 0 ) { unsigned long isa_temp = arch -> flags ; if ( ext != NULL ) { enum aarch64_parse_opt_result ext_res = aarch64_parse_extension ( ext , & isa_temp ) ; if ( ext_res != AARCH64_PARSE_OK ) return ext_res ; } * res = arch ; * isa_flags = isa_temp ; return AARCH64_PARSE_OK ; } } return AARCH64_PARSE_INVALID_ARG ; } </s>

Parse the TO_PARSE string and put the architecture struct that it selects into RES and the architectural features into ISA_FLAGS . Return an aarch64_parse_opt_result describing the parse result . If there is an error parsing , RES and ISA_FLAGS are left unchanged .


<s> static reg_class_t arc_secondary_reload ( bool in_p , rtx x , reg_class_t cl , machine_mode , secondary_reload_info * ) { if ( cl == DOUBLE_REGS ) return GENERAL_REGS ; if ( ( cl == LPCOUNT_REG || cl == WRITABLE_CORE_REGS ) && in_p && MEM_P ( x ) ) return GENERAL_REGS ; return NO_REGS ; } </s>

For ARC base register + offset addressing , the validity of the address is mode-dependent for most of the offset range , as the offset can be scaled by the access size . We do n't expose these as mode-dependent addresses in the mode_dependent_address_p target hook , because that would disable lots of optimizations , and most uses of these addresses are for 32 or 64 bit accesses anyways , which are fine . However , that leaves some addresses for 8 / 16 bit values not properly reloaded by the generic code , which is why we have to schedule secondary reloads for these .


<s>
SDValue
RISCVTargetLowering
::
LowerReturn
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
IsVarArg
,
const
SmallVectorImpl
<
ISD
::
OutputArg
>
&
Outs
,
const
SmallVectorImpl
<
SDValue
>
&
OutVals
,
const
SDLoc
&
DL
,
SelectionDAG
&
DAG
)
const
{
MachineFunction
&
MF
=
DAG
.
getMachineFunction
(
)
;
SmallVector
<
CCValAssign
,
16
>
RetLocs
;
CCState
RetCCInfo
(
CallConv
,
IsVarArg
,
MF
,
RetLocs
,
*
DAG
.
getContext
(
)
)
;
if
(
Subtarget
.
isRV64
(
)
)
RetCCInfo
.
AnalyzeReturn
(
Outs
,
RetCC_RISCV64
)
;
else
RetCCInfo
.
AnalyzeReturn
(
Outs
,
RetCC_RISCV32
)
;
SDValue
Glue
;
if
(
RetLocs
.
empty
(
)
)
return
DAG
.
getNode
(
RISCVISD
::
RET_FLAG
,
DL
,
MVT
::
Other
,
Chain
)
;
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
(
RISCVISD
::
RET_FLAG
,
DL
,
MVT
::
Other
,
RetOps
)
;
}
</s>

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


<s> std :: pair < unsigned , const TargetRegisterClass * > XCoreTargetLowering :: getRegForInlineAsmConstraint ( const std :: string & Constraint , EVT VT ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { default : break ; case 'r' : return std :: make_pair ( 0U , XCore :: GRRegsRegisterClass ) ; } } return TargetLowering :: getRegForInlineAsmConstraint ( Constraint , VT ) ; } </s>