<s> static void ix86_output_indirect_branch_via_push ( rtx call_op , const char * xasm , bool sibcall_p ) { char thunk_name_buf [ 32 ] ; char * thunk_name ; char push_buf [ 64 ] ; enum indirect_thunk_prefix need_prefix = indirect_thunk_need_prefix ( current_output_insn ) ; int regno = - 1 ; if ( cfun -> machine -> indirect_branch_type != indirect_branch_thunk_inline ) { if ( cfun -> machine -> indirect_branch_type == indirect_branch_thunk ) indirect_thunk_needed = true ; indirect_thunk_name ( thunk_name_buf , regno , need_prefix , false ) ; thunk_name = thunk_name_buf ; } else thunk_name = NULL ; snprintf ( push_buf , sizeof ( push_buf ) , "push{%c}\t%s" , TARGET_64BIT ? 'q' : 'l' , xasm ) ; if ( sibcall_p ) { output_asm_insn ( push_buf , & call_op ) ; ix86_output_jmp_thunk_or_indirect ( thunk_name , regno ) ; } else { char indirectlabel1 [ 32 ] ; char indirectlabel2 [ 32 ] ; ASM_GENERATE_INTERNAL_LABEL ( indirectlabel1 , INDIRECT_LABEL , indirectlabelno ++ ) ; ASM_GENERATE_INTERNAL_LABEL ( indirectlabel2 , INDIRECT_LABEL , indirectlabelno ++ ) ; fputs ( "\tjmp\t" , asm_out_file ) ; assemble_name_raw ( asm_out_file , indirectlabel2 ) ; fputc ( '\n' , asm_out_file ) ; ASM_OUTPUT_INTERNAL_LABEL ( asm_out_file , indirectlabel1 ) ; if ( MEM_P ( call_op ) ) { struct ix86_address parts ; rtx addr = XEXP ( call_op , 0 ) ; if ( ix86_decompose_address ( addr , & parts ) && parts . base == stack_pointer_rtx ) { if ( parts . index ) { addr = gen_rtx_MULT ( Pmode , parts . index , GEN_INT ( parts . scale ) ) ; addr = gen_rtx_PLUS ( Pmode , stack_pointer_rtx , addr ) ; } else addr = stack_pointer_rtx ; rtx disp ; if ( parts . disp != NULL_RTX ) disp = plus_constant ( Pmode , parts . disp , UNITS_PER_WORD ) ; else disp = GEN_INT ( UNITS_PER_WORD ) ; addr = gen_rtx_PLUS ( Pmode , addr , disp ) ; call_op = gen_rtx_MEM ( GET_MODE ( call_op ) , addr ) ; } } output_asm_insn ( push_buf , & call_op ) ; ix86_output_jmp_thunk_or_indirect ( thunk_name , regno ) ; ASM_OUTPUT_INTERNAL_LABEL ( asm_out_file , indirectlabel2 ) ; fputs ( "\tcall\t" , asm_out_file ) ; assemble_name_raw ( asm_out_file , indirectlabel1 ) ; fputc ( '\n' , asm_out_file ) ; } } </s>

Output indirect branch via a call and return thunk . CALL_OP is the branch target . XASM is the assembly template for CALL_OP . Branch is a tail call if SIBCALL_P is true . A normal call is converted to : jmp L2 L1 : push CALL_OP jmp __x86_indirect_thunk L2 : call L1 and a tail call is converted to : push CALL_OP jmp __x86_indirect_thunk


<s> void rs6000_emit_swdiv ( rtx dst , rtx n , rtx d , bool note_p ) { machine_mode mode = GET_MODE ( dst ) ; rtx one , x0 , e0 , x1 , xprev , eprev , xnext , enext , u , v ; int i ; int passes = ( TARGET_RECIP_PRECISION ) ? 1 : 3 ; if ( mode == DFmode || mode == V2DFmode ) passes ++ ; enum insn_code code = optab_handler ( smul_optab , mode ) ; insn_gen_fn gen_mul = GEN_FCN ( code ) ; gcc_assert ( code != CODE_FOR_nothing ) ; one = rs6000_load_constant_and_splat ( mode , dconst1 ) ; x0 = gen_reg_rtx ( mode ) ; emit_insn ( gen_rtx_SET ( x0 , gen_rtx_UNSPEC ( mode , gen_rtvec ( 1 , d ) , UNSPEC_FRES ) ) ) ; if ( passes > 1 ) { e0 = gen_reg_rtx ( mode ) ; rs6000_emit_nmsub ( e0 , d , x0 , one ) ; x1 = gen_reg_rtx ( mode ) ; rs6000_emit_madd ( x1 , e0 , x0 , x0 ) ; for ( i = 0 , xprev = x1 , eprev = e0 ; i < passes - 2 ; ++ i , xprev = xnext , eprev = enext ) { enext = gen_reg_rtx ( mode ) ; emit_insn ( gen_mul ( enext , eprev , eprev ) ) ; xnext = gen_reg_rtx ( mode ) ; rs6000_emit_madd ( xnext , enext , xprev , xprev ) ; } } else xprev = x0 ; u = gen_reg_rtx ( mode ) ; emit_insn ( gen_mul ( u , n , xprev ) ) ; v = gen_reg_rtx ( mode ) ; rs6000_emit_nmsub ( v , d , u , n ) ; rs6000_emit_madd ( dst , v , xprev , u ) ; if ( note_p ) add_reg_note ( get_last_insn ( ) , REG_EQUAL , gen_rtx_DIV ( mode , n , d ) ) ; } </s>

Newton-Raphson approximation of floating point divide DST = N/D . If NOTE_P , add a reg_note saying that this was a division . Support both scalar and vector divide . Assumes no trapping math and finite arguments .


<s> bool isReg ( ) const { return Kind == k_Register ; } </s>


<s> int num_insns_constant_wide ( HOST_WIDE_INT value ) { if ( ( ( unsigned HOST_WIDE_INT ) value + 0x8000 ) < 0x10000 ) return 1 ; else if ( ( value & 0xffff ) == 0 && ( value >> 31 == - 1 || value >> 31 == 0 ) ) return 1 ; else if ( TARGET_POWERPC64 ) { HOST_WIDE_INT low = ( ( value & 0xffffffff ) ^ 0x80000000 ) - 0x80000000 ; HOST_WIDE_INT high = value >> 31 ; if ( high == 0 || high == - 1 ) return 2 ; high >>= 1 ; if ( low == 0 ) return num_insns_constant_wide ( high ) + 1 ; else if ( high == 0 ) return num_insns_constant_wide ( low ) + 1 ; else return ( num_insns_constant_wide ( high ) + num_insns_constant_wide ( low ) + 1 ) ; } else return 2 ; } </s>

Return the number of instructions it takes to form a constant in an integer register .


<s>
void
MipsInstPrinter
::
printInst
(
const
MCInst
*
MI
,
uint64_t
Address
,
StringRef
Annot
,
const
MCSubtargetInfo
&
STI
,
raw_ostream
&
O
)
{
switch
(
MI
->
getOpcode
(
)
)
{
default
:
break
;
case
Mips
::
RDHWR
:
case
Mips
::
RDHWR64
:
O
<<
"\t.set\tpush\n"
;
O
<<
"\t.set\tmips32r2\n"
;
break
;
case
Mips
::
Save16
:
O
<<
"\tsave\t"
;
printSaveRestore
(
MI
,
O
)
;
O
<<
" # 16 bit inst\n"
;
return
;
case
Mips
::
SaveX16
:
O
<<
"\tsave\t"
;
printSaveRestore
(
MI
,
O
)
;
O
<<
"\n"
;
return
;
case
Mips
::
Restore16
:
O
<<
"\trestore\t"
;
printSaveRestore
(
MI
,
O
)
;
O
<<
" # 16 bit inst\n"
;
return
;
case
Mips
::
RestoreX16
:
O
<<
"\trestore\t"
;
printSaveRestore
(
MI
,
O
)
;
O
<<
"\n"
;
return
;
}
if
(
!
printAliasInstr
(
MI
,
O
)
&&
!
printAlias
(
*
MI
,
O
)
)
printInstruction
(
MI
,
Address
,
O
)
;
printAnnotation
(
O
,
Annot
)
;
switch
(
MI
->
getOpcode
(
)
)
{
default
:
break
;
case
Mips
::
RDHWR
:
case
Mips
::
RDHWR64
:
O
<<
"\n\t.set\tpop"
;
}
}
</s>

Print the specified MCInst to the specified raw_ostream .


<s>
const
char
*
thumb2_output_casesi
(
rtx
*
operands
)
{
rtx
diff_vec
=
PATTERN
(
NEXT_INSN
(
as_a
<
rtx_insn
*
>
(
operands
[
2
]
)
)
)
;
gcc_assert
(
GET_CODE
(
diff_vec
)
==
ADDR_DIFF_VEC
)
;
output_asm_insn
(
"cmp\t%0, %1"
,
operands
)
;
output_asm_insn
(
"bhi\t%l3"
,
operands
)
;
switch
(
GET_MODE
(
diff_vec
)
)
{
case
E_QImode
:
return
"tbb\t[%|pc, %0]"
;
case
E_HImode
:
return
"tbh\t[%|pc, %0, lsl #1]"
;
case
E_SImode
:
if
(
flag_pic
)
{
output_asm_insn
(
"adr\t%4, %l2"
,
operands
)
;
output_asm_insn
(
"ldr\t%5, [%4, %0, lsl #2]"
,
operands
)
;
output_asm_insn
(
"add\t%4, %4, %5"
,
operands
)
;
return
"bx\t%4"
;
}
else
{
output_asm_insn
(
"adr\t%4, %l2"
,
operands
)
;
return
"ldr\t%|pc, [%4, %0, lsl #2]"
;
}
default
:
gcc_unreachable
(
)
;
}
}
</s>


<s> bool contains ( const MachineBasicBlock * MBB ) const { return BlockSet . count ( MBB ) ; } </s>

contains - Returns true if this trace contains the given basic block .


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

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


<s> int mcore_halfword_offset ( unsigned int mask ) { if ( mask == 0x0000ffffL ) return 0 ; else if ( mask == 0xffff0000L ) return 1 ; return - 1 ; } </s>


<s> static HOST_WIDE_INT aarch64_anchor_offset ( HOST_WIDE_INT offset , HOST_WIDE_INT size , machine_mode mode ) { if ( size > 16 ) return ( offset + 0x400 ) & ~ 0x7f0 ; if ( offset & ( size - 1 ) ) { if ( mode == BLKmode ) return ( offset + 512 ) & ~ 0x3ff ; return ( offset + 0x100 ) & ~ 0x1ff ; } if ( IN_RANGE ( offset , - 256 , 0 ) ) return 0 ; if ( mode == TImode || mode == TFmode ) return ( offset + 0x100 ) & ~ 0x1ff ; return offset & ( ~ 0xfff * size ) ; } </s>

OFFSET is an address offset for mode MODE , which has SIZE bytes . If OFFSET is out of range , return an offset of an anchor point that is in range . Return 0 otherwise .


<s> static void ix86_update_stack_boundary ( void ) { ix86_incoming_stack_boundary = ix86_minimum_incoming_stack_boundary ( false ) ; if ( TARGET_64BIT && cfun -> stdarg && crtl -> stack_alignment_estimated < 128 ) crtl -> stack_alignment_estimated = 128 ; } </s>

Update incoming stack boundary and estimated stack alignment .


<s> virtual const TargetRegisterInfo * getRegisterInfo ( ) const { return & InstrInfo . getRegisterInfo ( ) ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> BitVector MipsRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { static const uint16_t ReservedGPR32 [ ] = { Mips :: ZERO , Mips :: K0 , Mips :: K1 , Mips :: SP } ; static const uint16_t ReservedGPR64 [ ] = { Mips :: ZERO_64 , Mips :: K0_64 , Mips :: K1_64 , Mips :: SP_64 } ; BitVector Reserved ( getNumRegs ( ) ) ; typedef TargetRegisterClass :: const_iterator RegIter ; for ( unsigned I = 0 ; I < array_lengthof ( ReservedGPR32 ) ; ++ I ) Reserved . set ( ReservedGPR32 [ I ] ) ; for ( unsigned I = 0 ; I < array_lengthof ( ReservedGPR64 ) ; ++ I ) Reserved . set ( ReservedGPR64 [ I ] ) ; if ( Subtarget . isFP64bit ( ) ) { for ( RegIter Reg = Mips :: AFGR64RegClass . begin ( ) , EReg = Mips :: AFGR64RegClass . end ( ) ; Reg != EReg ; ++ Reg ) Reserved . set ( * Reg ) ; } else { for ( RegIter Reg = Mips :: FGR64RegClass . begin ( ) , EReg = Mips :: FGR64RegClass . end ( ) ; Reg != EReg ; ++ Reg ) Reserved . set ( * Reg ) ; } if ( MF . getTarget ( ) . getFrameLowering ( ) -> hasFP ( MF ) ) { if ( Subtarget . inMips16Mode ( ) ) Reserved . set ( Mips :: S0 ) ; else { Reserved . set ( Mips :: FP ) ; Reserved . set ( Mips :: FP_64 ) ; } } Reserved . set ( Mips :: HWR29 ) ; Reserved . set ( Mips :: DSPPos ) ; Reserved . set ( Mips :: DSPSCount ) ; Reserved . set ( Mips :: DSPCarry ) ; Reserved . set ( Mips :: DSPEFI ) ; Reserved . set ( Mips :: DSPOutFlag ) ; Reserved . set ( Mips :: MSAIR ) ; Reserved . set ( Mips :: MSACSR ) ; Reserved . set ( Mips :: MSAAccess ) ; Reserved . set ( Mips :: MSASave ) ; Reserved . set ( Mips :: MSAModify ) ; Reserved . set ( Mips :: MSARequest ) ; Reserved . set ( Mips :: MSAMap ) ; Reserved . set ( Mips :: MSAUnmap ) ; if ( Subtarget . inMips16Mode ( ) ) { Reserved . set ( Mips :: RA ) ; Reserved . set ( Mips :: RA_64 ) ; Reserved . set ( Mips :: T0 ) ; Reserved . set ( Mips :: T1 ) ; } if ( Subtarget . useSmallSection ( ) ) { Reserved . set ( Mips :: GP ) ; Reserved . set ( Mips :: GP_64 ) ; } 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> iterator begin ( ) { return ( Packet . begin ( ) ) ; } </s>


<s> static bool arm_assemble_integer ( rtx x , unsigned int size , int aligned_p ) { machine_mode mode ; if ( size == UNITS_PER_WORD && aligned_p ) { fputs ( "\t.word\t" , asm_out_file ) ; output_addr_const ( asm_out_file , x ) ; if ( NEED_GOT_RELOC && flag_pic && making_const_table && ( GET_CODE ( x ) == SYMBOL_REF || GET_CODE ( x ) == LABEL_REF ) ) { if ( ! arm_pic_data_is_text_relative || ( GET_CODE ( x ) == SYMBOL_REF && ( ! SYMBOL_REF_LOCAL_P ( x ) || ( SYMBOL_REF_DECL ( x ) ? DECL_WEAK ( SYMBOL_REF_DECL ( x ) ) : 0 ) ) ) ) fputs ( "(GOT)" , asm_out_file ) ; else fputs ( "(GOTOFF)" , asm_out_file ) ; } fputc ( '\n' , asm_out_file ) ; return true ; } mode = GET_MODE ( x ) ; if ( arm_vector_mode_supported_p ( mode ) ) { int i , units ; gcc_assert ( GET_CODE ( x ) == CONST_VECTOR ) ; units = CONST_VECTOR_NUNITS ( x ) ; size = GET_MODE_UNIT_SIZE ( mode ) ; if ( GET_MODE_CLASS ( mode ) == MODE_VECTOR_INT ) for ( i = 0 ; i < units ; i ++ ) { rtx elt = CONST_VECTOR_ELT ( x , i ) ; assemble_integer ( elt , size , i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT , 1 ) ; } else for ( i = 0 ; i < units ; i ++ ) { rtx elt = CONST_VECTOR_ELT ( x , i ) ; assemble_real ( * CONST_DOUBLE_REAL_VALUE ( elt ) , as_a < scalar_float_mode > ( GET_MODE_INNER ( mode ) ) , i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT ) ; } return true ; } return default_assemble_integer ( x , size , aligned_p ) ; } </s>

Target hook for assembling integer objects . The ARM version needs to handle word-sized values specially .


<s>
const
MCFixupKindInfo
&
WebAssemblyAsmBackend
::
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
WebAssembly
::
NumTargetFixupKinds
]
=
{
{
"fixup_sleb128_i32"
,
0
,
5
*
8
,
0
}
,
{
"fixup_sleb128_i64"
,
0
,
10
*
8
,
0
}
,
{
"fixup_uleb128_i32"
,
0
,
5
*
8
,
0
}
,
{
"fixup_uleb128_i64"
,
0
,
10
*
8
,
0
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s> static int stackSlotSize ( ) { return 4 ; } </s>


<s> static rtx fr30_libcall_value ( machine_mode mode , const_rtx fun ATTRIBUTE_UNUSED ) { return gen_rtx_REG ( mode , RETURN_VALUE_REGNUM ) ; } </s>


<s> bool hasMDs ( ) const { return NumModuleMDs < MDs . size ( ) ; } </s>

Check whether the current block has any metadata to emit .


<s> static void workaround_rts_anomaly ( void ) { rtx_insn * insn , * first_insn = NULL ; int cycles = 4 ; if ( ! ENABLE_WA_RETS ) return ; for ( insn = get_insns ( ) ; insn ; insn = NEXT_INSN ( insn ) ) { rtx pat ; if ( BARRIER_P ( insn ) ) return ; if ( NOTE_P ( insn ) || LABEL_P ( insn ) ) continue ; if ( JUMP_TABLE_DATA_P ( insn ) ) continue ; if ( first_insn == NULL_RTX ) first_insn = insn ; pat = PATTERN ( insn ) ; if ( GET_CODE ( pat ) == USE || GET_CODE ( pat ) == CLOBBER || GET_CODE ( pat ) == ASM_INPUT || asm_noperands ( pat ) >= 0 ) continue ; if ( CALL_P ( insn ) ) return ; if ( JUMP_P ( insn ) ) { if ( recog_memoized ( insn ) == CODE_FOR_return_internal ) break ; if ( ! any_condjump_p ( insn ) ) return ; if ( cycles <= 1 ) return ; cycles -- ; } else if ( INSN_P ( insn ) ) { rtx pat = PATTERN ( insn ) ; int this_cycles = 1 ; if ( GET_CODE ( pat ) == PARALLEL ) { if ( analyze_push_multiple_operation ( pat ) || analyze_pop_multiple_operation ( pat ) ) this_cycles = n_regs_to_save ; } else { int icode = recog_memoized ( insn ) ; if ( icode == CODE_FOR_link ) this_cycles = 4 ; else if ( icode == CODE_FOR_unlink ) this_cycles = 3 ; else if ( icode == CODE_FOR_mulsi3 ) this_cycles = 5 ; } if ( this_cycles >= cycles ) return ; cycles -= this_cycles ; } } while ( cycles > 0 ) { emit_insn_before ( gen_nop ( ) , first_insn ) ; cycles -- ; } } </s>

On some silicon revisions , functions shorter than a certain number of cycles can cause unpredictable behaviour . Work around this by adding NOPs as needed .


<s> MCObjectWriter * createObjectWriter ( raw_pwrite_stream & OS ) const override { return createLC3ELFObjectWriter ( OS , OSABI ) ; } </s>

Create a new MCObjectWriter instance for use by the assembler backend to emit the final object file .


<s> bool X86TargetLowering :: isShuffleMaskLegal ( const SmallVectorImpl < int > & M , EVT VT ) const { if ( ! VT . isSimple ( ) ) return false ; MVT SVT = VT . getSimpleVT ( ) ; if ( VT . getSizeInBits ( ) == 64 ) return false ; if ( ( SVT . is128BitVector ( ) && Subtarget -> hasSSSE3 ( ) ) || ( SVT . is256BitVector ( ) && Subtarget -> hasInt256 ( ) ) ) { bool isLegal = true ; for ( unsigned I = 0 , E = M . size ( ) ; I != E ; ++ I ) { if ( M [ I ] >= ( int ) SVT . getVectorNumElements ( ) || ShuffleCrosses128bitLane ( SVT , I , M [ I ] ) ) { isLegal = false ; break ; } } if ( isLegal ) return true ; } return ( SVT . getVectorNumElements ( ) == 2 || ShuffleVectorSDNode :: isSplatMask ( & M [ 0 ] , VT ) || isMOVLMask ( M , SVT ) || isMOVHLPSMask ( M , SVT ) || isSHUFPMask ( M , SVT ) || isPSHUFDMask ( M , SVT ) || isPSHUFHWMask ( M , SVT , Subtarget -> hasInt256 ( ) ) || isPSHUFLWMask ( M , SVT , Subtarget -> hasInt256 ( ) ) || isPALIGNRMask ( M , SVT , Subtarget ) || isUNPCKLMask ( M , SVT , Subtarget -> hasInt256 ( ) ) || isUNPCKHMask ( M , SVT , Subtarget -> hasInt256 ( ) ) || isUNPCKL_v_undef_Mask ( M , SVT , Subtarget -> hasInt256 ( ) ) || isUNPCKH_v_undef_Mask ( M , SVT , Subtarget -> hasInt256 ( ) ) || isBlendMask ( M , SVT , Subtarget -> hasSSE41 ( ) , Subtarget -> hasInt256 ( ) ) ) ; } </s>

Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations , those with specific masks .


<s> static bool find_mem_ref ( rtx pat , rtx * mem_ref ) { const char * fmt ; int i , j ; if ( tie_operand ( pat , VOIDmode ) ) return false ; if ( GET_CODE ( pat ) == MEM ) { * mem_ref = pat ; return true ; } fmt = GET_RTX_FORMAT ( GET_CODE ( pat ) ) ; for ( i = GET_RTX_LENGTH ( GET_CODE ( pat ) ) - 1 ; i >= 0 ; i -- ) { if ( fmt [ i ] == 'e' ) { if ( find_mem_ref ( XEXP ( pat , i ) , mem_ref ) ) return true ; } else if ( fmt [ i ] == 'E' ) for ( j = XVECLEN ( pat , i ) - 1 ; j >= 0 ; j -- ) { if ( find_mem_ref ( XVECEXP ( pat , i , j ) , mem_ref ) ) return true ; } } return false ; } </s>

Determine if PAT refers to memory . If so , set MEM_REF to the MEM rtx and return true .


<s> void Mips16RegisterInfo :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; if ( ! TFI -> hasReservedCallFrame ( MF ) ) { int64_t Amount = I -> getOperand ( 0 ) . getImm ( ) ; if ( I -> getOpcode ( ) == Mips :: ADJCALLSTACKDOWN ) Amount = - Amount ; const Mips16InstrInfo * II = static_cast < const Mips16InstrInfo * > ( & TII ) ; II -> adjustStackPtr ( Mips :: SP , Amount , MBB , I ) ; } MBB . erase ( I ) ; } </s>

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

Mips Mips 0 Mips::ADJCALLSTACKDOWN Mips Mips Mips::SP


<s> bool SparcPassConfig :: addPreEmitPass ( ) { addPass ( createSparcFPMoverPass ( getSparcTargetMachine ( ) ) ) ; addPass ( createSparcDelaySlotFillerPass ( getSparcTargetMachine ( ) ) ) ; return true ; } </s>

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


<s> void SHUXIInstPrinter :: printRegName ( raw_ostream & O , unsigned RegNo ) const { O << StringRef ( getRegisterName ( RegNo ) ) ; } </s>


"No expandLargeImm(SP, -StackSize, false, TII, MBB, MBBI, dl);"

emitProlog/emitEpilog - These methods insert prolog and epilog code into the function .


<s> bool PPCCallLowering :: lowerFormalArguments ( MachineIRBuilder & MIRBuilder , const Function & F , ArrayRef < ArrayRef < Register >> VRegs ) const { return VRegs . empty ( ) ; } </s>

This hook must be implemented to lower the incoming ( formal ) arguments , described by VRegs , for GlobalISel .


<s> static rtx scale_counter ( rtx countreg , int scale ) { rtx sc ; if ( scale == 1 ) return countreg ; if ( CONST_INT_P ( countreg ) ) return GEN_INT ( INTVAL ( countreg ) / scale ) ; gcc_assert ( REG_P ( countreg ) ) ; sc = expand_simple_binop ( GET_MODE ( countreg ) , LSHIFTRT , countreg , GEN_INT ( exact_log2 ( scale ) ) , NULL , 1 , OPTAB_DIRECT ) ; return sc ; } </s>


<s>
bool
fixupNeedsRelaxation
(
const
MCFixup
&
Fixup
,
uint64_t
Value
,
const
MCRelaxableFragment
*
DF
,
const
MCAsmLayout
&
Layout
)
const
{
assert
(
0
&&
"fixupNeedsRelaxation() unimplemented"
)
;
return
false
;
}
</s>

Simple predicate for targets where ! Resolved implies requiring relaxation .

Sparc
0
"fixupNeedsRelaxation() unimplemented"


<s> static bool expand_vec_perm_broadcast_1 ( struct expand_vec_perm_d * d ) { unsigned elt = d -> perm [ 0 ] , nelt2 = d -> nelt / 2 ; machine_mode vmode = d -> vmode ; unsigned char perm2 [ 4 ] ; rtx op0 = d -> op0 , dest ; bool ok ; switch ( vmode ) { case V4DFmode : case V8SFmode : gcc_unreachable ( ) ; case V2DFmode : case V2DImode : case V4SFmode : case V4SImode : gcc_unreachable ( ) ; case V8HImode : case V16QImode : if ( d -> testing_p ) return true ; do { rtx dest ; rtx ( * gen ) ( rtx , rtx , rtx ) = vmode == V16QImode ? gen_vec_interleave_lowv16qi : gen_vec_interleave_lowv8hi ; if ( elt >= nelt2 ) { gen = vmode == V16QImode ? gen_vec_interleave_highv16qi : gen_vec_interleave_highv8hi ; elt -= nelt2 ; } nelt2 /= 2 ; dest = gen_reg_rtx ( vmode ) ; emit_insn ( gen ( dest , op0 , op0 ) ) ; vmode = get_mode_wider_vector ( vmode ) ; op0 = gen_lowpart ( vmode , dest ) ; } while ( vmode != V4SImode ) ; memset ( perm2 , elt , 4 ) ; dest = gen_reg_rtx ( V4SImode ) ; ok = expand_vselect ( dest , op0 , perm2 , 4 , d -> testing_p ) ; gcc_assert ( ok ) ; if ( ! d -> testing_p ) emit_move_insn ( d -> target , gen_lowpart ( d -> vmode , dest ) ) ; return true ; case V64QImode : case V32QImode : case V16HImode : case V8SImode : case V4DImode : gcc_assert ( ! TARGET_AVX2 || d -> perm [ 0 ] ) ; return false ; default : gcc_unreachable ( ) ; } } </s>

A subroutine of ix86_expand_vec_perm_builtin_1 . Implement broadcast permutations . We assume that expand_vec_perm_1 has already failed .


<s> bool R600InstrInfo :: fitsReadPortLimitations ( const std :: vector < MachineInstr * > & IG , const DenseMap < unsigned , unsigned > & PV , std :: vector < BankSwizzle > & ValidSwizzle , bool isLastAluTrans ) const { std :: vector < std :: vector < std :: pair < int , unsigned >> > IGSrcs ; ValidSwizzle . clear ( ) ; unsigned ConstCount ; BankSwizzle TransBS = ALU_VEC_012_SCL_210 ; for ( MachineInstr * MI : IG ) { IGSrcs . push_back ( ExtractSrcs ( * MI , PV , ConstCount ) ) ; unsigned Op = getOperandIdx ( MI -> getOpcode ( ) , R600 :: OpName :: bank_swizzle ) ; ValidSwizzle . push_back ( ( R600InstrInfo :: BankSwizzle ) MI -> getOperand ( Op ) . getImm ( ) ) ; } std :: vector < std :: pair < int , unsigned >> TransOps ; if ( ! isLastAluTrans ) return FindSwizzleForVectorSlot ( IGSrcs , ValidSwizzle , TransOps , TransBS ) ; TransOps = std :: move ( IGSrcs . back ( ) ) ; IGSrcs . pop_back ( ) ; ValidSwizzle . pop_back ( ) ; static const R600InstrInfo :: BankSwizzle TransSwz [ ] = { ALU_VEC_012_SCL_210 , ALU_VEC_021_SCL_122 , ALU_VEC_120_SCL_212 , ALU_VEC_102_SCL_221 } ; for ( R600InstrInfo :: BankSwizzle TransBS : TransSwz ) { if ( ! isConstCompatible ( TransBS , TransOps , ConstCount ) ) continue ; bool Result = FindSwizzleForVectorSlot ( IGSrcs , ValidSwizzle , TransOps , TransBS ) ; if ( Result ) { ValidSwizzle . push_back ( TransBS ) ; return true ; } } return false ; } </s>

Given the order VEC_012 < VEC_021 < VEC_120 < VEC_102 < VEC_201 < VEC_210 returns true and the first ( in lexical order ) BankSwizzle affectation starting from the one already provided in the Instruction Group MIs that fits Read Port limitations in BS if available .


<s> static int ix86_division_cost ( const struct processor_costs * cost , enum machine_mode mode ) { machine_mode inner_mode = mode ; if ( VECTOR_MODE_P ( mode ) ) inner_mode = GET_MODE_INNER ( mode ) ; if ( SSE_FLOAT_MODE_P ( mode ) && TARGET_SSE_MATH ) return inner_mode == DFmode ? cost -> divsd : cost -> divss ; else if ( X87_FLOAT_MODE_P ( mode ) ) return cost -> fdiv ; else if ( FLOAT_MODE_P ( mode ) ) return ix86_vec_cost ( mode , inner_mode == DFmode ? cost -> divsd : cost -> divss , true ) ; else return cost -> divide [ MODE_INDEX ( mode ) ] ; } </s>


<s> const RegisterBankInfo * MipsSubtarget :: getRegBankInfo ( ) const { return RegBankInfo . get ( ) ; } </s>

If the information for the register banks is available , return it .


<s> void TVMInstrInfo :: copyPhysReg ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , const DebugLoc & DL , unsigned DestReg , unsigned SrcReg , bool KillSrc ) const { BuildMI ( MBB , I , DL , get ( TVM :: REG_TO_REG_COPY ) , DestReg ) . addReg ( SrcReg , KillSrc ? RegState :: Kill : 0 ) ; } </s>


<s> rtx aarch64_gen_stepped_int_parallel ( unsigned int nelts , int base , int step ) { rtvec vec = rtvec_alloc ( nelts ) ; for ( unsigned int i = 0 ; i < nelts ; ++ i ) RTVEC_ELT ( vec , i ) = gen_int_mode ( base + i * step , DImode ) ; return gen_rtx_PARALLEL ( VOIDmode , vec ) ; } </s>

Return a PARALLEL containing NELTS elements , with element I equal to BASE + I * STEP .


<s> rtx_insn * s390_emit_call ( rtx addr_location , rtx tls_call , rtx result_reg , rtx retaddr_reg ) { bool plt_call = false ; rtx_insn * insn ; rtx call ; rtx clobber ; rtvec vec ; if ( GET_CODE ( addr_location ) == SYMBOL_REF ) { if ( flag_pic && ! SYMBOL_REF_LOCAL_P ( addr_location ) ) { if ( retaddr_reg != NULL_RTX ) { addr_location = gen_rtx_UNSPEC ( Pmode , gen_rtvec ( 1 , addr_location ) , UNSPEC_PLT ) ; addr_location = gen_rtx_CONST ( Pmode , addr_location ) ; plt_call = true ; } else addr_location = force_reg ( Pmode , addr_location ) ; } if ( ! TARGET_SMALL_EXEC && ! TARGET_CPU_ZARCH ) { if ( flag_pic ) addr_location = legitimize_pic_address ( addr_location , 0 ) ; else addr_location = force_reg ( Pmode , addr_location ) ; } } if ( retaddr_reg == NULL_RTX && GET_CODE ( addr_location ) != SYMBOL_REF && ! plt_call ) { emit_move_insn ( gen_rtx_REG ( Pmode , SIBCALL_REGNUM ) , addr_location ) ; addr_location = gen_rtx_REG ( Pmode , SIBCALL_REGNUM ) ; } addr_location = gen_rtx_MEM ( QImode , addr_location ) ; call = gen_rtx_CALL ( VOIDmode , addr_location , const0_rtx ) ; if ( result_reg != NULL_RTX ) call = gen_rtx_SET ( VOIDmode , result_reg , call ) ; if ( retaddr_reg != NULL_RTX ) { clobber = gen_rtx_CLOBBER ( VOIDmode , retaddr_reg ) ; if ( tls_call != NULL_RTX ) vec = gen_rtvec ( 3 , call , clobber , gen_rtx_USE ( VOIDmode , tls_call ) ) ; else vec = gen_rtvec ( 2 , call , clobber ) ; call = gen_rtx_PARALLEL ( VOIDmode , vec ) ; } insn = emit_call_insn ( call ) ; if ( ( ! TARGET_64BIT && plt_call ) || tls_call != NULL_RTX ) { gcc_assert ( retaddr_reg != NULL_RTX ) ; use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , gen_rtx_REG ( Pmode , 12 ) ) ; } return insn ; } </s>

This function is used by the call expanders of the machine description . It emits the call insn itself together with the necessary operations to adjust the target address and returns the emitted insn . ADDR_LOCATION is the target address rtx TLS_CALL the location of the thread-local symbol RESULT_REG the register where the result of the call should be stored RETADDR_REG the register where the return address should be stored If this parameter is NULL_RTX the call is considered to be a sibling call .


<s> static rtx nds32_expand_triopimm_builtin ( enum insn_code icode , tree exp , rtx target , bool return_p , const char * name ) { rtx pat ; rtx op0 = nds32_read_argument ( exp , 0 ) ; rtx op1 = nds32_read_argument ( exp , 1 ) ; rtx op2 = nds32_read_argument ( exp , 2 ) ; int op0_num = return_p ? 1 : 0 ; int op1_num = return_p ? 2 : 1 ; int op2_num = return_p ? 3 : 2 ; if ( return_p ) target = nds32_legitimize_target ( icode , target ) ; if ( ! nds32_check_constant_argument ( icode , op2_num , op2 , name ) ) return NULL_RTX ; op0 = nds32_legitimize_argument ( icode , op0_num , op0 ) ; op1 = nds32_legitimize_argument ( icode , op1_num , op1 ) ; op2 = nds32_legitimize_argument ( icode , op2_num , op2 ) ; if ( return_p ) pat = GEN_FCN ( icode ) ( target , op0 , op1 , op2 ) ; else pat = GEN_FCN ( icode ) ( op0 , op1 , op2 ) ; if ( ! pat ) return NULL_RTX ; emit_insn ( pat ) ; return target ; } </s>

Expand builtins that take three operands and the third is immediate .


<s>
bool
fixupNeedsRelaxation
(
const
MCFixup
&
Fixup
,
uint64_t
Value
,
const
MCRelaxableFragment
*
DF
,
const
MCAsmLayout
&
Layout
)
const
override
{
assert
(
0
&&
"fixupNeedsRelaxation() unimplemented"
)
;
return
false
;
}
</s>


<s> bool aarch64_emit_approx_div ( rtx quo , rtx num , rtx den ) { machine_mode mode = GET_MODE ( quo ) ; if ( GET_MODE_INNER ( mode ) == HFmode ) return false ; bool use_approx_division_p = ( flag_mlow_precision_div || ( aarch64_tune_params . approx_modes -> division & AARCH64_APPROX_MODE ( mode ) ) ) ; if ( ! flag_finite_math_only || flag_trapping_math || ! flag_unsafe_math_optimizations || optimize_function_for_size_p ( cfun ) || ! use_approx_division_p ) return false ; if ( ! TARGET_SIMD && VECTOR_MODE_P ( mode ) ) return false ; rtx pg = NULL_RTX ; if ( aarch64_sve_mode_p ( mode ) ) pg = aarch64_ptrue_reg ( aarch64_sve_pred_mode ( mode ) ) ; rtx xrcp = gen_reg_rtx ( mode ) ; emit_insn ( gen_aarch64_frecpe ( mode , xrcp , den ) ) ; int iterations = ( GET_MODE_INNER ( mode ) == DFmode ) ? 3 : 2 ; if ( flag_mlow_precision_div ) iterations = ( GET_MODE_INNER ( mode ) == DFmode ? aarch64_double_recp_precision : aarch64_float_recp_precision ) ; rtx xtmp = gen_reg_rtx ( mode ) ; while ( iterations -- ) { emit_insn ( gen_aarch64_frecps ( mode , xtmp , xrcp , den ) ) ; if ( iterations > 0 ) aarch64_emit_mult ( xrcp , pg , xrcp , xtmp ) ; } if ( num != CONST1_RTX ( mode ) ) { rtx xnum = force_reg ( mode , num ) ; aarch64_emit_mult ( xrcp , pg , xrcp , xnum ) ; } aarch64_emit_mult ( quo , pg , xrcp , xtmp ) ; return true ; } </s>

Emit the instruction sequence to compute the approximation for the division of NUM by DEN in QUO and return whether the sequence was emitted or not .


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

Return information about object file lowering .


<s> static bool aarch64_if_then_else_costs ( rtx op0 , rtx op1 , rtx op2 , int * cost , bool speed ) { rtx inner ; rtx comparator ; enum rtx_code cmpcode ; if ( COMPARISON_P ( op0 ) ) { inner = XEXP ( op0 , 0 ) ; comparator = XEXP ( op0 , 1 ) ; cmpcode = GET_CODE ( op0 ) ; } else { inner = op0 ; comparator = const0_rtx ; cmpcode = NE ; } if ( GET_CODE ( op1 ) == PC || GET_CODE ( op2 ) == PC ) { if ( GET_MODE_CLASS ( GET_MODE ( inner ) ) == MODE_CC ) return true ; else { if ( cmpcode == NE || cmpcode == EQ ) { if ( comparator == const0_rtx ) { if ( GET_CODE ( inner ) == ZERO_EXTRACT ) * cost += rtx_cost ( XEXP ( inner , 0 ) , VOIDmode , ZERO_EXTRACT , 0 , speed ) ; else * cost += rtx_cost ( inner , VOIDmode , cmpcode , 0 , speed ) ; return true ; } } else if ( cmpcode == LT || cmpcode == GE ) { if ( comparator == const0_rtx ) return true ; } } } else if ( GET_MODE_CLASS ( GET_MODE ( inner ) ) == MODE_CC ) { if ( GET_CODE ( op1 ) == COMPARE ) { if ( XEXP ( op1 , 1 ) == const0_rtx ) * cost += 1 ; if ( speed ) { machine_mode mode = GET_MODE ( XEXP ( op1 , 0 ) ) ; const struct cpu_cost_table * extra_cost = aarch64_tune_params . insn_extra_cost ; if ( GET_MODE_CLASS ( mode ) == MODE_INT ) * cost += extra_cost -> alu . arith ; else * cost += extra_cost -> fp [ mode == DFmode ] . compare ; } return true ; } if ( GET_CODE ( op1 ) == NEG || GET_CODE ( op1 ) == NOT || ( GET_CODE ( op1 ) == PLUS && XEXP ( op1 , 1 ) == const1_rtx ) ) op1 = XEXP ( op1 , 0 ) ; else if ( GET_CODE ( op1 ) == ZERO_EXTEND && GET_CODE ( op2 ) == ZERO_EXTEND ) { op1 = XEXP ( op1 , 0 ) ; op2 = XEXP ( op2 , 0 ) ; } * cost += rtx_cost ( op1 , VOIDmode , IF_THEN_ELSE , 1 , speed ) ; * cost += rtx_cost ( op2 , VOIDmode , IF_THEN_ELSE , 2 , speed ) ; return true ; } return false ; } </s>

Calculate the cost of calculating ( if_then_else ( OP0 ) ( OP1 ) ( OP2 ) ) , storing it in * COST . Result is true if the total cost of the operation has now been calculated .


<s>
void
output_push_multiple
(
rtx
insn
,
rtx
*
operands
)
{
char
buf
[
80
]
;
int
ok
;
ok
=
analyze_push_multiple_operation
(
PATTERN
(
insn
)
)
;
gcc_assert
(
ok
)
;
if
(
first_dreg_to_save
==
8
)
sprintf
(
buf
,
"[--sp] = ( p5:%d );\n"
,
first_preg_to_save
)
;
else
if
(
first_preg_to_save
==
6
)
sprintf
(
buf
,
"[--sp] = ( r7:%d );\n"
,
first_dreg_to_save
)
;
else
sprintf
(
buf
,
"[--sp] = ( r7:%d, p5:%d );\n"
,
first_dreg_to_save
,
first_preg_to_save
)
;
output_asm_insn
(
buf
,
operands
)
;
}
</s>

Emit assembly code for one multi-register push described by INSN , with operands in OPERANDS .


<s>
bool
ARCFrameLowering
::
restoreCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
DEBUG
(
dbgs
(
)
<<
"Restore callee saved registers: "
<<
MBB
.
getParent
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>

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

ARC
ARC
"Restore callee saved registers: "
"\n"
ARC::R14


<s>
void
WebAssemblyAsmPrinter
::
EmitInstruction
(
const
MachineInstr
*
MI
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"EmitInstruction: "
<<
*
MI
<<
'\n'
)
;
switch
(
MI
->
getOpcode
(
)
)
{
case
WebAssembly
::
ARGUMENT_I32
:
case
WebAssembly
::
ARGUMENT_I64
:
case
WebAssembly
::
ARGUMENT_F32
:
case
WebAssembly
::
ARGUMENT_F64
:
case
WebAssembly
::
ARGUMENT_v16i8
:
case
WebAssembly
::
ARGUMENT_v8i16
:
case
WebAssembly
::
ARGUMENT_v4i32
:
case
WebAssembly
::
ARGUMENT_v2i64
:
case
WebAssembly
::
ARGUMENT_v4f32
:
case
WebAssembly
::
ARGUMENT_v2f64
:
break
;
case
WebAssembly
::
FALLTHROUGH_RETURN_I32
:
case
WebAssembly
::
FALLTHROUGH_RETURN_I64
:
case
WebAssembly
::
FALLTHROUGH_RETURN_F32
:
case
WebAssembly
::
FALLTHROUGH_RETURN_F64
:
case
WebAssembly
::
FALLTHROUGH_RETURN_v16i8
:
case
WebAssembly
::
FALLTHROUGH_RETURN_v8i16
:
case
WebAssembly
::
FALLTHROUGH_RETURN_v4i32
:
case
WebAssembly
::
FALLTHROUGH_RETURN_v2i64
:
case
WebAssembly
::
FALLTHROUGH_RETURN_v4f32
:
case
WebAssembly
::
FALLTHROUGH_RETURN_v2f64
:
{
assert
(
MFI
->
isVRegStackified
(
MI
->
getOperand
(
0
)
.
getReg
(
)
)
)
;
if
(
isVerbose
(
)
)
{
OutStreamer
->
AddComment
(
"fallthrough-return: $pop"
+
Twine
(
MFI
->
getWARegStackId
(
MFI
->
getWAReg
(
MI
->
getOperand
(
0
)
.
getReg
(
)
)
)
)
)
;
OutStreamer
->
AddBlankLine
(
)
;
}
break
;
}
case
WebAssembly
::
FALLTHROUGH_RETURN_VOID
:
if
(
isVerbose
(
)
)
{
OutStreamer
->
AddComment
(
"fallthrough-return"
)
;
OutStreamer
->
AddBlankLine
(
)
;
}
break
;
default
:
{
WebAssemblyMCInstLower
MCInstLowering
(
OutContext
,
*
this
)
;
MCInst
TmpInst
;
MCInstLowering
.
Lower
(
MI
,
TmpInst
)
;
EmitToStreamer
(
*
OutStreamer
,
TmpInst
)
;
break
;
}
}
}
</s>

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


<s> void PPCPostRASchedStrategy :: initialize ( ScheduleDAGMI * Dag ) { PostGenericScheduler :: initialize ( Dag ) ; } </s>

Initialize the strategy after building the DAG for a new region .


<s>
bool
SILoadStoreOptimizer
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
skipFunction
(
MF
.
getFunction
(
)
)
)
return
false
;
STM
=
&
MF
.
getSubtarget
<
GCNSubtarget
>
(
)
;
if
(
!
STM
->
loadStoreOptEnabled
(
)
)
return
false
;
TII
=
STM
->
getInstrInfo
(
)
;
TRI
=
&
TII
->
getRegisterInfo
(
)
;
MRI
=
&
MF
.
getRegInfo
(
)
;
AA
=
&
getAnalysis
<
AAResultsWrapperPass
>
(
)
.
getAAResults
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Running SILoadStoreOptimizer\n"
)
;
bool
Modified
=
false
;
SmallPtrSet
<
MachineInstr
*
,
4
>
AnchorList
;
MemInfoMap
Visited
;
for
(
MachineBasicBlock
&
MBB
:
MF
)
{
MachineBasicBlock
::
iterator
SectionEnd
;
for
(
MachineBasicBlock
::
iterator
I
=
MBB
.
begin
(
)
,
E
=
MBB
.
end
(
)
;
I
!=
E
;
I
=
SectionEnd
)
{
bool
CollectModified
;
std
::
list
<
std
::
list
<
CombineInfo
>>
MergeableInsts
;
std
::
tie
(
SectionEnd
,
CollectModified
)
=
collectMergeableInsts
(
I
,
E
,
Visited
,
AnchorList
,
MergeableInsts
)
;
Modified
|=
CollectModified
;
do
{
OptimizeAgain
=
false
;
Modified
|=
optimizeBlock
(
MergeableInsts
)
;
}
while
(
OptimizeAgain
)
;
}
Visited
.
clear
(
)
;
AnchorList
.
clear
(
)
;
}
return
Modified
;
}
</s>

runOnMachineFunction - Emit the function body .

AMDGPU
SI
"Running SILoadStoreOptimizer\n"
4


<s> bool aarch64_pad_arg_upward ( machine_mode mode , const_tree type ) { if ( ! BYTES_BIG_ENDIAN ) return true ; if ( type ? ( INTEGRAL_TYPE_P ( type ) || SCALAR_FLOAT_TYPE_P ( type ) || POINTER_TYPE_P ( type ) ) : ( SCALAR_INT_MODE_P ( mode ) || SCALAR_FLOAT_MODE_P ( mode ) ) ) return false ; return true ; } </s>

For use by FUNCTION_ARG_PADDING ( MODE , TYPE ) . Return true if an argument passed on the stack should be padded upwards , i.e . if the least-significant byte of the stack slot has useful data . Small aggregate types are placed in the lowest memory address . The related parameter passing rules are B.4 , C.3 , C.5 and C.14 .


<s>
SDValue
MipsSETargetLowering
::
PerformDAGCombine
(
SDNode
*
N
,
DAGCombinerInfo
&
DCI
)
const
{
SelectionDAG
&
DAG
=
DCI
.
DAG
;
SDValue
Val
;
switch
(
N
->
getOpcode
(
)
)
{
case
ISD
::
AND
:
Val
=
performANDCombine
(
N
,
DAG
,
DCI
,
Subtarget
)
;
break
;
case
ISD
::
OR
:
Val
=
performORCombine
(
N
,
DAG
,
DCI
,
Subtarget
)
;
break
;
case
ISD
::
MUL
:
return
performMULCombine
(
N
,
DAG
,
DCI
,
this
)
;
case
ISD
::
SHL
:
Val
=
performSHLCombine
(
N
,
DAG
,
DCI
,
Subtarget
)
;
break
;
case
ISD
::
SRA
:
return
performSRACombine
(
N
,
DAG
,
DCI
,
Subtarget
)
;
case
ISD
::
SRL
:
return
performSRLCombine
(
N
,
DAG
,
DCI
,
Subtarget
)
;
case
ISD
::
VSELECT
:
return
performVSELECTCombine
(
N
,
DAG
)
;
case
ISD
::
XOR
:
Val
=
performXORCombine
(
N
,
DAG
,
Subtarget
)
;
break
;
case
ISD
::
SETCC
:
Val
=
performSETCCCombine
(
N
,
DAG
)
;
break
;
}
if
(
Val
.
getNode
(
)
)
{
DEBUG
(
dbgs
(
)
<<
"\nMipsSE DAG Combine:\n"
;
N
->
printrWithDepth
(
dbgs
(
)
,
&
DAG
)
;
dbgs
(
)
<<
"\n=> \n"
;
Val
.
getNode
(
)
->
printrWithDepth
(
dbgs
(
)
,
&
DAG
)
;
dbgs
(
)
<<
"\n"
)
;
return
Val
;
}
return
MipsTargetLowering
::
PerformDAGCombine
(
N
,
DCI
)
;
}
</s>

This method will be invoked for all target nodes and for any target-independent nodes that the target has registered with invoke it for .

Mips
Mips
ISD::AND
ISD::OR
ISD::MUL
ISD::SHL
ISD::SRA
ISD::SRL
ISD::VSELECT
ISD::XOR
ISD::SETCC
"\nMipsSE DAG Combine:\n"
"\n=> \n"
"\n"
Mips


<s> void alpha_set_memflags ( rtx seq , rtx ref ) { rtx_insn * insn ; if ( ! MEM_P ( ref ) ) return ; if ( ! MEM_VOLATILE_P ( ref ) && ! MEM_NOTRAP_P ( ref ) && ! MEM_READONLY_P ( ref ) ) return ; subrtx_var_iterator :: array_type array ; for ( insn = as_a < rtx_insn * > ( seq ) ; insn ; insn = NEXT_INSN ( insn ) ) if ( INSN_P ( insn ) ) FOR_EACH_SUBRTX_VAR ( iter , array , PATTERN ( insn ) , NONCONST ) { rtx x = * iter ; if ( MEM_P ( x ) ) { MEM_VOLATILE_P ( x ) = MEM_VOLATILE_P ( ref ) ; MEM_NOTRAP_P ( x ) = MEM_NOTRAP_P ( ref ) ; MEM_READONLY_P ( x ) = MEM_READONLY_P ( ref ) ; iter . skip_subrtxes ( ) ; } } else gcc_unreachable ( ) ; } </s>

Given INSN , which is an INSN list or the PATTERN of a single insn generated to perform a memory operation , look for any MEMs in either a SET_DEST or a SET_SRC and copy the in-struct , unchanging , and volatile flags from REF into each of the MEMs found . If REF is not a MEM , do n't do anything .


<s> static bool mips_vectorize_vec_perm_const ( machine_mode vmode , rtx target , rtx op0 , rtx op1 , const vec_perm_indices & sel ) { struct expand_vec_perm_d d ; int i , nelt , which ; unsigned char orig_perm [ MAX_VECT_LEN ] ; bool ok ; d . target = target ; if ( op0 ) { rtx nop0 = force_reg ( vmode , op0 ) ; if ( op0 == op1 ) op1 = nop0 ; op0 = nop0 ; } if ( op1 ) op1 = force_reg ( vmode , op1 ) ; d . op0 = op0 ; d . op1 = op1 ; d . vmode = vmode ; gcc_assert ( VECTOR_MODE_P ( vmode ) ) ; d . nelt = nelt = GET_MODE_NUNITS ( vmode ) ; d . testing_p = ! target ; memset ( orig_perm , 0 , MAX_VECT_LEN ) ; for ( i = which = 0 ; i < nelt ; ++ i ) { int ei = sel [ i ] & ( 2 * nelt - 1 ) ; which |= ( ei < nelt ? 1 : 2 ) ; orig_perm [ i ] = ei ; } memcpy ( d . perm , orig_perm , MAX_VECT_LEN ) ; switch ( which ) { default : gcc_unreachable ( ) ; case 3 : d . one_vector_p = false ; if ( d . testing_p || ! rtx_equal_p ( d . op0 , d . op1 ) ) break ; case 2 : for ( i = 0 ; i < nelt ; ++ i ) d . perm [ i ] &= nelt - 1 ; d . op0 = d . op1 ; d . one_vector_p = true ; break ; case 1 : d . op1 = d . op0 ; d . one_vector_p = true ; break ; } if ( d . testing_p ) { d . target = gen_raw_REG ( d . vmode , LAST_VIRTUAL_REGISTER + 1 ) ; d . op1 = d . op0 = gen_raw_REG ( d . vmode , LAST_VIRTUAL_REGISTER + 2 ) ; if ( ! d . one_vector_p ) d . op1 = gen_raw_REG ( d . vmode , LAST_VIRTUAL_REGISTER + 3 ) ; start_sequence ( ) ; ok = mips_expand_vec_perm_const_1 ( & d ) ; end_sequence ( ) ; return ok ; } ok = mips_expand_vec_perm_const_1 ( & d ) ; if ( ! ok && which == 3 ) { d . op0 = op0 ; d . op1 = op1 ; d . one_vector_p = false ; memcpy ( d . perm , orig_perm , MAX_VECT_LEN ) ; ok = mips_expand_vec_perm_const_1 ( & d ) ; } return ok ; } </s>


<s>
void
AArch64TargetLowering
::
LowerAsmOperandForConstraint
(
SDValue
Op
,
std
::
string
&
Constraint
,
std
::
vector
<
SDValue
>
&
Ops
,
SelectionDAG
&
DAG
)
const
{
SDValue
Result
(
0
,
0
)
;
if
(
Constraint
.
size
(
)
!=
1
)
return
;
switch
(
Constraint
[
0
]
)
{
default
:
break
;
case
'I'
:
case
'J'
:
case
'K'
:
case
'L'
:
case
'M'
:
case
'N'
:
case
'Z'
:
{
ConstantSDNode
*
C
=
dyn_cast
<
ConstantSDNode
>
(
Op
)
;
if
(
!
C
)
return
;
uint64_t
CVal
=
C
->
getZExtValue
(
)
;
uint32_t
Bits
;
switch
(
Constraint
[
0
]
)
{
default
:
llvm_unreachable
(
"Unimplemented C_Other constraint"
)
;
case
'I'
:
if
(
CVal
<=
0xfff
)
break
;
return
;
case
'K'
:
if
(
A64Imms
::
isLogicalImm
(
32
,
CVal
,
Bits
)
)
break
;
return
;
case
'L'
:
if
(
A64Imms
::
isLogicalImm
(
64
,
CVal
,
Bits
)
)
break
;
return
;
case
'Z'
:
if
(
CVal
==
0
)
break
;
return
;
}
Result
=
DAG
.
getTargetConstant
(
CVal
,
Op
.
getValueType
(
)
)
;
break
;
}
case
'S'
:
{
if
(
const
GlobalAddressSDNode
*
GA
=
dyn_cast
<
GlobalAddressSDNode
>
(
Op
)
)
{
Result
=
DAG
.
getTargetGlobalAddress
(
GA
->
getGlobal
(
)
,
Op
.
getDebugLoc
(
)
,
GA
->
getValueType
(
0
)
)
;
}
else
if
(
const
BlockAddressSDNode
*
BA
=
dyn_cast
<
BlockAddressSDNode
>
(
Op
)
)
{
Result
=
DAG
.
getTargetBlockAddress
(
BA
->
getBlockAddress
(
)
,
BA
->
getValueType
(
0
)
)
;
}
else
if
(
const
ExternalSymbolSDNode
*
ES
=
dyn_cast
<
ExternalSymbolSDNode
>
(
Op
)
)
{
Result
=
DAG
.
getTargetExternalSymbol
(
ES
->
getSymbol
(
)
,
ES
->
getValueType
(
0
)
)
;
}
else
return
;
break
;
}
case
'Y'
:
if
(
const
ConstantFPSDNode
*
CFP
=
dyn_cast
<
ConstantFPSDNode
>
(
Op
)
)
{
if
(
CFP
->
isExactlyValue
(
0.0
)
)
{
Result
=
DAG
.
getTargetConstantFP
(
0.0
,
CFP
->
getValueType
(
0
)
)
;
break
;
}
}
return
;
}
if
(
Result
.
getNode
(
)
)
{
Ops
.
push_back
(
Result
)
;
return
;
}
TargetLowering
::
LowerAsmOperandForConstraint
(
Op
,
Constraint
,
Ops
,
DAG
)
;
}
</s>

Lower the specified operand into the Ops vector .


<s> rtx ix86_expand_fast_convert_bf_to_sf ( rtx val ) { rtx op = gen_lowpart ( HImode , val ) , ret ; if ( CONST_INT_P ( op ) ) { ret = simplify_const_unary_operation ( FLOAT_EXTEND , SFmode , val , BFmode ) ; if ( ret ) return ret ; ret = gen_reg_rtx ( SImode ) ; emit_move_insn ( ret , GEN_INT ( INTVAL ( op ) & 0xffff ) ) ; emit_insn ( gen_ashlsi3 ( ret , ret , GEN_INT ( 16 ) ) ) ; return gen_lowpart ( SFmode , ret ) ; } ret = gen_reg_rtx ( SFmode ) ; emit_insn ( gen_extendbfsf2_1 ( ret , force_reg ( BFmode , val ) ) ) ; return ret ; } </s>

Convert a BFmode VAL to SFmode without signaling sNaNs . This is done by returning SF SUBREG of ( ( HI SUBREG ) ( VAL ) ) < < 16 .


"%qE attribute only applies to functions"

"an interrupt handler cannot be compiled with -muser-mode"

Handle an `` interrupt_handler '' attribute ; arguments as in struct attribute_spec.handler .


"SI Lower control flow pseudo instructions"

getPassName - Return a nice clean name for a pass .


"WebAssembly Fix Irreducible Control Flow"


<s>
StringRef
getPassName
(
)
const
override
{
return
"Hexagon CFG Optimizer"
;
}
</s>


<s> bool HexagonSplitConst32AndConst64 :: runOnMachineFunction ( MachineFunction & Fn ) { auto & HST = Fn . getSubtarget < HexagonSubtarget > ( ) ; auto & HTM = static_cast < const HexagonTargetMachine & > ( Fn . getTarget ( ) ) ; auto & TLOF = * HTM . getObjFileLowering ( ) ; if ( HST . useSmallData ( ) && TLOF . isSmallDataEnabled ( HTM ) ) return false ; const TargetInstrInfo * TII = HST . getInstrInfo ( ) ; const TargetRegisterInfo * TRI = HST . getRegisterInfo ( ) ; for ( MachineBasicBlock & B : Fn ) { for ( MachineInstr & MI : llvm :: make_early_inc_range ( B ) ) { unsigned Opc = MI . getOpcode ( ) ; if ( Opc == Hexagon :: CONST32 ) { Register DestReg = MI . getOperand ( 0 ) . getReg ( ) ; uint64_t ImmValue = MI . getOperand ( 1 ) . getImm ( ) ; const DebugLoc & DL = MI . getDebugLoc ( ) ; BuildMI ( B , MI , DL , TII -> get ( Hexagon :: A2_tfrsi ) , DestReg ) . addImm ( ImmValue ) ; B . erase ( & MI ) ; } else if ( Opc == Hexagon :: CONST64 ) { Register DestReg = MI . getOperand ( 0 ) . getReg ( ) ; int64_t ImmValue = MI . getOperand ( 1 ) . getImm ( ) ; const DebugLoc & DL = MI . getDebugLoc ( ) ; Register DestLo = TRI -> getSubReg ( DestReg , Hexagon :: isub_lo ) ; Register DestHi = TRI -> getSubReg ( DestReg , Hexagon :: isub_hi ) ; int32_t LowWord = ( ImmValue & 0xFFFFFFFF ) ; int32_t HighWord = ( ImmValue >> 32 ) & 0xFFFFFFFF ; BuildMI ( B , MI , DL , TII -> get ( Hexagon :: A2_tfrsi ) , DestLo ) . addImm ( LowWord ) ; BuildMI ( B , MI , DL , TII -> get ( Hexagon :: A2_tfrsi ) , DestHi ) . addImm ( HighWord ) ; B . erase ( & MI ) ; } } } return true ; } </s>


<s> unsigned RISCVTargetLowering :: getExceptionPointerRegister ( const Constant * PersonalityFn ) const { if ( Subtarget . isRV64 ( ) ) return RISCV :: epc_64 ; else return RISCV :: epc ; } </s>

If a physical register , this returns the register that receives the exception address on entry to an EH pad .


<s> void print ( raw_ostream & OS ) const override { switch ( Kind ) { case Token : OS << "Tok:" << Tok . Tok ; break ; case Local : OS << "Loc:" << Reg . RegNo << ":" << static_cast < int > ( Reg . Type ) ; break ; case Stack : OS << "Stk:" << Reg . RegNo << ":" << static_cast < int > ( Reg . Type ) ; break ; case Integer : OS << "Int:" << Int . Val ; break ; case Float : OS << "Flt:" << Flt . Val ; break ; case Symbol : OS << "Sym:" << Sym . Exp ; break ; } } </s>

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

WebAssembly "Tok:" "Loc:" ":" "Stk:" ":" "Int:" "Flt:" "Sym:"


<s> static void sh_setup_incoming_varargs ( cumulative_args_t ca , const function_arg_info & arg , int * pretend_arg_size , int second_time ATTRIBUTE_UNUSED ) { gcc_assert ( cfun -> stdarg ) ; if ( TARGET_VARARGS_PRETEND_ARGS ( current_function_decl ) ) { int named_parm_regs , anon_parm_regs ; named_parm_regs = ( sh_round_reg ( * get_cumulative_args ( ca ) , arg . mode ) + CEIL ( arg . promoted_size_in_bytes ( ) , UNITS_PER_WORD ) ) ; anon_parm_regs = NPARM_REGS ( SImode ) - named_parm_regs ; if ( anon_parm_regs > 0 ) * pretend_arg_size = anon_parm_regs * 4 ; } } </s>

We actually emit the code in sh_expand_prologue . We used to use a static variable to flag that we need to emit this code , but that does n't when inlining , when functions are deferred and then emitted later . Fortunately , we already have two flags that are part of struct function that tell if a function uses varargs or stdarg .


<s> CCAssignFn * MipsTargetLowering :: CCAssignFnForReturn ( ) const { return RetCC_Mips ; } </s>

Selects the correct CCAssignFn for a given CallingConvention value .


"Instr doesn't have FrameIndex operand!"

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


<s>
void
RISCVAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
,
const
MCSubtargetInfo
*
STI
)
const
{
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
MCFixupKindInfo
Info
=
getFixupKindInfo
(
Fixup
.
getKind
(
)
)
;
if
(
!
Value
)
return
;
Value
=
adjustFixupValue
(
Fixup
,
Value
,
Ctx
)
;
Value
<<=
Info
.
TargetOffset
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
unsigned
NumBytes
=
alignTo
(
Info
.
TargetSize
+
Info
.
TargetOffset
,
8
)
/
8
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
Data
[
Offset
+
i
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>

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


<s> static rtx aarch64_gen_storewb_pair ( machine_mode mode , rtx base , rtx reg , rtx reg2 , HOST_WIDE_INT adjustment ) { switch ( mode ) { case DImode : return gen_storewb_pairdi_di ( base , base , reg , reg2 , GEN_INT ( - adjustment ) , GEN_INT ( UNITS_PER_WORD - adjustment ) ) ; case DFmode : return gen_storewb_pairdf_di ( base , base , reg , reg2 , GEN_INT ( - adjustment ) , GEN_INT ( UNITS_PER_WORD - adjustment ) ) ; default : gcc_unreachable ( ) ; } } </s>

Generate and return an instruction to store the pair of registers REG and REG2 of mode MODE to location BASE with write-back adjusting the stack location BASE by ADJUSTMENT .


<s> const char * TriCoreTargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( ( TriCoreISD :: NodeType ) Opcode ) { case TriCoreISD :: FIRST_NUMBER : break ; case TriCoreISD :: RET_FLAG : return "TriCoreISD::RetFlag" ; case TriCoreISD :: LOAD_SYM : return "TriCoreISD::LOAD_SYM" ; case TriCoreISD :: MOVEi32 : return "TriCoreISD::MOVEi32" ; case TriCoreISD :: CALL : return "TriCoreISD::CALL" ; case TriCoreISD :: BR_CC : return "TriCoreISD::BR_CC" ; case TriCoreISD :: SELECT_CC : return "TriCoreISD::SELECT_CC" ; case TriCoreISD :: LOGICCMP : return "TriCoreISD::LOGICCMP" ; case TriCoreISD :: CMP : return "TriCoreISD::CMP" ; case TriCoreISD :: IMASK : return "TriCoreISD::IMASK" ; case TriCoreISD :: Wrapper : return "TriCoreISD::Wrapper" ; case TriCoreISD :: SH : return "TriCoreISD::SH" ; case TriCoreISD :: SHA : return "TriCoreISD::SHA" ; case TriCoreISD :: EXTR : return "TriCoreISD::EXTR" ; case TriCoreISD :: ABS : return "TriCoreISD::ABS" ; } return nullptr ; } </s>

getTargetNodeName - This method returns the name of a target specific

TriCore TriCore TriCoreISD::NodeType TriCoreISD::FIRST_NUMBER TriCoreISD::RET_FLAG "TriCoreISD::RetFlag" TriCoreISD::LOAD_SYM "TriCoreISD::LOAD_SYM" TriCoreISD::MOVEi32 "TriCoreISD::MOVEi32" TriCoreISD::CALL "TriCoreISD::CALL" TriCoreISD::BR_CC "TriCoreISD::BR_CC" TriCoreISD::SELECT_CC "TriCoreISD::SELECT_CC" TriCoreISD::LOGICCMP "TriCoreISD::LOGICCMP" TriCoreISD::CMP "TriCoreISD::CMP" TriCoreISD::IMASK "TriCoreISD::IMASK" TriCoreISD::Wrapper "TriCoreISD::Wrapper" TriCoreISD::SH "TriCoreISD::SH" TriCoreISD::SHA "TriCoreISD::SHA" TriCoreISD::EXTR "TriCoreISD::EXTR" TriCoreISD::ABS "TriCoreISD::ABS"


<s> void BPFMCCodeEmitter :: encodeInstruction ( const MCInst & MI , raw_ostream & OS , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { unsigned Opcode = MI . getOpcode ( ) ; support :: endian :: Writer < support :: little > LE ( OS ) ; support :: endian :: Writer < support :: big > BE ( OS ) ; if ( Opcode == BPF :: LD_imm64 || Opcode == BPF :: LD_pseudo ) { uint64_t Value = getBinaryCodeForInstr ( MI , Fixups , STI ) ; LE . write < uint8_t > ( Value >> 56 ) ; if ( IsLittleEndian ) LE . write < uint8_t > ( ( Value >> 48 ) & 0xff ) ; else LE . write < uint8_t > ( SwapBits ( ( Value >> 48 ) & 0xff ) ) ; LE . write < uint16_t > ( 0 ) ; if ( IsLittleEndian ) LE . write < uint32_t > ( Value & 0xffffFFFF ) ; else BE . write < uint32_t > ( Value & 0xffffFFFF ) ; const MCOperand & MO = MI . getOperand ( 1 ) ; uint64_t Imm = MO . isImm ( ) ? MO . getImm ( ) : 0 ; LE . write < uint8_t > ( 0 ) ; LE . write < uint8_t > ( 0 ) ; LE . write < uint16_t > ( 0 ) ; if ( IsLittleEndian ) LE . write < uint32_t > ( Imm >> 32 ) ; else BE . write < uint32_t > ( Imm >> 32 ) ; } else { uint64_t Value = getBinaryCodeForInstr ( MI , Fixups , STI ) ; LE . write < uint8_t > ( Value >> 56 ) ; if ( IsLittleEndian ) { LE . write < uint8_t > ( ( Value >> 48 ) & 0xff ) ; LE . write < uint16_t > ( ( Value >> 32 ) & 0xffff ) ; LE . write < uint32_t > ( Value & 0xffffFFFF ) ; } else { LE . write < uint8_t > ( SwapBits ( ( Value >> 48 ) & 0xff ) ) ; BE . write < uint16_t > ( ( Value >> 32 ) & 0xffff ) ; BE . write < uint32_t > ( Value & 0xffffFFFF ) ; } } } </s>

Encode the given Inst to bytes and append to CB .


<s> static pad_direction ia64_function_arg_padding ( machine_mode mode , const_tree type ) { if ( TARGET_HPUX && type && AGGREGATE_TYPE_P ( type ) && int_size_in_bytes ( type ) < UNITS_PER_WORD ) return PAD_UPWARD ; return default_function_arg_padding ( mode , type ) ; } </s>

Implement TARGET_FUNCTION_ARG_PADDING . For the HP-UX IA64 aggregate parameters are passed stored in the most significant bits of the stack slot .


<s> void xtensa_expand_atomic ( enum rtx_code code , rtx target , rtx mem , rtx val , bool after ) { machine_mode mode = GET_MODE ( mem ) ; struct alignment_context ac ; rtx_code_label * csloop = gen_label_rtx ( ) ; rtx cmp , tmp ; rtx old = gen_reg_rtx ( SImode ) ; rtx new_rtx = gen_reg_rtx ( SImode ) ; rtx orig = NULL_RTX ; init_alignment_context ( & ac , mem ) ; if ( ac . shift != NULL_RTX ) val = xtensa_expand_mask_and_shift ( val , mode , ac . shift ) ; switch ( code ) { case PLUS : case MINUS : orig = gen_reg_rtx ( SImode ) ; convert_move ( orig , val , 1 ) ; break ; case SET : case IOR : case XOR : break ; case MULT : case AND : val = expand_simple_binop ( SImode , XOR , val , ac . modemaski , NULL_RTX , 1 , OPTAB_DIRECT ) ; break ; default : gcc_unreachable ( ) ; } cmp = force_reg ( SImode , ac . memsi ) ; emit_label ( csloop ) ; emit_move_insn ( old , cmp ) ; switch ( code ) { case PLUS : case MINUS : val = expand_simple_binop ( SImode , code , old , orig , NULL_RTX , 1 , OPTAB_DIRECT ) ; val = expand_simple_binop ( SImode , AND , val , ac . modemask , NULL_RTX , 1 , OPTAB_DIRECT ) ; case SET : tmp = expand_simple_binop ( SImode , AND , old , ac . modemaski , NULL_RTX , 1 , OPTAB_DIRECT ) ; tmp = expand_simple_binop ( SImode , IOR , tmp , val , new_rtx , 1 , OPTAB_DIRECT ) ; break ; case AND : case IOR : case XOR : tmp = expand_simple_binop ( SImode , code , old , val , new_rtx , 1 , OPTAB_DIRECT ) ; break ; case MULT : tmp = expand_simple_binop ( SImode , AND , old , val , NULL_RTX , 1 , OPTAB_DIRECT ) ; tmp = expand_simple_binop ( SImode , XOR , tmp , ac . modemask , new_rtx , 1 , OPTAB_DIRECT ) ; break ; default : gcc_unreachable ( ) ; } if ( tmp != new_rtx ) emit_move_insn ( new_rtx , tmp ) ; emit_insn ( gen_sync_compare_and_swapsi ( cmp , ac . memsi , old , new_rtx ) ) ; emit_cmp_and_jump_insns ( cmp , old , NE , const0_rtx , SImode , true , csloop ) ; if ( target ) { tmp = ( after ? new_rtx : cmp ) ; convert_move ( target , ( ac . shift == NULL_RTX ? tmp : expand_simple_binop ( SImode , LSHIFTRT , tmp , ac . shift , NULL_RTX , 1 , OPTAB_DIRECT ) ) , 1 ) ; } } </s>

Expand an atomic operation CODE of mode MODE ( either HImode or QImode -- the default expansion works fine for SImode ) . MEM is the memory location and VAL the value to play with . If AFTER is true then store the value MEM holds after the operation , if AFTER is false then store the value MEM holds before the operation . If TARGET is zero then discard that value , else store it to TARGET .


<s> static rtx frv_read_argument ( tree exp , unsigned int index ) { return expand_normal ( CALL_EXPR_ARG ( exp , index ) ) ; } </s>

Read a value from the head of the tree list pointed to by ARGLISTPTR . Return the value as an rtx and replace * ARGLISTPTR with the tail of the list .


<s>
void
CJGInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
const
DebugLoc
&
DL
,
unsigned
DestReg
,
unsigned
SrcReg
,
bool
KillSrc
)
const
{
if
(
CJG
::
GPRegsRegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
I
,
DL
,
get
(
CJG
::
CPYrr
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
else
{
llvm_unreachable
(
"Impossible reg-to-reg copy"
)
;
}
}
</s>

CJG
CJG
CJG::GPRegsRegClass
CJG::CPYrr
"Impossible reg-to-reg copy"


<s> virtual bool mayNeedRelaxation ( const MCInst & Inst ) const { return false ; } </s>

Check whether the given instruction may need relaxation .


<s> bool Dcpu16PassConfig :: addPreEmitPass ( ) { return false ; } </s>

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


"Cannot align scalable vectors more than 16 bytes"

"There must be a free register after frame setup"

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


<s> DecodeStatus ARMDisassembler :: getInstruction ( MCInst & MI , uint64_t & Size , ArrayRef < uint8_t > Bytes , uint64_t Address , raw_ostream & CS ) const { if ( STI . getFeatureBits ( ) [ ARM :: ModeThumb ] ) return getThumbInstruction ( MI , Size , Bytes , Address , CS ) ; return getARMInstruction ( MI , Size , Bytes , Address , CS ) ; } </s>

Returns the disassembly of a single instruction .


<s> static void rs6000_emit_madd ( rtx target , rtx m1 , rtx m2 , rtx a ) { machine_mode mode = GET_MODE ( target ) ; rtx dst ; dst = expand_ternary_op ( mode , fma_optab , m1 , m2 , a , target , 0 ) ; gcc_assert ( dst != NULL ) ; if ( dst != target ) emit_move_insn ( target , dst ) ; } </s>


<s> TargetLowering :: ConstraintWeight PPCTargetLowering :: getSingleConstraintMatchWeight ( AsmOperandInfo & info , const char * constraint ) const { ConstraintWeight weight = CW_Invalid ; Value * CallOperandVal = info . CallOperandVal ; if ( CallOperandVal == NULL ) return CW_Default ; Type * type = CallOperandVal -> getType ( ) ; if ( StringRef ( constraint ) == "wc" && type -> isIntegerTy ( 1 ) ) return CW_Register ; else if ( ( StringRef ( constraint ) == "wa" || StringRef ( constraint ) == "wd" || StringRef ( constraint ) == "wf" ) && type -> isVectorTy ( ) ) return CW_Register ; else if ( StringRef ( constraint ) == "ws" && type -> isDoubleTy ( ) ) return CW_Register ; switch ( * constraint ) { default : weight = TargetLowering :: getSingleConstraintMatchWeight ( info , constraint ) ; break ; case 'b' : if ( type -> isIntegerTy ( ) ) weight = CW_Register ; break ; case 'f' : if ( type -> isFloatTy ( ) ) weight = CW_Register ; break ; case 'd' : if ( type -> isDoubleTy ( ) ) weight = CW_Register ; break ; case 'v' : if ( type -> isVectorTy ( ) ) weight = CW_Register ; break ; case 'y' : weight = CW_Register ; break ; case 'Z' : weight = CW_Memory ; break ; } return weight ; } </s>

Examine constraint string and operand type and determine a weight value .


<s> bool WebAssemblyTargetLowering :: getTgtMemIntrinsic ( IntrinsicInfo & Info , const CallInst & I , MachineFunction & MF , unsigned Intrinsic ) const { switch ( Intrinsic ) { case Intrinsic :: wasm_atomic_notify : Info . opc = ISD :: INTRINSIC_W_CHAIN ; Info . memVT = MVT :: i32 ; Info . ptrVal = I . getArgOperand ( 0 ) ; Info . offset = 0 ; Info . align = Align ( 4 ) ; Info . flags = MachineMemOperand :: MOVolatile | MachineMemOperand :: MOLoad ; return true ; case Intrinsic :: wasm_atomic_wait_i32 : Info . opc = ISD :: INTRINSIC_W_CHAIN ; Info . memVT = MVT :: i32 ; Info . ptrVal = I . getArgOperand ( 0 ) ; Info . offset = 0 ; Info . align = Align ( 4 ) ; Info . flags = MachineMemOperand :: MOVolatile | MachineMemOperand :: MOLoad ; return true ; case Intrinsic :: wasm_atomic_wait_i64 : Info . opc = ISD :: INTRINSIC_W_CHAIN ; Info . memVT = MVT :: i64 ; Info . ptrVal = I . getArgOperand ( 0 ) ; Info . offset = 0 ; Info . align = Align ( 8 ) ; Info . flags = MachineMemOperand :: MOVolatile | MachineMemOperand :: MOLoad ; return true ; case Intrinsic :: wasm_load32_zero : case Intrinsic :: wasm_load64_zero : Info . opc = ISD :: INTRINSIC_W_CHAIN ; Info . memVT = Intrinsic == Intrinsic :: wasm_load32_zero ? MVT :: i32 : MVT :: i64 ; Info . ptrVal = I . getArgOperand ( 0 ) ; Info . offset = 0 ; Info . align = Info . memVT == MVT :: i32 ? Align ( 4 ) : Align ( 8 ) ; Info . flags = MachineMemOperand :: MOLoad ; return true ; default : return false ; } } </s>

Given an intrinsic , checks if on the target the intrinsic will need to map to a MemIntrinsicNode ( touches memory ) .


<s>
const
MCExpr
*
ARMElfTargetObjectFile
::
getTTypeGlobalReference
(
const
GlobalValue
*
GV
,
unsigned
Encoding
,
Mangler
&
Mang
,
const
TargetMachine
&
TM
,
MachineModuleInfo
*
MMI
,
MCStreamer
&
Streamer
)
const
{
assert
(
Encoding
==
DW_EH_PE_absptr
&&
"Can handle absptr encoding only"
)
;
return
MCSymbolRefExpr
::
Create
(
TM
.
getSymbol
(
GV
,
Mang
)
,
MCSymbolRefExpr
::
VK_ARM_TARGET2
,
getContext
(
)
)
;
}
</s>

The mach-o version of this method defaults to returning a stub reference .

ARM
ARM
"Can handle absptr encoding only"
ARM


<s> int iq2000_check_split ( rtx address , machine_mode mode ) { if ( GET_MODE_SIZE ( mode ) > ( unsigned ) UNITS_PER_WORD ) return 0 ; if ( ( GET_CODE ( address ) == SYMBOL_REF ) || ( GET_CODE ( address ) == CONST && GET_CODE ( XEXP ( XEXP ( address , 0 ) , 0 ) ) == SYMBOL_REF ) || GET_CODE ( address ) == LABEL_REF ) return 1 ; return 0 ; } </s>

Return nonzero if we split the address into high and low parts .


<s> void R600MachineCFGStructurizer :: removeSuccessor ( MachineBasicBlock * MBB ) { while ( MBB -> succ_size ( ) ) MBB -> removeSuccessor ( * MBB -> succ_begin ( ) ) ; } </s>

Remove specified successor from the successors list of this MachineBasicBlock .


<s> static unsigned nvptx_process_pars ( parallel * par ) { if ( nvptx_optimize ) nvptx_optimize_inner ( par ) ; unsigned inner_mask = par -> mask ; if ( par -> inner ) { par -> inner_mask = nvptx_process_pars ( par -> inner ) ; inner_mask |= par -> inner_mask ; } if ( par -> mask & GOMP_DIM_MASK ( GOMP_DIM_MAX ) ) ; else if ( par -> mask & GOMP_DIM_MASK ( GOMP_DIM_WORKER ) ) { nvptx_wpropagate ( false , par -> forked_block , par -> forked_insn ) ; nvptx_wpropagate ( true , par -> forked_block , par -> fork_insn ) ; emit_insn_after ( nvptx_wsync ( false ) , par -> forked_insn ) ; emit_insn_before ( nvptx_wsync ( true ) , par -> joining_insn ) ; } else if ( par -> mask & GOMP_DIM_MASK ( GOMP_DIM_VECTOR ) ) nvptx_vpropagate ( par -> forked_block , par -> forked_insn ) ; if ( par -> next ) inner_mask |= nvptx_process_pars ( par -> next ) ; return inner_mask ; } </s>

Process the parallel PAR and all its contained parallels . We do everything but the neutering . Return mask of partitioned modes used within this parallel .


"\tARM::shouldCoalesce - Coalesced Weight: "


<s> static int fp_regs_to_save ( void ) { int i , n = 0 ; if ( ! TARGET_AM33_2 ) return 0 ; for ( i = FIRST_FP_REGNUM ; i <= LAST_FP_REGNUM ; ++ i ) if ( df_regs_ever_live_p ( i ) && ! call_used_regs [ i ] ) ++ n ; return n ; } </s>

Count the number of FP registers that have to be saved .


<s> unsigned SparcMCCodeEmitter :: getBranchTargetOpValue ( const MCInst & MI , unsigned OpNo , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { const MCOperand & MO = MI . getOperand ( OpNo ) ; if ( MO . isReg ( ) || MO . isImm ( ) ) return getMachineOpValue ( MI , MO , Fixups , STI ) ; Fixups . push_back ( MCFixup :: Create ( 0 , MO . getExpr ( ) , ( MCFixupKind ) Sparc :: fixup_sparc_br22 ) ) ; return 0 ; } </s>

getBranchTargetOpValue - Return binary encoding of the branch target operand .


<s> Status intersect ( const Status & S ) const { unsigned NewMask = ( Mask & S . Mask ) & ( Mode ^ ~ S . Mode ) ; unsigned NewMode = ( Mode & NewMask ) ; return Status ( NewMask , NewMode ) ; } </s>

Intersect this set with a temporary other set in place .


"Code generation for MIPS-I is not implemented"

"Code generation for MIPS-V is not implemented"

"MSA requires a 64-bit FPU register file (FR=1 mode). "

"-mattr=+nooddspreg requires the O32 ABI."

"FPXX is not permitted for the N32/N64 ABI's."

"position-independent code requires '-mabicalls'"

"warning: cannot use small-data accesses for '-mabicalls'"

This constructor initializes the data members to match that of the specified triple .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { TII = MF . getSubtarget < TGSISubtarget > ( ) . getInstrInfo ( ) ; TRI = & TII -> getRegisterInfo ( ) ; DEBUG ( MF . dump ( ) ; ) ; OrderedBlks . clear ( ) ; Visited . clear ( ) ; FuncRep = & MF ; MLI = & getAnalysis < MachineLoopInfo > ( ) ; DEBUG ( dbgs ( ) << "LoopInfo:\n" ; PrintLoopinfo ( * MLI ) ; ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; DEBUG ( MDT -> print ( dbgs ( ) , ( const llvm :: Module * ) nullptr ) ; ) ; PDT = & getAnalysis < MachinePostDominatorTree > ( ) ; DEBUG ( PDT -> print ( dbgs ( ) ) ; ) ; prepare ( ) ; run ( ) ; DEBUG ( MF . dump ( ) ; ) ; return true ; } </s>

runOnMachineFunction - Emit the function body .


<s> static int ix86_mode_exit ( int entity ) { switch ( entity ) { case X86_DIRFLAG : return X86_DIRFLAG_ANY ; case AVX_U128 : return ix86_avx_u128_mode_exit ( ) ; 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 exit .


<s> static int aarch64_builtin_vectorization_cost ( enum vect_cost_for_stmt type_of_cost , tree vectype , int misalign ATTRIBUTE_UNUSED ) { unsigned elements ; const cpu_vector_cost * costs = aarch64_tune_params . vec_costs ; bool fp = false ; if ( vectype != NULL ) fp = FLOAT_TYPE_P ( vectype ) ; switch ( type_of_cost ) { case scalar_stmt : return fp ? costs -> scalar_fp_stmt_cost : costs -> scalar_int_stmt_cost ; case scalar_load : return costs -> scalar_load_cost ; case scalar_store : return costs -> scalar_store_cost ; case vector_stmt : return fp ? costs -> vec_fp_stmt_cost : costs -> vec_int_stmt_cost ; case vector_load : return costs -> vec_align_load_cost ; case vector_store : return costs -> vec_store_cost ; case vec_to_scalar : return costs -> vec_to_scalar_cost ; case scalar_to_vec : return costs -> scalar_to_vec_cost ; case unaligned_load : case vector_gather_load : return costs -> vec_unalign_load_cost ; case unaligned_store : case vector_scatter_store : return costs -> vec_unalign_store_cost ; case cond_branch_taken : return costs -> cond_taken_branch_cost ; case cond_branch_not_taken : return costs -> cond_not_taken_branch_cost ; case vec_perm : return costs -> vec_permute_cost ; case vec_promote_demote : return fp ? costs -> vec_fp_stmt_cost : costs -> vec_int_stmt_cost ; case vec_construct : elements = estimated_poly_value ( TYPE_VECTOR_SUBPARTS ( vectype ) ) ; return elements / 2 + 1 ; default : gcc_unreachable ( ) ; } } </s>


<s> static void dump_constants ( struct mips16_constant * constants , rtx insn ) { struct mips16_constant * c , * next ; int align ; align = 0 ; for ( c = constants ; c != NULL ; c = next ) { if ( align < GET_MODE_SIZE ( c -> mode ) ) { int align_log = floor_log2 ( GET_MODE_SIZE ( c -> mode ) ) ; insn = emit_insn_after ( gen_align ( GEN_INT ( align_log ) ) , insn ) ; } align = GET_MODE_SIZE ( c -> mode ) ; insn = emit_label_after ( c -> label , insn ) ; insn = dump_constants_1 ( c -> mode , c -> value , insn ) ; next = c -> next ; free ( c ) ; } emit_barrier_after ( insn ) ; } </s>

Dump out the constants in CONSTANTS after INSN .


<s> bool X86PassConfig :: addPostFastRegAllocRewrite ( ) { addPass ( createX86FastTileConfigPass ( ) ) ; return true ; } </s>

addPostFastRegAllocRewrite - Add passes to the optimized register allocation pipeline after fast register allocation is complete .


<s> AArch64Subtarget :: AArch64Subtarget ( const Triple & TT , const std :: string & CPU , const std :: string & FS , const TargetMachine & TM , bool LittleEndian ) : AArch64GenSubtargetInfo ( TT , CPU , FS ) , ARMProcFamily ( Others ) , HasV8_1aOps ( false ) , HasV8_2aOps ( false ) , HasFPARMv8 ( false ) , HasNEON ( false ) , HasCrypto ( false ) , HasCRC ( false ) , HasPerfMon ( false ) , HasFullFP16 ( false ) , HasZeroCycleRegMove ( false ) , HasZeroCycleZeroing ( false ) , StrictAlign ( false ) , ReserveX18 ( TT . isOSDarwin ( ) ) , IsLittle ( LittleEndian ) , CPUString ( CPU ) , TargetTriple ( TT ) , FrameLowering ( ) , InstrInfo ( initializeSubtargetDependencies ( FS ) ) , TSInfo ( ) , TLInfo ( TM , * this ) { } </s>


"frame pointer should not have been eliminated"

"SecondSPAdjustAmount should be greater than zero"


<s> bool AArch64LoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( skipFunction ( * Fn . getFunction ( ) ) ) return false ; Subtarget = & static_cast < const AArch64Subtarget & > ( Fn . getSubtarget ( ) ) ; TII = static_cast < const AArch64InstrInfo * > ( Subtarget -> getInstrInfo ( ) ) ; TRI = Subtarget -> getRegisterInfo ( ) ; ModifiedRegs . resize ( TRI -> getNumRegs ( ) ) ; UsedRegs . resize ( TRI -> getNumRegs ( ) ) ; bool Modified = false ; bool enableNarrowLdOpt = Subtarget -> mergeNarrowLoads ( ) && ! Subtarget -> requiresStrictAlign ( ) ; for ( auto & MBB : Fn ) Modified |= optimizeBlock ( MBB , enableNarrowLdOpt ) ; return Modified ; } </s>


<s>
void
RISCVInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MBBI
,
const
DebugLoc
&
DL
,
MCRegister
DstReg
,
MCRegister
SrcReg
,
bool
KillSrc
)
const
{
if
(
RISCV
::
GPRRegClass
.
contains
(
DstReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
RISCV
::
ADDI
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
.
addImm
(
0
)
;
return
;
}
unsigned
Opc
;
if
(
RISCV
::
FPR32RegClass
.
contains
(
DstReg
,
SrcReg
)
)
Opc
=
RISCV
::
FSGNJ_S
;
else
if
(
RISCV
::
FPR64RegClass
.
contains
(
DstReg
,
SrcReg
)
)
Opc
=
RISCV
::
FSGNJ_D
;
else
llvm_unreachable
(
"Impossible reg-to-reg copy"
)
;
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
Opc
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
</s>


<s> virtual void print ( raw_ostream & OS ) const { } </s>

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


<s> bool PatmosInstrInfo :: isUnpredicatedTerminator ( const MachineInstr * MI ) const { if ( ! MI -> isTerminator ( ) ) return false ; if ( MI -> isBranch ( ) && isPredicated ( MI ) ) return true ; return ! isPredicated ( MI ) ; } </s>

Returns true if the instruction is a terminator instruction that has not been predicated .


<s> PPC :: AddrMode PPCTargetLowering :: SelectForceXFormMode ( SDValue N , SDValue & Disp , SDValue & Base , SelectionDAG & DAG ) const { PPC :: AddrMode Mode = PPC :: AM_XForm ; int16_t ForceXFormImm = 0 ; if ( provablyDisjointOr ( DAG , N ) && ! isIntS16Immediate ( N . getOperand ( 1 ) , ForceXFormImm ) ) { Disp = N . getOperand ( 0 ) ; Base = N . getOperand ( 1 ) ; return Mode ; } if ( N . getOpcode ( ) == ISD :: ADD && ( ! isIntS16Immediate ( N . getOperand ( 1 ) , ForceXFormImm ) || ! N . getOperand ( 1 ) . hasOneUse ( ) || ! N . getOperand ( 0 ) . hasOneUse ( ) ) ) { Disp = N . getOperand ( 0 ) ; Base = N . getOperand ( 1 ) ; return Mode ; } Disp = DAG . getRegister ( Subtarget . isPPC64 ( ) ? PPC :: ZERO8 : PPC :: ZERO , N . getValueType ( ) ) ; Base = N ; return Mode ; } </s>

SelectForceXFormMode - Given the specified address , force it to be represented as an indexed [ r+r ] operation ( an XForm instruction ) .


"__attribute__ ((__used__, visibility (\"hidden\"),\n"

"section (\".gnu.offload_funcs\"))) = { };\n\n"

"section (\".gnu.offload_vars\"))) = { };\n"

Generates object file with __offload_ * _end symbols for the target library .


<s> bool storeOfVectorConstantIsCheap ( EVT MemVT , unsigned NumElem , unsigned AddrSpace ) const override { return NumElem > 2 ; } </s>

Return true if it is expected to be cheaper to do a store of vector constant with the given size and type for the address space than to store the individual scalar element constants .


<s>
void
c4x_override_options
(
)
{
if
(
c4x_rpts_cycles_string
)
c4x_rpts_cycles
=
atoi
(
c4x_rpts_cycles_string
)
;
else
c4x_rpts_cycles
=
0
;
if
(
TARGET_C30
)
c4x_cpu_version
=
30
;
else
if
(
TARGET_C31
)
c4x_cpu_version
=
31
;
else
if
(
TARGET_C32
)
c4x_cpu_version
=
32
;
else
if
(
TARGET_C33
)
c4x_cpu_version
=
33
;
else
if
(
TARGET_C40
)
c4x_cpu_version
=
40
;
else
if
(
TARGET_C44
)
c4x_cpu_version
=
44
;
else
c4x_cpu_version
=
40
;
if
(
c4x_cpu_version_string
)
{
const
char
*
p
=
c4x_cpu_version_string
;
if
(
*
p
==
'c'
||
*
p
==
'C'
)
p
++
;
c4x_cpu_version
=
atoi
(
p
)
;
}
target_flags
&=
~
(
C30_FLAG
|
C31_FLAG
|
C32_FLAG
|
C33_FLAG
|
C40_FLAG
|
C44_FLAG
)
;
switch
(
c4x_cpu_version
)
{
case
30
:
target_flags
|=
C30_FLAG
;
break
;
case
31
:
target_flags
|=
C31_FLAG
;
break
;
case
32
:
target_flags
|=
C32_FLAG
;
break
;
case
33
:
target_flags
|=
C33_FLAG
;
break
;
case
40
:
target_flags
|=
C40_FLAG
;
break
;
case
44
:
target_flags
|=
C44_FLAG
;
break
;
default
:
warning
(
"unknown CPU version %d, using 40.\n"
,
c4x_cpu_version
)
;
c4x_cpu_version
=
40
;
target_flags
|=
C40_FLAG
;
}
if
(
TARGET_C30
||
TARGET_C31
||
TARGET_C32
||
TARGET_C33
)
target_flags
|=
C3X_FLAG
;
else
target_flags
&=
~
C3X_FLAG
;
set_fast_math_flags
(
)
;
if
(
!
TARGET_ALIASES
&&
!
flag_argument_noalias
)
flag_argument_noalias
=
1
;
c4x_add_gc_roots
(
)
;
}
</s>

Override command line options . Called once after all options have been parsed . Mostly we process the processor type and sometimes adjust other TARGET_ options .


<s> static rtx m32r_function_arg ( cumulative_args_t cum_v , machine_mode mode , const_tree type ATTRIBUTE_UNUSED , bool named ATTRIBUTE_UNUSED ) { CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; return ( PASS_IN_REG_P ( * cum , mode , type ) ? gen_rtx_REG ( mode , ROUND_ADVANCE_CUM ( * cum , mode , type ) ) : NULL_RTX ) ; } </s>

On the M32R the first M32R_MAX_PARM_REGS args are normally in registers and the rest are pushed .


<s> ScheduleDAGInstrs * createMachineScheduler ( MachineSchedContext * C ) const override { return createPPCMachineScheduler ( C ) ; } </s>

Create an instance of ScheduleDAGInstrs to be run within the standard MachineScheduler pass for this function and target at the current optimization level .


<s> static int csky_address_cost ( rtx x , machine_mode mode ATTRIBUTE_UNUSED , addr_space_t as ATTRIBUTE_UNUSED , bool speed ATTRIBUTE_UNUSED ) { enum rtx_code code = GET_CODE ( x ) ; if ( code == REG ) return COSTS_N_INSNS ( 1 ) ; if ( code == PLUS && REG_P ( XEXP ( x , 0 ) ) && CONST_INT_P ( XEXP ( x , 1 ) ) ) return COSTS_N_INSNS ( 1 ) ; return COSTS_N_INSNS ( 3 ) ; } </s>

Implement TARGET_ADDRESS_COST to estimate cost of the memory address X . For C-SKY , ( register ) and ( register + offset ) have the same cost . Other situations cost more .


<s> static unsigned findDeadCallerSavedReg ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , const TargetRegisterInfo & TRI , bool Is64Bit ) { const MachineFunction * MF = MBB . getParent ( ) ; const Function * F = MF -> getFunction ( ) ; if ( ! F || MF -> getMMI ( ) . callsEHReturn ( ) ) return 0 ; static const uint16_t CallerSavedRegs32Bit [ ] = { X86 :: EAX , X86 :: EDX , X86 :: ECX , 0 } ; static const uint16_t CallerSavedRegs64Bit [ ] = { X86 :: RAX , X86 :: RDX , X86 :: RCX , X86 :: RSI , X86 :: RDI , X86 :: R8 , X86 :: R9 , X86 :: R10 , X86 :: R11 , 0 } ; unsigned Opc = MBBI -> getOpcode ( ) ; switch ( Opc ) { default : return 0 ; case X86 :: RET : case X86 :: RETI : case X86 :: TCRETURNdi : case X86 :: TCRETURNri : case X86 :: TCRETURNmi : case X86 :: TCRETURNdi64 : case X86 :: TCRETURNri64 : case X86 :: TCRETURNmi64 : case X86 :: EH_RETURN : case X86 :: EH_RETURN64 : { SmallSet < uint16_t , 8 > Uses ; for ( unsigned i = 0 , e = MBBI -> getNumOperands ( ) ; i != e ; ++ i ) { MachineOperand & MO = MBBI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isDef ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( ! Reg ) continue ; for ( MCRegAliasIterator AI ( Reg , & TRI , true ) ; AI . isValid ( ) ; ++ AI ) Uses . insert ( * AI ) ; } const uint16_t * CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit ; for ( ; * CS ; ++ CS ) if ( ! Uses . count ( * CS ) ) return * CS ; } } return 0 ; } </s>

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


<s> static bool csky_cannot_force_const_mem ( machine_mode mode ATTRIBUTE_UNUSED , rtx x ) { return csky_tls_referenced_p ( x ) ; } </s>

Implement TARGET_CANNOT_FORCE_CONST_MEM . Determine if it 's legal to put X into the constant pool . This is not possible for the address of thread-local symbols , which is checked above .


<s> static rtx nds32_expand_unop_builtin ( enum insn_code icode , tree exp , rtx target , bool return_p ) { rtx pat ; rtx op0 = nds32_read_argument ( exp , 0 ) ; int op0_num = return_p ? 1 : 0 ; if ( return_p ) target = nds32_legitimize_target ( icode , target ) ; op0 = nds32_legitimize_argument ( icode , op0_num , op0 ) ; if ( return_p ) pat = GEN_FCN ( icode ) ( target , op0 ) ; else pat = GEN_FCN ( icode ) ( op0 ) ; if ( ! pat ) return NULL_RTX ; emit_insn ( pat ) ; return target ; } </s>


<s> static void sparc64_initialize_trampoline ( rtx m_tramp , rtx fnaddr , rtx cxt ) { emit_move_insn ( adjust_address ( m_tramp , SImode , 0 ) , GEN_INT ( trunc_int_for_mode ( 0x83414000 , SImode ) ) ) ; emit_move_insn ( adjust_address ( m_tramp , SImode , 4 ) , GEN_INT ( trunc_int_for_mode ( 0xca586018 , SImode ) ) ) ; emit_move_insn ( adjust_address ( m_tramp , SImode , 8 ) , GEN_INT ( trunc_int_for_mode ( 0x81c14000 , SImode ) ) ) ; emit_move_insn ( adjust_address ( m_tramp , SImode , 12 ) , GEN_INT ( trunc_int_for_mode ( 0xca586010 , SImode ) ) ) ; emit_move_insn ( adjust_address ( m_tramp , DImode , 16 ) , cxt ) ; emit_move_insn ( adjust_address ( m_tramp , DImode , 24 ) , fnaddr ) ; emit_insn ( gen_flushdi ( validize_mem ( adjust_address ( m_tramp , DImode , 0 ) ) ) ) ; if ( sparc_cpu != PROCESSOR_ULTRASPARC && sparc_cpu != PROCESSOR_ULTRASPARC3 && sparc_cpu != PROCESSOR_NIAGARA && sparc_cpu != PROCESSOR_NIAGARA2 && sparc_cpu != PROCESSOR_NIAGARA3 && sparc_cpu != PROCESSOR_NIAGARA4 && sparc_cpu != PROCESSOR_NIAGARA7 ) emit_insn ( gen_flushdi ( validize_mem ( adjust_address ( m_tramp , DImode , 8 ) ) ) ) ; emit_library_call ( gen_rtx_SYMBOL_REF ( Pmode , "__enable_execute_stack" ) , LCT_NORMAL , VOIDmode , 1 , XEXP ( m_tramp , 0 ) , Pmode ) ; } </s>

The 64 bit version is simpler because it makes more sense to load the values as `` immediate '' data out of the trampoline . It 's also easier since we can read the PC without clobbering a register .


"RV16K DAG->DAG Pattern Instruction Selection"

getPassName - Return a nice clean name for a pass .


<s> SparcSubtarget & SparcSubtarget :: initializeSubtargetDependencies ( StringRef CPU , StringRef FS ) { IsV9 = false ; V8DeprecatedInsts = false ; IsVIS = false ; HasHardQuad = false ; UsePopc = false ; std :: string CPUName = CPU ; if ( CPUName . empty ( ) ) CPUName = ( Is64Bit ) ? "v9" : "v8" ; ParseSubtargetFeatures ( CPUName , FS ) ; if ( ! IsV9 ) UsePopc = false ; return * this ; } </s>

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


"optionally flag setting instruction missing optional def operand"

checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not expressible via match classes .


<s> const MCPhysReg * AMDGPURegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return & CalleeSavedReg ; } </s>


<s> Value * X86TargetLowering :: getSafeStackPointerLocation ( IRBuilderBase & IRB ) const { if ( Subtarget . getTargetTriple ( ) . isOSContiki ( ) ) return getDefaultSafeStackPointerLocation ( IRB , false ) ; if ( Subtarget . isTargetAndroid ( ) ) { int Offset = ( Subtarget . is64Bit ( ) ) ? 0x48 : 0x24 ; return SegmentOffset ( IRB , Offset , getAddressSpace ( ) ) ; } if ( Subtarget . isTargetFuchsia ( ) ) { return SegmentOffset ( IRB , 0x18 , getAddressSpace ( ) ) ; } return TargetLowering :: getSafeStackPointerLocation ( IRB ) ; } </s>

Return true if the target stores SafeStack pointer at a fixed offset in some non-standard address space , and populates the address space and offset as appropriate .


"Instruction should be in a basic block!"

"Generic instruction has unexpected implicit operands\n"

Select the ( possibly generic ) instruction I to only use target-specific opcodes .


<s> const PatmosInstrInfo * getInstrInfo ( ) const override { return InstrInfo . get ( ) ; } </s>


<s> int arc_attr_type ( rtx_insn * insn ) { if ( NONJUMP_INSN_P ( insn ) ? ( GET_CODE ( PATTERN ( insn ) ) == USE || GET_CODE ( PATTERN ( insn ) ) == CLOBBER ) : JUMP_P ( insn ) ? ( GET_CODE ( PATTERN ( insn ) ) == ADDR_VEC || GET_CODE ( PATTERN ( insn ) ) == ADDR_DIFF_VEC ) : ! CALL_P ( insn ) ) return - 1 ; return get_attr_type ( insn ) ; } </s>

Return the integer value of the `` type '' attribute for INSN , or -1 if INSN ca n't have attributes .


<s> bool AMDGPULowerIntrinsics :: runOnModule ( Module & M ) { bool Changed = false ; for ( Function & F : M ) { if ( ! F . isDeclaration ( ) ) continue ; switch ( F . getIntrinsicID ( ) ) { case Intrinsic :: memcpy : case Intrinsic :: memmove : case Intrinsic :: memset : if ( expandMemIntrinsicUses ( F ) ) Changed = true ; break ; case Intrinsic :: r600_read_tidig_x : case Intrinsic :: r600_read_tidig_y : case Intrinsic :: r600_read_tidig_z : case Intrinsic :: r600_read_local_size_x : case Intrinsic :: r600_read_local_size_y : case Intrinsic :: r600_read_local_size_z : Changed |= makeLIDRangeMetadata ( F ) ; break ; default : break ; } } return Changed ; } </s>

runOnModule - Virtual method overriden by subclasses to process the module being operated on .


<s> bool writeNopData ( uint64_t Count , MCObjectWriter * OW ) const { uint64_t NumNops = Count / 4 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> Write32 ( 0x60000000 ) ; switch ( Count % 4 ) { default : break ; case 1 : OW -> Write8 ( 0 ) ; break ; case 2 : OW -> Write16 ( 0 ) ; break ; case 3 : OW -> Write16 ( 0 ) ; OW -> Write8 ( 0 ) ; break ; } return true ; } </s>

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


<s> bool PPCLoopDataPrefetch :: runOnFunction ( Function & F ) { LI = & getAnalysis < LoopInfoWrapperPass > ( ) . getLoopInfo ( ) ; SE = & getAnalysis < ScalarEvolution > ( ) ; DL = & F . getParent ( ) -> getDataLayout ( ) ; AC = & getAnalysis < AssumptionCacheTracker > ( ) . getAssumptionCache ( F ) ; TTI = & getAnalysis < TargetTransformInfoWrapperPass > ( ) . getTTI ( F ) ; bool MadeChange = false ; for ( LoopInfo :: iterator I = LI -> begin ( ) , E = LI -> end ( ) ; I != E ; ++ I ) { Loop * L = * I ; MadeChange |= runOnLoop ( L ) ; } return MadeChange ; } </s>

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


<s> void PTXAsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { std :: string str ; str . reserve ( 64 ) ; raw_string_ostream OS ( str ) ; printInstruction ( MI , OS ) ; OS << ';' ; OS . flush ( ) ; size_t pos ; if ( ( pos = str . find ( "%type" ) ) != std :: string :: npos ) str . replace ( pos , 5 , getInstructionTypeName ( MI ) ) ; StringRef strref = StringRef ( str ) ; OutStreamer . EmitRawText ( strref ) ; } </s>

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


<s>
bool
fixupNeedsRelaxation
(
const
MCFixup
&
Fixup
,
uint64_t
Value
,
const
MCRelaxableFragment
*
DF
,
const
MCAsmLayout
&
Layout
)
const
override
{
llvm_unreachable
(
"RelaxInstruction() unimplemented"
)
;
return
false
;
}
</s>

Simple predicate for targets where ! Resolved implies requiring relaxation .


<s> void XNCMAsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { XNCMMCInstLower MCInstLowering ( OutContext , * Mang , * this ) ; MCInst TmpInst ; MCInstLowering . Lower ( MI , TmpInst ) ; OutStreamer . EmitInstruction ( TmpInst ) ; } </s>


<s> bool TPCPipeliner :: runOnMachineFunction ( MachineFunction & MF ) { if ( ! EnablePipelining ) { return false ; } MLI = & getAnalysis < MachineLoopInfo > ( ) ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; TII = MF . getSubtarget < TPCSubtarget > ( ) . getInstrInfo ( ) ; TRI = MF . getSubtarget < TPCSubtarget > ( ) . getRegisterInfo ( ) ; LMF = & MF ; bool Changed = false ; for ( auto & L : * MLI ) { Changed |= findInnermostLoop ( L ) ; } return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s> static bool bpf_small_register_classes_for_mode_p ( machine_mode mode ) { if ( TARGET_XBPF ) return 1 ; else return ( mode != FUNCTION_MODE ) ; } </s>

Implement target hook small_register_classes_for_mode_p .


<s>
bool
HexagonOptAddrMode
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
skipFunction
(
*
MF
.
getFunction
(
)
)
)
return
false
;
bool
Changed
=
false
;
auto
&
HST
=
MF
.
getSubtarget
<
HexagonSubtarget
>
(
)
;
auto
&
MRI
=
MF
.
getRegInfo
(
)
;
HII
=
HST
.
getInstrInfo
(
)
;
const
auto
&
MDF
=
getAnalysis
<
MachineDominanceFrontier
>
(
)
;
MDT
=
&
getAnalysis
<
MachineDominatorTree
>
(
)
;
const
auto
&
TRI
=
*
MF
.
getSubtarget
(
)
.
getRegisterInfo
(
)
;
const
TargetOperandInfo
TOI
(
*
HII
)
;
DataFlowGraph
G
(
MF
,
*
HII
,
TRI
,
*
MDT
,
MDF
,
TOI
)
;
G
.
build
(
BuildOptions
::
KeepDeadPhis
)
;
DFG
=
&
G
;
Liveness
L
(
MRI
,
*
DFG
)
;
L
.
computePhiInfo
(
)
;
LV
=
&
L
;
Deleted
.
clear
(
)
;
NodeAddr
<
FuncNode
*
>
FA
=
DFG
->
getFunc
(
)
;
DEBUG
(
dbgs
(
)
<<
"==== [RefMap#]=====:\n "
<<
Print
<
NodeAddr
<
FuncNode
*
>>
(
FA
,
*
DFG
)
<<
"\n"
)
;
for
(
NodeAddr
<
BlockNode
*
>
BA
:
FA
.
Addr
->
members
(
*
DFG
)
)
Changed
|=
processBlock
(
BA
)
;
for
(
auto
MI
:
Deleted
)
MI
->
eraseFromParent
(
)
;
if
(
Changed
)
{
G
.
build
(
)
;
L
.
computeLiveIns
(
)
;
L
.
resetLiveIns
(
)
;
L
.
resetKills
(
)
;
}
return
Changed
;
}
</s>

Hexagon
Hexagon
Hexagon
"==== [RefMap#]=====:\n "
"\n"


<s> void lm32_expand_scc ( rtx operands [ ] ) { rtx target = operands [ 0 ] ; enum rtx_code code = GET_CODE ( operands [ 1 ] ) ; rtx op0 = operands [ 2 ] ; rtx op1 = operands [ 3 ] ; gen_int_relational ( code , target , op0 , op1 , NULL_RTX ) ; } </s>

Try performing the comparison in OPERANDS [ 1 ] , whose arms are OPERANDS [ 2 ] and OPERAND [ 3 ] . Store the result in OPERANDS [ 0 ] .


<s> static void sparc_function_arg_advance ( cumulative_args_t cum_v , machine_mode mode , const_tree type , bool named ) { CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; int regno , padding ; function_arg_slotno ( cum , mode , type , named , false , & regno , & padding ) ; cum -> words += padding ; if ( TARGET_ARCH32 ) cum -> words += CEIL_NWORDS ( GET_MODE_SIZE ( mode ) ) ; else { if ( type && ( AGGREGATE_TYPE_P ( type ) || VECTOR_FLOAT_TYPE_P ( type ) ) ) { const int size = int_size_in_bytes ( type ) ; if ( size <= 0 ) cum -> words ++ ; else cum -> words += CEIL_NWORDS ( size ) ; } else cum -> words += CEIL_NWORDS ( GET_MODE_SIZE ( mode ) ) ; } } </s>

Handle the TARGET_FUNCTION_ARG_ADVANCE hook . Update the data in CUM to advance over an argument of mode MODE and data type TYPE . TYPE is null for libcalls where that information may not be available .


<s> static bool any_sibcall_could_use_r3 ( void ) { edge_iterator ei ; edge e ; if ( ! crtl -> tail_call_emit ) return false ; FOR_EACH_EDGE ( e , ei , EXIT_BLOCK_PTR_FOR_FN ( cfun ) -> preds ) if ( e -> flags & EDGE_SIBCALL ) { rtx_insn * call = BB_END ( e -> src ) ; if ( ! CALL_P ( call ) ) call = prev_nonnote_nondebug_insn ( call ) ; gcc_assert ( CALL_P ( call ) && SIBLING_CALL_P ( call ) ) ; if ( find_regno_fusage ( call , USE , 3 ) || is_indirect_tailcall_p ( call ) ) return true ; } return false ; } </s>

Return true if r3 is used by any of the tail call insns in the current function .


"%qE attribute only applies to variables"

"%qE attribute cannot be specified for local variables"

"section of %q+D conflicts with previous declaration"

Handle a `` l1_data '' , `` l1_data_A '' or `` l1_data_B '' attribute ; arguments as in struct attribute_spec.handler .


"Unconditional branch with multiple successors!"

Insert branch code into the end of the specified MachineBasicBlock .


<s> static rtx riscv_force_temporary ( rtx dest , rtx value ) { if ( can_create_pseudo_p ( ) ) return force_reg ( Pmode , value ) ; else { riscv_emit_move ( dest , value ) ; return dest ; } } </s>

Copy VALUE to a register and return that register . If new pseudos are allowed , copy it into a new register , otherwise use DEST .


<s> DFAPacketizer * R600InstrInfo :: CreateTargetScheduleState ( const TargetMachine * TM , const ScheduleDAG * DAG ) const { const InstrItineraryData * II = TM -> getInstrItineraryData ( ) ; return TM -> getSubtarget < AMDGPUSubtarget > ( ) . createDFAPacketizer ( II ) ; } </s>

Create machine specific model for scheduling .


<s> unsigned X86FrameLowering :: getWinEHFuncletFrameSize ( const MachineFunction & MF ) const { const X86MachineFunctionInfo * X86FI = MF . getInfo < X86MachineFunctionInfo > ( ) ; unsigned CSSize = X86FI -> getCalleeSavedFrameSize ( ) ; const auto & WinEHXMMSlotInfo = X86FI -> getWinEHXMMSlotInfo ( ) ; unsigned XMMSize = WinEHXMMSlotInfo . size ( ) * TRI -> getSpillSize ( X86 :: VR128RegClass ) ; unsigned UsedSize ; EHPersonality Personality = classifyEHPersonality ( MF . getFunction ( ) . getPersonalityFn ( ) ) ; if ( Personality == EHPersonality :: CoreCLR ) { UsedSize = getPSPSlotOffsetFromSP ( MF ) + SlotSize ; } else { UsedSize = MF . getFrameInfo ( ) . getMaxCallFrameSize ( ) ; } unsigned FrameSizeMinusRBP = alignTo ( CSSize + UsedSize , getStackAlign ( ) ) ; return FrameSizeMinusRBP + XMMSize - CSSize ; } </s>

Funclets only need to account for space for the callee saved registers , as the locals are accounted for in the parent 's stack frame .


"Should be handled target independently"


<s> void LC3InstPrinter :: printRegName ( raw_ostream & OS , unsigned RegNo ) const { OS << StringRef ( getRegisterName ( RegNo ) ) . lower ( ) ; } </s>


<s> bool SIInstrInfo :: isInlineConstant ( const MachineOperand & MO ) const { union { int32_t I ; float F ; } Imm ; if ( MO . isImm ( ) ) { Imm . I = MO . getImm ( ) ; } else if ( MO . isFPImm ( ) ) { Imm . F = MO . getFPImm ( ) -> getValueAPF ( ) . convertToFloat ( ) ; } else { return false ; } return ( Imm . I >= - 16 && Imm . I <= 64 ) || Imm . F == 0.0f || Imm . F == 0.5f || Imm . F == - 0.5f || Imm . F == 1.0f || Imm . F == - 1.0f || Imm . F == 2.0f || Imm . F == - 2.0f || Imm . F == 4.0f || Imm . F == - 4.0f ; } </s>

returns true if the operand OpIdx in MI is a valid inline immediate .


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


<s> unsigned PPCInstrInfo :: getInstrLatency ( const InstrItineraryData * ItinData , const MachineInstr & MI , unsigned * PredCost ) const { if ( ! ItinData || UseOldLatencyCalc ) return PPCGenInstrInfo :: getInstrLatency ( ItinData , MI , PredCost ) ; unsigned Latency = 1 ; unsigned DefClass = MI . getDesc ( ) . getSchedClass ( ) ; for ( unsigned i = 0 , e = MI . getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI . getOperand ( i ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) || MO . isImplicit ( ) ) continue ; int Cycle = ItinData -> getOperandCycle ( DefClass , i ) ; if ( Cycle < 0 ) continue ; Latency = std :: max ( Latency , ( unsigned ) Cycle ) ; } return Latency ; } </s>

Compute the instruction latency of a given instruction .


<s> static bool arc_allocate_stack_slots_for_args ( void ) { unsigned int fn_type = arc_compute_function_type ( cfun ) ; return ! ARC_NAKED_P ( fn_type ) ; } </s>

Implement ` TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS '


<s> int first_reg_to_save ( void ) { int first_reg ; for ( first_reg = 13 ; first_reg <= 31 ; first_reg ++ ) if ( save_reg_p ( first_reg ) ) break ; if ( flag_pic && crtl -> uses_pic_offset_table && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM ) return RS6000_PIC_OFFSET_TABLE_REGNUM ; return first_reg ; } </s>

Return the first register that is required to be saved . 16 if none .


<s> static void nds32_group_insns ( rtx_insn * sethi ) { df_ref def_record , use_record ; df_link * link ; rtx_insn * use_insn = NULL ; rtx group_id ; bool valid ; def_record = DF_INSN_DEFS ( sethi ) ; for ( link = DF_REF_CHAIN ( def_record ) ; link ; link = link -> next ) { if ( ! DF_REF_INSN_INFO ( link -> ref ) ) continue ; use_insn = DF_REF_INSN ( link -> ref ) ; if ( ! dominated_by_p ( CDI_DOMINATORS , BLOCK_FOR_INSN ( use_insn ) , BLOCK_FOR_INSN ( sethi ) ) ) return ; use_record = DF_INSN_USES ( use_insn ) ; if ( DF_REF_CHAIN ( use_record ) && DF_REF_CHAIN ( use_record ) -> next ) return ; if ( ! active_insn_p ( use_insn ) ) return ; if ( ! ( recog_memoized ( use_insn ) == CODE_FOR_lo_sum || nds32_symbol_load_store_p ( use_insn ) || ( nds32_reg_base_load_store_p ( use_insn ) && ! nds32_sp_base_or_plus_load_store_p ( use_insn ) ) ) ) return ; } group_id = GEN_INT ( nds32_alloc_relax_group_id ( ) ) ; emit_insn_before ( gen_relax_group ( group_id ) , sethi ) ; for ( link = DF_REF_CHAIN ( def_record ) ; link ; link = link -> next ) { if ( ! DF_REF_INSN_INFO ( link -> ref ) ) continue ; use_insn = DF_REF_INSN ( link -> ref ) ; if ( active_insn_p ( use_insn ) ) emit_insn_before ( gen_relax_group ( group_id ) , use_insn ) ; if ( use_insn != NULL && recog_memoized ( use_insn ) == CODE_FOR_lo_sum && ! nds32_const_unspec_p ( XEXP ( SET_SRC ( PATTERN ( use_insn ) ) , 1 ) ) ) { int sym_type = nds32_pic_tls_symbol_type ( use_insn ) ; valid = nds32_pic_tls_group ( use_insn , RELAX_ORI , sym_type ) ; while ( ! nds32_group_infos . is_empty ( ) ) { use_insn = nds32_group_infos . pop ( ) ; if ( valid ) emit_insn_before ( gen_relax_group ( group_id ) , use_insn ) ; } } } } </s>

Group the relax candidates with group id .


<s>
void
pa_asm_output_aligned_bss
(
FILE
*
stream
,
const
char
*
name
,
unsigned
HOST_WIDE_INT
size
,
unsigned
int
align
)
{
switch_to_section
(
bss_section
)
;
fprintf
(
stream
,
"\t.align %u\n"
,
align
/
BITS_PER_UNIT
)
;
ASM_OUTPUT_TYPE_DIRECTIVE
(
stream
,
name
,
"object"
)
;
ASM_OUTPUT_SIZE_DIRECTIVE
(
stream
,
name
,
size
)
;
fprintf
(
stream
,
"\t.align %u\n"
,
align
/
BITS_PER_UNIT
)
;
ASM_OUTPUT_LABEL
(
stream
,
name
)
;
fprintf
(
stream
,
"\t.block "
HOST_WIDE_INT_PRINT_UNSIGNED
"\n"
,
size
)
;
}
</s>

This function places uninitialized global data in the bss section . The ASM_OUTPUT_ALIGNED_BSS macro needs to be defined to call this function on the SOM port to prevent uninitialized global data from being placed in the data section .

pa
"\t.align %u\n"
"object"
"\t.align %u\n"
"\t.block "
"\n"


<s> bool RISCVAsmBackend :: mayNeedRelaxation ( const MCInst & Inst ) const { return getRelaxedOpcode ( Inst . getOpcode ( ) ) != Inst . getOpcode ( ) ; } </s>

Check whether the given instruction may need relaxation .


<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 ) ) { output_addr_const ( file , CONST_CAST_RTX ( tocrel_base ) ) ; 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 , 0 , 1 ) ) ] ) ; } else gcc_unreachable ( ) ; } </s>

Print the operand address represented by the rtx addr


<s> const GCNSubtarget * GCNTargetMachine :: getSubtargetImpl ( const Function & F ) const { StringRef GPU = getGPUName ( F ) ; StringRef FS = getFeatureString ( F ) ; SmallString < 128 > SubtargetKey ( GPU ) ; SubtargetKey . append ( FS ) ; auto & I = SubtargetMap [ SubtargetKey ] ; if ( ! I ) { resetTargetOptions ( F ) ; I = llvm :: make_unique < GCNSubtarget > ( TargetTriple , GPU , FS , * this ) ; } I -> setScalarizeGlobalBehavior ( ScalarizeGlobal ) ; return I . get ( ) ; } </s>

Virtual method implemented by subclasses that returns a reference to that target 's TargetSubtargetInfo-derived member variable .


<s> static void mt_emit_save_fp ( enum save_direction direction , struct mt_frame_info info ) { rtx base_reg ; int reg_mask = info . reg_mask & ~ ( FP_MASK | LINK_MASK ) ; int offset = info . total_size ; int stack_offset = info . total_size ; if ( ! info . save_fp && ! info . save_lr && ! reg_mask ) return ; if ( CONST_OK_FOR_LETTER_P ( offset , 'O' ) ) base_reg = stack_pointer_rtx ; else { base_reg = gen_rtx_REG ( SImode , GPR_R9 ) ; offset = 0 ; } if ( info . save_fp ) { offset -= UNITS_PER_WORD ; stack_offset -= UNITS_PER_WORD ; mt_emit_save_restore ( direction , gen_rtx_REG ( SImode , GPR_FP ) , gen_rtx_MEM ( SImode , gen_rtx_PLUS ( SImode , base_reg , GEN_INT ( offset ) ) ) , stack_offset ) ; } } </s>

Emit code to save the frame pointer in the prologue and restore frame pointer in epilogue .