<s> static bool rs6000_modes_tieable_p ( machine_mode mode1 , machine_mode mode2 ) { if ( mode1 == PTImode ) return mode2 == PTImode ; if ( mode2 == PTImode ) return false ; if ( ALTIVEC_OR_VSX_VECTOR_MODE ( mode1 ) ) return ALTIVEC_OR_VSX_VECTOR_MODE ( mode2 ) ; if ( ALTIVEC_OR_VSX_VECTOR_MODE ( mode2 ) ) return false ; if ( SCALAR_FLOAT_MODE_P ( mode1 ) ) return SCALAR_FLOAT_MODE_P ( mode2 ) ; if ( SCALAR_FLOAT_MODE_P ( mode2 ) ) return false ; if ( GET_MODE_CLASS ( mode1 ) == MODE_CC ) return GET_MODE_CLASS ( mode2 ) == MODE_CC ; if ( GET_MODE_CLASS ( mode2 ) == MODE_CC ) return false ; if ( SPE_VECTOR_MODE ( mode1 ) ) return SPE_VECTOR_MODE ( mode2 ) ; if ( SPE_VECTOR_MODE ( mode2 ) ) return false ; return true ; } </s>

Implement TARGET_MODES_TIEABLE_P . PTImode can not tie with other modes because PTImode is restricted to even GPR registers , and TImode can go in any GPR as well as VSX registers ( PR 57744 ) . Similarly , do n't allow OOmode ( vector pair , restricted to even VSX registers ) or XOmode ( vector quad , restricted to FPR registers divisible by 4 ) to tie with other modes . Altivec/VSX vector tests were moved ahead of scalar float mode , so that IEEE 128-bit floating point on VSX systems ties with other vectors .


Return nonzero if the CONSUMER instruction is some sort of arithmetic or logic + shift operation , and the register we are writing in PRODUCER is not used in a register shift by register operation .


<s>
bool
X86AsmParser
::
ParseDirective
(
AsmToken
DirectiveID
)
{
MCAsmParser
&
Parser
=
getParser
(
)
;
StringRef
IDVal
=
DirectiveID
.
getIdentifier
(
)
;
if
(
IDVal
.
startswith
(
".code"
)
)
return
ParseDirectiveCode
(
IDVal
,
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
.
startswith
(
".att_syntax"
)
)
{
getParser
(
)
.
setParsingInlineAsm
(
false
)
;
if
(
getLexer
(
)
.
isNot
(
AsmToken
::
EndOfStatement
)
)
{
if
(
Parser
.
getTok
(
)
.
getString
(
)
==
"prefix"
)
Parser
.
Lex
(
)
;
else
if
(
Parser
.
getTok
(
)
.
getString
(
)
==
"noprefix"
)
return
Error
(
DirectiveID
.
getLoc
(
)
,
"'.att_syntax noprefix' is not "
"supported: registers must have a "
"'%' prefix in .att_syntax"
)
;
}
getParser
(
)
.
setAssemblerDialect
(
0
)
;
return
false
;
}
else
if
(
IDVal
.
startswith
(
".intel_syntax"
)
)
{
getParser
(
)
.
setAssemblerDialect
(
1
)
;
getParser
(
)
.
setParsingInlineAsm
(
true
)
;
if
(
getLexer
(
)
.
isNot
(
AsmToken
::
EndOfStatement
)
)
{
if
(
Parser
.
getTok
(
)
.
getString
(
)
==
"noprefix"
)
Parser
.
Lex
(
)
;
else
if
(
Parser
.
getTok
(
)
.
getString
(
)
==
"prefix"
)
return
Error
(
DirectiveID
.
getLoc
(
)
,
"'.intel_syntax prefix' is not "
"supported: registers must not have "
"a '%' prefix in .intel_syntax"
)
;
}
return
false
;
}
else
if
(
IDVal
==
".even"
)
return
parseDirectiveEven
(
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
==
".cv_fpo_proc"
)
return
parseDirectiveFPOProc
(
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
==
".cv_fpo_setframe"
)
return
parseDirectiveFPOSetFrame
(
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
==
".cv_fpo_pushreg"
)
return
parseDirectiveFPOPushReg
(
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
==
".cv_fpo_stackalloc"
)
return
parseDirectiveFPOStackAlloc
(
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
==
".cv_fpo_stackalign"
)
return
parseDirectiveFPOStackAlign
(
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
==
".cv_fpo_endprologue"
)
return
parseDirectiveFPOEndPrologue
(
DirectiveID
.
getLoc
(
)
)
;
else
if
(
IDVal
==
".cv_fpo_endproc"
)
return
parseDirectiveFPOEndProc
(
DirectiveID
.
getLoc
(
)
)
;
return
true
;
}
</s>

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


<s> static bool save_local_or_in_reg_p ( unsigned int regno , int leaf_function ) { if ( ! call_used_regs [ regno ] && df_regs_ever_live_p ( regno ) ) return true ; if ( regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed ) return true ; if ( regno == RETURN_ADDR_REGNUM && return_addr_reg_needed_p ( leaf_function ) ) return true ; if ( regno == PIC_OFFSET_TABLE_REGNUM && crtl -> uses_pic_offset_table ) return true ; if ( crtl -> accesses_prior_frames && ( regno == HARD_FRAME_POINTER_REGNUM || regno == RETURN_ADDR_REGNUM ) ) return true ; return false ; } </s>

Return whether REGNO , a local or in register , must be saved/restored .


<s> static save_entry * sh5_schedule_saves ( HARD_REG_SET * live_regs_mask , save_schedule * schedule , int offset_base ) { int align , i ; save_entry * entry = schedule -> entries ; int tmpx = 0 ; int offset ; if ( ! current_function_interrupt ) for ( i = FIRST_GENERAL_REG ; tmpx < MAX_TEMPS && i <= LAST_GENERAL_REG ; i ++ ) if ( call_really_used_regs [ i ] && ! fixed_regs [ i ] && i != PR_MEDIA_REG && ! FUNCTION_ARG_REGNO_P ( i ) && i != FIRST_RET_REG && ! ( cfun -> static_chain_decl != NULL && i == STATIC_CHAIN_REGNUM ) && ! ( crtl -> calls_eh_return && ( i == EH_RETURN_STACKADJ_REGNO || ( ( unsigned ) i >= EH_RETURN_DATA_REGNO ( 0 ) && ( unsigned ) i <= EH_RETURN_DATA_REGNO ( 3 ) ) ) ) ) schedule -> temps [ tmpx ++ ] = i ; entry -> reg = - 1 ; entry -> mode = VOIDmode ; entry -> offset = offset_base ; entry ++ ; offset = offset_base ; for ( align = 1 ; align >= 0 ; align -- ) { for ( i = FIRST_PSEUDO_REGISTER - 1 ; i >= 0 ; i -- ) if ( TEST_HARD_REG_BIT ( * live_regs_mask , i ) ) { machine_mode mode = REGISTER_NATURAL_MODE ( i ) ; int reg = i ; if ( current_function_interrupt ) { if ( TARGET_REGISTER_P ( i ) ) continue ; if ( GENERAL_REGISTER_P ( i ) ) mode = DImode ; } if ( mode == SFmode && ( i % 2 ) == 1 && ! TARGET_FPU_SINGLE && FP_REGISTER_P ( i ) && ( TEST_HARD_REG_BIT ( * live_regs_mask , ( i ^ 1 ) ) ) ) { mode = DFmode ; i -- ; reg -- ; } if ( ( GET_MODE_SIZE ( mode ) % ( STACK_BOUNDARY / BITS_PER_UNIT ) == 0 ) != align ) continue ; if ( current_function_interrupt && GENERAL_REGISTER_P ( i ) && tmpx < MAX_TEMPS ) schedule -> temps [ tmpx ++ ] = i ; offset -= GET_MODE_SIZE ( mode ) ; entry -> reg = i ; entry -> mode = mode ; entry -> offset = offset ; entry ++ ; } if ( align && current_function_interrupt ) for ( i = LAST_TARGET_REG ; i >= FIRST_TARGET_REG ; i -- ) if ( TEST_HARD_REG_BIT ( * live_regs_mask , i ) ) { offset -= GET_MODE_SIZE ( DImode ) ; entry -> reg = i ; entry -> mode = DImode ; entry -> offset = offset ; entry ++ ; } } entry -> reg = - 1 ; entry -> mode = VOIDmode ; entry -> offset = offset ; schedule -> temps [ tmpx ] = - 1 ; return entry - 1 ; } </s>

Fill in SCHEDULE according to LIVE_REGS_MASK . If RESTORE is nonzero , use reverse order . Returns the last entry written to ( not counting the delimiter ) . OFFSET_BASE is a number to be added to all offset entries .


<s> void ix86_setup_frame_addresses ( void ) { cfun -> machine -> accesses_prev_frame = 1 ; } </s>

Record that the current function accesses previous call frames .


<s> static bool spe_func_has_64bit_regs_p ( void ) { rtx_insn * insns , * insn ; if ( crtl -> calls_eh_return || cfun -> calls_setjmp || crtl -> has_nonlocal_goto ) return true ; insns = get_insns ( ) ; for ( insn = NEXT_INSN ( insns ) ; insn != NULL_RTX ; insn = NEXT_INSN ( insn ) ) { if ( INSN_P ( insn ) ) { rtx i ; i = PATTERN ( insn ) ; if ( GET_CODE ( i ) == SET ) { machine_mode mode = GET_MODE ( SET_SRC ( i ) ) ; if ( SPE_VECTOR_MODE ( mode ) ) return true ; if ( TARGET_E500_DOUBLE && ( mode == DFmode || FLOAT128_2REG_P ( mode ) ) ) return true ; } } } return false ; } </s>

Return true if the current function uses any GPRs in 64-bit SIMD mode .


"the destination register can't equal the base register in an "

"instruction that modifies the base register."

ParseInstruction - Parse one assembly instruction .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { const PPCSubtarget & STI = MF . getSubtarget < PPCSubtarget > ( ) ; if ( ! STI . hasVSX ( ) ) return false ; bool Changed = false ; initialize ( MF ) ; if ( gatherVectorInstructions ( ) ) { formWebs ( ) ; recordUnoptimizableWebs ( ) ; markSwapsForRemoval ( ) ; Changed = removeSwaps ( ) ; } delete EC ; return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { bool Changed = false ; for ( MachineBasicBlock & B : llvm :: make_early_inc_range ( MF ) ) if ( processBlock ( B ) ) Changed = true ; return Changed ; } </s>


"TargetInstrInfo::findCommutedOpIndices() can't handle bundles"

Returns true iff the routine could find two commutable operands in the given machine instruction .


<s> bool ix86_libc_has_function ( enum function_class fn_class ) { return targetm . libc_has_function ( fn_class , NULL_TREE ) ; } </s>

We add this as a workaround in order to use libc_has_function hook in i386.md .


<s>
bool
X86ATTAsmPrinter
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
const
Function
*
F
=
MF
.
getFunction
(
)
;
this
->
MF
=
&
MF
;
unsigned
CC
=
F
->
getCallingConv
(
)
;
SetupMachineFunction
(
MF
)
;
O
<<
"\n\n"
;
if
(
CC
==
CallingConv
::
X86_StdCall
||
CC
==
CallingConv
::
X86_FastCall
)
FunctionInfoMap
[
F
]
=
*
MF
.
getInfo
<
X86MachineFunctionInfo
>
(
)
;
EmitConstantPool
(
MF
.
getConstantPool
(
)
)
;
if
(
F
->
hasDLLExportLinkage
(
)
)
DLLExportedFns
.
insert
(
Mang
->
getMangledName
(
F
)
)
;
emitFunctionHeader
(
MF
)
;
if
(
TAI
->
doesSupportDebugInformation
(
)
||
TAI
->
doesSupportExceptionHandling
(
)
)
DW
->
BeginFunction
(
&
MF
)
;
bool
hasAnyRealCode
=
false
;
for
(
MachineFunction
::
const_iterator
I
=
MF
.
begin
(
)
,
E
=
MF
.
end
(
)
;
I
!=
E
;
++
I
)
{
if
(
!
VerboseAsm
&&
(
I
->
pred_empty
(
)
||
I
->
isOnlyReachableByFallthrough
(
)
)
)
{
}
else
{
printBasicBlockLabel
(
I
,
true
,
true
,
VerboseAsm
)
;
O
<<
'\n'
;
}
for
(
MachineBasicBlock
::
const_iterator
II
=
I
->
begin
(
)
,
IE
=
I
->
end
(
)
;
II
!=
IE
;
++
II
)
{
if
(
!
II
->
isLabel
(
)
)
hasAnyRealCode
=
true
;
printMachineInstruction
(
II
)
;
}
}
if
(
Subtarget
->
isTargetDarwin
(
)
&&
!
hasAnyRealCode
)
{
O
<<
"\tnop\n"
;
}
if
(
TAI
->
hasDotTypeDotSizeDirective
(
)
)
O
<<
"\t.size\t"
<<
CurrentFnName
<<
", .-"
<<
CurrentFnName
<<
'\n'
;
if
(
TAI
->
doesSupportDebugInformation
(
)
||
TAI
->
doesSupportExceptionHandling
(
)
)
DW
->
EndFunction
(
&
MF
)
;
EmitJumpTableInfo
(
MF
.
getJumpTableInfo
(
)
,
MF
)
;
return
false
;
}
</s>


<s>
static
void
rs6000_file_start
(
void
)
{
size_t
i
;
char
buffer
[
80
]
;
const
char
*
start
=
buffer
;
struct
rs6000_cpu_select
*
ptr
;
const
char
*
default_cpu
=
TARGET_CPU_DEFAULT
;
FILE
*
file
=
asm_out_file
;
default_file_start
(
)
;
if
(
(
TARGET_DEFAULT
^
target_flags
)
&
MASK_64BIT
)
default_cpu
=
0
;
if
(
flag_verbose_asm
)
{
sprintf
(
buffer
,
"\n%s rs6000/powerpc options:"
,
ASM_COMMENT_START
)
;
rs6000_select
[
0
]
.
string
=
default_cpu
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
rs6000_select
)
;
i
++
)
{
ptr
=
&
rs6000_select
[
i
]
;
if
(
ptr
->
string
!=
(
char
*
)
0
&&
ptr
->
string
[
0
]
!=
'\0'
)
{
fprintf
(
file
,
"%s %s%s"
,
start
,
ptr
->
name
,
ptr
->
string
)
;
start
=
""
;
}
}
if
(
PPC405_ERRATUM77
)
{
fprintf
(
file
,
"%s PPC405CR_ERRATUM77"
,
start
)
;
start
=
""
;
}
switch
(
rs6000_sdata
)
{
case
SDATA_NONE
:
fprintf
(
file
,
"%s -msdata=none"
,
start
)
;
start
=
""
;
break
;
case
SDATA_DATA
:
fprintf
(
file
,
"%s -msdata=data"
,
start
)
;
start
=
""
;
break
;
case
SDATA_SYSV
:
fprintf
(
file
,
"%s -msdata=sysv"
,
start
)
;
start
=
""
;
break
;
case
SDATA_EABI
:
fprintf
(
file
,
"%s -msdata=eabi"
,
start
)
;
start
=
""
;
break
;
}
if
(
rs6000_sdata
&&
g_switch_value
)
{
fprintf
(
file
,
"%s -G "
HOST_WIDE_INT_PRINT_UNSIGNED
,
start
,
g_switch_value
)
;
start
=
""
;
}
if
(
*
start
==
'\0'
)
putc
(
'\n'
,
file
)
;
}
if
(
DEFAULT_ABI
==
ABI_AIX
||
(
TARGET_ELF
&&
flag_pic
==
2
)
)
{
toc_section
(
)
;
text_section
(
)
;
}
}
</s>

Do anything needed at the start of the asm file .


<s>
StringRef
getPassName
(
)
const
override
{
return
"X86 Optimize Call Frame"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> static void expand_setmem_epilogue_via_loop ( rtx destmem , rtx destptr , rtx value , rtx count , int max_size ) { count = expand_simple_binop ( counter_mode ( count ) , AND , count , GEN_INT ( max_size - 1 ) , count , 1 , OPTAB_DIRECT ) ; expand_set_or_movmem_via_loop ( destmem , NULL , destptr , NULL , gen_lowpart ( QImode , value ) , count , QImode , 1 , max_size / 2 , true ) ; } </s>

Output code to set at most count & ( max_size - 1 ) bytes starting by DEST .


<s> static unsigned char csky_class_max_nregs ( reg_class_t rclass , machine_mode mode ) { if ( rclass == V_REGS ) return 1 ; else return CSKY_NUM_REGS ( mode ) ; } </s>

Implement TARGET_CLASS_MAX_NREGS . Return the maximum number of consecutive registers of class rclass needed to hold a value of mode mode . On the csky , this is the size of MODE in words , except in the FP regs , where a single reg is always enough .


<s> int aarch64_host_wide_int_compare ( const void * x , const void * y ) { return wi :: cmps ( * ( ( const HOST_WIDE_INT * ) x ) , * ( ( const HOST_WIDE_INT * ) y ) ) ; } </s>

Taking X and Y to be HOST_WIDE_INT pointers , return the result of a comparison between the two .


<s> static void cygwin_d_os_builtins ( void ) { d_add_builtin_version ( "Windows" ) ; d_add_builtin_version ( "Cygwin" ) ; d_add_builtin_version ( "Posix" ) ; d_add_builtin_version ( "CRuntime_Newlib" ) ; } </s>

Implement TARGET_D_OS_VERSIONS for Cygwin targets .


<s> unsigned int call_properties ( const function_instance & ) const OVERRIDE { return 0 ; } </s>

Default implementation of function_base : :call_properties , with conservatively correct behavior for floating-point instructions .


<s> Register getExceptionSelectorRegister ( const Constant * PersonalityFn ) const override { return SystemZ :: R7D ; } </s>

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


<s> bool isIntDivCheap ( EVT , AttributeList ) const override { return false ; } </s>

Return true if integer divide is usually cheaper than a sequence of several shifts , adds , and multiplies for this target .


<s> SDValue SystemZTargetLowering :: PerformDAGCombine ( SDNode * N , DAGCombinerInfo & DCI ) const { switch ( N -> getOpcode ( ) ) { default : break ; case ISD :: ZERO_EXTEND : return combineZERO_EXTEND ( N , DCI ) ; case ISD :: SIGN_EXTEND : return combineSIGN_EXTEND ( N , DCI ) ; case ISD :: SIGN_EXTEND_INREG : return combineSIGN_EXTEND_INREG ( N , DCI ) ; case SystemZISD :: MERGE_HIGH : case SystemZISD :: MERGE_LOW : return combineMERGE ( N , DCI ) ; case ISD :: STORE : return combineSTORE ( N , DCI ) ; case ISD :: EXTRACT_VECTOR_ELT : return combineEXTRACT_VECTOR_ELT ( N , DCI ) ; case SystemZISD :: JOIN_DWORDS : return combineJOIN_DWORDS ( N , DCI ) ; case ISD :: FP_ROUND : return combineFP_ROUND ( N , DCI ) ; case ISD :: BSWAP : return combineBSWAP ( N , DCI ) ; case SystemZISD :: BR_CCMASK : return combineBR_CCMASK ( N , DCI ) ; case SystemZISD :: SELECT_CCMASK : return combineSELECT_CCMASK ( N , DCI ) ; case SystemZISD :: GET_CCMASK : return combineGET_CCMASK ( N , DCI ) ; case ISD :: SDIV : case ISD :: UDIV : case ISD :: SREM : case ISD :: UREM : return combineIntDIVREM ( N , DCI ) ; } return SDValue ( ) ; } </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 .


<s> bool PPCSubtarget :: enableMachinePipeliner ( ) const { return ( DarwinDirective == PPC :: DIR_PWR9 ) && EnableMachinePipeliner ; } </s>

True if the subtarget should run MachinePipeliner .


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

Load the specified register of the given register class from the specified stack frame index .

ARM ARM::GPRRegisterClass ARM::tGPRRegisterClass ARM::tcGPRRegisterClass ARM::rGPRRegisterClass ARM::t2LDRi12 0 ARM


<s>
void
MipsInstrInfo
::
storeRegToStackSlot
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
unsigned
SrcReg
,
bool
isKill
,
int
FI
,
const
TargetRegisterClass
*
RC
)
const
{
DebugLoc
DL
=
DebugLoc
::
getUnknownLoc
(
)
;
if
(
I
!=
MBB
.
end
(
)
)
DL
=
I
->
getDebugLoc
(
)
;
if
(
RC
==
Mips
::
CPURegsRegisterClass
)
BuildMI
(
MBB
,
I
,
DL
,
get
(
Mips
::
SW
)
)
.
addReg
(
SrcReg
,
getKillRegState
(
isKill
)
)
.
addImm
(
0
)
.
addFrameIndex
(
FI
)
;
else
if
(
RC
==
Mips
::
FGR32RegisterClass
)
BuildMI
(
MBB
,
I
,
DL
,
get
(
Mips
::
SWC1
)
)
.
addReg
(
SrcReg
,
getKillRegState
(
isKill
)
)
.
addImm
(
0
)
.
addFrameIndex
(
FI
)
;
else
if
(
RC
==
Mips
::
AFGR64RegisterClass
)
{
if
(
!
TM
.
getSubtarget
<
MipsSubtarget
>
(
)
.
isMips1
(
)
)
{
BuildMI
(
MBB
,
I
,
DL
,
get
(
Mips
::
SDC1
)
)
.
addReg
(
SrcReg
,
getKillRegState
(
isKill
)
)
.
addImm
(
0
)
.
addFrameIndex
(
FI
)
;
}
else
{
const
TargetRegisterInfo
*
TRI
=
MBB
.
getParent
(
)
->
getTarget
(
)
.
getRegisterInfo
(
)
;
const
unsigned
*
SubSet
=
TRI
->
getSubRegisters
(
SrcReg
)
;
BuildMI
(
MBB
,
I
,
DL
,
get
(
Mips
::
SWC1
)
)
.
addReg
(
SubSet
[
0
]
,
getKillRegState
(
isKill
)
)
.
addImm
(
0
)
.
addFrameIndex
(
FI
)
;
BuildMI
(
MBB
,
I
,
DL
,
get
(
Mips
::
SWC1
)
)
.
addReg
(
SubSet
[
1
]
,
getKillRegState
(
isKill
)
)
.
addImm
(
4
)
.
addFrameIndex
(
FI
)
;
}
}
else
llvm_unreachable
(
"Register class not handled!"
)
;
}
</s>

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


<s> static void loongarch_emit_int_order_test ( enum rtx_code code , bool * invert_ptr , rtx target , rtx cmp0 , rtx cmp1 ) { machine_mode mode ; mode = GET_MODE ( cmp0 ) ; if ( loongarch_canonicalize_int_order_test ( & code , & cmp1 , mode ) ) loongarch_emit_binary ( code , target , cmp0 , cmp1 ) ; else { enum rtx_code inv_code = reverse_condition ( code ) ; if ( ! loongarch_canonicalize_int_order_test ( & inv_code , & cmp1 , mode ) ) { cmp1 = force_reg ( mode , cmp1 ) ; loongarch_emit_int_order_test ( code , invert_ptr , target , cmp0 , cmp1 ) ; } else if ( invert_ptr == 0 ) { rtx inv_target ; inv_target = loongarch_force_binary ( GET_MODE ( target ) , inv_code , cmp0 , cmp1 ) ; loongarch_emit_binary ( XOR , target , inv_target , const1_rtx ) ; } else { * invert_ptr = ! * invert_ptr ; loongarch_emit_binary ( inv_code , target , cmp0 , cmp1 ) ; } } } </s>

Compare CMP0 and CMP1 using ordering test CODE and store the result in TARGET . CMP0 and TARGET are register_operands . If INVERT_PTR is nonnull , it 's OK to set TARGET to the inverse of the result and flip * INVERT_PTR instead .


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

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


<s> static unsigned loongarch_save_libcall_count ( unsigned mask ) { for ( unsigned n = GP_REG_LAST ; n > GP_REG_FIRST ; n -- ) if ( BITSET_P ( mask , n ) ) return CALLEE_SAVED_REG_NUMBER ( n ) + 1 ; abort ( ) ; } </s>

Determine which GPR save/restore routine to call .


<s>
void
ARMInstrInfo
::
loadRegFromStackSlot
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
unsigned
DestReg
,
int
FI
,
const
TargetRegisterClass
*
RC
)
const
{
DebugLoc
DL
=
DebugLoc
::
getUnknownLoc
(
)
;
if
(
I
!=
MBB
.
end
(
)
)
DL
=
I
->
getDebugLoc
(
)
;
if
(
RC
==
ARM
::
GPRRegisterClass
)
{
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
ARMFunctionInfo
*
AFI
=
MF
.
getInfo
<
ARMFunctionInfo
>
(
)
;
assert
(
!
AFI
->
isThumbFunction
(
)
)
;
AddDefaultPred
(
BuildMI
(
MBB
,
I
,
DL
,
get
(
ARM
::
LDR
)
,
DestReg
)
.
addFrameIndex
(
FI
)
.
addReg
(
0
)
.
addImm
(
0
)
)
;
}
else
if
(
RC
==
ARM
::
tGPRRegisterClass
)
{
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
ARMFunctionInfo
*
AFI
=
MF
.
getInfo
<
ARMFunctionInfo
>
(
)
;
assert
(
AFI
->
isThumbFunction
(
)
)
;
BuildMI
(
MBB
,
I
,
DL
,
get
(
ARM
::
tRestore
)
,
DestReg
)
.
addFrameIndex
(
FI
)
.
addImm
(
0
)
;
}
else
if
(
RC
==
ARM
::
DPRRegisterClass
)
{
AddDefaultPred
(
BuildMI
(
MBB
,
I
,
DL
,
get
(
ARM
::
FLDD
)
,
DestReg
)
.
addFrameIndex
(
FI
)
.
addImm
(
0
)
)
;
}
else
{
assert
(
RC
==
ARM
::
SPRRegisterClass
&&
"Unknown regclass!"
)
;
AddDefaultPred
(
BuildMI
(
MBB
,
I
,
DL
,
get
(
ARM
::
FLDS
)
,
DestReg
)
.
addFrameIndex
(
FI
)
.
addImm
(
0
)
)
;
}
}
</s>

ARM
ARM
ARM::GPRRegisterClass
ARM
ARM
ARM::LDR
0
0
ARM::tGPRRegisterClass
ARM
ARM
ARM::tRestore
0
ARM::DPRRegisterClass
ARM::FLDD
0
ARM::SPRRegisterClass
"Unknown regclass!"
ARM::FLDS
0


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


<s> static rtx_code_label * mips16_add_constant ( struct mips16_constant_pool * pool , rtx value , machine_mode mode ) { struct mips16_constant * * p , * c ; bool first_of_size_p ; first_of_size_p = true ; for ( p = & pool -> first ; * p != 0 ; p = & ( * p ) -> next ) { if ( mode == ( * p ) -> mode && rtx_equal_p ( value , ( * p ) -> value ) ) return ( * p ) -> label ; if ( GET_MODE_SIZE ( mode ) < GET_MODE_SIZE ( ( * p ) -> mode ) ) break ; if ( GET_MODE_SIZE ( mode ) == GET_MODE_SIZE ( ( * p ) -> mode ) ) first_of_size_p = false ; } if ( pool -> first == 0 ) pool -> highest_address = pool -> insn_address - ( UNITS_PER_WORD - 2 ) + 0x8000 ; pool -> highest_address -= GET_MODE_SIZE ( mode ) ; if ( first_of_size_p ) pool -> highest_address -= GET_MODE_SIZE ( mode ) - 1 ; c = XNEW ( struct mips16_constant ) ; c -> value = value ; c -> mode = mode ; c -> label = gen_label_rtx ( ) ; c -> next = * p ; * p = c ; return c -> label ; } </s>

Add constant VALUE to POOL and return its label . MODE is the value 's mode ( used for CONST_INTs , etc . ) .


<s>
bool
AArch64AdvSIMDScalar
::
runOnMachineFunction
(
MachineFunction
&
mf
)
{
bool
Changed
=
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
"***** AArch64AdvSIMDScalar *****\n"
)
;
if
(
skipFunction
(
mf
.
getFunction
(
)
)
)
return
false
;
MRI
=
&
mf
.
getRegInfo
(
)
;
TII
=
mf
.
getSubtarget
(
)
.
getInstrInfo
(
)
;
for
(
MachineFunction
::
iterator
I
=
mf
.
begin
(
)
,
E
=
mf
.
end
(
)
;
I
!=
E
;
++
I
)
if
(
processMachineBasicBlock
(
&
*
I
)
)
Changed
=
true
;
return
Changed
;
}
</s>

runOnMachineFunction - Emit the function body .


<s> unsigned char X86Subtarget :: classifyLocalReference ( const GlobalValue * GV ) const { if ( is64Bit ( ) ) return X86II :: MO_NO_FLAG ; if ( ! isPositionIndependent ( ) ) return X86II :: MO_NO_FLAG ; if ( isTargetCOFF ( ) ) return X86II :: MO_NO_FLAG ; if ( isTargetDarwin ( ) ) { if ( GV && ( GV -> isDeclarationForLinker ( ) || GV -> hasCommonLinkage ( ) ) ) return X86II :: MO_DARWIN_NONLAZY_PIC_BASE ; return X86II :: MO_PIC_BASE_OFFSET ; } return X86II :: MO_GOTOFF ; } </s>

Classify a global variable reference for the current subtarget according to how we should reference it in a non-pcrel context .


<s> bool SparcAsmPrinter :: doInitialization ( Module & M ) { Mang = new Mangler ( M , "" , TAI -> getPrivateGlobalPrefix ( ) ) ; return false ; } </s>


<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 .


"Instr doesn't have FrameIndex operand!"

"Requesting 64-bit offset in 32-bit immediate!"

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


<s> static bool aarch64_return_in_msb ( const_tree valtype ) { machine_mode dummy_mode ; int dummy_int ; if ( ! BYTES_BIG_ENDIAN ) return false ; if ( ! aarch64_composite_type_p ( valtype , TYPE_MODE ( valtype ) ) || int_size_in_bytes ( valtype ) <= 0 || int_size_in_bytes ( valtype ) > 16 ) return false ; if ( aarch64_vfp_is_call_or_return_candidate ( TYPE_MODE ( valtype ) , valtype , & dummy_mode , & dummy_int , NULL , false ) ) return false ; pure_scalable_type_info pst_info ; if ( pst_info . analyze_registers ( valtype ) ) return false ; return true ; } </s>

Return TRUE if VALTYPE is padded to its least significant bits .


<s>
bool
ARM64AdvSIMDScalar
::
runOnMachineFunction
(
MachineFunction
&
mf
)
{
if
(
!
AdvSIMDScalar
)
return
false
;
bool
Changed
=
false
;
DEBUG
(
dbgs
(
)
<<
"***** ARM64AdvSIMDScalar *****\n"
)
;
const
TargetMachine
&
TM
=
mf
.
getTarget
(
)
;
MRI
=
&
mf
.
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARM64InstrInfo
*
>
(
TM
.
getInstrInfo
(
)
)
;
for
(
MachineFunction
::
iterator
I
=
mf
.
begin
(
)
,
E
=
mf
.
end
(
)
;
I
!=
E
;
++
I
)
if
(
processMachineBasicBlock
(
I
)
)
Changed
=
true
;
return
Changed
;
}
</s>


<s> static void register_vector_type ( vector_type_index type ) { if ( vector_types [ type ] . requires_float && ! TARGET_HAVE_MVE_FLOAT ) return ; tree vectype = abi_vector_types [ type ] ; tree id = get_identifier ( vector_types [ type ] . acle_name ) ; tree decl = build_decl ( input_location , TYPE_DECL , id , vectype ) ; decl = lang_hooks . decls . pushdecl ( decl ) ; if ( decl && TREE_CODE ( decl ) == TYPE_DECL && TREE_TYPE ( decl ) != error_mark_node && TYPE_MAIN_VARIANT ( TREE_TYPE ( decl ) ) == vectype ) vectype = TREE_TYPE ( decl ) ; acle_vector_types [ 0 ] [ type ] = vectype ; } </s>

Register vector type TYPE under its risv_vector.h name .


<s> void rs6000_sibcall_aix ( rtx value , rtx func_desc , rtx tlsarg , rtx cookie ) { rtx call [ 2 ] ; rtx insn ; rtx r12 = NULL_RTX ; rtx func_addr = func_desc ; gcc_assert ( INTVAL ( cookie ) == 0 ) ; if ( global_tlsarg ) tlsarg = global_tlsarg ; if ( GET_CODE ( func_desc ) != SYMBOL_REF && DEFAULT_ABI == ABI_ELFv2 ) { r12 = gen_rtx_REG ( Pmode , 12 ) ; emit_move_insn ( r12 , func_desc ) ; func_addr = gen_rtx_REG ( Pmode , CTR_REGNO ) ; emit_move_insn ( func_addr , r12 ) ; } call [ 0 ] = gen_rtx_CALL ( VOIDmode , gen_rtx_MEM ( SImode , func_addr ) , tlsarg ) ; if ( value != NULL_RTX ) call [ 0 ] = gen_rtx_SET ( value , call [ 0 ] ) ; call [ 1 ] = simple_return_rtx ; insn = gen_rtx_PARALLEL ( VOIDmode , gen_rtvec_v ( 2 , call ) ) ; insn = emit_call_insn ( insn ) ; if ( ! rs6000_pcrel_p ( ) ) use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , gen_rtx_REG ( Pmode , TOC_REGNUM ) ) ; if ( r12 ) use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , r12 ) ; } </s>

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


<s> static void mips_encode_section_info ( tree decl , rtx rtl , int first ) { default_encode_section_info ( decl , rtl , first ) ; if ( TREE_CODE ( decl ) == FUNCTION_DECL && lookup_attribute ( "long_call" , TYPE_ATTRIBUTES ( TREE_TYPE ( decl ) ) ) ) { rtx symbol = XEXP ( rtl , 0 ) ; SYMBOL_REF_FLAGS ( symbol ) |= SYMBOL_FLAG_LONG_CALL ; } } </s>

Set SYMBOL_REF_FLAGS for the SYMBOL_REF inside RTL , which belongs to DECL . FIRST is true if this is the first time handling this decl .


<s> static int get_some_local_dynamic_name_1 ( rtx * px , void * data ATTRIBUTE_UNUSED ) { rtx x = * px ; if ( x && GET_CODE ( x ) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL ( x ) == TLS_MODEL_LOCAL_DYNAMIC ) { cfun -> machine -> some_ld_name = XSTR ( x , 0 ) ; return 1 ; } return 0 ; } </s>


<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> bool sh_ashlsi_clobbers_t_reg_p ( rtx shift_amount ) { gcc_assert ( CONST_INT_P ( shift_amount ) ) ; const int shift_amount_i = INTVAL ( shift_amount ) & 31 ; if ( shift_amount_i == 31 ) return true ; return ( ashl_lshr_seq [ shift_amount_i ] . clobbers_t & ASHL_CLOBBERS_T ) != 0 ; } </s>

Return true if a shift left consisting of 1/2/8/16 shift instructions will clobber the T bit .


<s>
void
i386_pe_file_end
(
void
)
{
struct
extern_list
*
p
;
ix86_file_end
(
)
;
for
(
p
=
extern_head
;
p
!=
;
p
=
p
->
next
)
{
tree
decl
;
decl
=
p
->
decl
;
if
(
!
TREE_ASM_WRITTEN
(
decl
)
&&
TREE_SYMBOL_REFERENCED
(
DECL_ASSEMBLER_NAME
(
decl
)
)
)
{
TREE_ASM_WRITTEN
(
decl
)
=
1
;
i386_pe_declare_function_type
(
asm_out_file
,
p
->
name
,
TREE_PUBLIC
(
decl
)
)
;
}
}
if
(
export_head
)
{
struct
export_list
*
q
;
drectve_section
(
)
;
for
(
q
=
export_head
;
q
!=
;
q
=
q
->
next
)
{
fprintf
(
asm_out_file
,
"\t.ascii \" -export:%s%s\"\n"
,
i386_pe_strip_name_encoding
(
q
->
name
)
,
(
q
->
is_data
)
",data"
:
""
)
;
}
}
}
</s>

This is called at the end of assembly . For each external function which has not been defined , we output a declaration now . We also output the .drectve section .


"XNCM DAG->DAG Pattern Instruction Selection"

getPassName - Return a nice clean name for a pass .


<s> bool AArch64FrameLowering :: hasFP ( const MachineFunction & MF ) const { const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const TargetRegisterInfo * RegInfo = MF . getSubtarget ( ) . getRegisterInfo ( ) ; if ( MF . hasEHFunclets ( ) ) return true ; if ( MFI . hasCalls ( ) && MF . getTarget ( ) . Options . DisableFramePointerElim ( MF ) ) return true ; if ( MFI . hasVarSizedObjects ( ) || MFI . isFrameAddressTaken ( ) || MFI . hasStackMap ( ) || MFI . hasPatchPoint ( ) || RegInfo -> needsStackRealignment ( MF ) ) return true ; if ( ! MFI . isMaxCallFrameSizeComputed ( ) || MFI . getMaxCallFrameSize ( ) > DefaultSafeSPDisplacement ) return true ; if ( MF . hasLocalEscape ( ) ) return true ; return false ; } </s>

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


<s>
int
X86FrameLowering
::
getFrameIndexReferencePreferSP
(
const
MachineFunction
&
MF
,
int
FI
,
unsigned
&
FrameReg
,
bool
IgnoreSPUpdates
)
const
{
const
MachineFrameInfo
&
MFI
=
MF
.
getFrameInfo
(
)
;
const
uint64_t
StackSize
=
MFI
.
getStackSize
(
)
;
if
(
MFI
.
isFixedObjectIndex
(
FI
)
&&
TRI
->
needsStackRealignment
(
MF
)
&&
!
STI
.
isTargetWin64
(
)
)
return
getFrameIndexReference
(
MF
,
FI
,
FrameReg
)
;
const
TargetFrameLowering
*
TFI
=
MF
.
getSubtarget
(
)
.
getFrameLowering
(
)
;
if
(
!
IgnoreSPUpdates
&&
!
TFI
->
hasReservedCallFrame
(
MF
)
)
return
getFrameIndexReference
(
MF
,
FI
,
FrameReg
)
;
assert
(
MF
.
getInfo
<
X86MachineFunctionInfo
>
(
)
->
getTCReturnAddrDelta
(
)
>=
0
&&
"we don't handle this case!"
)
;
FrameReg
=
TRI
->
getStackRegister
(
)
;
int
Offset
=
MFI
.
getObjectOffset
(
FI
)
getOffsetOfLocalArea
(
)
;
return
Offset
+
StackSize
;
}
</s>

Same as getFrameIndexReference , except that the stack pointer ( as opposed to the frame pointer ) will be the preferred value for FrameReg .


<s> class LLVM_LIBRARY_VISIBILITY SystemZMCInstLower { MCContext & Ctx ; SystemZAsmPrinter & AsmPrinter ; public : SystemZMCInstLower ( MCContext & ctx , SystemZAsmPrinter & asmPrinter ) ; void lower ( const MachineInstr * MI , MCInst & OutMI ) const ; MCOperand lowerOperand ( const MachineOperand & MO ) const ; const MCExpr * getExpr ( const MachineOperand & MO , MCSymbolRefExpr :: VariantKind Kind ) const ; } </s>

Implementation of the SCEVPredicate interface .


<s> bool MipsFrameLowering :: hasFP ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; return MF . getTarget ( ) . Options . DisableFramePointerElim ( MF ) || MFI -> hasVarSizedObjects ( ) || MFI -> isFrameAddressTaken ( ) ; } </s>


<s> unsigned getArithmeticInstrCost ( unsigned Opcode , Type * Ty , TTI :: OperandValueKind Opd1Info = TTI :: OK_AnyValue , TTI :: OperandValueKind Opd2Info = TTI :: OK_AnyValue , TTI :: OperandValueProperties Opd1PropInfo = TTI :: OP_None , TTI :: OperandValueProperties Opd2PropInfo = TTI :: OP_None , ArrayRef < const Value * > Args = ArrayRef < const Value * > ( ) , const Instruction * CxtI = nullptr ) { int ISD = TLI -> InstructionOpcodeToISD ( Opcode ) ; switch ( ISD ) { default : return BaseT :: getArithmeticInstrCost ( Opcode , Ty , Opd1Info , Opd2Info , Opd1PropInfo , Opd2PropInfo ) ; case ISD :: MUL : case ISD :: SDIV : case ISD :: UDIV : case ISD :: UREM : return 64 * BaseT :: getArithmeticInstrCost ( Opcode , Ty , Opd1Info , Opd2Info , Opd1PropInfo , Opd2PropInfo ) ; } } </s>

This is an approximation of reciprocal throughput of a math/logic op .

Lanai ISD::MUL ISD::SDIV ISD::UDIV ISD::UREM 64


<s> bool pcrel_opt_valid_mem_p ( rtx reg , machine_mode mode , rtx mem ) { enum non_prefixed_form non_prefixed = reg_to_non_prefixed ( reg , mode ) ; if ( non_prefixed == NON_PREFIXED_X ) return false ; rtx addr = XEXP ( mem , 0 ) ; enum insn_form iform = address_to_insn_form ( addr , mode , non_prefixed ) ; return ( iform == INSN_FORM_BASE_REG || iform == INSN_FORM_D || iform == INSN_FORM_DS || iform == INSN_FORM_DQ ) ; } </s>

Return true if an REG with a given MODE is loaded from or stored into a MEM location uses a non-prefixed D/DS/DQ-form address . This is used to validate the load or store with the PCREL_OPT optimization to make sure it is an instruction that can be optimized . We need to specify the MODE separately from the REG to allow for loads that include zero/sign/float extension .


<s> rtx loongarch_prefetch_cookie ( rtx write , rtx locality ) { if ( INTVAL ( locality ) <= 0 ) return GEN_INT ( INTVAL ( write ) + 4 ) ; if ( INTVAL ( locality ) <= 2 ) return write ; return GEN_INT ( INTVAL ( write ) + 6 ) ; } </s>

Given that we have an rtx of the form ( prefetch ... WRITE LOCALITY ) , return the first operand of the associated PREF or PREFX insn .


<s> bool CSKYInstPrinter :: applyTargetSpecificCLOption ( StringRef Opt ) { if ( Opt == "no-aliases" ) { NoAliases = true ; return true ; } if ( Opt == "numeric" ) { ArchRegNames = true ; return true ; } return false ; } </s>

Customize the printer according to a command line option .


<s> static bool has_immediate ( rtx_insn * insn ) { int num_imm_operand ; int num_imm32_operand ; int num_imm64_operand ; if ( insn ) return get_num_immediates ( insn , & num_imm_operand , & num_imm32_operand , & num_imm64_operand ) ; return false ; } </s>

This function indicates if an operand of an instruction is an immediate .


<s> bool SystemZTargetLowering :: isLegalAddressingMode ( const DataLayout & DL , const AddrMode & AM , Type * Ty , unsigned AS , Instruction * I ) const { if ( AM . BaseGV ) return false ; if ( ! isInt < 20 > ( AM . BaseOffs ) ) return false ; AddressingMode SupportedAM ( true , true ) ; if ( I != nullptr ) SupportedAM = supportedAddressingMode ( I , Subtarget . hasVector ( ) ) ; if ( ! SupportedAM . LongDisplacement && ! isUInt < 12 > ( AM . BaseOffs ) ) return false ; if ( ! SupportedAM . IndexReg ) return AM . Scale == 0 ; else return AM . Scale == 0 || AM . Scale == 1 ; } </s>

isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target , for a load/store of the specified type .


<s> unsigned char X86Subtarget :: classifyGlobalReference ( const GlobalValue * GV , const Module & M ) const { if ( TM . getCodeModel ( ) == CodeModel :: Large && ! isPositionIndependent ( ) ) return X86II :: MO_NO_FLAG ; if ( GV ) { if ( Optional < ConstantRange > CR = GV -> getAbsoluteSymbolRange ( ) ) { if ( CR -> getUnsignedMax ( ) . ult ( 128 ) ) return X86II :: MO_ABS8 ; else return X86II :: MO_NO_FLAG ; } } if ( TM . shouldAssumeDSOLocal ( M , GV ) ) return classifyLocalReference ( GV ) ; if ( isTargetCOFF ( ) ) { if ( ! GV ) return X86II :: MO_NO_FLAG ; if ( GV -> hasDLLImportStorageClass ( ) ) return X86II :: MO_DLLIMPORT ; return X86II :: MO_COFFSTUB ; } if ( isOSWindows ( ) ) return X86II :: MO_NO_FLAG ; if ( is64Bit ( ) ) { if ( TM . getCodeModel ( ) == CodeModel :: Large ) return isTargetELF ( ) ? X86II :: MO_GOT : X86II :: MO_NO_FLAG ; if ( AllowTaggedGlobals && GV && ! isa < Function > ( GV ) ) return X86II :: MO_GOTPCREL_NORELAX ; return X86II :: MO_GOTPCREL ; } if ( isTargetDarwin ( ) ) { if ( ! isPositionIndependent ( ) ) return X86II :: MO_DARWIN_NONLAZY ; return X86II :: MO_DARWIN_NONLAZY_PIC_BASE ; } if ( TM . getRelocationModel ( ) == Reloc :: Static ) return X86II :: MO_NO_FLAG ; return X86II :: MO_GOT ; } </s>

Classify a global variable reference for the current subtarget according to how we should reference it in a non-pcrel context .


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { AU . setPreservesCFG ( ) ; AU . addRequired < MachineDominatorTree > ( ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ; } </s>

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> static tree pru_builtin_decl ( unsigned code , bool initialize_p ATTRIBUTE_UNUSED ) { switch ( code ) { case PRU_BUILTIN_DELAY_CYCLES : case PRU_BUILTIN_HALT : case PRU_BUILTIN_LMBD : return pru_builtins [ code ] ; default : return error_mark_node ; } } </s>


<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 ) ; const simd_vec_cost * simd_costs = aarch64_simd_vec_costs ( 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 ? simd_costs -> fp_stmt_cost : simd_costs -> int_stmt_cost ; case vector_load : return simd_costs -> align_load_cost ; case vector_store : return simd_costs -> store_cost ; case vec_to_scalar : return simd_costs -> vec_to_scalar_cost ; case scalar_to_vec : return simd_costs -> scalar_to_vec_cost ; case unaligned_load : case vector_gather_load : return simd_costs -> unalign_load_cost ; case unaligned_store : case vector_scatter_store : return simd_costs -> 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 simd_costs -> permute_cost ; case vec_promote_demote : return fp ? simd_costs -> fp_stmt_cost : simd_costs -> int_stmt_cost ; case vec_construct : elements = estimated_poly_value ( TYPE_VECTOR_SUBPARTS ( vectype ) ) ; return elements / 2 + 1 ; default : gcc_unreachable ( ) ; } } </s>


<s>
void
i386_pe_seh_cold_init
(
FILE
*
f
,
const
char
*
name
)
{
struct
seh_frame_state
*
seh
;
HOST_WIDE_INT
alloc_offset
,
offset
;
if
(
!
TARGET_SEH
)
return
;
if
(
cfun
->
is_thunk
)
return
;
seh
=
cfun
->
machine
->
seh
;
fputs
(
"\t.seh_proc\t"
,
f
)
;
assemble_name
(
f
,
name
)
;
fputc
(
'\n'
,
f
)
;
if
(
crtl
->
accesses_prior_frames
)
alloc_offset
=
seh
->
cfa_offset
;
else
alloc_offset
=
seh
->
sp_offset
;
offset
=
alloc_offset
INCOMING_FRAME_SP_OFFSET
;
if
(
offset
>
0
&&
offset
<
SEH_MAX_FRAME_SIZE
)
fprintf
(
f
,
"\t.seh_stackalloc\t"
HOST_WIDE_INT_PRINT_DEC
"\n"
,
offset
)
;
for
(
int
regno
=
0
;
regno
<
FIRST_PSEUDO_REGISTER
;
regno
++
)
if
(
seh
->
reg_offset
[
regno
]
>
0
)
{
fputs
(
(
SSE_REGNO_P
(
regno
)
"\t.seh_savexmm\t"
:
GENERAL_REGNO_P
(
regno
)
"\t.seh_savereg\t"
:
(
gcc_unreachable
(
)
,
""
)
)
,
f
)
;
print_reg
(
gen_rtx_REG
(
DImode
,
regno
)
,
0
,
f
)
;
fprintf
(
f
,
", "
HOST_WIDE_INT_PRINT_DEC
"\n"
,
alloc_offset
seh
->
reg_offset
[
regno
]
)
;
}
if
(
seh
->
cfa_reg
!=
stack_pointer_rtx
)
{
offset
=
alloc_offset
seh
->
cfa_offset
;
gcc_assert
(
(
offset
&
15
)
==
0
)
;
gcc_assert
(
IN_RANGE
(
offset
,
0
,
240
)
)
;
fputs
(
"\t.seh_setframe\t"
,
f
)
;
print_reg
(
seh
->
cfa_reg
,
0
,
f
)
;
fprintf
(
f
,
", "
HOST_WIDE_INT_PRINT_DEC
"\n"
,
offset
)
;
}
if
(
crtl
->
accesses_prior_frames
)
{
offset
=
seh
->
sp_offset
alloc_offset
;
if
(
offset
>
0
&&
offset
<
SEH_MAX_FRAME_SIZE
)
fprintf
(
f
,
"\t.seh_stackalloc\t"
HOST_WIDE_INT_PRINT_DEC
"\n"
,
offset
)
;
}
fputs
(
"\t.seh_endprologue\n"
,
f
)
;
}
</s>

Emit assembler directives to reconstruct the SEH state .


<s> std :: unique_ptr < MCObjectWriter > createObjectWriter ( raw_pwrite_stream & OS ) const override { return createARMELFObjectWriter ( OS , OSABI , isLittle ( ) ) ; } </s>

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


<s> virtual void * getAdjustedAnalysisPointer ( const void * ID ) { if ( ID == & TargetTransformInfo :: ID ) return ( TargetTransformInfo * ) this ; return this ; } </s>

getAdjustedAnalysisPointer - This method is used when a pass implements an analysis interface through multiple inheritance .


<s> X86TargetLowering :: ConstraintType X86TargetLowering :: getConstraintType ( StringRef Constraint ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { case 'R' : case 'q' : case 'Q' : case 'f' : case 't' : case 'u' : case 'y' : case 'x' : case 'v' : case 'Y' : case 'l' : case 'k' : return C_RegisterClass ; case 'a' : case 'b' : case 'c' : case 'd' : case 'S' : case 'D' : case 'A' : return C_Register ; case 'I' : case 'J' : case 'K' : case 'L' : case 'M' : case 'N' : case 'G' : case 'C' : case 'e' : case 'Z' : return C_Other ; default : break ; } } else if ( Constraint . size ( ) == 2 ) { switch ( Constraint [ 0 ] ) { default : break ; case 'Y' : switch ( Constraint [ 1 ] ) { default : break ; case 'z' : case '0' : return C_Register ; case 'i' : case 'm' : case 'k' : case 't' : case '2' : return C_RegisterClass ; } } } return TargetLowering :: getConstraintType ( Constraint ) ; } </s>

Given a constraint letter , return the type of constraint for this target .


<s> static bool mips_symbol_binds_local_p ( const_rtx x ) { return ( SYMBOL_REF_DECL ( x ) ? targetm . binds_local_p ( SYMBOL_REF_DECL ( x ) ) : SYMBOL_REF_LOCAL_P ( x ) ) ; } </s>

Return true if SYMBOL_REF X binds locally .


<s> void X86ATTInstPrinter :: printRegName ( raw_ostream & OS , unsigned RegNo ) const { OS << markup ( "<reg:" ) << '%' << getRegisterName ( RegNo ) << markup ( ">" ) ; } </s>


<s> static void ix86_encode_section_info ( tree decl , rtx rtl , int first ) { default_encode_section_info ( decl , rtl , first ) ; if ( TREE_CODE ( decl ) == VAR_DECL && ( TREE_STATIC ( decl ) || DECL_EXTERNAL ( decl ) ) && ix86_in_large_data_p ( decl ) ) SYMBOL_REF_FLAGS ( XEXP ( rtl , 0 ) ) |= SYMBOL_FLAG_FAR_ADDR ; } </s>

Implements target vector targetm.asm.encode_section_info .


<s> void CSKYAsmBackend :: applyFixup ( const MCAssembler & Asm , const MCFixup & Fixup , const MCValue & Target , MutableArrayRef < char > Data , uint64_t Value , bool IsResolved , const MCSubtargetInfo * STI ) const { return ; } </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> void Mips16FrameLowering :: emitPrologue ( MachineFunction & MF ) const { MachineBasicBlock & MBB = MF . front ( ) ; MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; const Mips16InstrInfo & TII = * static_cast < const Mips16InstrInfo * > ( MF . getTarget ( ) . getInstrInfo ( ) ) ; MachineBasicBlock :: iterator MBBI = MBB . begin ( ) ; DebugLoc dl = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; uint64_t StackSize = MFI -> getStackSize ( ) ; if ( StackSize == 0 && ! MFI -> adjustsStack ( ) ) return ; MachineModuleInfo & MMI = MF . getMMI ( ) ; const MCRegisterInfo * MRI = MMI . getContext ( ) . getRegisterInfo ( ) ; MachineLocation DstML , SrcML ; TII . makeFrame ( Mips :: SP , StackSize , MBB , MBBI ) ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , - StackSize ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) ; const std :: vector < CalleeSavedInfo > & CSI = MFI -> getCalleeSavedInfo ( ) ; if ( CSI . size ( ) ) { const std :: vector < CalleeSavedInfo > & CSI = MFI -> getCalleeSavedInfo ( ) ; for ( std :: vector < CalleeSavedInfo > :: const_iterator I = CSI . begin ( ) , E = CSI . end ( ) ; I != E ; ++ I ) { int64_t Offset = MFI -> getObjectOffset ( I -> getFrameIdx ( ) ) ; unsigned Reg = I -> getReg ( ) ; unsigned DReg = MRI -> getDwarfRegNum ( Reg , true ) ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createOffset ( nullptr , DReg , Offset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) ; } } if ( hasFP ( MF ) ) BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: MoveR3216 ) , Mips :: S0 ) . addReg ( Mips :: SP ) . setMIFlag ( MachineInstr :: FrameSetup ) ; } </s>

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

Mips Mips Mips Mips 0 Mips::SP Mips::MoveR3216 Mips::S0 Mips::SP


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


<s> static rtx emit_multi_reg_push ( unsigned long mask , unsigned long dwarf_regs_mask ) { int num_regs = 0 ; int num_dwarf_regs = 0 ; int i , j ; rtx par ; rtx dwarf ; int dwarf_par_index ; rtx tmp , reg ; dwarf_regs_mask &= ~ ( 1 << PC_REGNUM ) ; for ( i = 0 ; i <= LAST_ARM_REGNUM ; i ++ ) { if ( mask & ( 1 << i ) ) num_regs ++ ; if ( dwarf_regs_mask & ( 1 << i ) ) num_dwarf_regs ++ ; } gcc_assert ( num_regs && num_regs <= 16 ) ; gcc_assert ( ( dwarf_regs_mask & ~ mask ) == 0 ) ; par = gen_rtx_PARALLEL ( VOIDmode , rtvec_alloc ( num_regs ) ) ; dwarf = gen_rtx_SEQUENCE ( VOIDmode , rtvec_alloc ( num_dwarf_regs + 1 ) ) ; dwarf_par_index = 1 ; for ( i = 0 ; i <= LAST_ARM_REGNUM ; i ++ ) { if ( mask & ( 1 << i ) ) { reg = gen_rtx_REG ( SImode , i ) ; XVECEXP ( par , 0 , 0 ) = gen_rtx_SET ( VOIDmode , gen_frame_mem ( BLKmode , gen_rtx_PRE_MODIFY ( Pmode , stack_pointer_rtx , plus_constant ( Pmode , stack_pointer_rtx , - 4 * num_regs ) ) ) , gen_rtx_UNSPEC ( BLKmode , gen_rtvec ( 1 , reg ) , UNSPEC_PUSH_MULT ) ) ; if ( dwarf_regs_mask & ( 1 << i ) ) { tmp = gen_rtx_SET ( VOIDmode , gen_frame_mem ( SImode , stack_pointer_rtx ) , reg ) ; RTX_FRAME_RELATED_P ( tmp ) = 1 ; XVECEXP ( dwarf , 0 , dwarf_par_index ++ ) = tmp ; } break ; } } for ( j = 1 , i ++ ; j < num_regs ; i ++ ) { if ( mask & ( 1 << i ) ) { reg = gen_rtx_REG ( SImode , i ) ; XVECEXP ( par , 0 , j ) = gen_rtx_USE ( VOIDmode , reg ) ; if ( dwarf_regs_mask & ( 1 << i ) ) { tmp = gen_rtx_SET ( VOIDmode , gen_frame_mem ( SImode , plus_constant ( Pmode , stack_pointer_rtx , 4 * j ) ) , reg ) ; RTX_FRAME_RELATED_P ( tmp ) = 1 ; XVECEXP ( dwarf , 0 , dwarf_par_index ++ ) = tmp ; } j ++ ; } } par = emit_insn ( par ) ; tmp = gen_rtx_SET ( VOIDmode , stack_pointer_rtx , plus_constant ( Pmode , stack_pointer_rtx , - 4 * num_regs ) ) ; RTX_FRAME_RELATED_P ( tmp ) = 1 ; XVECEXP ( dwarf , 0 , 0 ) = tmp ; add_reg_note ( par , REG_FRAME_RELATED_EXPR , dwarf ) ; return par ; } </s>

Generate and emit an insn that we will recognize as a push_multi . Unfortunately , since this insn does not reflect very well the actual semantics of the operation , we need to annotate the insn for the benefit of DWARF2 frame unwind information .


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

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


<s> EVT VETargetLowering :: getSetCCResultType ( const DataLayout & , LLVMContext & , EVT VT ) const { return MVT :: i32 ; } </s>

Return the value type to use for ISD : :SETCC .


<s> bool X86TargetLowering :: isLegalAddressingMode ( const DataLayout & DL , const AddrMode & AM , Type * Ty , unsigned AS ) const { CodeModel :: Model M = getTargetMachine ( ) . getCodeModel ( ) ; if ( ! X86 :: isOffsetSuitableForCodeModel ( AM . BaseOffs , M , AM . BaseGV != nullptr ) ) return false ; if ( AM . BaseGV ) { unsigned GVFlags = Subtarget . classifyGlobalReference ( AM . BaseGV ) ; if ( isGlobalStubReference ( GVFlags ) ) return false ; if ( AM . HasBaseReg && isGlobalRelativeToPICBase ( GVFlags ) ) return false ; if ( ( M != CodeModel :: Small || isPositionIndependent ( ) ) && Subtarget . is64Bit ( ) && ( AM . BaseOffs || AM . Scale > 1 ) ) return false ; } switch ( AM . Scale ) { case 0 : case 1 : case 2 : case 4 : case 8 : break ; case 3 : case 5 : case 9 : if ( AM . HasBaseReg ) return false ; break ; default : return false ; } return true ; } </s>


"8-byte alignment required for for all register save slots"

This function will assign callee saved gprs to volatile vector registers for prologue spills when applicable .


"64-bit code requested on a subtarget that doesn't "

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


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


<s>
void
ARMTTIImpl
::
getUnrollingPreferences
(
Loop
*
L
,
ScalarEvolution
&
SE
,
TTI
::
UnrollingPreferences
&
UP
)
{
if
(
!
ST
->
isMClass
(
)
)
return
BasicTTIImplBase
::
getUnrollingPreferences
(
L
,
SE
,
UP
)
;
UP
.
OptSizeThreshold
=
0
;
UP
.
PartialOptSizeThreshold
=
0
;
if
(
L
->
getHeader
(
)
->
getParent
(
)
->
hasOptSize
(
)
)
return
;
if
(
!
ST
->
isThumb2
(
)
)
return
;
SmallVector
<
BasicBlock
*
,
4
>
ExitingBlocks
;
L
->
getExitingBlocks
(
ExitingBlocks
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Loop has:\n"
<<
"Blocks: "
<<
L
->
getNumBlocks
(
)
<<
"\n"
<<
"Exit blocks: "
<<
ExitingBlocks
.
size
(
)
<<
"\n"
)
;
if
(
ExitingBlocks
.
size
(
)
>
2
)
return
;
if
(
ST
->
hasBranchPredictor
(
)
&&
L
->
getNumBlocks
(
)
>
4
)
return
;
if
(
getBooleanLoopAttribute
(
L
,
"llvm.loop.isvectorized"
)
)
return
;
unsigned
Cost
=
0
;
for
(
auto
*
BB
:
L
->
getBlocks
(
)
)
{
for
(
auto
&
I
:
*
BB
)
{
if
(
I
.
getType
(
)
->
isVectorTy
(
)
)
return
;
if
(
isa
<
CallInst
>
(
I
)
||
isa
<
InvokeInst
>
(
I
)
)
{
if
(
const
Function
*
F
=
cast
<
CallBase
>
(
I
)
.
getCalledFunction
(
)
)
{
if
(
!
isLoweredToCall
(
F
)
)
continue
;
}
return
;
}
SmallVector
<
const
Value
*
,
4
>
Operands
(
I
.
operand_values
(
)
)
;
Cost
+=
getUserCost
(
&
I
,
Operands
,
TargetTransformInfo
::
TCK_SizeAndLatency
)
;
}
}
LLVM_DEBUG
(
dbgs
(
)
<<
"Cost of loop: "
<<
Cost
<<
"\n"
)
;
UP
.
Partial
=
true
;
UP
.
Runtime
=
true
;
UP
.
UpperBound
=
true
;
UP
.
UnrollRemainder
=
true
;
UP
.
DefaultUnrollRuntimeCount
=
4
;
UP
.
UnrollAndJam
=
true
;
UP
.
UnrollAndJamInnerLoopThreshold
=
60
;
if
(
Cost
<
12
)
UP
.
Force
=
true
;
}
</s>

Get target-customized preferences for the generic loop unrolling transformation .


<s> void ia64_expand_compare ( rtx * expr , rtx * op0 , rtx * op1 ) { enum rtx_code code = GET_CODE ( * expr ) ; rtx cmp ; if ( GET_MODE ( * op0 ) == BImode ) { gcc_assert ( ( code == NE || code == EQ ) && * op1 == const0_rtx ) ; cmp = * op0 ; } else if ( TARGET_HPUX && GET_MODE ( * op0 ) == TFmode ) { enum qfcmp_magic { QCMP_INV = 1 , QCMP_UNORD = 2 , QCMP_EQ = 4 , QCMP_LT = 8 , QCMP_GT = 16 } ; int magic ; enum rtx_code ncode ; rtx ret ; gcc_assert ( cmptf_libfunc && GET_MODE ( * op1 ) == TFmode ) ; switch ( code ) { case EQ : magic = QCMP_EQ ; ncode = NE ; break ; case NE : magic = QCMP_EQ ; ncode = EQ ; break ; case UNORDERED : magic = QCMP_UNORD ; ncode = NE ; break ; case ORDERED : magic = QCMP_UNORD ; ncode = EQ ; break ; case LT : magic = QCMP_LT | QCMP_INV ; ncode = NE ; break ; case LE : magic = QCMP_LT | QCMP_EQ | QCMP_INV ; ncode = NE ; break ; case GT : magic = QCMP_GT | QCMP_INV ; ncode = NE ; break ; case GE : magic = QCMP_GT | QCMP_EQ | QCMP_INV ; ncode = NE ; break ; case UNLT : magic = QCMP_LT | QCMP_UNORD ; ncode = NE ; break ; case UNLE : magic = QCMP_LT | QCMP_EQ | QCMP_UNORD ; ncode = NE ; break ; case UNGT : magic = QCMP_GT | QCMP_UNORD ; ncode = NE ; break ; case UNGE : magic = QCMP_GT | QCMP_EQ | QCMP_UNORD ; ncode = NE ; break ; case UNEQ : case LTGT : default : gcc_unreachable ( ) ; } start_sequence ( ) ; ret = emit_library_call_value ( cmptf_libfunc , 0 , LCT_CONST , DImode , * op0 , TFmode , * op1 , TFmode , GEN_INT ( magic ) , DImode ) ; cmp = gen_reg_rtx ( BImode ) ; emit_insn ( gen_rtx_SET ( cmp , gen_rtx_fmt_ee ( ncode , BImode , ret , const0_rtx ) ) ) ; rtx_insn * insns = get_insns ( ) ; end_sequence ( ) ; emit_libcall_block ( insns , cmp , cmp , gen_rtx_fmt_ee ( code , BImode , * op0 , * op1 ) ) ; code = NE ; } else { cmp = gen_reg_rtx ( BImode ) ; emit_insn ( gen_rtx_SET ( cmp , gen_rtx_fmt_ee ( code , BImode , * op0 , * op1 ) ) ) ; code = NE ; } * expr = gen_rtx_fmt_ee ( code , VOIDmode , cmp , const0_rtx ) ; * op0 = cmp ; * op1 = const0_rtx ; } </s>

Emit comparison instruction if necessary , returning the expression that holds the compare result in the proper mode .


<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 ( ) ; 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 ; } return weight ; } </s>

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


<s> void PPCPassConfig :: addPreEmitPass ( ) { addPass ( createPPCPreEmitPeepholePass ( ) ) ; addPass ( createPPCExpandISELPass ( ) ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) addPass ( createPPCEarlyReturnPass ( ) ) ; addPass ( createPPCBranchSelectionPass ( ) ) ; } </s>

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


<s> bool aarch64_split_dimode_const_store ( rtx dst , rtx src ) { rtx lo = gen_lowpart ( SImode , src ) ; rtx hi = gen_highpart_mode ( SImode , DImode , src ) ; bool size_p = optimize_function_for_size_p ( cfun ) ; if ( ! rtx_equal_p ( lo , hi ) ) return false ; unsigned int orig_cost = aarch64_internal_mov_immediate ( NULL_RTX , src , false , DImode ) ; unsigned int lo_cost = aarch64_internal_mov_immediate ( NULL_RTX , lo , false , SImode ) ; if ( size_p && orig_cost <= lo_cost ) return false ; if ( ! size_p && ( orig_cost <= lo_cost + 1 ) ) return false ; rtx mem_lo = adjust_address ( dst , SImode , 0 ) ; if ( ! aarch64_mem_pair_operand ( mem_lo , SImode ) ) return false ; rtx tmp_reg = gen_reg_rtx ( SImode ) ; aarch64_expand_mov_immediate ( tmp_reg , lo ) ; rtx mem_hi = aarch64_move_pointer ( mem_lo , GET_MODE_SIZE ( SImode ) ) ; emit_move_insn ( mem_lo , tmp_reg ) ; emit_move_insn ( mem_hi , tmp_reg ) ; return true ; } </s>

Split a DImode store of a CONST_INT SRC to MEM DST as two SImode stores . Handle the case when the constant has identical bottom and top halves . This is beneficial when the two stores can be merged into an STP and we avoid synthesising potentially expensive immediates twice . Return true if such a split is possible .


<s> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const override { return createARMELFObjectWriter ( OS , OSABI , isLittle ( ) ) ; } </s>

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


<s> void ix86_expand_rint ( rtx operand0 , rtx operand1 ) { machine_mode mode = GET_MODE ( operand0 ) ; rtx res , xa , TWO52 , mask ; rtx_code_label * label ; TWO52 = ix86_gen_TWO52 ( mode ) ; res = copy_to_reg ( operand1 ) ; xa = ix86_expand_sse_fabs ( res , & mask ) ; label = ix86_expand_sse_compare_and_jump ( UNLE , TWO52 , xa , false ) ; if ( flag_rounding_math ) { ix86_sse_copysign_to_positive ( TWO52 , TWO52 , res , mask ) ; xa = res ; } xa = expand_simple_binop ( mode , PLUS , xa , TWO52 , NULL_RTX , 0 , OPTAB_DIRECT ) ; xa = expand_simple_binop ( mode , MINUS , xa , TWO52 , xa , 0 , OPTAB_DIRECT ) ; if ( HONOR_SIGNED_ZEROS ( mode ) && flag_rounding_math ) xa = ix86_expand_sse_fabs ( xa , NULL ) ; ix86_sse_copysign_to_positive ( res , xa , res , mask ) ; emit_label ( label ) ; LABEL_NUSES ( label ) = 1 ; emit_move_insn ( operand0 , res ) ; } </s>

Expand rint ( IEEE round to nearest ) rounding OPERAND1 and storing the result in OPERAND0 .


<s> bool is_fast_interrupt_func ( const_tree decl ) { return has_func_attr ( decl , "fast_interrupt" ) ; } </s>

Returns true if the provided function has the `` fast_interrupt '' attribute .


<s> static bool call_ABI_of_interest ( tree fndecl ) { if ( rs6000_gnu_attr && symtab -> state == EXPANSION ) { struct cgraph_node * c_node ; if ( fndecl == NULL_TREE ) return true ; if ( DECL_EXTERNAL ( fndecl ) ) return true ; c_node = cgraph_node :: get ( fndecl ) ; c_node = c_node -> ultimate_alias_target ( ) ; return ! c_node -> only_called_directly_p ( ) ; } return false ; } </s>

Return TRUE if a call to function FNDECL may be one that potentially affects the function calling ABI of the object file .


"Caller should have checked for a comparison"

analyzeCompare - For a comparison instruction , return the source registers in SrcReg and SrcReg2 if having two register operands , and the value it compares against in CmpValue .


<s> int X86TargetLowering :: getScalingFactorCost ( const AddrMode & AM , Type * Ty , unsigned AS ) const { if ( isLegalAddressingMode ( AM , Ty , AS ) ) return AM . Scale != 0 ; return - 1 ; } </s>

Return the cost of the scaling factor used in the addressing mode represented by AM for this target , for a load/store of the specified type .


<s> void SparcAsmPrinter :: emitInstruction ( const MachineInstr * MI ) { switch ( MI -> getOpcode ( ) ) { default : break ; case TargetOpcode :: DBG_VALUE : return ; case SP :: GETPCX : LowerGETPCXAndEmitMCInsts ( MI , getSubtargetInfo ( ) ) ; return ; } MachineBasicBlock :: const_instr_iterator I = MI -> getIterator ( ) ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; do { MCInst TmpInst ; LowerSparcMachineInstrToMCInst ( & * I , TmpInst , * this ) ; EmitToStreamer ( * OutStreamer , TmpInst ) ; } while ( ( ++ I != E ) && I -> isInsideBundle ( ) ) ; } </s>

Targets should implement this to emit instructions .


<s> bool AArch64InstrInfo :: analyzeBranch ( MachineBasicBlock & MBB , MachineBasicBlock * & TBB , MachineBasicBlock * & FBB , SmallVectorImpl < MachineOperand > & Cond , bool AllowModify ) const { MachineBasicBlock :: iterator I = MBB . getLastNonDebugInstr ( ) ; if ( I == MBB . end ( ) ) return false ; if ( I -> getOpcode ( ) == AArch64 :: SpeculationBarrierISBDSBEndBB || I -> getOpcode ( ) == AArch64 :: SpeculationBarrierSBEndBB ) { -- I ; } if ( ! isUnpredicatedTerminator ( * I ) ) return false ; MachineInstr * LastInst = & * I ; unsigned LastOpc = LastInst -> getOpcode ( ) ; if ( I == MBB . begin ( ) || ! isUnpredicatedTerminator ( * -- I ) ) { if ( isUncondBranchOpcode ( LastOpc ) ) { TBB = LastInst -> getOperand ( 0 ) . getMBB ( ) ; return false ; } if ( isCondBranchOpcode ( LastOpc ) ) { parseCondBranch ( LastInst , TBB , Cond ) ; return false ; } return true ; } MachineInstr * SecondLastInst = & * I ; unsigned SecondLastOpc = SecondLastInst -> getOpcode ( ) ; if ( AllowModify && isUncondBranchOpcode ( LastOpc ) ) { while ( isUncondBranchOpcode ( SecondLastOpc ) ) { LastInst -> eraseFromParent ( ) ; LastInst = SecondLastInst ; LastOpc = LastInst -> getOpcode ( ) ; if ( I == MBB . begin ( ) || ! isUnpredicatedTerminator ( * -- I ) ) { TBB = LastInst -> getOperand ( 0 ) . getMBB ( ) ; return false ; } else { SecondLastInst = & * I ; SecondLastOpc = SecondLastInst -> getOpcode ( ) ; } } } if ( SecondLastInst && I != MBB . begin ( ) && isUnpredicatedTerminator ( * -- I ) ) return true ; if ( isCondBranchOpcode ( SecondLastOpc ) && isUncondBranchOpcode ( LastOpc ) ) { parseCondBranch ( SecondLastInst , TBB , Cond ) ; FBB = LastInst -> getOperand ( 0 ) . getMBB ( ) ; return false ; } if ( isUncondBranchOpcode ( SecondLastOpc ) && isUncondBranchOpcode ( LastOpc ) ) { TBB = SecondLastInst -> getOperand ( 0 ) . getMBB ( ) ; I = LastInst ; if ( AllowModify ) I -> eraseFromParent ( ) ; return false ; } if ( isIndirectBranchOpcode ( SecondLastOpc ) && isUncondBranchOpcode ( LastOpc ) ) { I = LastInst ; if ( AllowModify ) I -> eraseFromParent ( ) ; return true ; } return true ; } </s>

analyzeBranch - Analyze the branching code at the end of MBB , returning true if it can not be understood ( e.g .


<s> unsigned DLXRegisterInfo :: getFrameRegister ( const MachineFunction & ) const { return DLX :: FP ; } </s>


<s> int standard_80387_constant_p ( rtx x ) { machine_mode mode = GET_MODE ( x ) ; REAL_VALUE_TYPE r ; if ( ! ( X87_FLOAT_MODE_P ( mode ) && ( GET_CODE ( x ) == CONST_DOUBLE ) ) ) return - 1 ; if ( x == CONST0_RTX ( mode ) ) return 1 ; if ( x == CONST1_RTX ( mode ) ) return 2 ; REAL_VALUE_FROM_CONST_DOUBLE ( r , x ) ; if ( mode == XFmode && ( optimize_function_for_size_p ( cfun ) || TARGET_EXT_80387_CONSTANTS ) ) { int i ; if ( ! ext_80387_constants_init ) init_ext_80387_constants ( ) ; for ( i = 0 ; i < 5 ; i ++ ) if ( real_identical ( & r , & ext_80387_constants_table [ i ] ) ) return i + 3 ; } if ( real_isnegzero ( & r ) ) return 8 ; if ( real_identical ( & r , & dconstm1 ) ) return 9 ; return 0 ; } </s>

Return true if the constant is something that can be loaded with a special instruction .


<s> static int rs6000_emit_p9_fp_minmax ( rtx dest , rtx op , rtx true_cond , rtx false_cond ) { enum rtx_code code = GET_CODE ( op ) ; rtx op0 = XEXP ( op , 0 ) ; rtx op1 = XEXP ( op , 1 ) ; machine_mode compare_mode = GET_MODE ( op0 ) ; machine_mode result_mode = GET_MODE ( dest ) ; bool max_p = false ; if ( result_mode != compare_mode ) return 0 ; if ( code == GE || code == GT ) max_p = true ; else if ( code == LE || code == LT ) max_p = false ; else return 0 ; if ( rtx_equal_p ( op0 , true_cond ) && rtx_equal_p ( op1 , false_cond ) ) ; else if ( rtx_equal_p ( op1 , true_cond ) && rtx_equal_p ( op0 , false_cond ) && ! HONOR_NANS ( compare_mode ) && ! HONOR_SIGNED_ZEROS ( compare_mode ) ) max_p = ! max_p ; else return 0 ; rs6000_emit_minmax ( dest , max_p ? SMAX : SMIN , op0 , op1 ) ; return 1 ; } </s>

ISA 3.0 ( power9 ) minmax subcase to emit a XSMAXCDP or XSMINCDP instruction for SF/DF scalars . Move TRUE_COND to DEST if OP of the operands of the last comparison is nonzero/true , FALSE_COND if it is zero/false . Return 0 if the hardware has no such operation .


<s> static bool arm_cannot_copy_insn_p ( rtx_insn * insn ) { if ( recog_memoized ( insn ) == CODE_FOR_tlscall ) return true ; subrtx_iterator :: array_type array ; FOR_EACH_SUBRTX ( iter , array , PATTERN ( insn ) , ALL ) { const_rtx x = * iter ; if ( GET_CODE ( x ) == UNSPEC && ( XINT ( x , 1 ) == UNSPEC_PIC_BASE || XINT ( x , 1 ) == UNSPEC_PIC_UNIFIED ) ) return true ; } return false ; } </s>

Must not copy any rtx that uses a pc-relative address .


<s> static bool mep_reuse_lo_p_1 ( rtx lo , rtx gpr , rtx_insn * insn , bool gpr_dead_p ) { do { insn = PREV_INSN ( insn ) ; if ( INSN_P ( insn ) ) switch ( recog_memoized ( insn ) ) { case CODE_FOR_mulsi3_1 : extract_insn ( insn ) ; if ( rtx_equal_p ( recog_data . operand [ 0 ] , gpr ) ) { mep_rewrite_mulsi3 ( insn , gpr_dead_p ? NULL : recog_data . operand [ 0 ] , recog_data . operand [ 1 ] , recog_data . operand [ 2 ] ) ; return true ; } return false ; case CODE_FOR_maddsi3 : extract_insn ( insn ) ; if ( rtx_equal_p ( recog_data . operand [ 0 ] , gpr ) ) { mep_rewrite_maddsi3 ( insn , gpr_dead_p ? NULL : recog_data . operand [ 0 ] , recog_data . operand [ 1 ] , recog_data . operand [ 2 ] , recog_data . operand [ 3 ] ) ; return true ; } return false ; case CODE_FOR_mulsi3r : case CODE_FOR_maddsi3r : extract_insn ( insn ) ; return rtx_equal_p ( recog_data . operand [ 1 ] , gpr ) ; default : if ( reg_set_p ( lo , insn ) || reg_set_p ( gpr , insn ) || volatile_insn_p ( PATTERN ( insn ) ) ) return false ; if ( gpr_dead_p && reg_referenced_p ( gpr , PATTERN ( insn ) ) ) gpr_dead_p = false ; break ; } } while ( ! NOTE_INSN_BASIC_BLOCK_P ( insn ) ) ; return false ; } </s>

Return true if $ lo has the same value as integer register GPR when instruction INSN is reached . If necessary , rewrite the instruction that sets $ lo so that it uses a proper SET , not a CLOBBER . LO is an rtx for ( reg : SI LO_REGNO ) . This function is intended to be used by the peephole2 pass . Since that pass goes from the end of a basic block to the beginning , and propagates liveness information on the way , there is no need to update register notes here . If GPR_DEAD_P is true on entry , and this function returns true , then the caller will replace _every_ use of GPR in and after INSN with LO . This means that if the instruction that sets $ lo is a mulr- or maddr-type instruction , we can rewrite it to use mul or madd instead . In combination with the copy progagation pass , this allows us to replace sequences like : mov GPR , R1 mulr GPR , R2 with : mul R1 , R2 if GPR is no longer used .


<s> sbitmap rs6000_get_separate_components ( void ) { rs6000_stack_t * info = rs6000_stack_info ( ) ; if ( WORLD_SAVE_P ( info ) ) return NULL ; gcc_assert ( ! ( info -> savres_strategy & SAVE_MULTIPLE ) && ! ( info -> savres_strategy & REST_MULTIPLE ) ) ; cfun -> machine -> n_components = 64 ; sbitmap components = sbitmap_alloc ( cfun -> machine -> n_components ) ; bitmap_clear ( components ) ; int reg_size = TARGET_32BIT ? 4 : 8 ; int fp_reg_size = 8 ; if ( ( info -> savres_strategy & SAVE_INLINE_GPRS ) && ( info -> savres_strategy & REST_INLINE_GPRS ) ) { int offset = info -> gp_save_offset ; if ( info -> push_p ) offset += info -> total_size ; for ( unsigned regno = info -> first_gp_reg_save ; regno < 32 ; regno ++ ) { if ( IN_RANGE ( offset , - 0x8000 , 0x7fff ) && save_reg_p ( regno ) ) bitmap_set_bit ( components , regno ) ; offset += reg_size ; } } if ( frame_pointer_needed ) bitmap_clear_bit ( components , HARD_FRAME_POINTER_REGNUM ) ; if ( ( TARGET_TOC && TARGET_MINIMAL_TOC ) || ( flag_pic == 1 && DEFAULT_ABI == ABI_V4 ) || ( flag_pic && DEFAULT_ABI == ABI_DARWIN ) ) bitmap_clear_bit ( components , RS6000_PIC_OFFSET_TABLE_REGNUM ) ; if ( ( info -> savres_strategy & SAVE_INLINE_FPRS ) && ( info -> savres_strategy & REST_INLINE_FPRS ) ) { int offset = info -> fp_save_offset ; if ( info -> push_p ) offset += info -> total_size ; for ( unsigned regno = info -> first_fp_reg_save ; regno < 64 ; regno ++ ) { if ( IN_RANGE ( offset , - 0x8000 , 0x7fff ) && save_reg_p ( regno ) ) bitmap_set_bit ( components , regno ) ; offset += fp_reg_size ; } } if ( info -> lr_save_p && ! ( flag_pic && ( DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN ) ) && ( info -> savres_strategy & SAVE_INLINE_GPRS ) && ( info -> savres_strategy & REST_INLINE_GPRS ) && ( info -> savres_strategy & SAVE_INLINE_FPRS ) && ( info -> savres_strategy & REST_INLINE_FPRS ) && ( info -> savres_strategy & SAVE_INLINE_VRS ) && ( info -> savres_strategy & REST_INLINE_VRS ) ) { int offset = info -> lr_save_offset ; if ( info -> push_p ) offset += info -> total_size ; if ( IN_RANGE ( offset , - 0x8000 , 0x7fff ) ) bitmap_set_bit ( components , 0 ) ; } if ( cfun -> machine -> save_toc_in_prologue ) bitmap_set_bit ( components , 2 ) ; return components ; } </s>


<s> bool X86EncodeLiteralsPass :: runOnMachineFunction ( MachineFunction & MF ) { bool Changed = false ; MRI = & MF . getRegInfo ( ) ; TII = MF . getSubtarget < X86Subtarget > ( ) . getInstrInfo ( ) ; TRI = MF . getSubtarget < X86Subtarget > ( ) . getRegisterInfo ( ) ; if ( ! EnableEncodeLiterals ) return false ; for ( auto & MBB : MF ) { unsigned Index = 0 ; for ( MachineBasicBlock :: iterator MI = MBB . begin ( ) , E = MBB . end ( ) ; MI != E ; ++ MI , ++ Index ) { if ( isStoreLocalValue ( * MI ) ) { obfuscateLiteralOperand ( MF , * MI , Index ) ; Changed = true ; } } } return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s>
unsigned
Mips16InstrInfo
::
getOppositeBranchOpc
(
unsigned
Opc
)
const
{
switch
(
Opc
)
{
default
:
llvm_unreachable
(
"Illegal opcode!"
)
;
case
Mips
::
BeqzRxImmX16
:
return
Mips
::
BnezRxImmX16
;
case
Mips
::
BnezRxImmX16
:
return
Mips
::
BeqzRxImmX16
;
case
Mips
::
BteqzT8CmpX16
:
return
Mips
::
BtnezT8CmpX16
;
case
Mips
::
BteqzT8SltX16
:
return
Mips
::
BtnezT8SltX16
;
case
Mips
::
BteqzT8SltiX16
:
return
Mips
::
BtnezT8SltiX16
;
case
Mips
::
BtnezX16
:
return
Mips
::
BteqzX16
;
case
Mips
::
BtnezT8CmpiX16
:
return
Mips
::
BteqzT8CmpiX16
;
case
Mips
::
BtnezT8SltuX16
:
return
Mips
::
BteqzT8SltuX16
;
case
Mips
::
BtnezT8SltiuX16
:
return
Mips
::
BteqzT8SltiuX16
;
case
Mips
::
BteqzX16
:
return
Mips
::
BtnezX16
;
case
Mips
::
BteqzT8CmpiX16
:
return
Mips
::
BtnezT8CmpiX16
;
case
Mips
::
BteqzT8SltuX16
:
return
Mips
::
BtnezT8SltuX16
;
case
Mips
::
BteqzT8SltiuX16
:
return
Mips
::
BtnezT8SltiuX16
;
case
Mips
::
BtnezT8CmpX16
:
return
Mips
::
BteqzT8CmpX16
;
case
Mips
::
BtnezT8SltX16
:
return
Mips
::
BteqzT8SltX16
;
case
Mips
::
BtnezT8SltiX16
:
return
Mips
::
BteqzT8SltiX16
;
}
assert
(
false
&&
"Implement this function."
)
;
return
0
;
}
</s>

getOppositeBranchOpc - Return the inverse of the specified opcode , e.g .


<s> static HOST_WIDE_INT aarch64_simd_vector_alignment ( const_tree type ) { if ( GET_MODE_CLASS ( TYPE_MODE ( type ) ) == MODE_VECTOR_BOOL ) return 16 ; widest_int min_size = constant_lower_bound ( wi :: to_poly_widest ( TYPE_SIZE ( type ) ) ) ; return wi :: umin ( min_size , 128 ) . to_uhwi ( ) ; } </s>

Implement target hook TARGET_VECTOR_ALIGNMENT . The AAPCS64 sets the maximum alignment of a vector to 128 bits .


<s> bool KudeyarFrameLowering :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; DebugLoc DL ; if ( MI != MBB . end ( ) ) DL = MI -> getDebugLoc ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF . getTarget ( ) . getInstrInfo ( ) ; if ( CSI . size ( ) > 1 ) { MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( Kudeyar :: POPA ) ) ; for ( unsigned i = CSI . size ( ) ; i != 0 ; -- i ) { unsigned Reg = CSI [ i - 1 ] . getReg ( ) ; MIB . addReg ( Reg , getDefRegState ( true ) ) ; } } else { unsigned Reg = CSI [ 0 ] . getReg ( ) ; BuildMI ( MBB , MI , DL , TII . get ( Kudeyar :: POP_R ) , Reg ) ; } for ( unsigned i = 0 , e = CSI . size ( ) ; i != e ; ++ i ) BuildMI ( MBB , MI , DL , TII . get ( Kudeyar :: POP_R ) , CSI [ i ] . getReg ( ) ) ; return true ; } </s>

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


<s> TargetLoweringBase :: LegalizeTypeAction X86TargetLowering :: getPreferredVectorAction ( EVT VT ) const { if ( ExperimentalVectorWideningLegalization && VT . getVectorNumElements ( ) != 1 && VT . getVectorElementType ( ) . getSimpleVT ( ) != MVT :: i1 ) return TypeWidenVector ; return TargetLoweringBase :: getPreferredVectorAction ( VT ) ; } </s>

Customize the preferred legalization strategy for certain types .


<s> static unsigned getFramePointerSaveOffset ( bool isPPC64 , bool isDarwinABI ) { if ( isDarwinABI ) return isPPC64 ? - 8U : - 4U ; return isPPC64 ? - 8U : - 4U ; } </s>

getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer .


<s> bool isImm ( ) const { return Kind == k_Immediate ; } </s>


<s>
const
char
*
emit_fusion_p9_load
(
rtx
reg
,
rtx
mem
,
rtx
tmp_reg
)
{
machine_mode
mode
=
GET_MODE
(
reg
)
;
rtx
hi
;
rtx
lo
;
rtx
addr
;
const
char
*
load_string
;
int
r
;
if
(
GET_CODE
(
mem
)
==
FLOAT_EXTEND
||
GET_CODE
(
mem
)
==
ZERO_EXTEND
)
{
mem
=
XEXP
(
mem
,
0
)
;
mode
=
GET_MODE
(
mem
)
;
}
if
(
GET_CODE
(
reg
)
==
SUBREG
)
{
gcc_assert
(
SUBREG_BYTE
(
reg
)
==
0
)
;
reg
=
SUBREG_REG
(
reg
)
;
}
if
(
!
REG_P
(
reg
)
)
fatal_insn
(
"emit_fusion_p9_load, bad reg #1"
,
reg
)
;
r
=
REGNO
(
reg
)
;
if
(
FP_REGNO_P
(
r
)
)
{
if
(
mode
==
SFmode
)
load_string
=
"lfs"
;
else
if
(
mode
==
DFmode
||
mode
==
DImode
)
load_string
=
"lfd"
;
else
gcc_unreachable
(
)
;
}
else
if
(
ALTIVEC_REGNO_P
(
r
)
&&
TARGET_P9_VECTOR
)
{
if
(
mode
==
SFmode
)
load_string
=
"lxssp"
;
else
if
(
mode
==
DFmode
||
mode
==
DImode
)
load_string
=
"lxsd"
;
else
gcc_unreachable
(
)
;
}
else
if
(
INT_REGNO_P
(
r
)
)
{
switch
(
mode
)
{
case
E_QImode
:
load_string
=
"lbz"
;
break
;
case
E_HImode
:
load_string
=
"lhz"
;
break
;
case
E_SImode
:
case
E_SFmode
:
load_string
=
"lwz"
;
break
;
case
E_DImode
:
case
E_DFmode
:
if
(
!
TARGET_POWERPC64
)
gcc_unreachable
(
)
;
load_string
=
"ld"
;
break
;
default
:
gcc_unreachable
(
)
;
}
}
else
fatal_insn
(
"emit_fusion_p9_load, bad reg #2"
,
reg
)
;
if
(
!
MEM_P
(
mem
)
)
fatal_insn
(
"emit_fusion_p9_load not MEM"
,
mem
)
;
addr
=
XEXP
(
mem
,
0
)
;
fusion_split_address
(
addr
,
&
hi
,
&
lo
)
;
emit_fusion_addis
(
tmp_reg
,
hi
)
;
emit_fusion_load_store
(
reg
,
tmp_reg
,
lo
,
load_string
)
;
return
""
;
}
</s>

Return a string to fuse an addis instruction with a load using extended fusion . The address that is used is the logical address that was formed during peephole2 : ( lo_sum ( high ) ( low-part ) ) The code is complicated , so we call output_asm_insn directly , and just return `` '' .

rs6000
0
0
"emit_fusion_p9_load, bad reg #1"
"lfs"
"lfd"
"lxssp"
"lxsd"
"lbz"
"lhz"
"lwz"
"ld"
"emit_fusion_p9_load, bad reg #2"
"emit_fusion_p9_load not MEM"
0
""


<s> bool shouldInsertFencesForAtomic ( const Instruction * I ) const override { return true ; } </s>

Helper functions for atomic operations .


<s> bool isValid ( ) const { return ScalableBytes % 2 == 0 ; } </s>

Returns true if this iterator is still pointing at a valid entry .


<s> void AArch64BranchFixup :: verify ( ) { for ( MachineFunction :: iterator MBBI = MF -> begin ( ) , E = MF -> end ( ) ; MBBI != E ; ++ MBBI ) { MachineBasicBlock * MBB = MBBI ; unsigned MBBId = MBB -> getNumber ( ) ; assert ( ! MBBId || BBInfo [ MBBId - 1 ] . postOffset ( ) <= BBInfo [ MBBId ] . Offset ) ; } } </s>


<s> int mmix_dbx_register_number ( int regno ) { regno = MMIX_OUTPUT_REGNO ( regno ) ; return regno >= 224 ? ( regno - 224 ) : ( regno + 48 ) ; } </s>


"Should only have an r11 thunk on 64-bit targets"


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { AU . addRequired < MachineDominatorTree > ( ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ; } </s>

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


"parameter passing for argument of type "

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


<s> bool runOnMachineFunction ( MachineFunction & MF ) { for ( MachineFunction :: iterator bItr = MF . begin ( ) ; bItr != MF . end ( ) ; ++ bItr ) { bool foundTestFunc = false ; for ( MachineBasicBlock :: iterator iItr = bItr -> begin ( ) ; iItr != bItr -> end ( ) ; ++ iItr ) { if ( foundTestFunc ) { errs ( ) << * iItr << "\n" ; } if ( iItr -> isCall ( ) ) { MachineOperand MO = iItr -> getOperand ( 0 ) ; const GlobalValue * GV = MO . getGlobal ( ) ; std :: string funcName = GV -> getName ( ) ; if ( ! compareCallToFunctionNames ( funcName ) ) { foundTestFunc = false ; } else { foundTestFunc = true ; } } } } return true ; } </s>


<s> bool SystemZTargetLowering :: isFMAFasterThanFMulAndFAdd ( const MachineFunction & MF , EVT VT ) const { VT = VT . getScalarType ( ) ; if ( ! VT . isSimple ( ) ) return false ; switch ( VT . getSimpleVT ( ) . SimpleTy ) { case MVT :: f32 : case MVT :: f64 : return true ; case MVT :: f128 : return Subtarget . hasVectorEnhancements1 ( ) ; default : break ; } return false ; } </s>

Return true if an FMA operation is faster than a pair of fmul and fadd instructions .


<s> SDValue MipsTargetLowering :: LowerCallResult ( SDValue Chain , SDValue InFlag , CallingConv :: ID CallConv , bool IsVarArg , const SmallVectorImpl < ISD :: InputArg > & Ins , SDLoc DL , SelectionDAG & DAG , SmallVectorImpl < SDValue > & InVals , const SDNode * CallNode , const Type * RetTy ) const { SmallVector < CCValAssign , 16 > RVLocs ; CCState CCInfo ( CallConv , IsVarArg , DAG . getMachineFunction ( ) , RVLocs , * DAG . getContext ( ) ) ; MipsCC MipsCCInfo ( CallConv , Subtarget . isABI_O32 ( ) , Subtarget . isFP64bit ( ) , CCInfo ) ; MipsCCInfo . analyzeCallResult ( Ins , Subtarget . abiUsesSoftFloat ( ) , CallNode , RetTy ) ; for ( unsigned i = 0 ; i != RVLocs . size ( ) ; ++ i ) { SDValue Val = DAG . getCopyFromReg ( Chain , DL , RVLocs [ i ] . getLocReg ( ) , RVLocs [ i ] . getLocVT ( ) , InFlag ) ; Chain = Val . getValue ( 1 ) ; InFlag = Val . getValue ( 2 ) ; if ( RVLocs [ i ] . getValVT ( ) != RVLocs [ i ] . getLocVT ( ) ) Val = DAG . getNode ( ISD :: BITCAST , DL , RVLocs [ i ] . getValVT ( ) , Val ) ; InVals . push_back ( Val ) ; } return Chain ; } </s>

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


<s> bool MipsTargetLowering :: CanLowerReturn ( CallingConv :: ID CallConv , MachineFunction & MF , bool IsVarArg , const SmallVectorImpl < ISD :: OutputArg > & Outs , LLVMContext & Context ) const { SmallVector < CCValAssign , 16 > RVLocs ; CCState CCInfo ( CallConv , IsVarArg , MF , getTargetMachine ( ) , RVLocs , Context ) ; return CCInfo . CheckReturn ( Outs , RetCC_Mips ) ; } </s>

This hook should be implemented to check whether the return values described by the Outs array can fit into the return registers .


<s> static rtx ix86_ssecom_setcc ( const enum rtx_code comparison , bool check_unordered , machine_mode mode , rtx set_dst , rtx target ) { rtx_code_label * label = NULL ; if ( check_unordered ) { gcc_assert ( comparison == EQ || comparison == NE ) ; rtx flag = gen_rtx_REG ( CCFPmode , FLAGS_REG ) ; label = gen_label_rtx ( ) ; rtx tmp = gen_rtx_fmt_ee ( UNORDERED , VOIDmode , flag , const0_rtx ) ; tmp = gen_rtx_IF_THEN_ELSE ( VOIDmode , tmp , gen_rtx_LABEL_REF ( VOIDmode , label ) , pc_rtx ) ; emit_jump_insn ( gen_rtx_SET ( pc_rtx , tmp ) ) ; } if ( GET_MODE ( set_dst ) != mode ) { gcc_assert ( mode == CCAmode || mode == CCCmode || mode == CCOmode || mode == CCPmode || mode == CCSmode || mode == CCZmode ) ; set_dst = gen_rtx_REG ( mode , FLAGS_REG ) ; } emit_insn ( gen_rtx_SET ( gen_rtx_STRICT_LOW_PART ( VOIDmode , target ) , gen_rtx_fmt_ee ( comparison , QImode , set_dst , const0_rtx ) ) ) ; if ( label ) emit_label ( label ) ; return SUBREG_REG ( target ) ; } </s>

Subroutine of ix86_sse_comi and ix86_sse_comi_round to take care of * ordered EQ or unordered NE , generate PF jump .


"sret virtual register not created in the entry block"

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


"\n# of loads of an address of an external symbol = %lu\n"

"# of PCREL_OPT loads = %lu (adjacent %lu)\n"

"# of PCREL_OPT stores = %lu (adjacent %lu)\n"

Optimize pcrel external variable references .


<s> BitVector AArch64RegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const AArch64FrameLowering * TFI = getFrameLowering ( MF ) ; BitVector Reserved ( getNumRegs ( ) ) ; markSuperRegs ( Reserved , AArch64 :: SP ) ; markSuperRegs ( Reserved , AArch64 :: XZR ) ; markSuperRegs ( Reserved , AArch64 :: WSP ) ; markSuperRegs ( Reserved , AArch64 :: WZR ) ; if ( TFI -> hasFP ( MF ) || TT . isOSDarwin ( ) ) { markSuperRegs ( Reserved , AArch64 :: FP ) ; markSuperRegs ( Reserved , AArch64 :: W29 ) ; } if ( MF . getSubtarget < AArch64Subtarget > ( ) . isX18Reserved ( ) ) { markSuperRegs ( Reserved , AArch64 :: X18 ) ; markSuperRegs ( Reserved , AArch64 :: W18 ) ; } if ( hasBasePointer ( MF ) ) { markSuperRegs ( Reserved , AArch64 :: X19 ) ; markSuperRegs ( Reserved , AArch64 :: W19 ) ; } assert ( checkAllSuperRegsMarked ( Reserved ) ) ; return Reserved ; } </s>

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


<s> void fixup_addr_diff_vecs ( rtx first ) { rtx insn ; for ( insn = first ; insn ; insn = NEXT_INSN ( insn ) ) { rtx vec_lab , pat , prev , prevpat , x , braf_label ; if ( GET_CODE ( insn ) != JUMP_INSN || GET_CODE ( PATTERN ( insn ) ) != ADDR_DIFF_VEC ) continue ; pat = PATTERN ( insn ) ; vec_lab = XEXP ( XEXP ( pat , 0 ) , 0 ) ; for ( prev = vec_lab ; ; prev = PREV_INSN ( prev ) ) { if ( GET_CODE ( prev ) != JUMP_INSN ) continue ; prevpat = PATTERN ( prev ) ; if ( GET_CODE ( prevpat ) != PARALLEL || XVECLEN ( prevpat , 0 ) != 2 ) continue ; x = XVECEXP ( prevpat , 0 , 1 ) ; if ( GET_CODE ( x ) != USE ) continue ; x = XEXP ( x , 0 ) ; if ( GET_CODE ( x ) == LABEL_REF && XEXP ( x , 0 ) == vec_lab ) break ; } if ( ! prev ) continue ; braf_label = XEXP ( XEXP ( SET_SRC ( XVECEXP ( prevpat , 0 , 0 ) ) , 1 ) , 0 ) ; emit_label_after ( braf_label , prev ) ; XEXP ( XEXP ( pat , 0 ) , 0 ) = braf_label ; } } </s>


<s> const unsigned * MipsRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { static const unsigned SingleFloatOnlyCalleeSavedRegs [ ] = { Mips :: F31 , Mips :: F30 , Mips :: F29 , Mips :: F28 , Mips :: F27 , Mips :: F26 , Mips :: F25 , Mips :: F24 , Mips :: F23 , Mips :: F22 , Mips :: F21 , Mips :: F20 , Mips :: RA , Mips :: FP , Mips :: S7 , Mips :: S6 , Mips :: S5 , Mips :: S4 , Mips :: S3 , Mips :: S2 , Mips :: S1 , Mips :: S0 , 0 } ; static const unsigned Mips32CalleeSavedRegs [ ] = { Mips :: D15 , Mips :: D14 , Mips :: D13 , Mips :: D12 , Mips :: D11 , Mips :: D10 , Mips :: RA , Mips :: FP , Mips :: S7 , Mips :: S6 , Mips :: S5 , Mips :: S4 , Mips :: S3 , Mips :: S2 , Mips :: S1 , Mips :: S0 , 0 } ; static const unsigned N32CalleeSavedRegs [ ] = { Mips :: D31_64 , Mips :: D29_64 , Mips :: D27_64 , Mips :: D25_64 , Mips :: D23_64 , Mips :: D21_64 , Mips :: RA_64 , Mips :: FP_64 , Mips :: GP_64 , Mips :: S7_64 , Mips :: S6_64 , Mips :: S5_64 , Mips :: S4_64 , Mips :: S3_64 , Mips :: S2_64 , Mips :: S1_64 , Mips :: S0_64 , 0 } ; static const unsigned N64CalleeSavedRegs [ ] = { Mips :: D31_64 , Mips :: D30_64 , Mips :: D29_64 , Mips :: D28_64 , Mips :: D27_64 , Mips :: D26_64 , Mips :: D25_64 , Mips :: D24_64 , Mips :: RA_64 , Mips :: FP_64 , Mips :: GP_64 , Mips :: S7_64 , Mips :: S6_64 , Mips :: S5_64 , Mips :: S4_64 , Mips :: S3_64 , Mips :: S2_64 , Mips :: S1_64 , Mips :: S0_64 , 0 } ; if ( Subtarget . isSingleFloat ( ) ) return SingleFloatOnlyCalleeSavedRegs ; else if ( ! Subtarget . hasMips64 ( ) ) return Mips32CalleeSavedRegs ; else if ( Subtarget . isABI_N32 ( ) ) return N32CalleeSavedRegs ; assert ( Subtarget . isABI_N64 ( ) ) ; return N64CalleeSavedRegs ; } </s>


<s>
MachineInstr
*
ARMBaseInstrInfo
::
optimizeSelect
(
MachineInstr
*
MI
,
SmallPtrSetImpl
<
MachineInstr
*
>
&
SeenMIs
,
bool
PreferFalse
)
const
{
assert
(
(
MI
->
getOpcode
(
)
==
ARM
::
MOVCCr
||
MI
->
getOpcode
(
)
==
ARM
::
t2MOVCCr
)
&&
"Unknown select instruction"
)
;
MachineRegisterInfo
&
MRI
=
MI
->
getParent
(
)
->
getParent
(
)
->
getRegInfo
(
)
;
MachineInstr
*
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
2
)
.
getReg
(
)
,
MRI
,
this
)
;
bool
Invert
=
!
DefMI
;
if
(
!
DefMI
)
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
1
)
.
getReg
(
)
,
MRI
,
this
)
;
if
(
!
DefMI
)
return
nullptr
;
MachineOperand
FalseReg
=
MI
->
getOperand
(
Invert
2
:
1
)
;
unsigned
DestReg
=
MI
->
getOperand
(
0
)
.
getReg
(
)
;
const
TargetRegisterClass
*
PreviousClass
=
MRI
.
getRegClass
(
FalseReg
.
getReg
(
)
)
;
if
(
!
MRI
.
constrainRegClass
(
DestReg
,
PreviousClass
)
)
return
nullptr
;
MachineInstrBuilder
NewMI
=
BuildMI
(
*
MI
->
getParent
(
)
,
MI
,
MI
->
getDebugLoc
(
)
,
DefMI
->
getDesc
(
)
,
DestReg
)
;
const
MCInstrDesc
&
DefDesc
=
DefMI
->
getDesc
(
)
;
for
(
unsigned
i
=
1
,
e
=
DefDesc
.
getNumOperands
(
)
;
i
!=
e
&&
!
DefDesc
.
OpInfo
[
i
]
.
isPredicate
(
)
;
++
i
)
NewMI
.
addOperand
(
DefMI
->
getOperand
(
i
)
)
;
unsigned
CondCode
=
MI
->
getOperand
(
3
)
.
getImm
(
)
;
if
(
Invert
)
NewMI
.
addImm
(
ARMCC
::
getOppositeCondition
(
ARMCC
::
CondCodes
(
CondCode
)
)
)
;
else
NewMI
.
addImm
(
CondCode
)
;
NewMI
.
addOperand
(
MI
->
getOperand
(
4
)
)
;
if
(
NewMI
->
hasOptionalDef
(
)
)
AddDefaultCC
(
NewMI
)
;
FalseReg
.
setImplicit
(
)
;
NewMI
.
addOperand
(
FalseReg
)
;
NewMI
->
tieOperands
(
0
,
NewMI
->
getNumOperands
(
)
1
)
;
SeenMIs
.
insert
(
NewMI
)
;
SeenMIs
.
erase
(
DefMI
)
;
if
(
DefMI
->
getParent
(
)
!=
MI
->
getParent
(
)
)
NewMI
->
clearKillInfo
(
)
;
DefMI
->
eraseFromParent
(
)
;
return
NewMI
;
}
</s>

Given a select instruction that was understood by analyzeSelect and returned Optimizable = true , attempt to optimize MI by merging it with one of its operands .


<s> void ARMBankConflictHazardRecognizer :: EmitInstruction ( SUnit * SU ) { MachineInstr & MI = * SU -> getInstr ( ) ; if ( ! MI . mayLoad ( ) || MI . mayStore ( ) || MI . getNumMemOperands ( ) != 1 ) return ; auto MO = * MI . memoperands ( ) . begin ( ) ; uint64_t Size1 = MO -> getSize ( ) ; if ( Size1 > 4 ) return ; Accesses . push_back ( & MI ) ; } </s>

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


<s> int arm_attr_length_move_neon ( rtx_insn * insn ) { rtx reg , mem , addr ; int load ; machine_mode mode ; extract_insn_cached ( insn ) ; if ( REG_P ( recog_data . operand [ 0 ] ) && REG_P ( recog_data . operand [ 1 ] ) ) { mode = GET_MODE ( recog_data . operand [ 0 ] ) ; switch ( mode ) { case E_EImode : case E_OImode : return 8 ; case E_CImode : return 12 ; case E_XImode : return 16 ; default : gcc_unreachable ( ) ; } } load = REG_P ( recog_data . operand [ 0 ] ) ; reg = recog_data . operand [ ! load ] ; mem = recog_data . operand [ load ] ; gcc_assert ( MEM_P ( mem ) ) ; addr = XEXP ( mem , 0 ) ; if ( GET_CODE ( addr ) == CONST && GET_CODE ( XEXP ( addr , 0 ) ) == PLUS ) addr = XEXP ( addr , 0 ) ; if ( LABEL_REF_P ( addr ) || GET_CODE ( addr ) == PLUS ) { int insns = REG_NREGS ( reg ) / 2 ; return insns * 4 ; } else return 4 ; } </s>

Compute and return the length of neon_mov < mode > , where < mode > is one of VSTRUCT modes : EI , OI , CI or XI .


<s> void generate_6432_conversion ( rtx target , rtx sub_result ) { if ( TARGET_64BIT ) { rtx tmp_reg_ca = gen_reg_rtx ( DImode ) ; emit_insn ( gen_subfdi3_carry_in_xx ( tmp_reg_ca ) ) ; rtx popcnt = gen_reg_rtx ( DImode ) ; emit_insn ( gen_popcntddi2 ( popcnt , sub_result ) ) ; rtx tmp2 = gen_reg_rtx ( DImode ) ; emit_insn ( gen_iordi3 ( tmp2 , popcnt , tmp_reg_ca ) ) ; emit_insn ( gen_movsi ( target , gen_lowpart ( SImode , tmp2 ) ) ) ; } else { rtx tmp_reg_ca = gen_reg_rtx ( SImode ) ; emit_insn ( gen_subfsi3_carry_in_xx ( tmp_reg_ca ) ) ; rtx popcnt = gen_reg_rtx ( SImode ) ; emit_insn ( gen_popcntdsi2 ( popcnt , sub_result ) ) ; emit_insn ( gen_iorsi3 ( target , popcnt , tmp_reg_ca ) ) ; } } </s>

Generate code to convert a DImode-plus-carry subtract result into a SImode result that has the same < 0 / ==0 / > 0 properties to produce the final result from memcmp . TARGET is the rtx for the register to receive the memcmp result . SUB_RESULT is the rtx for the register contining the subtract result .


<s> bool ARMTargetLowering :: isShuffleMaskLegal ( const SmallVectorImpl < int > & M , EVT VT ) const { if ( VT . getVectorNumElements ( ) == 4 && ( VT . is128BitVector ( ) || VT . is64BitVector ( ) ) ) { unsigned PFIndexes [ 4 ] ; for ( unsigned i = 0 ; i != 4 ; ++ i ) { if ( M [ i ] < 0 ) PFIndexes [ i ] = 8 ; else PFIndexes [ i ] = M [ i ] ; } unsigned PFTableIndex = PFIndexes [ 0 ] * 9 * 9 * 9 + PFIndexes [ 1 ] * 9 * 9 + PFIndexes [ 2 ] * 9 + PFIndexes [ 3 ] ; unsigned PFEntry = PerfectShuffleTable [ PFTableIndex ] ; unsigned Cost = ( PFEntry >> 30 ) ; if ( Cost <= 4 ) return true ; } bool ReverseVEXT ; unsigned Imm , WhichResult ; unsigned EltSize = VT . getVectorElementType ( ) . getSizeInBits ( ) ; return ( EltSize >= 32 || ShuffleVectorSDNode :: isSplatMask ( & M [ 0 ] , VT ) || isVREVMask ( M , VT , 64 ) || isVREVMask ( M , VT , 32 ) || isVREVMask ( M , VT , 16 ) || isVEXTMask ( M , VT , ReverseVEXT , Imm ) || isVTBLMask ( M , VT ) || isVTRNMask ( M , VT , WhichResult ) || isVUZPMask ( M , VT , WhichResult ) || isVZIPMask ( M , VT , WhichResult ) || isVTRN_v_undef_Mask ( M , VT , WhichResult ) || isVUZP_v_undef_Mask ( M , VT , WhichResult ) || isVZIP_v_undef_Mask ( M , VT , WhichResult ) || ( ( VT == MVT :: v8i16 || VT == MVT :: v16i8 ) && isReverseMask ( M , VT ) ) ) ; } </s>

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


<s> const TargetRegisterClass * MipsSERegisterInfo :: intRegClass ( unsigned Size ) const { if ( Size == 4 ) return & Mips :: CPURegsRegClass ; assert ( Size == 8 ) ; return & Mips :: CPU64RegsRegClass ; } </s>


<s> bool ARMAsmBackend :: writeNopData ( uint64_t Count , MCObjectWriter * OW ) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0 ; const uint16_t Thumb2_16bitNopEncoding = 0xbf00 ; const uint32_t ARMv4_NopEncoding = 0xe1a0000 ; const uint32_t ARMv6T2_NopEncoding = 0xe320f000 ; if ( isThumb ( ) ) { const uint16_t nopEncoding = hasNOP ( ) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding ; uint64_t NumNops = Count / 2 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> Write16 ( nopEncoding ) ; if ( Count & 1 ) OW -> Write8 ( 0 ) ; return true ; } const uint32_t nopEncoding = hasNOP ( ) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding ; uint64_t NumNops = Count / 4 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> Write32 ( nopEncoding ) ; switch ( Count % 4 ) { default : break ; case 1 : OW -> Write8 ( 0 ) ; break ; case 2 : OW -> Write16 ( 0 ) ; break ; case 3 : OW -> Write16 ( 0 ) ; OW -> Write8 ( 0xa0 ) ; break ; } return true ; } </s>

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


<s> void crx_expand_prologue ( void ) { crx_compute_frame ( ) ; crx_compute_save_regs ( ) ; if ( size_for_adjusting_sp + sum_regs == 0 ) return ; if ( last_reg_to_save != - 1 ) emit_insn ( gen_push_for_prologue ( GEN_INT ( sum_regs ) ) ) ; if ( size_for_adjusting_sp > 0 ) emit_insn ( gen_addsi3 ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( - size_for_adjusting_sp ) ) ) ; if ( frame_pointer_needed ) emit_move_insn ( frame_pointer_rtx , stack_pointer_rtx ) ; } </s>

CompactRISC CRX Architecture stack layout : 0 + -- -- -- -- -- -- -- -- -- -- - | . . | +==================== Sp ( x ) =Ap ( x+1 ) A | Args for functions | | called by X and Dynamically | | Dynamic allocations allocated and | | ( alloca , variable deallocated Stack | length arrays ) . grows + -- -- -- -- -- -- -- -- -- -- Fp ( x ) down| | Local variables of X ward| + -- -- -- -- -- -- -- -- -- -- | | Regs saved for X-1 | +==================== Sp ( x-1 ) =Ap ( x ) | Args for func X | pushed by X-1 + -- -- -- -- -- -- -- -- -- -- Fp ( x-1 ) | | V


<s> static int ix86_i387_mode_needed ( int entity , rtx_insn * insn ) { enum attr_i387_cw mode ; if ( CALL_P ( insn ) || ( NONJUMP_INSN_P ( insn ) && ( asm_noperands ( PATTERN ( insn ) ) >= 0 || GET_CODE ( PATTERN ( insn ) ) == ASM_INPUT ) ) ) return I387_CW_UNINITIALIZED ; if ( recog_memoized ( insn ) < 0 ) return I387_CW_ANY ; mode = get_attr_i387_cw ( insn ) ; switch ( entity ) { case I387_TRUNC : if ( mode == I387_CW_TRUNC ) return mode ; break ; case I387_FLOOR : if ( mode == I387_CW_FLOOR ) return mode ; break ; case I387_CEIL : if ( mode == I387_CW_CEIL ) return mode ; break ; case I387_MASK_PM : if ( mode == I387_CW_MASK_PM ) return mode ; break ; default : gcc_unreachable ( ) ; } return I387_CW_ANY ; } </s>

Return mode that i387 must be switched into prior to the execution of insn .


<s> VariantKind getKind ( ) const { return static_cast < VariantKind > ( Kind ) ; } </s>


<s>
SDValue
LanaiTargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
case
ISD
::
MUL
:
return
LowerMUL
(
Op
,
DAG
)
;
case
ISD
::
BR_CC
:
return
LowerBR_CC
(
Op
,
DAG
)
;
case
ISD
::
ConstantPool
:
return
LowerConstantPool
(
Op
,
DAG
)
;
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
BlockAddress
:
return
LowerBlockAddress
(
Op
,
DAG
)
;
case
ISD
::
JumpTable
:
return
LowerJumpTable
(
Op
,
DAG
)
;
case
ISD
::
SELECT_CC
:
return
LowerSELECT_CC
(
Op
,
DAG
)
;
case
ISD
::
SETCC
:
return
LowerSETCC
(
Op
,
DAG
)
;
case
ISD
::
SETCCE
:
return
LowerSETCCE
(
Op
,
DAG
)
;
case
ISD
::
SHL_PARTS
:
return
LowerSHL_PARTS
(
Op
,
DAG
)
;
case
ISD
::
SRL_PARTS
:
return
LowerSRL_PARTS
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
LowerVASTART
(
Op
,
DAG
)
;
case
ISD
::
DYNAMIC_STACKALLOC
:
return
LowerDYNAMIC_STACKALLOC
(
Op
,
DAG
)
;
case
ISD
::
RETURNADDR
:
return
LowerRETURNADDR
(
Op
,
DAG
)
;
case
ISD
::
FRAMEADDR
:
return
LowerFRAMEADDR
(
Op
,
DAG
)
;
default
:
llvm_unreachable
(
"unimplemented operand"
)
;
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .

Lanai
Lanai
ISD::MUL
ISD::BR_CC
ISD::ConstantPool
ISD::GlobalAddress
ISD::BlockAddress
ISD::JumpTable
ISD::SELECT_CC
ISD::SETCC
ISD::SETCCE
ISD::SHL_PARTS
ISD::SRL_PARTS
ISD::VASTART
ISD::DYNAMIC_STACKALLOC
ISD::RETURNADDR
ISD::FRAMEADDR
"unimplemented operand"


<s> static int ia64_adjust_cost ( rtx_insn * insn , int dep_type1 , rtx_insn * dep_insn , int cost , dw_t dw ) { enum reg_note dep_type = ( enum reg_note ) dep_type1 ; enum attr_itanium_class dep_class ; enum attr_itanium_class insn_class ; insn_class = ia64_safe_itanium_class ( insn ) ; dep_class = ia64_safe_itanium_class ( dep_insn ) ; if ( dep_type == REG_DEP_TRUE && ( dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF ) && ( insn_class == ITANIUM_CLASS_BR || insn_class == ITANIUM_CLASS_SCALL ) ) return 0 ; if ( dw == MIN_DEP_WEAK ) return PARAM_VALUE ( PARAM_SCHED_MEM_TRUE_DEP_COST ) ; else if ( dw > MIN_DEP_WEAK ) { if ( mflag_sched_fp_mem_deps_zero_cost && dep_class == ITANIUM_CLASS_STF ) return 0 ; else return cost ; } if ( dep_type != REG_DEP_OUTPUT ) return cost ; if ( dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF || insn_class == ITANIUM_CLASS_ST || insn_class == ITANIUM_CLASS_STF ) return 0 ; return cost ; } </s>

Adjust the cost of a scheduling dependency . Return the new cost of a dependency LINK or INSN on DEP_INSN . COST is the current cost .


<s> static void move_to_end_of_ready ( rtx_insn * * ready , int pos , int lastpos ) { rtx_insn * tmp ; int i ; tmp = ready [ pos ] ; for ( i = pos ; i < lastpos ; i ++ ) ready [ i ] = ready [ i + 1 ] ; ready [ lastpos ] = tmp ; } </s>

Move instruction at POS to the end of the READY list .


<s>
void
AArch64AsmBackend
::
applyFixup
(
const
MCFixup
&
Fixup
,
char
*
Data
,
unsigned
DataSize
,
uint64_t
Value
,
bool
IsPCRel
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
if
(
!
Value
)
return
;
MCFixupKindInfo
Info
=
getFixupKindInfo
(
Fixup
.
getKind
(
)
)
;
Value
=
adjustFixupValue
(
Fixup
,
Value
,
nullptr
)
;
Value
<<=
Info
.
TargetOffset
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
DataSize
&&
"Invalid fixup offset!"
)
;
unsigned
FulleSizeInBytes
=
getFixupKindContainereSizeInBytes
(
Fixup
.
getKind
(
)
)
;
if
(
FulleSizeInBytes
==
0
)
{
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
Data
[
Offset
+
i
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
else
{
assert
(
(
Offset
+
FulleSizeInBytes
)
<=
DataSize
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FulleSizeInBytes
&&
"Invalid fixup size!"
)
;
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
FulleSizeInBytes
1
i
;
Data
[
Offset
+
Idx
]
|=
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> unsigned PPCFrameLowering :: getFramePointerSaveOffset ( ) const { return FramePointerSaveOffset ; } </s>

getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer .