<s> bool RISCVTargetLowering :: getTgtMemIntrinsic ( IntrinsicInfo & Info , const CallInst & I , MachineFunction & MF , unsigned Intrinsic ) const { switch ( Intrinsic ) { default : return false ; case Intrinsic :: riscv_masked_atomicrmw_xchg_i32 : case Intrinsic :: riscv_masked_atomicrmw_add_i32 : case Intrinsic :: riscv_masked_atomicrmw_sub_i32 : case Intrinsic :: riscv_masked_atomicrmw_nand_i32 : case Intrinsic :: riscv_masked_atomicrmw_max_i32 : case Intrinsic :: riscv_masked_atomicrmw_min_i32 : case Intrinsic :: riscv_masked_atomicrmw_umax_i32 : case Intrinsic :: riscv_masked_atomicrmw_umin_i32 : case Intrinsic :: riscv_masked_cmpxchg_i32 : PointerType * PtrTy = cast < PointerType > ( I . getArgOperand ( 0 ) -> getType ( ) ) ; Info . opc = ISD :: INTRINSIC_W_CHAIN ; Info . memVT = MVT :: getVT ( PtrTy -> getElementType ( ) ) ; Info . ptrVal = I . getArgOperand ( 0 ) ; Info . offset = 0 ; Info . align = Align ( 4 ) ; Info . flags = MachineMemOperand :: MOLoad | MachineMemOperand :: MOStore | MachineMemOperand :: MOVolatile ; return true ; } } </s>


<s> static bool scalar_move_insn_p ( rtx_insn * rinsn ) { return get_attr_type ( rinsn ) == TYPE_VIMOVXV || get_attr_type ( rinsn ) == TYPE_VFMOVFV ; } </s>

Return true if the instruction is scalar move instruction .


<s> bool RISCVAsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count ) const { bool HasStdExtC = STI . getFeatureBits ( ) [ RISCV :: FeatureStdExtC ] ; unsigned MinNopLen = HasStdExtC ? 2 : 4 ; if ( ( Count % MinNopLen ) != 0 ) return false ; uint64_t Nop32Count = Count / 4 ; for ( uint64_t i = Nop32Count ; i != 0 ; -- i ) OS . write ( "\x13\0\0\0" , 4 ) ; if ( HasStdExtC ) { uint64_t Nop16Count = ( Count - Nop32Count * 4 ) / 2 ; for ( uint64_t i = Nop16Count ; i != 0 ; -- i ) OS . write ( "\x01\0" , 2 ) ; } return true ; } </s>

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


<s> bool RISCVPassConfig :: addInstSelector ( ) { addPass ( createRISCVISelDag ( getRISCVTargetMachine ( ) ) ) ; return false ; } </s>

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


<s> bool RISCVPassConfig :: addIRTranslator ( ) { addPass ( new IRTranslator ( getOptLevel ( ) ) ) ; return false ; } </s>

This method should install an IR translator pass , which converts from LLVM code to machine instructions with possibly generic opcodes .


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

Returns true if the target requires post PEI scavenging of registers for materializing frame index constants .


<s> bool shouldInsertFencesForAtomic ( const Instruction * I ) const override { return isa < LoadInst > ( I ) || isa < StoreInst > ( I ) ; } </s>

Helper functions for atomic operations .


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

getPassName - Return a nice clean name for a pass .


"ReadCycleWrite is only to be used on riscv32"

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


<s> bool isLegalMaskedGather ( Type * DataType , Align Alignment ) { return isLegalMaskedGatherScatter ( DataType , Alignment ) ; } </s>

Return true if the target supports masked gather .


<s> static bool riscv_int_order_operand_ok_p ( enum rtx_code code , rtx cmp1 ) { switch ( code ) { case GT : case GTU : return reg_or_0_operand ( cmp1 , VOIDmode ) ; case GE : case GEU : return cmp1 == const1_rtx ; case LT : case LTU : return arith_operand ( cmp1 , VOIDmode ) ; case LE : return sle_operand ( cmp1 , VOIDmode ) ; case LEU : return sleu_operand ( cmp1 , VOIDmode ) ; default : gcc_unreachable ( ) ; } } </s>

Return true if CMP1 is a suitable second operand for integer ordering test CODE . See also the * sCC patterns in riscv.md .


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

Simple predicate for targets where ! Resolved implies requiring relaxation .


<s> bool RISCVPassConfig :: addGlobalInstructionSelect ( ) { addPass ( new InstructionSelect ( getOptLevel ( ) ) ) ; return false ; } </s>

This method should install a ( global ) instruction selector pass , which converts possibly generic instructions to fully target-specific instructions , thereby constraining all generic virtual registers to register classes .


<s> static void th_mempair_restore_regs ( rtx operands [ 4 ] ) { rtx set1 = gen_rtx_SET ( operands [ 0 ] , operands [ 1 ] ) ; rtx set2 = gen_rtx_SET ( operands [ 2 ] , operands [ 3 ] ) ; rtx insn = emit_insn ( gen_rtx_PARALLEL ( VOIDmode , gen_rtvec ( 2 , set1 , set2 ) ) ) ; RTX_FRAME_RELATED_P ( insn ) = 1 ; add_reg_note ( insn , REG_CFA_RESTORE , operands [ 0 ] ) ; add_reg_note ( insn , REG_CFA_RESTORE , operands [ 2 ] ) ; } </s>

Similar like riscv_restore_reg , but restores two registers from memory and marks the instruction frame-related .


<s>
const
char
*
th_mempair_output_move
(
rtx
operands
[
4
]
,
bool
load_p
,
machine_mode
mode
,
RTX_CODE
code
)
{
rtx
reg1
,
reg2
,
mem1
,
mem2
,
base1
,
base2
;
HOST_WIDE_INT
offset1
,
offset2
;
rtx
output_operands
[
5
]
;
const
char
*
format
;
gcc_assert
(
mode
==
SImode
||
mode
==
DImode
)
;
unsigned
shamt
=
(
mode
==
DImode
)
4
:
3
;
if
(
load_p
)
{
reg1
=
copy_rtx
(
operands
[
0
]
)
;
reg2
=
copy_rtx
(
operands
[
2
]
)
;
mem1
=
copy_rtx
(
operands
[
1
]
)
;
mem2
=
copy_rtx
(
operands
[
3
]
)
;
if
(
mode
==
SImode
)
if
(
code
==
ZERO_EXTEND
)
format
=
"th.lwud\t%0, %1, (%2), %3, %4"
;
else
format
=
"th.lwd\t%0, %1, (%2), %3, %4"
;
else
format
=
"th.ldd\t%0, %1, (%2), %3, %4"
;
}
else
{
reg1
=
copy_rtx
(
operands
[
1
]
)
;
reg2
=
copy_rtx
(
operands
[
3
]
)
;
mem1
=
copy_rtx
(
operands
[
0
]
)
;
mem2
=
copy_rtx
(
operands
[
2
]
)
;
if
(
mode
==
SImode
)
format
=
"th.swd\t%z0, %z1, (%2), %3, %4"
;
else
format
=
"th.sdd\t%z0, %z1, (%2), %3, %4"
;
}
split_plus
(
XEXP
(
mem1
,
0
)
,
&
base1
,
&
offset1
)
;
split_plus
(
XEXP
(
mem2
,
0
)
,
&
base2
,
&
offset2
)
;
gcc_assert
(
rtx_equal_p
(
base1
,
base2
)
)
;
auto
size1
=
MEM_SIZE
(
mem1
)
;
auto
size2
=
MEM_SIZE
(
mem2
)
;
gcc_assert
(
known_eq
(
size1
,
size2
)
)
;
gcc_assert
(
known_eq
(
offset1
+
size1
,
offset2
)
)
;
HOST_WIDE_INT
imm2
=
offset1
>>
shamt
;
gcc_assert
(
imm2
>=
0
&&
imm2
<
4
)
;
gcc_assert
(
(
imm2
<<
shamt
)
==
offset1
)
;
gcc_assert
(
REG_P
(
reg1
)
)
;
gcc_assert
(
REG_P
(
reg2
)
)
;
gcc_assert
(
REG_P
(
base1
)
)
;
if
(
load_p
)
{
gcc_assert
(
REGNO
(
reg1
)
!=
REGNO
(
reg2
)
)
;
gcc_assert
(
REGNO
(
reg1
)
!=
REGNO
(
base1
)
)
;
gcc_assert
(
REGNO
(
reg2
)
!=
REGNO
(
base1
)
)
;
}
output_operands
[
0
]
=
copy_rtx
(
reg1
)
;
output_operands
[
1
]
=
copy_rtx
(
reg2
)
;
output_operands
[
2
]
=
copy_rtx
(
base1
)
;
output_operands
[
3
]
=
gen_rtx_CONST_INT
(
mode
,
imm2
)
;
output_operands
[
4
]
=
gen_rtx_CONST_INT
(
mode
,
shamt
)
;
output_asm_insn
(
format
,
output_operands
)
;
return
""
;
}
</s>

Output a mempair instruction with the provided OPERANDS . LOAD_P is true if a we have a pair of loads ( stores otherwise ) . MODE is the access mode ( DI or SI ) . CODE is the extension code ( UNKNOWN , SIGN_EXTEND or ZERO_EXTEND ) . This instruction does not handle invalid inputs gracefully , but is full of assertions to ensure that only valid instructions are emitted .


<s>
void
dump
(
)
{
errs
(
)
<<
"RISCVAddressingMode "
<<
this
<<
'\n'
;
errs
(
)
<<
" Base "
;
if
(
Base
.
getNode
(
)
!=
0
)
Base
.
getNode
(
)
->
dump
(
)
;
else
errs
(
)
<<
"null\n"
;
errs
(
)
<<
" Offset "
<<
Offset
;
}
</s>

Dump the plan to stderr ( for debugging ) .

RISCV
"RISCVAddressingMode "
" Base "
0
"null\n"
" Offset "


<s>
void
addExpr
(
MCInst
&
Inst
,
const
MCExpr
*
Expr
)
const
{
assert
(
Expr
&&
"Expr shouldn't be null!"
)
;
int64_t
Imm
=
0
;
RISCVMCExpr
::
VariantKind
VK
;
bool
IsConstant
=
evaluateConstantImm
(
Expr
,
Imm
,
VK
)
;
if
(
IsConstant
)
Inst
.
addOperand
(
MCOperand
::
createImm
(
Imm
)
)
;
else
Inst
.
addOperand
(
MCOperand
::
createExpr
(
Expr
)
)
;
}
</s>


<s> bool RISCVMCExpr :: evaluateAsConstant ( int64_t & Res ) const { MCValue Value ; if ( Kind == VK_RISCV_PCREL_HI || Kind == VK_RISCV_PCREL_LO || Kind == VK_RISCV_CALL ) return false ; if ( ! getSubExpr ( ) -> evaluateAsRelocatable ( Value , nullptr , nullptr ) ) return false ; if ( ! Value . isAbsolute ( ) ) return false ; Res = evaluateAsInt64 ( Value . getConstant ( ) ) ; return true ; } </s>

Evaluates the fixup as a constant value .


For stack frames that ca n't be allocated with a single ADDI instruction , compute the best value to initially allocate . It must at a minimum allocate enough space to spill the callee-saved registers .


<s>
MachineBasicBlock
*
RISCVTargetLowering
::
EmitInstrWithCustomInserter
(
MachineInstr
&
MI
,
MachineBasicBlock
*
BB
)
const
{
switch
(
MI
.
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Unexpected instr type to insert"
)
;
case
RISCV
::
Select_GPR_Using_CC_GPR
:
case
RISCV
::
Select_FPR32_Using_CC_GPR
:
case
RISCV
::
Select_FPR64_Using_CC_GPR
:
return
emitSelectPseudo
(
MI
,
BB
)
;
case
RISCV
::
BuildPairF64Pseudo
:
return
emitBuildPairF64Pseudo
(
MI
,
BB
)
;
case
RISCV
::
SplitF64Pseudo
:
return
emitSplitF64Pseudo
(
MI
,
BB
)
;
}
}
</s>


<s> void riscv_expand_prologue ( void ) { struct riscv_frame_info * frame = & cfun -> machine -> frame ; HOST_WIDE_INT size = frame -> total_size ; unsigned mask = frame -> mask ; rtx insn ; if ( flag_stack_usage_info ) current_function_static_stack_size = size ; if ( cfun -> machine -> naked_p ) return ; if ( riscv_use_save_libcall ( frame ) ) { rtx dwarf = NULL_RTX ; dwarf = riscv_adjust_libcall_cfi_prologue ( ) ; size -= frame -> save_libcall_adjustment ; insn = emit_insn ( riscv_gen_gpr_save_insn ( frame ) ) ; frame -> mask = 0 ; RTX_FRAME_RELATED_P ( insn ) = 1 ; REG_NOTES ( insn ) = dwarf ; } if ( ( frame -> mask | frame -> fmask ) != 0 ) { HOST_WIDE_INT step1 = MIN ( size , riscv_first_stack_step ( frame ) ) ; insn = gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( - step1 ) ) ; RTX_FRAME_RELATED_P ( emit_insn ( insn ) ) = 1 ; size -= step1 ; riscv_for_each_saved_reg ( size , riscv_save_reg , false , false ) ; } frame -> mask = mask ; if ( frame_pointer_needed ) { insn = gen_add3_insn ( hard_frame_pointer_rtx , stack_pointer_rtx , GEN_INT ( frame -> hard_frame_pointer_offset - size ) ) ; RTX_FRAME_RELATED_P ( emit_insn ( insn ) ) = 1 ; riscv_emit_stack_tie ( ) ; } if ( size > 0 ) { if ( SMALL_OPERAND ( - size ) ) { insn = gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( - size ) ) ; RTX_FRAME_RELATED_P ( emit_insn ( insn ) ) = 1 ; } else { riscv_emit_move ( RISCV_PROLOGUE_TEMP ( Pmode ) , GEN_INT ( - size ) ) ; emit_insn ( gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , RISCV_PROLOGUE_TEMP ( Pmode ) ) ) ; insn = plus_constant ( Pmode , stack_pointer_rtx , - size ) ; insn = gen_rtx_SET ( stack_pointer_rtx , insn ) ; riscv_set_frame_expr ( insn ) ; } } } </s>


<s> static void riscv_block_move_straight ( rtx dest , rtx src , unsigned HOST_WIDE_INT length ) { unsigned HOST_WIDE_INT offset , delta ; unsigned HOST_WIDE_INT bits ; int i ; enum machine_mode mode ; rtx * regs ; bits = MAX ( BITS_PER_UNIT , MIN ( BITS_PER_WORD , MIN ( MEM_ALIGN ( src ) , MEM_ALIGN ( dest ) ) ) ) ; mode = mode_for_size ( bits , MODE_INT , 0 ) . require ( ) ; delta = bits / BITS_PER_UNIT ; regs = XALLOCAVEC ( rtx , length / delta ) ; for ( offset = 0 , i = 0 ; offset + delta <= length ; offset += delta , i ++ ) { regs [ i ] = gen_reg_rtx ( mode ) ; riscv_emit_move ( regs [ i ] , adjust_address ( src , mode , offset ) ) ; } for ( offset = 0 , i = 0 ; offset + delta <= length ; offset += delta , i ++ ) riscv_emit_move ( adjust_address ( dest , mode , offset ) , regs [ i ] ) ; if ( offset < length ) { src = adjust_address ( src , BLKmode , offset ) ; dest = adjust_address ( dest , BLKmode , offset ) ; move_by_pieces ( dest , src , length - offset , MIN ( MEM_ALIGN ( src ) , MEM_ALIGN ( dest ) ) , RETURN_BEGIN ) ; } } </s>

Emit straight-line code to move LENGTH bytes from SRC to DEST . Assume that the areas do not overlap .


<s> const TargetRegisterClass * RISCVRegisterInfo :: getPointerRegClass ( const MachineFunction & MF , unsigned Kind ) const { return & RISCV :: GPRRegClass ; } </s>

getPointerRegClass - Returns a TargetRegisterClass used for pointer values .


<s> unsigned RISCVTargetLowering :: ComputeNumSignBitsForTargetNode ( SDValue Op , const APInt & DemandedElts , const SelectionDAG & DAG , unsigned Depth ) const { switch ( Op . getOpcode ( ) ) { default : break ; case RISCVISD :: SLLW : case RISCVISD :: SRAW : case RISCVISD :: SRLW : case RISCVISD :: DIVW : case RISCVISD :: DIVUW : case RISCVISD :: REMUW : case RISCVISD :: ROLW : case RISCVISD :: RORW : case RISCVISD :: GREVIW : case RISCVISD :: GORCIW : case RISCVISD :: FSLW : case RISCVISD :: FSRW : return 33 ; case RISCVISD :: VMV_X_S : return Subtarget . getXLen ( ) - Op . getOperand ( 0 ) . getScalarValueSizeInBits ( ) + 1 ; } return 1 ; } </s>

Determine the number of bits in the operation that are sign bits .

RISCV RISCV RISCVISD::SLLW RISCVISD::SRAW RISCVISD::SRLW RISCVISD::DIVW RISCVISD::DIVUW RISCVISD::REMUW RISCVISD::ROLW RISCVISD::RORW RISCVISD::GREVIW RISCVISD::GORCIW RISCVISD::FSLW RISCVISD::FSRW 33 RISCVISD::VMV_X_S 0 1 1


<s>
bool
RISCVInstrInfo
::
reverseBranchCondition
(
SmallVectorImpl
<
MachineOperand
>
&
Cond
)
const
{
assert
(
(
Cond
.
size
(
)
==
3
)
&&
"Invalid branch condition!"
)
;
Cond
[
0
]
.
setImm
(
getOppositeBranchOpcode
(
Cond
[
0
]
.
getImm
(
)
)
)
;
return
false
;
}
</s>

Reverses the branch condition of the specified condition list , returning false on success and true if it can not be reversed .


<s> bool RISCVPassConfig :: addInstSelector ( ) { addPass ( createRISCVISelDag ( getRISCVTargetMachine ( ) , getOptLevel ( ) ) ) ; return false ; } </s>

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


<s> bool pass_vsetvl :: hard_empty_block_p ( const bb_info * bb , const vector_insn_info & info ) const { if ( ! info . dirty_p ( ) || ! info . has_avl_reg ( ) ) return false ; basic_block cfg_bb = bb -> cfg_bb ( ) ; sbitmap avin = m_vector_manager -> vector_avin [ cfg_bb -> index ] ; set_info * set = info . get_avl_source ( ) ; rtx avl = gen_rtx_REG ( Pmode , set -> regno ( ) ) ; hash_set < set_info * > sets = get_all_sets ( set , true , false , false ) ; hash_set < basic_block > pred_cfg_bbs = get_all_predecessors ( cfg_bb ) ; if ( find_reg_killed_by ( bb , avl ) ) { gcc_assert ( info . dirty_with_killed_avl_p ( ) ) ; if ( info . get_avl_source ( ) && get_same_bb_set ( sets , bb -> cfg_bb ( ) ) == info . get_avl_source ( ) ) return false ; } if ( bitmap_empty_p ( avin ) ) { bool hard_empty_p = true ; for ( const basic_block pred_cfg_bb : pred_cfg_bbs ) { if ( pred_cfg_bb == ENTRY_BLOCK_PTR_FOR_FN ( cfun ) ) continue ; sbitmap avout = m_vector_manager -> vector_avout [ pred_cfg_bb -> index ] ; if ( ! bitmap_empty_p ( avout ) ) { hard_empty_p = false ; break ; } } if ( hard_empty_p ) return true ; } edge e ; edge_iterator ei ; bool has_avl_killed_insn_p = false ; FOR_EACH_EDGE ( e , ei , cfg_bb -> succs ) { const auto block_info = m_vector_manager -> vector_block_infos [ e -> dest -> index ] ; if ( block_info . local_dem . dirty_with_killed_avl_p ( ) ) { has_avl_killed_insn_p = true ; break ; } } if ( ! has_avl_killed_insn_p ) return false ; bool any_set_in_bbs_p = false ; for ( const basic_block pred_cfg_bb : pred_cfg_bbs ) { insn_info * def_insn = extract_single_source ( set ) ; if ( def_insn ) { insn_info * last_killed_insn = find_reg_killed_by ( crtl -> ssa -> bb ( pred_cfg_bb ) , avl ) ; if ( ! last_killed_insn || pred_cfg_bb == def_insn -> bb ( ) -> cfg_bb ( ) ) continue ; if ( source_equal_p ( last_killed_insn , def_insn ) ) { any_set_in_bbs_p = true ; break ; } } else { if ( any_set_in_bb_p ( sets , crtl -> ssa -> bb ( pred_cfg_bb ) ) ) { any_set_in_bbs_p = true ; break ; } } } if ( ! any_set_in_bbs_p ) return true ; return false ; } </s>

We almost enable all cases in get_backward_fusion_type , this function disable the backward fusion by changing dirty blocks into hard empty blocks in forward dataflow . We can have more accurate optimization by this method .


<s> void RISCVPassConfig :: addIRPasses ( ) { addPass ( createAtomicExpandPass ( ) ) ; addPass ( createRISCVGatherScatterLoweringPass ( ) ) ; TargetPassConfig :: addIRPasses ( ) ; } </s>

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


"frame pointer should not have been eliminated"


<s> bool RISCVTargetLowering :: 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 , RVLocs , Context ) ; Optional < unsigned > FirstMaskArgument ; if ( Subtarget . hasVInstructions ( ) ) FirstMaskArgument = preAssignMask ( Outs ) ; for ( unsigned i = 0 , e = Outs . size ( ) ; i != e ; ++ i ) { MVT VT = Outs [ i ] . VT ; ISD :: ArgFlagsTy ArgFlags = Outs [ i ] . Flags ; RISCVABI :: ABI ABI = MF . getSubtarget < RISCVSubtarget > ( ) . getTargetABI ( ) ; if ( CC_RISCV ( MF . getDataLayout ( ) , ABI , i , VT , VT , CCValAssign :: Full , ArgFlags , CCInfo , true , true , nullptr , * this , FirstMaskArgument ) ) return false ; } return true ; } </s>

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

RISCV RISCV ISD::OutputArg 16 0 ISD::ArgFlagsTy RISCVABI::ABI RISCV RISCV


<s> unsigned RISCVInstrInfo :: isStoreToStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : return 0 ; case RISCV :: SB : case RISCV :: SH : case RISCV :: SW : case RISCV :: FSW : case RISCV :: SD : case RISCV :: FSD : break ; } if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } return 0 ; } </s>

isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot , return the virtual or physical register number of the source reg along with the FrameIndex of the loaded stack slot .


<s> MCSection * RISCVELFTargetObjectFile :: getSectionForConstant ( const DataLayout & DL , SectionKind Kind , const Constant * C , unsigned & Align ) const { if ( isConstantInSmallSection ( DL , C ) ) return SmallDataSection ; return TargetLoweringObjectFileELF :: getSectionForConstant ( DL , Kind , C , Align ) ; } </s>

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


<s> bool RISCVAsmBackend :: fixupNeedsRelaxationAdvanced ( const MCFixup & Fixup , bool Resolved , uint64_t Value , const MCRelaxableFragment * DF , const MCAsmLayout & Layout , const bool WasForced ) const { if ( ! Resolved && ! WasForced ) return true ; int64_t Offset = int64_t ( Value ) ; switch ( Fixup . getTargetKind ( ) ) { default : return false ; case RISCV :: fixup_riscv_rvc_branch : return Offset > 254 || Offset < - 256 ; case RISCV :: fixup_riscv_rvc_jump : return Offset > 2046 || Offset < - 2048 ; } } </s>

Target specific predicate for whether a given fixup requires the associated instruction to be relaxed .


<s> unsigned RISCVAsmParser :: validateTargetOperandClass ( MCParsedAsmOperand & AsmOp , unsigned Kind ) { RISCVOperand & Op = static_cast < RISCVOperand & > ( AsmOp ) ; if ( ! Op . isReg ( ) ) return Match_InvalidOperand ; MCRegister Reg = Op . getReg ( ) ; bool IsRegFPR64 = RISCVMCRegisterClasses [ RISCV :: FPR64RegClassID ] . contains ( Reg ) ; bool IsRegFPR64C = RISCVMCRegisterClasses [ RISCV :: FPR64CRegClassID ] . contains ( Reg ) ; if ( ( IsRegFPR64 && Kind == MCK_FPR32 ) || ( IsRegFPR64C && Kind == MCK_FPR32C ) ) { Op . Reg . RegNum = convertFPR64ToFPR32 ( Reg ) ; return Match_Success ; } if ( IsRegFPR64 && Kind == MCK_FPR16 ) { Op . Reg . RegNum = convertFPR64ToFPR16 ( Reg ) ; return Match_Success ; } return Match_InvalidOperand ; } </s>

Allow a target to add special case operand matching for things that tblgen doesn't/ca n't handle effectively .

RISCV RISCV RISCV RISCV RISCV RISCV::FPR64RegClassID RISCV RISCV::FPR64CRegClassID


<s> static bool available_occurrence_p ( const bb_info * bb , const vector_insn_info dem ) { insn_info * insn = dem . get_insn ( ) ; if ( dem . has_avl_reg ( ) ) { if ( ! vlmax_avl_p ( dem . get_avl ( ) ) ) { rtx dest = NULL_RTX ; if ( vsetvl_insn_p ( insn -> rtl ( ) ) ) dest = get_vl ( insn -> rtl ( ) ) ; for ( const insn_info * i = insn ; real_insn_and_same_bb_p ( i , bb ) ; i = i -> next_nondebug_insn ( ) ) { if ( read_vl_insn_p ( i -> rtl ( ) ) ) continue ; if ( find_access ( i -> defs ( ) , REGNO ( dem . get_avl ( ) ) ) ) return false ; if ( dest && find_access ( i -> defs ( ) , REGNO ( dest ) ) ) return false ; } } } return true ; } </s>

An `` available occurrence '' is one that is the last occurrence in the basic block and the operands are not modified by following statements in the basic block [ including this insn ] . For VSETVL instruction , we have these following formats : 1. vsetvl zero , rs1 . 2. vsetvl zero , imm . 3. vsetvl rd , rs1 . So base on these circumstances , a DEM is considered as a local available occurrence should satisfy these following conditions : 1 ) . rs1 ( avl ) are not modified by following statements in the basic block . 2 ) . rd ( vl ) are not modified by following statements in the basic block . Note : We do n't need to check VL/VTYPE here since DEM is UNKNOWN if VL/VTYPE is modified prior to the occurrence . This case is already considered as a non-local available occurrence .


<s>
void
RISCVFrameLowering
::
emitPrologue
(
MachineFunction
&
MF
,
MachineBasicBlock
&
MBB
)
const
{
assert
(
&
MF
.
front
(
)
==
&
MBB
&&
"Shrink-wrapping not yet supported"
)
;
MachineFrameInfo
&
MFI
=
MF
.
getFrameInfo
(
)
;
auto
*
RVFI
=
MF
.
getInfo
<
RISCVMachineFunctionInfo
>
(
)
;
MachineBasicBlock
::
iterator
MBBI
=
MBB
.
begin
(
)
;
unsigned
FPReg
=
getFPReg
(
STI
)
;
unsigned
SPReg
=
getSPReg
(
STI
)
;
DebugLoc
DL
;
determineFrameLayout
(
MF
)
;
uint64_t
StackSize
=
MFI
.
getStackSize
(
)
;
if
(
StackSize
==
0
&&
!
MFI
.
adjustsStack
(
)
)
return
;
adjustReg
(
MBB
,
MBBI
,
DL
,
SPReg
,
SPReg
,
StackSize
,
MachineInstr
::
FrameSetup
)
;
const
std
::
vector
<
CalleeSavedInfo
>
&
CSI
=
MFI
.
getCalleeSavedInfo
(
)
;
std
::
advance
(
MBBI
,
CSI
.
size
(
)
)
;
if
(
hasFP
(
MF
)
)
adjustReg
(
MBB
,
MBBI
,
DL
,
FPReg
,
SPReg
,
StackSize
RVFI
->
getVarArgsSaveSize
(
)
,
MachineInstr
::
FrameSetup
)
;
}
</s>

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

RISCV
RISCV
"Shrink-wrapping not yet supported"
RISCV
0


"SecondSPAdjustAmount should be greater than zero"


<s> static void riscv_conditional_register_usage ( void ) { if ( ! TARGET_HARD_FLOAT ) { for ( int regno = FP_REG_FIRST ; regno <= FP_REG_LAST ; regno ++ ) fixed_regs [ regno ] = call_used_regs [ regno ] = 1 ; } if ( UNITS_PER_FP_ARG == 0 ) { for ( int regno = FP_REG_FIRST ; regno <= FP_REG_LAST ; regno ++ ) call_used_regs [ regno ] = 1 ; } } </s>


<s> bool riscv_gimple_fold_builtin ( gimple_stmt_iterator * gsi ) { gcall * stmt = as_a < gcall * > ( gsi_stmt ( * gsi ) ) ; tree fndecl = gimple_call_fndecl ( stmt ) ; unsigned int code = DECL_MD_FUNCTION_CODE ( fndecl ) ; unsigned int subcode = code >> RISCV_BUILTIN_SHIFT ; gimple * new_stmt = NULL ; switch ( code & RISCV_BUILTIN_CLASS ) { case RISCV_BUILTIN_GENERAL : new_stmt = NULL ; break ; case RISCV_BUILTIN_VECTOR : new_stmt = riscv_vector :: gimple_fold_builtin ( subcode , gsi , stmt ) ; break ; } if ( ! new_stmt ) return false ; gsi_replace ( gsi , new_stmt , false ) ; return true ; } </s>


<s> char * get_name ( function_builder & b , const function_instance & instance , bool overloaded_p ) const override { if ( overloaded_p ) if ( instance . pred == PRED_TYPE_none || instance . pred == PRED_TYPE_mu ) return nullptr ; tree type = builtin_types [ instance . type . index ] . vector ; machine_mode mode = TYPE_MODE ( type ) ; int sew = GET_MODE_BITSIZE ( GET_MODE_INNER ( mode ) ) ; b . append_name ( "__riscv_" ) ; b . append_name ( "vle" ) ; b . append_sew ( sew ) ; b . append_name ( "ff" ) ; if ( ! overloaded_p ) { b . append_name ( operand_suffixes [ instance . op_info -> op ] ) ; b . append_name ( type_suffixes [ instance . type . index ] . vector ) ; } if ( overloaded_p && instance . pred == PRED_TYPE_m ) return b . finish_name ( ) ; b . append_name ( predication_suffixes [ instance . pred ] ) ; return b . finish_name ( ) ; } </s>

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


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

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


<s> void riscv_expand_prologue ( void ) { struct riscv_frame_info * frame = & cfun -> machine -> frame ; HOST_WIDE_INT size = frame -> total_size ; unsigned mask = frame -> mask ; rtx insn ; if ( flag_stack_usage_info ) current_function_static_stack_size = size ; if ( riscv_use_save_libcall ( frame ) ) { rtx dwarf = NULL_RTX ; dwarf = riscv_adjust_libcall_cfi_prologue ( ) ; frame -> mask = 0 ; size -= frame -> save_libcall_adjustment ; insn = emit_insn ( gen_gpr_save ( GEN_INT ( mask ) ) ) ; RTX_FRAME_RELATED_P ( insn ) = 1 ; REG_NOTES ( insn ) = dwarf ; } if ( ( frame -> mask | frame -> fmask ) != 0 ) { HOST_WIDE_INT step1 = MIN ( size , riscv_first_stack_step ( frame ) ) ; insn = gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( - step1 ) ) ; RTX_FRAME_RELATED_P ( emit_insn ( insn ) ) = 1 ; size -= step1 ; riscv_for_each_saved_reg ( size , riscv_save_reg ) ; } frame -> mask = mask ; if ( frame_pointer_needed ) { insn = gen_add3_insn ( hard_frame_pointer_rtx , stack_pointer_rtx , GEN_INT ( frame -> hard_frame_pointer_offset - size ) ) ; RTX_FRAME_RELATED_P ( emit_insn ( insn ) ) = 1 ; riscv_emit_stack_tie ( ) ; } if ( size > 0 ) { if ( SMALL_OPERAND ( - size ) ) { insn = gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( - size ) ) ; RTX_FRAME_RELATED_P ( emit_insn ( insn ) ) = 1 ; } else { riscv_emit_move ( RISCV_PROLOGUE_TEMP ( Pmode ) , GEN_INT ( - size ) ) ; emit_insn ( gen_add3_insn ( stack_pointer_rtx , stack_pointer_rtx , RISCV_PROLOGUE_TEMP ( Pmode ) ) ) ; insn = plus_constant ( Pmode , stack_pointer_rtx , - size ) ; insn = gen_rtx_SET ( stack_pointer_rtx , insn ) ; riscv_set_frame_expr ( insn ) ; } } } </s>


<s> unsigned RISCVTargetLowering :: ComputeNumSignBitsForTargetNode ( SDValue Op , const APInt & DemandedElts , const SelectionDAG & DAG , unsigned Depth ) const { switch ( Op . getOpcode ( ) ) { default : break ; case RISCVISD :: SLLW : case RISCVISD :: SRAW : case RISCVISD :: SRLW : case RISCVISD :: DIVW : case RISCVISD :: DIVUW : case RISCVISD :: REMUW : case RISCVISD :: ROLW : case RISCVISD :: RORW : case RISCVISD :: GREVIW : case RISCVISD :: GORCIW : case RISCVISD :: FSLW : case RISCVISD :: FSRW : return 33 ; } return 1 ; } </s>

RISCV RISCV RISCVISD::SLLW RISCVISD::SRAW RISCVISD::SRLW RISCVISD::DIVW RISCVISD::DIVUW RISCVISD::REMUW RISCVISD::ROLW RISCVISD::RORW RISCVISD::GREVIW RISCVISD::GORCIW RISCVISD::FSLW RISCVISD::FSRW 33 1


<s> void RISCVInstrInfo :: loadImmediate ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , unsigned * Reg , int64_t Value ) const { DebugLoc DL = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; unsigned Opcode ; MachineRegisterInfo & RegInfo = MBB . getParent ( ) -> getRegInfo ( ) ; const TargetRegisterClass * RC = STI . isRV64 ( ) ? & RISCV :: GR64BitRegClass : & RISCV :: GR32BitRegClass ; unsigned ZERO = STI . isRV64 ( ) ? RISCV :: zero_64 : RISCV :: zero ; * Reg = RegInfo . createVirtualRegister ( RC ) ; if ( isInt < 12 > ( Value ) ) { Opcode = STI . isRV64 ( ) ? RISCV :: ADDI64 : RISCV :: ADDI ; BuildMI ( MBB , MBBI , DL , get ( Opcode ) , * Reg ) . addReg ( ZERO ) . addImm ( Value ) ; } else { BuildMI ( MBB , MBBI , DL , get ( RISCV :: LI ) , * Reg ) . addImm ( Value ) ; } } </s>

Emit a series of instructions to load an immediate .


<s>
StringRef
getPassName
(
)
const
override
{
return
"RISCV sext.w Removal"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> static rtx riscv_emit_binary ( enum rtx_code code , rtx dest , rtx x , rtx y ) { return riscv_emit_set ( dest , gen_rtx_fmt_ee ( code , GET_MODE ( dest ) , x , y ) ) ; } </s>

Emit an instruction of the form ( set DEST ( CODE X Y ) ) .


<s> void RISCVPassConfig :: addMachineSSAOptimization ( ) { TargetPassConfig :: addMachineSSAOptimization ( ) ; addPass ( createRISCVOptimizeVSETVLUsesPass ( ) ) ; } </s>

Methods with trivial inline returns are convenient points in the common codegen pass pipeline where targets may insert passes .


<s> SDValue X86SelectionDAGInfo :: EmitTargetCodeForMemcpy ( SelectionDAG & DAG , const SDLoc & dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , Align Alignment , bool isVolatile , bool AlwaysInline , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { if ( DstPtrInfo . getAddrSpace ( ) >= 256 || SrcPtrInfo . getAddrSpace ( ) >= 256 ) return SDValue ( ) ; const MCPhysReg ClobberSet [ ] = { X86 :: RCX , X86 :: RSI , X86 :: RDI , X86 :: ECX , X86 :: ESI , X86 :: EDI } ; if ( isBaseRegConflictPossible ( DAG , ClobberSet ) ) return SDValue ( ) ; const X86Subtarget & Subtarget = DAG . getMachineFunction ( ) . getSubtarget < X86Subtarget > ( ) ; if ( UseFSRMForMemcpy && Subtarget . hasFSRM ( ) ) return emitRepmovs ( Subtarget , DAG , dl , Chain , Dst , Src , Size , MVT :: i8 ) ; if ( ConstantSDNode * ConstantSize = dyn_cast < ConstantSDNode > ( Size ) ) return emitConstantSizeRepmov ( DAG , Subtarget , dl , Chain , Dst , Src , ConstantSize -> getZExtValue ( ) , Size . getValueType ( ) , Alignment . value ( ) , isVolatile , AlwaysInline , DstPtrInfo , SrcPtrInfo ) ; return SDValue ( ) ; } </s>

Emit target-specific code that performs a memcpy .


runOnMachineFunction - Emit the function body .


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

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


<s> enum reg_class arm_regno_class ( int regno ) { if ( regno == PC_REGNUM ) return NO_REGS ; if ( IS_VPR_REGNUM ( regno ) ) return VPR_REG ; if ( TARGET_THUMB1 ) { if ( regno == STACK_POINTER_REGNUM ) return STACK_REG ; if ( regno == CC_REGNUM ) return CC_REG ; if ( regno < 8 ) return LO_REGS ; return HI_REGS ; } if ( TARGET_THUMB2 && regno < 8 ) return LO_REGS ; if ( regno <= LAST_ARM_REGNUM || regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM ) return TARGET_THUMB2 ? HI_REGS : GENERAL_REGS ; if ( regno == CC_REGNUM || regno == VFPCC_REGNUM ) return TARGET_THUMB2 ? CC_REG : NO_REGS ; if ( IS_VFP_REGNUM ( regno ) ) { if ( regno <= D7_VFP_REGNUM ) return VFP_D0_D7_REGS ; else if ( regno <= LAST_LO_VFP_REGNUM ) return VFP_LO_REGS ; else return VFP_HI_REGS ; } if ( IS_IWMMXT_REGNUM ( regno ) ) return IWMMXT_REGS ; if ( IS_IWMMXT_GR_REGNUM ( regno ) ) return IWMMXT_GR_REGS ; return NO_REGS ; } </s>

For efficiency and historical reasons LO_REGS , HI_REGS and CC_REGS are not used in arm mode .


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

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


<s> int ARMFrameLowering :: getFrameIndexReference ( const MachineFunction & MF , int FI , Register & FrameReg ) const { return ResolveFrameIndexReference ( MF , FI , FrameReg , 0 ) ; } </s>

getFrameIndexReference - This method should return the base register and offset used to reference a frame index location .


<s> static bool insn_terminates_group_p ( rtx insn , enum group_termination which_group ) { enum attr_type type ; if ( ! insn ) return false ; type = get_attr_type ( insn ) ; if ( is_microcoded_insn ( insn ) ) return true ; if ( which_group == current_group ) { if ( is_branch_slot_insn ( insn ) ) return true ; return false ; } else if ( which_group == previous_group ) { if ( is_dispatch_slot_restricted ( insn ) ) return true ; return false ; } return false ; } </s>

Return whether the presence of INSN causes a dispatch group termination of group WHICH_GROUP . If WHICH_GROUP == current_group , this function will return true if INSN causes the termination of the current group ( i.e , the dispatch group to which INSN belongs ) . This means that INSN will be the last insn in the group it belongs to . If WHICH_GROUP == previous_group , this function will return true if INSN causes the termination of the previous group ( i.e , the dispatch group that precedes the group to which INSN belongs ) . This means that INSN will be the first insn in the group it belongs to ) .


<s> static rtvec rs6000_const_vec ( machine_mode mode ) { int i , subparts ; rtvec v ; switch ( mode ) { case V1TImode : subparts = 1 ; break ; case V2DFmode : case V2DImode : subparts = 2 ; break ; case V4SFmode : case V4SImode : subparts = 4 ; break ; case V8HImode : subparts = 8 ; break ; case V16QImode : subparts = 16 ; break ; default : gcc_unreachable ( ) ; } v = rtvec_alloc ( subparts ) ; for ( i = 0 ; i < subparts / 2 ; ++ i ) RTVEC_ELT ( v , i ) = gen_rtx_CONST_INT ( DImode , i + subparts / 2 ) ; for ( i = subparts / 2 ; i < subparts ; ++ i ) RTVEC_ELT ( v , i ) = gen_rtx_CONST_INT ( DImode , i - subparts / 2 ) ; return v ; } </s>

Generate a vector of constants to permute MODE for a little-endian storage operation by swapping the two halves of a vector .


<s> bool ARMPagerandoOptimizer :: runOnMachineFunction ( MachineFunction & MF ) { auto & F = MF . getFunction ( ) ; if ( ! F . isPagerando ( ) || skipFunction ( F ) ) { return false ; } auto BinPrefix = F . getSectionPrefix ( ) . getValue ( ) ; auto & CPEntries = MF . getConstantPool ( ) -> getConstants ( ) ; SmallSet < int , 8 > CPIndices ; int Index = 0 ; for ( auto & E : CPEntries ) { if ( isIntraBin ( E , BinPrefix ) ) CPIndices . insert ( Index ) ; Index ++ ; } if ( CPIndices . empty ( ) ) return false ; std :: vector < MachineInstr * > Uses ; for ( auto & BB : MF ) { for ( auto & MI : BB ) { int Index = getCPIndex ( MI ) ; if ( CPIndices . count ( Index ) ) Uses . push_back ( & MI ) ; } } for ( auto * MI : Uses ) { int Index = getCPIndex ( * MI ) ; auto * Callee = getCallee ( CPEntries [ Index ] ) ; optimizeCalls ( MI , Callee ) ; } deleteCPEntries ( MF , CPIndices ) ; return true ; } </s>


<s> static bool rs6000_function_parms_need_stack ( tree fun , bool incoming ) { tree fntype , result ; CUMULATIVE_ARGS args_so_far_v ; cumulative_args_t args_so_far ; if ( ! fun ) return false ; fntype = fun ; if ( ! TYPE_P ( fun ) ) fntype = TREE_TYPE ( fun ) ; if ( ( ! incoming && ! prototype_p ( fntype ) ) || stdarg_p ( fntype ) ) return true ; INIT_CUMULATIVE_INCOMING_ARGS ( args_so_far_v , fntype , NULL_RTX ) ; args_so_far = pack_cumulative_args ( & args_so_far_v ) ; if ( incoming ) { gcc_assert ( DECL_P ( fun ) ) ; result = DECL_RESULT ( fun ) ; } else result = TREE_TYPE ( fntype ) ; if ( result && aggregate_value_p ( result , fntype ) ) { if ( ! TYPE_P ( result ) ) result = TREE_TYPE ( result ) ; result = build_pointer_type ( result ) ; rs6000_parm_needs_stack ( args_so_far , result ) ; } if ( incoming ) { tree parm ; for ( parm = DECL_ARGUMENTS ( fun ) ; parm && parm != void_list_node ; parm = TREE_CHAIN ( parm ) ) if ( rs6000_parm_needs_stack ( args_so_far , TREE_TYPE ( parm ) ) ) return true ; } else { function_args_iterator args_iter ; tree arg_type ; FOREACH_FUNCTION_ARGS ( fntype , arg_type , args_iter ) if ( rs6000_parm_needs_stack ( args_so_far , arg_type ) ) return true ; } return false ; } </s>

Return true if FUN has no prototype , has a variable argument list , or passes any parameter in memory .


<s> static bool arm_const_double_prefer_rsbs_rsc ( rtx op ) { if ( TARGET_THUMB || ! CONST_INT_P ( op ) ) return false ; HOST_WIDE_INT hi , lo ; lo = UINTVAL ( op ) & 0xffffffffULL ; hi = UINTVAL ( op ) >> 32 ; return const_ok_for_arm ( lo ) && const_ok_for_arm ( hi ) ; } </s>

Return TRUE if op is a constant where both the low and top words are suitable for RSB/RSC instructions . This is never true for Thumb , since we do not have RSC in that case .


<s> bool ARMTargetLowering :: isFPImmLegal ( const APFloat & Imm , EVT VT , bool ForCodeSize ) const { if ( ! Subtarget -> hasVFP3 ( ) ) return false ; if ( VT == MVT :: f16 && Subtarget -> hasFullFP16 ( ) ) return ARM_AM :: getFP16Imm ( Imm ) != - 1 ; if ( VT == MVT :: f32 ) return ARM_AM :: getFP32Imm ( Imm ) != - 1 ; if ( VT == MVT :: f64 && ! Subtarget -> isFPOnlySP ( ) ) return ARM_AM :: getFP64Imm ( Imm ) != - 1 ; return false ; } </s>

Returns true if the target can instruction select the specified FP immediate natively .


<s> static bool aarch64_mode_valid_for_sched_fusion_p ( machine_mode mode ) { return mode == SImode || mode == DImode || mode == SFmode || mode == DFmode || ( aarch64_vector_mode_supported_p ( mode ) && ( known_eq ( GET_MODE_SIZE ( mode ) , 8 ) || ( known_eq ( GET_MODE_SIZE ( mode ) , 16 ) && ( aarch64_tune_params . extra_tuning_flags & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS ) == 0 ) ) ) ; } </s>

Return true if MODE is one of the modes for which we support LDP/STP operations .


<s> const uint32_t * SystemZRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { if ( MF . getSubtarget ( ) . getTargetLowering ( ) -> supportSwiftError ( ) && MF . getFunction ( ) . getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) return CSR_SystemZ_SwiftError_RegMask ; return CSR_SystemZ_RegMask ; } </s>

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


<s> static void aarch64_finish_cost ( void * data , unsigned * prologue_cost , unsigned * body_cost , unsigned * epilogue_cost ) { auto * costs = static_cast < aarch64_vector_costs * > ( data ) ; * prologue_cost = costs -> region [ vect_prologue ] ; * body_cost = costs -> region [ vect_body ] ; * epilogue_cost = costs -> region [ vect_epilogue ] ; if ( costs -> is_loop && costs -> vec_flags && aarch64_use_new_vector_costs_p ( ) ) * body_cost = aarch64_adjust_body_cost ( costs , * body_cost ) ; } </s>


"%qE attribute only applies to functions"

"%qE attribute argument not an integer constant"

"%qE attribute argument should be between 0 to 255"

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


"%<-mindirect-branch=%s%> and %<-mcmodel=large%> are not "

"%<-fcheck-pointer-bounds%> are not compatible"

"%<-mfunction-return=%s%> and %<-mcmodel=large%> are not "

Set the indirect_branch_type field from the function FNDECL .


<s> bool emit_scc_insn ( rtx operands [ ] ) { rtx tem , x , y ; enum rtx_code code ; machine_mode mode ; if ( GET_MODE ( operands [ 2 ] ) == TFmode && ! TARGET_HARD_QUAD ) { operands [ 1 ] = sparc_emit_float_lib_cmp ( operands [ 2 ] , operands [ 3 ] , GET_CODE ( operands [ 1 ] ) ) ; operands [ 2 ] = XEXP ( operands [ 1 ] , 0 ) ; operands [ 3 ] = XEXP ( operands [ 1 ] , 1 ) ; } code = GET_CODE ( operands [ 1 ] ) ; x = operands [ 2 ] ; y = operands [ 3 ] ; mode = GET_MODE ( x ) ; if ( ( code == EQ || code == NE ) && ( mode == SImode || mode == DImode ) ) { if ( y != const0_rtx ) x = force_reg ( mode , gen_rtx_XOR ( mode , x , y ) ) ; rtx pat = gen_rtx_SET ( operands [ 0 ] , gen_rtx_fmt_ee ( code , GET_MODE ( operands [ 0 ] ) , x , const0_rtx ) ) ; if ( mode == SImode || ( code == NE && TARGET_VIS3 ) ) { rtx clobber = gen_rtx_CLOBBER ( VOIDmode , gen_rtx_REG ( mode == SImode ? CCmode : CCXmode , SPARC_ICC_REG ) ) ; pat = gen_rtx_PARALLEL ( VOIDmode , gen_rtvec ( 2 , pat , clobber ) ) ; } emit_insn ( pat ) ; return true ; } if ( TARGET_ARCH64 && mode == DImode && ! ( ( code == LTU || code == GTU ) && TARGET_VIS3 ) && gen_v9_scc ( operands [ 0 ] , code , x , y ) ) return true ; if ( code == GTU || code == LEU ) { if ( ( GET_CODE ( x ) == REG || GET_CODE ( x ) == SUBREG ) && ( GET_CODE ( y ) == REG || GET_CODE ( y ) == SUBREG ) ) { tem = x ; x = y ; y = tem ; code = swap_condition ( code ) ; } } if ( code == LTU || code == GEU ) { emit_insn ( gen_rtx_SET ( operands [ 0 ] , gen_rtx_fmt_ee ( code , GET_MODE ( operands [ 0 ] ) , gen_compare_reg_1 ( code , x , y ) , const0_rtx ) ) ) ; return true ; } if ( TARGET_V9 && gen_v9_scc ( operands [ 0 ] , code , x , y ) ) return true ; return false ; } </s>

Emit an scc insn . For seq , sne , sgeu , and sltu , we can do this without jumps using the addx/subx instructions .


<s>
void
encodeInstruction
(
const
MCInst
&
MI
,
raw_ostream
&
OS
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
override
{
verifyInstructionPredicates
(
MI
,
computeAvailableFeatures
(
STI
.
getFeatureBits
(
)
)
)
;
unsigned
Opcode
=
MI
.
getOpcode
(
)
;
const
MCInstrDesc
&
Desc
=
MCII
.
get
(
Opcode
)
;
uint64_t
Bits
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
unsigned
Size
=
Desc
.
getSize
(
)
;
support
::
endianness
E
=
IsLittleEndian
support
::
little
:
support
::
big
;
switch
(
Size
)
{
case
0
:
break
;
case
4
:
support
::
endian
::
write
<
uint32_t
>
(
OS
,
Bits
,
E
)
;
break
;
case
8
:
support
::
endian
::
write
<
uint32_t
>
(
OS
,
Bits
>>
32
,
E
)
;
support
::
endian
::
write
<
uint32_t
>
(
OS
,
Bits
,
E
)
;
break
;
default
:
llvm_unreachable
(
"Invalid instruction size"
)
;
}
++
MCNumEmitted
;
}
</s>

Encode the given Inst to bytes and append to CB .

PowerPC
support::endianness
support::little
support::big
0
4
support::endian
8
support::endian
32
support::endian
"Invalid instruction size"


<s>
const
char
*
output_probe_stack_range
(
rtx
reg1
,
rtx
reg2
)
{
static
int
labelno
=
0
;
char
loop_lab
[
32
]
,
end_lab
[
32
]
;
rtx
xops
[
3
]
;
ASM_GENERATE_INTERNAL_LABEL
(
loop_lab
,
"LPSRL"
,
labelno
)
;
ASM_GENERATE_INTERNAL_LABEL
(
end_lab
,
"LPSRE"
,
labelno
++
)
;
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
loop_lab
)
;
xops
[
0
]
=
reg1
;
xops
[
1
]
=
reg2
;
xops
[
2
]
=
gen_rtx_REG
(
BImode
,
PR_REG
(
6
)
)
;
output_asm_insn
(
"cmp.eq %2, %I2 = %0, %1"
,
xops
)
;
fprintf
(
asm_out_file
,
"\t(%s) br.cond.dpnt "
,
reg_names
[
REGNO
(
xops
[
2
]
)
]
)
;
assemble_name_raw
(
asm_out_file
,
end_lab
)
;
fputc
(
'\n'
,
asm_out_file
)
;
xops
[
1
]
=
GEN_INT
(
PROBE_INTERVAL
)
;
output_asm_insn
(
"addl %0 = %1, %0"
,
xops
)
;
fputs
(
"\t;;\n"
,
asm_out_file
)
;
output_asm_insn
(
"probe.w.fault %0, 0"
,
xops
)
;
fprintf
(
asm_out_file
,
"\tbr "
)
;
assemble_name_raw
(
asm_out_file
,
loop_lab
)
;
fputc
(
'\n'
,
asm_out_file
)
;
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
end_lab
)
;
return
""
;
}
</s>

Wrapper around the output_probe_stack_range routines .


<s> bool VETargetLowering :: hasAndNot ( SDValue Y ) const { EVT VT = Y . getValueType ( ) ; if ( VT . isVector ( ) ) return false ; if ( auto * C = dyn_cast < ConstantSDNode > ( Y ) ) return false ; return true ; } </s>

Return true if the target has a bitwise and-not operation : X = ~A & B This can be used to simplify select or other instructions .


<s>
bool
runOnMachineFunction
(
MachineFunction
&
MF
)
override
{
LLVM_DEBUG
(
dbgs
(
)
<<
"### runOnMachineFunction\n"
)
;
Subtarget
=
&
MF
.
getSubtarget
<
Comet2Subtarget
>
(
)
;
return
SelectionDAGISel
::
runOnMachineFunction
(
MF
)
;
}
</s>

runOnMachineFunction - Emit the function body .


<s>
MachineBasicBlock
*
CJGTargetLowering
::
EmitInstrWithCustomInserter
(
MachineInstr
&
MI
,
MachineBasicBlock
*
BB
)
const
{
unsigned
Opc
=
MI
.
getOpcode
(
)
;
const
TargetInstrInfo
&
TII
=
*
BB
->
getParent
(
)
->
getSubtarget
(
)
.
getInstrInfo
(
)
;
DebugLoc
dl
=
MI
.
getDebugLoc
(
)
;
assert
(
Opc
==
CJG
::
Select
&&
"Unexpected instr type to insert"
)
;
const
BasicBlock
*
LLVM_BB
=
BB
->
getBasicBlock
(
)
;
MachineFunction
::
iterator
I
=
++
BB
->
getIterator
(
)
;
MachineBasicBlock
*
thisMBB
=
BB
;
MachineFunction
*
F
=
BB
->
getParent
(
)
;
MachineBasicBlock
*
copy0MBB
=
F
->
CreateMachineBasicBlock
(
LLVM_BB
)
;
MachineBasicBlock
*
copy1MBB
=
F
->
CreateMachineBasicBlock
(
LLVM_BB
)
;
F
->
insert
(
I
,
copy0MBB
)
;
F
->
insert
(
I
,
copy1MBB
)
;
copy1MBB
->
splice
(
copy1MBB
->
begin
(
)
,
BB
,
std
::
next
(
MachineBasicBlock
::
iterator
(
MI
)
)
,
BB
->
end
(
)
)
;
copy1MBB
->
transferSuccessorsAndUpdatePHIs
(
BB
)
;
BB
->
addSuccessor
(
copy0MBB
)
;
BB
->
addSuccessor
(
copy1MBB
)
;
BuildMI
(
BB
,
dl
,
TII
.
get
(
CJG
::
JCC
)
)
.
addMBB
(
copy1MBB
)
.
addImm
(
MI
.
getOperand
(
3
)
.
getImm
(
)
)
;
BB
=
copy0MBB
;
BB
->
addSuccessor
(
copy1MBB
)
;
BB
=
copy1MBB
;
BuildMI
(
*
BB
,
BB
->
begin
(
)
,
dl
,
TII
.
get
(
CJG
::
PHI
)
,
MI
.
getOperand
(
0
)
.
getReg
(
)
)
.
addReg
(
MI
.
getOperand
(
2
)
.
getReg
(
)
)
.
addMBB
(
copy0MBB
)
.
addReg
(
MI
.
getOperand
(
1
)
.
getReg
(
)
)
.
addMBB
(
thisMBB
)
;
MI
.
eraseFromParent
(
)
;
return
BB
;
}
</s>

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


<s> bool ARMSubtarget :: enablePostRAScheduler ( ) const { if ( enableMachineScheduler ( ) ) return false ; if ( disablePostRAScheduler ( ) ) return false ; return ! isThumb1Only ( ) ; } </s>

True if the subtarget should run a scheduler after register allocation .


<s> bool AArch64InstrInfo :: analyzeCompare ( const MachineInstr * MI , unsigned & SrcReg , unsigned & SrcReg2 , int & CmpMask , int & CmpValue ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case AArch64 :: SUBSWrr : case AArch64 :: SUBSWrs : case AArch64 :: SUBSWrx : case AArch64 :: SUBSXrr : case AArch64 :: SUBSXrs : case AArch64 :: SUBSXrx : case AArch64 :: ADDSWrr : case AArch64 :: ADDSWrs : case AArch64 :: ADDSWrx : case AArch64 :: ADDSXrr : case AArch64 :: ADDSXrs : case AArch64 :: ADDSXrx : SrcReg = MI -> getOperand ( 1 ) . getReg ( ) ; SrcReg2 = MI -> getOperand ( 2 ) . getReg ( ) ; CmpMask = ~ 0 ; CmpValue = 0 ; return true ; case AArch64 :: SUBSWri : case AArch64 :: ADDSWri : case AArch64 :: SUBSXri : case AArch64 :: ADDSXri : SrcReg = MI -> getOperand ( 1 ) . getReg ( ) ; SrcReg2 = 0 ; CmpMask = ~ 0 ; CmpValue = MI -> getOperand ( 2 ) . getImm ( ) ; return true ; case AArch64 :: ANDSWri : case AArch64 :: ANDSXri : SrcReg = MI -> getOperand ( 1 ) . getReg ( ) ; SrcReg2 = 0 ; CmpMask = ~ 0 ; CmpValue = AArch64_AM :: decodeLogicalImmediate ( MI -> getOperand ( 2 ) . getImm ( ) , MI -> getOpcode ( ) == AArch64 :: ANDSWri ? 32 : 64 ) ; return true ; } return false ; } </s>

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> const RegisterBankInfo * PPCSubtarget :: getRegBankInfo ( ) const { return RegBankInfo . get ( ) ; } </s>

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


<s> bool PPCSubtarget :: enablePostRAScheduler ( CodeGenOpt :: Level OptLevel , TargetSubtargetInfo :: AntiDepBreakMode & Mode , RegClassVector & CriticalPathRCs ) const { if ( DarwinDirective == PPC :: DIR_440 ) return false ; Mode = TargetSubtargetInfo :: ANTIDEP_CRITICAL ; CriticalPathRCs . clear ( ) ; if ( isPPC64 ( ) ) CriticalPathRCs . push_back ( & PPC :: G8RCRegClass ) ; else CriticalPathRCs . push_back ( & PPC :: GPRCRegClass ) ; return OptLevel >= CodeGenOpt :: Default ; } </s>

PowerPC PPC PPC::DIR_440 PPC PPC::G8RCRegClass PPC::GPRCRegClass


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


<s> static bool ix86_is_empty_record ( const_tree type ) { if ( ! TARGET_64BIT ) return false ; return default_is_empty_record ( type ) ; } </s>


Return true if INSN is a multiply-add or multiply-subtract instruction and PREV assigns to the accumulator operand .


<s> X86Subtarget :: X86Subtarget ( const std :: string & TT , const std :: string & CPU , const std :: string & FS , unsigned StackAlignOverride ) : X86GenSubtargetInfo ( TT , CPU , FS ) , X86ProcFamily ( Others ) , PICStyle ( PICStyles :: None ) , TargetTriple ( TT ) , StackAlignOverride ( StackAlignOverride ) , In64BitMode ( TargetTriple . getArch ( ) == Triple :: x86_64 ) , In32BitMode ( TargetTriple . getArch ( ) == Triple :: x86 && TargetTriple . getEnvironment ( ) != Triple :: CODE16 ) , In16BitMode ( TargetTriple . getArch ( ) == Triple :: x86 && TargetTriple . getEnvironment ( ) == Triple :: CODE16 ) { initializeEnvironment ( ) ; resetSubtargetFeatures ( CPU , FS ) ; } </s>

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


"Wasn't expecting to be able to lower this!"

LowerOperation - Provide custom lowering hooks for some operations .


<s> static void push_minipool_barrier ( rtx_insn * insn , HOST_WIDE_INT address ) { Mfix * fix = ( Mfix * ) obstack_alloc ( & minipool_obstack , sizeof ( * fix ) ) ; fix -> insn = insn ; fix -> address = address ; fix -> next = NULL ; if ( minipool_fix_head != NULL ) minipool_fix_tail -> next = fix ; else minipool_fix_head = fix ; minipool_fix_tail = fix ; } </s>

Record that there is a natural barrier in the insn stream at ADDRESS .


<s> static void mips_add_gc_roots ( ) { ggc_add_rtx_root ( & mips_load_reg , 1 ) ; ggc_add_rtx_root ( & mips_load_reg2 , 1 ) ; ggc_add_rtx_root ( & mips_load_reg3 , 1 ) ; ggc_add_rtx_root ( & mips_load_reg4 , 1 ) ; ggc_add_rtx_root ( branch_cmp , sizeof ( branch_cmp ) / sizeof ( rtx ) ) ; ggc_add_rtx_root ( & embedded_pic_fnaddr_rtx , 1 ) ; ggc_add_rtx_root ( & mips16_gp_pseudo_rtx , 1 ) ; } </s>

Called to register all of our global variables with the garbage collector .


<s> bool MipsInstrInfo :: HasFPUDelaySlot ( const MachineInstr & MI ) const { switch ( MI . getOpcode ( ) ) { case Mips :: MTC1 : case Mips :: MFC1 : case Mips :: MTC1_D64 : case Mips :: MFC1_D64 : case Mips :: DMTC1 : case Mips :: DMFC1 : case Mips :: FCMP_S32 : case Mips :: FCMP_D32 : case Mips :: FCMP_D64 : return true ; default : return false ; } } </s>

Predicate to determine if an instruction has an FPU delay slot .


<s> void X86IntelInstPrinter :: printInst ( const MCInst * MI , uint64_t Address , StringRef Annot , const MCSubtargetInfo & STI , raw_ostream & OS ) { printInstFlags ( MI , OS ) ; if ( MI -> getOpcode ( ) == X86 :: DATA16_PREFIX && STI . getFeatureBits ( ) [ X86 :: Mode16Bit ] ) { OS << "\tdata32" ; } else if ( ! printAliasInstr ( MI , Address , OS ) && ! printVecCompareInstr ( MI , OS ) ) printInstruction ( MI , Address , OS ) ; printAnnotation ( OS , Annot ) ; if ( CommentStream ) EmitAnyX86InstComments ( MI , * CommentStream , MII ) ; } </s>

Print the specified MCInst to the specified raw_ostream .


<s>
LLVM_DUMP_METHOD
void
dump
(
const
MachineRegisterInfo
*
MRI
)
const
{
dbgs
(
)
<<
"Registers: "
;
bool
First
=
true
;
for
(
Register
Reg
:
Edges
)
{
if
(
!
First
)
dbgs
(
)
<<
", "
;
First
=
false
;
dbgs
(
)
<<
printReg
(
Reg
,
MRI
->
getTargetRegisterInfo
(
)
,
0
,
MRI
)
;
}
dbgs
(
)
<<
"\n"
<<
"Instructions:"
;
for
(
MachineInstr
*
MI
:
Instrs
)
{
dbgs
(
)
<<
"\n  "
;
MI
->
print
(
dbgs
(
)
)
;
}
dbgs
(
)
<<
"\n"
;
}
</s>

Dump the plan to stderr ( for debugging ) .

X86
"Registers: "
", "
0
"\n"
"Instructions:"
"\n  "
"\n"


<s> static bool get_memref_parts ( rtx mem , rtx * base , HOST_WIDE_INT * offset , HOST_WIDE_INT * size ) { rtx addr_rtx ; if ( MEM_SIZE_KNOWN_P ( mem ) ) * size = MEM_SIZE ( mem ) ; else return false ; addr_rtx = ( XEXP ( mem , 0 ) ) ; if ( GET_CODE ( addr_rtx ) == PRE_MODIFY ) addr_rtx = XEXP ( addr_rtx , 1 ) ; * offset = 0 ; while ( GET_CODE ( addr_rtx ) == PLUS && CONST_INT_P ( XEXP ( addr_rtx , 1 ) ) ) { * offset += INTVAL ( XEXP ( addr_rtx , 1 ) ) ; addr_rtx = XEXP ( addr_rtx , 0 ) ; } if ( ! REG_P ( addr_rtx ) ) return false ; * base = addr_rtx ; return true ; } </s>

Try to determine base/offset/size parts of the given MEM . Return true if successful , false if all the values could n't be determined . This function only looks for REG or REG+CONST address forms . REG+REG address form will return false .


<s> X86TargetMachine :: X86TargetMachine ( const Target & T , const Triple & TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Optional < Reloc :: Model > RM , Optional < CodeModel :: Model > CM , CodeGenOpt :: Level OL , bool JIT ) : LLVMTargetMachine ( T , computeDataLayout ( TT ) , TT , CPU , FS , Options , getEffectiveRelocModel ( TT , RM ) , getEffectiveCodeModel ( CM , JIT , TT . getArch ( ) == Triple :: x86_64 ) , OL ) , TLOF ( createTLOF ( getTargetTriple ( ) ) ) { if ( ( TT . isOSWindows ( ) && TT . getArch ( ) == Triple :: x86_64 ) || TT . isPS4 ( ) || TT . isOSBinFormatMachO ( ) ) this -> Options . TrapUnreachable = true ; initAsmInfo ( ) ; } </s>


<s>
void
AArch64Operand
::
print
(
raw_ostream
&
OS
)
const
{
switch
(
Kind
)
{
case
k_FPImm
:
OS
<<
"<fpimm "
<<
getFPImm
(
)
.
bitcastToAPInt
(
)
.
getZExtValue
(
)
;
if
(
!
getFPImmIsExact
(
)
)
OS
<<
" (inexact)"
;
OS
<<
">"
;
break
;
case
k_Barrier
:
{
StringRef
Name
=
getBarrierName
(
)
;
if
(
!
Name
.
empty
(
)
)
OS
<<
"<barrier "
<<
Name
<<
">"
;
else
OS
<<
"<barrier invalid #"
<<
getBarrier
(
)
<<
">"
;
break
;
}
case
k_Immediate
:
OS
<<
*
getImm
(
)
;
break
;
case
k_ShiftedImm
:
{
unsigned
Shift
=
getShiftedImmShift
(
)
;
OS
<<
"<shiftedimm "
;
OS
<<
*
getShiftedImmVal
(
)
;
OS
<<
", lsl #"
<<
AArch64_AM
::
getShiftValue
(
Shift
)
<<
">"
;
break
;
}
case
k_CondCode
:
OS
<<
"<condcode "
<<
getCondCode
(
)
<<
">"
;
break
;
case
k_VectorList
:
{
OS
<<
"<vectorlist "
;
unsigned
Reg
=
getVectorListStart
(
)
;
for
(
unsigned
i
=
0
,
e
=
getVectorListCount
(
)
;
i
!=
e
;
++
i
)
OS
<<
Reg
+
i
<<
" "
;
OS
<<
">"
;
break
;
}
case
k_VectorIndex
:
OS
<<
"<vectorindex "
<<
getVectorIndex
(
)
<<
">"
;
break
;
case
k_SysReg
:
OS
<<
"<sysreg: "
<<
getSysReg
(
)
<<
'>'
;
break
;
case
k_Token
:
OS
<<
"'"
<<
getToken
(
)
<<
"'"
;
break
;
case
k_SysCR
:
OS
<<
"c"
<<
getSysCR
(
)
;
break
;
case
k_Prefetch
:
{
StringRef
Name
=
getPrefetchName
(
)
;
if
(
!
Name
.
empty
(
)
)
OS
<<
"<prfop "
<<
Name
<<
">"
;
else
OS
<<
"<prfop invalid #"
<<
getPrefetch
(
)
<<
">"
;
break
;
}
case
k_PSBHint
:
OS
<<
getPSBHintName
(
)
;
break
;
case
k_Register
:
OS
<<
"<register "
<<
getReg
(
)
<<
">"
;
if
(
!
getShiftExtendAmount
(
)
&&
!
hasShiftExtendAmount
(
)
)
break
;
LLVM_FALLTHROUGH
;
case
k_BTIHint
:
OS
<<
getBTIHintName
(
)
;
break
;
case
k_ShiftExtend
:
OS
<<
"<"
<<
AArch64_AM
::
getShiftExtendName
(
getShiftExtendType
(
)
)
<<
" #"
<<
getShiftExtendAmount
(
)
;
if
(
!
hasShiftExtendAmount
(
)
)
OS
<<
"<imp>"
;
OS
<<
'>'
;
break
;
}
}
</s>

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

AArch64
AArch64
"<fpimm "
" (inexact)"
">"
"<barrier "
">"
"<barrier invalid #"
">"
"<shiftedimm "
", lsl #"
AArch64_AM::getShiftValue
">"
"<condcode "
">"
"<vectorlist "
0
" "
">"
"<vectorindex "
">"
"<sysreg: "
"'"
"'"
"c"
"<prfop "
">"
"<prfop invalid #"
">"
"<register "
">"
"<"
AArch64_AM::getShiftExtendName
" #"
"<imp>"


<s> void validate_condition_mode ( enum rtx_code code , machine_mode mode ) { gcc_assert ( ( GET_RTX_CLASS ( code ) == RTX_COMPARE || GET_RTX_CLASS ( code ) == RTX_COMM_COMPARE ) && GET_MODE_CLASS ( mode ) == MODE_CC ) ; gcc_assert ( ( code != GT && code != LT && code != GE && code != LE ) || mode != CCUNSmode ) ; gcc_assert ( ( code != GTU && code != LTU && code != GEU && code != LEU ) || mode == CCUNSmode ) ; gcc_assert ( mode == CCFPmode || ( code != ORDERED && code != UNORDERED && code != UNEQ && code != LTGT && code != UNGT && code != UNLT && code != UNGE && code != UNLE ) ) ; gcc_assert ( mode != CCEQmode || code == EQ || code == NE ) ; } </s>

A validation routine : say whether CODE , a condition code , and MODE match . The other alternatives either do n't make sense or should never be generated .


<s>
void
Mips16FrameLowering
::
emitPrologue
(
MachineFunction
&
MF
,
MachineBasicBlock
&
MBB
)
const
{
assert
(
&
MF
.
front
(
)
==
&
MBB
&&
"Shrink-wrapping not yet supported"
)
;
MachineFrameInfo
&
MFI
=
MF
.
getFrameInfo
(
)
;
const
Mips16InstrInfo
&
TII
=
*
static_cast
<
const
Mips16InstrInfo
*
>
(
STI
.
getInstrInfo
(
)
)
;
MachineBasicBlock
::
iterator
MBBI
=
MBB
.
begin
(
)
;
DebugLoc
dl
;
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
=
MF
.
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
.
empty
(
)
)
{
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
=
MF
.
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
"Shrink-wrapping not yet supported"
Mips
Mips
0
Mips::SP
Mips::MoveR3216
Mips::S0
Mips::SP


"\tARM::shouldCoalesce - Coalesced Weight: "


<s> bool XNCMTargetLowering :: isZExtFree ( EVT VT1 , EVT VT2 ) const { return 0 && VT1 == MVT :: i8 && VT2 == MVT :: i16 ; } </s>

Return true if zero-extending the specific node Val to type VT2 is free ( either because it 's implicitly zero-extended such as ARM ldrb / ldrh or because it 's folded such as X86 zero-extending loads ) .


<s> SMLoc getStartLoc ( ) const override { return StartLoc ; } </s>

getStartLoc - Get the location of the first token of this operand .


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

Can this function use the red zone for local allocations .


<s> void assignValueToReg ( unsigned ValVReg , unsigned PhysReg , CCValAssign & VA ) override { markPhysRegUsed ( PhysReg ) ; switch ( VA . getLocInfo ( ) ) { default : { unsigned PhysRegSize = MRI . getTargetRegisterInfo ( ) -> getRegSizeInBits ( PhysReg , MRI ) ; unsigned ValSize = VA . getValVT ( ) . getSizeInBits ( ) ; unsigned LocSize = VA . getLocVT ( ) . getSizeInBits ( ) ; if ( PhysRegSize > ValSize && LocSize == ValSize ) { auto Copy = MIRBuilder . buildCopy ( LLT :: scalar ( PhysRegSize ) , PhysReg ) ; MIRBuilder . buildTrunc ( ValVReg , Copy ) ; return ; } MIRBuilder . buildCopy ( ValVReg , PhysReg ) ; break ; } case CCValAssign :: LocInfo :: SExt : case CCValAssign :: LocInfo :: ZExt : case CCValAssign :: LocInfo :: AExt : { auto Copy = MIRBuilder . buildCopy ( LLT { VA . getLocVT ( ) } , PhysReg ) ; MIRBuilder . buildTrunc ( ValVReg , Copy ) ; break ; } } } </s>

The specified value has been assigned to a physical register , handle the appropriate COPY ( either to or from ) and mark any relevant uses/defines as needed .


<s>
unsigned
X86TTIImpl
::
getScalarizationOverhead
(
Type
*
Ty
,
bool
Insert
,
bool
Extract
)
{
assert
(
Ty
->
isVectorTy
(
)
&&
"Can only scalarize vectors"
)
;
unsigned
Cost
=
0
;
for
(
int
i
=
0
,
e
=
Ty
->
getVectorNumElements
(
)
;
i
<
e
;
++
i
)
{
if
(
Insert
)
Cost
+=
getVectorInstrCost
(
Instruction
::
InsertElement
,
Ty
,
i
)
;
if
(
Extract
)
Cost
+=
getVectorInstrCost
(
Instruction
::
ExtractElement
,
Ty
,
i
)
;
}
return
Cost
;
}
</s>

Estimate the overhead of scalarizing an instruction .


<s> bool PPCTargetLowering :: isFMAFasterThanFMulAndFAdd ( const Function & F , Type * Ty ) const { switch ( Ty -> getScalarType ( ) -> getTypeID ( ) ) { case Type :: FloatTyID : case Type :: DoubleTyID : return true ; case Type :: FP128TyID : return Subtarget . hasP9Vector ( ) ; default : return false ; } } </s>

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


<s> bool X86TargetLowering :: isCheapToSpeculateCtlz ( ) const { return Subtarget -> hasLZCNT ( ) ; } </s>

Return true if it is cheap to speculate a call to intrinsic ctlz .


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

Solaris implementation of TARGET_ASM_NAMED_SECTION .

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


"Invalid mixing of IEEE 128-bit and IBM 128-bit floating "

Return the diagnostic message string if the binary operation OP is not permitted on TYPE1 and TYPE2 , NULL otherwise .


<s> bool AArch64PassConfig :: addGlobalInstructionSelect ( ) { addPass ( new InstructionSelect ( getOptLevel ( ) ) ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) addPass ( createAArch64PostSelectOptimize ( ) ) ; return false ; } </s>

This method should install a ( global ) instruction selector pass , which converts possibly generic instructions to fully target-specific instructions , thereby constraining all generic virtual registers to register classes .


<s>
void
AArch64InstrInfo
::
loadRegFromStackSlot
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MBBI
,
unsigned
DestReg
,
int
FrameIdx
,
const
TargetRegisterClass
*
RC
,
const
TargetRegisterInfo
*
TRI
)
const
{
DebugLoc
DL
=
MBB
.
findDebugLoc
(
MBBI
)
;
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
MachineFrameInfo
&
MFI
=
*
MF
.
getFrameInfo
(
)
;
unsigned
Align
=
MFI
.
getObjectAlignment
(
FrameIdx
)
;
MachineMemOperand
*
MMO
=
MF
.
getMachineMemOperand
(
MachinePointerInfo
::
getFixedStack
(
FrameIdx
)
,
MachineMemOperand
::
MOLoad
,
MFI
.
getObjectSize
(
FrameIdx
)
,
Align
)
;
unsigned
LoadOp
=
0
;
if
(
RC
->
hasType
(
MVT
::
i64
)
||
RC
->
hasType
(
MVT
::
i32
)
)
{
switch
(
RC
->
getSize
(
)
)
{
case
4
:
LoadOp
=
AArch64
::
LS32_LDR
;
break
;
case
8
:
LoadOp
=
AArch64
::
LS64_LDR
;
break
;
default
:
llvm_unreachable
(
"Unknown size for regclass"
)
;
}
}
else
if
(
AArch64
::
FPR8RegClass
.
hasSubClassEq
(
RC
)
)
{
LoadOp
=
AArch64
::
LSFP8_LDR
;
}
else
if
(
AArch64
::
FPR16RegClass
.
hasSubClassEq
(
RC
)
)
{
LoadOp
=
AArch64
::
LSFP16_LDR
;
}
else
if
(
RC
->
hasType
(
MVT
::
f32
)
||
RC
->
hasType
(
MVT
::
f64
)
||
RC
->
hasType
(
MVT
::
f128
)
)
{
switch
(
RC
->
getSize
(
)
)
{
case
4
:
LoadOp
=
AArch64
::
LSFP32_LDR
;
break
;
case
8
:
LoadOp
=
AArch64
::
LSFP64_LDR
;
break
;
case
16
:
LoadOp
=
AArch64
::
LSFP128_LDR
;
break
;
default
:
llvm_unreachable
(
"Unknown size for regclass"
)
;
}
}
else
{
if
(
AArch64
::
DPairRegClass
.
hasSubClassEq
(
RC
)
)
LoadOp
=
AArch64
::
LD1x2_8B
;
else
if
(
AArch64
::
DTripleRegClass
.
hasSubClassEq
(
RC
)
)
LoadOp
=
AArch64
::
LD1x3_8B
;
else
if
(
AArch64
::
DQuadRegClass
.
hasSubClassEq
(
RC
)
)
LoadOp
=
AArch64
::
LD1x4_8B
;
else
if
(
AArch64
::
QPairRegClass
.
hasSubClassEq
(
RC
)
)
LoadOp
=
AArch64
::
LD1x2_16B
;
else
if
(
AArch64
::
QTripleRegClass
.
hasSubClassEq
(
RC
)
)
LoadOp
=
AArch64
::
LD1x3_16B
;
else
if
(
AArch64
::
QQuadRegClass
.
hasSubClassEq
(
RC
)
)
LoadOp
=
AArch64
::
LD1x4_16B
;
else
llvm_unreachable
(
"Unknown reg class"
)
;
MachineInstrBuilder
NewMI
=
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
LoadOp
)
,
DestReg
)
;
NewMI
.
addFrameIndex
(
FrameIdx
)
.
addMemOperand
(
MMO
)
;
return
;
}
MachineInstrBuilder
NewMI
=
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
LoadOp
)
,
DestReg
)
;
NewMI
.
addFrameIndex
(
FrameIdx
)
.
addImm
(
0
)
.
addMemOperand
(
MMO
)
;
}
</s>

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


<s> int MipsSEFrameLowering :: getFrameIndexReference ( const MachineFunction & MF , int FI , Register & FrameReg ) const { const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; MipsABIInfo ABI = STI . getABI ( ) ; if ( MFI . isFixedObjectIndex ( FI ) ) FrameReg = hasFP ( MF ) ? ABI . GetFramePtr ( ) : ABI . GetStackPtr ( ) ; else FrameReg = hasBP ( MF ) ? ABI . GetBasePtr ( ) : ABI . GetStackPtr ( ) ; return MFI . getObjectOffset ( FI ) + MFI . getStackSize ( ) - getOffsetOfLocalArea ( ) + MFI . getOffsetAdjustment ( ) ; } </s>

getFrameIndexReference - This method should return the base register and offset used to reference a frame index location .


<s> const Comet2RegisterInfo * getRegisterInfo ( ) const override { return & RegInfo ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> void aarch64_simd_emit_pair_result_insn ( machine_mode mode , rtx ( * intfn ) ( rtx , rtx , rtx ) , rtx destaddr , rtx op1 ) { rtx mem = gen_rtx_MEM ( mode , destaddr ) ; rtx tmp1 = gen_reg_rtx ( mode ) ; rtx tmp2 = gen_reg_rtx ( mode ) ; emit_insn ( intfn ( tmp1 , op1 , tmp2 ) ) ; emit_move_insn ( mem , tmp1 ) ; mem = adjust_address ( mem , mode , GET_MODE_SIZE ( mode ) ) ; emit_move_insn ( mem , tmp2 ) ; } </s>

Emit code to place a AdvSIMD pair result in memory locations ( with equal registers ) .


<s> void ARMPassConfig :: addIRPasses ( ) { if ( TM -> Options . ThreadModel == ThreadModel :: Single ) addPass ( createLowerAtomicPass ( ) ) ; else addPass ( createAtomicExpandPass ( ) ) ; if ( TM -> getOptLevel ( ) != CodeGenOpt :: None && EnableAtomicTidy ) addPass ( createCFGSimplificationPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) . sinkCommonInsts ( true ) , [ this ] ( const Function & F ) { const auto & ST = this -> TM -> getSubtarget < ARMSubtarget > ( F ) ; return ST . hasAnyDataBarrier ( ) && ! ST . isThumb1Only ( ) ; } ) ) ; addPass ( createMVEGatherScatterLoweringPass ( ) ) ; addPass ( createMVELaneInterleavingPass ( ) ) ; TargetPassConfig :: addIRPasses ( ) ; if ( getOptLevel ( ) == CodeGenOpt :: Aggressive ) addPass ( createARMParallelDSPPass ( ) ) ; if ( TM -> getOptLevel ( ) != CodeGenOpt :: None ) addPass ( createInterleavedAccessPass ( ) ) ; if ( TM -> getTargetTriple ( ) . isOSWindows ( ) ) addPass ( createCFGuardCheckPass ( ) ) ; } </s>

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


"frame pointer should not have been eliminated"


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

Calculate the cost of materializing a 64-bit value .


<s>
static
void
rs6000_debug_target_options
(
tree
args
,
const
char
*
prefix
)
{
if
(
args
==
NULL_TREE
)
fprintf
(
stderr
,
"%s<NULL>"
,
prefix
)
;
else
if
(
TREE_CODE
(
args
)
==
STRING_CST
)
{
char
*
p
=
ASTRDUP
(
TREE_STRING_POINTER
(
args
)
)
;
char
*
q
;
while
(
(
q
=
strtok
(
p
,
","
)
)
!=
)
{
p
=
;
fprintf
(
stderr
,
"%s\"%s\""
,
prefix
,
q
)
;
prefix
=
", "
;
}
}
else
if
(
TREE_CODE
(
args
)
==
TREE_LIST
)
{
do
{
tree
value
=
TREE_VALUE
(
args
)
;
if
(
value
)
{
rs6000_debug_target_options
(
value
,
prefix
)
;
prefix
=
", "
;
}
args
=
TREE_CHAIN
(
args
)
;
}
while
(
args
!=
NULL_TREE
)
;
}
else
gcc_unreachable
(
)
;
return
;
}
</s>

Print out the target options as a list for -mdebug=target .


<s> bool ShouldShrinkFPConstant ( EVT VT ) const override { return ! X86ScalarSSEf64 || VT == MVT :: f80 ; } </s>

If true , then instruction selection should seek to shrink the FP constant of the specified type to a smaller type in order to save space and / or reduce runtime .


<s> bool LanaiAsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count ) const { if ( ( Count % 4 ) != 0 ) return false ; for ( uint64_t i = 0 ; i < Count ; i += 4 ) OS . write ( "\x15\0\0\0" , 4 ) ; return true ; } </s>

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


<s> ScheduleHazardRecognizer * ARMBaseInstrInfo :: CreateTargetMIHazardRecognizer ( const InstrItineraryData * II , const ScheduleDAGMI * DAG ) const { MultiHazardRecognizer * MHR = new MultiHazardRecognizer ( ) ; if ( Subtarget . isCortexM7 ( ) && ! DAG -> hasVRegLiveness ( ) ) MHR -> AddHazardRecognizer ( std :: make_unique < ARMBankConflictHazardRecognizer > ( DAG , 0x4 , true ) ) ; auto BHR = TargetInstrInfo :: CreateTargetMIHazardRecognizer ( II , DAG ) ; MHR -> AddHazardRecognizer ( std :: unique_ptr < ScheduleHazardRecognizer > ( BHR ) ) ; return MHR ; } </s>

Allocate and return a hazard recognizer to use for this target when scheduling the machine instructions before register allocation .


<s> MachineInstr * ARMBaseInstrInfo :: commuteInstructionImpl ( MachineInstr * MI , bool NewMI , unsigned OpIdx1 , unsigned OpIdx2 ) const { switch ( MI -> getOpcode ( ) ) { case ARM :: MOVCCr : case ARM :: t2MOVCCr : { unsigned PredReg = 0 ; ARMCC :: CondCodes CC = getInstrPredicate ( MI , PredReg ) ; if ( CC == ARMCC :: AL || PredReg != ARM :: CPSR ) return nullptr ; MI = TargetInstrInfo :: commuteInstructionImpl ( MI , NewMI , OpIdx1 , OpIdx2 ) ; if ( ! MI ) return nullptr ; MI -> getOperand ( MI -> findFirstPredOperandIdx ( ) ) . setImm ( ARMCC :: getOppositeCondition ( CC ) ) ; return MI ; } } return TargetInstrInfo :: commuteInstructionImpl ( MI , NewMI , OpIdx1 , OpIdx2 ) ; } </s>

Commutes the operands in the given instruction by changing the operands order and/or changing the instruction 's opcode and/or the immediate value operand .

ARM ARM ARM::MOVCCr ARM::t2MOVCCr 0 ARMCC::CondCodes ARMCC::AL ARM::CPSR ARMCC::getOppositeCondition


<s> void XNCMFrameLowering :: emitEpilogue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { } </s>


<s> static int sparc_arg_partial_bytes ( cumulative_args_t cum , machine_mode mode , tree type , bool named ) { int slotno , regno , padding ; slotno = function_arg_slotno ( get_cumulative_args ( cum ) , mode , type , named , false , & regno , & padding ) ; if ( slotno == - 1 ) return 0 ; if ( TARGET_ARCH32 ) { if ( ( slotno + ( mode == BLKmode ? ROUND_ADVANCE ( int_size_in_bytes ( type ) ) : ROUND_ADVANCE ( GET_MODE_SIZE ( mode ) ) ) ) > SPARC_INT_ARG_MAX ) return ( SPARC_INT_ARG_MAX - slotno ) * UNITS_PER_WORD ; } else { if ( type && AGGREGATE_TYPE_P ( type ) ) { int size = int_size_in_bytes ( type ) ; if ( size > UNITS_PER_WORD && slotno == SPARC_INT_ARG_MAX - 1 ) return UNITS_PER_WORD ; } else if ( GET_MODE_CLASS ( mode ) == MODE_COMPLEX_INT || ( GET_MODE_CLASS ( mode ) == MODE_COMPLEX_FLOAT && ! ( TARGET_FPU && named ) ) ) { if ( GET_MODE_SIZE ( mode ) > UNITS_PER_WORD && slotno == SPARC_INT_ARG_MAX - 1 ) return UNITS_PER_WORD ; } else if ( GET_MODE_CLASS ( mode ) == MODE_COMPLEX_FLOAT ) { if ( ( slotno + GET_MODE_SIZE ( mode ) / UNITS_PER_WORD ) > SPARC_FP_ARG_MAX ) return UNITS_PER_WORD ; } } return 0 ; } </s>

For an arg passed partly in registers and partly in memory , this is the number of bytes of registers used . For args passed entirely in registers or entirely in memory , zero . Any arg that starts in the first 6 regs but wo n't entirely fit in them needs partial registers on v8 . On v9 , structures with integer values in arg slots 5,6 will be passed in % o5 and SP+176 , and complex fp values that begin in the last fp reg [ where `` last fp reg '' varies with the mode ] will be split between that reg and memory .


<s> rtx widen_mem_for_ldd_peep ( rtx mem1 , rtx mem2 , machine_mode mode ) { rtx x = widen_memory_access ( mem1 , mode , 0 ) ; MEM_NOTRAP_P ( x ) = MEM_NOTRAP_P ( mem1 ) && MEM_NOTRAP_P ( mem2 ) ; return x ; } </s>

Return the widened memory access made of MEM1 and MEM2 in MODE .


"Can't load this register from stack slot"


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

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


"%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>"

Set the value of FLT_EVAL_METHOD in float.h . When using only the FPU , assume that the fpcw is set to extended precision ; when using only SSE , rounding is correct ; when using both SSE and the FPU , the rounding precision is indeterminate , since either may be chosen apparently at random .


<s> static rtx_insn * emit_frame_save ( rtx frame_reg , machine_mode mode , unsigned int regno , int offset , HOST_WIDE_INT frame_reg_to_sp ) { rtx reg ; gcc_checking_assert ( ! ( ( TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE ( mode ) ) || ( TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE ( mode ) ) || ( TARGET_E500_DOUBLE && mode == DFmode ) || ( TARGET_SPE_ABI && SPE_VECTOR_MODE ( mode ) && ! SPE_CONST_OFFSET_OK ( offset ) ) ) ) ; reg = gen_rtx_REG ( mode , regno ) ; rtx_insn * insn = emit_insn ( gen_frame_store ( reg , frame_reg , offset ) ) ; return rs6000_frame_related ( insn , frame_reg , frame_reg_to_sp , NULL_RTX , NULL_RTX ) ; } </s>

Save a register into the frame , and emit RTX_FRAME_RELATED_P notes . Save REGNO into [ FRAME_REG + OFFSET ] in mode MODE .


Return an array that contains the bitmask target flag values and their names .

PowerPC PPC PPC "ppc-plt" "ppc-pic" "ppc-pcrel" "ppc-got" "ppc-opt-pcrel"


<s> MCObjectStreamer & getStreamer ( ) { return static_cast < MCObjectStreamer & > ( Streamer ) ; } </s>

Return the output streamer for the assembler .


<s> void X86PassConfig :: addPreEmitPass2 ( ) { addPass ( createX86RetpolineThunksPass ( ) ) ; const Triple & TT = TM -> getTargetTriple ( ) ; const MCAsmInfo * MAI = TM -> getMCAsmInfo ( ) ; if ( ! TT . isOSDarwin ( ) && ( ! TT . isOSWindows ( ) || MAI -> getExceptionHandlingType ( ) == ExceptionHandling :: DwarfCFI ) ) addPass ( createCFIInstrInserter ( ) ) ; } </s>

Targets may add passes immediately before machine code is emitted in this callback .


<s> static bool mips_interrupt_type_p ( tree type ) { return lookup_attribute ( "interrupt" , TYPE_ATTRIBUTES ( type ) ) != NULL ; } </s>

Check if the interrupt attribute is set for a function .


<s> unsigned MipsAsmParser :: getReg ( int RC , int RegNo ) { return * ( getContext ( ) . getRegisterInfo ( ) . getRegClass ( RC ) . begin ( ) + RegNo ) ; } </s>

Returns the register associated with this edge .


<s> void OutgoingValueHandler :: assignValueToReg ( Register ValVReg , const CCValAssign & VA , const EVT & VT ) { Register PhysReg = VA . getLocReg ( ) ; const MipsSubtarget & STI = static_cast < const MipsSubtarget & > ( MIRBuilder . getMF ( ) . getSubtarget ( ) ) ; if ( VT == MVT :: f64 && PhysReg >= Mips :: A0 && PhysReg <= Mips :: A3 ) { MIRBuilder . buildInstr ( STI . isFP64bit ( ) ? Mips :: ExtractElementF64_64 : Mips :: ExtractElementF64 ) . addDef ( PhysReg + ( STI . isLittle ( ) ? 1 : 0 ) ) . addUse ( ValVReg ) . addImm ( 1 ) . constrainAllUses ( MIRBuilder . getTII ( ) , * STI . getRegisterInfo ( ) , * STI . getRegBankInfo ( ) ) ; MIRBuilder . buildInstr ( STI . isFP64bit ( ) ? Mips :: ExtractElementF64_64 : Mips :: ExtractElementF64 ) . addDef ( PhysReg + ( STI . isLittle ( ) ? 0 : 1 ) ) . addUse ( ValVReg ) . addImm ( 0 ) . constrainAllUses ( MIRBuilder . getTII ( ) , * STI . getRegisterInfo ( ) , * STI . getRegBankInfo ( ) ) ; } else if ( VT == MVT :: f32 && PhysReg >= Mips :: A0 && PhysReg <= Mips :: A3 ) { MIRBuilder . buildInstr ( Mips :: MFC1 ) . addDef ( PhysReg ) . addUse ( ValVReg ) . constrainAllUses ( MIRBuilder . getTII ( ) , * STI . getRegisterInfo ( ) , * STI . getRegBankInfo ( ) ) ; } else { Register ExtReg = extendRegister ( ValVReg , VA ) ; MIRBuilder . buildCopy ( PhysReg , ExtReg ) ; MIB . addUse ( PhysReg , RegState :: Implicit ) ; } } </s>

The specified value has been assigned to a physical register , handle the appropriate COPY ( either to or from ) and mark any relevant uses/defines as needed .


<s>
static
tree
resolve_vec_step
(
resolution
*
res
,
vec
<
tree
,
va_gc
>
*
arglist
,
unsigned
nargs
)
{
if
(
nargs
!=
1
)
{
error
(
"builtin %qs only accepts 1 argument"
,
"vec_step"
)
;
*
res
=
resolved
;
return
error_mark_node
;
}
tree
arg0
=
(
*
arglist
)
[
0
]
;
tree
arg0_type
=
TREE_TYPE
(
arg0
)
;
if
(
TREE_CODE
(
arg0_type
)
!=
VECTOR_TYPE
)
{
*
res
=
resolved_bad
;
return
error_mark_node
;
}
*
res
=
resolved
;
return
build_int_cst
(
NULL_TREE
,
TYPE_VECTOR_SUBPARTS
(
arg0_type
)
)
;
}
</s>

Resolve an overloaded vec_step call and return a tree expression for the resolved call if successful . NARGS is the number of arguments to the call . ARGLIST contains the arguments . RES must be set to indicate the status of the resolution attempt .


<s> static void register_builtin_types ( ) { scalar_types [ VECTOR_TYPE_ ## ACLE_NAME ] = SCALAR_TYPE ; for ( unsigned int i = 0 ; i < NUM_VECTOR_TYPES ; ++ i ) { tree eltype = scalar_types [ i ] ; tree vectype ; unsigned int num_zr = 0 , num_pr = 0 ; if ( eltype == boolean_type_node ) { vectype = build_truth_vector_type_for_mode ( BYTES_PER_SVE_VECTOR , VNx16BImode ) ; gcc_assert ( TYPE_MODE ( vectype ) == VNx16BImode && TYPE_MODE ( vectype ) == TYPE_MODE_RAW ( vectype ) && TYPE_ALIGN ( vectype ) == 16 && known_eq ( wi :: to_poly_offset ( TYPE_SIZE ( vectype ) ) , BYTES_PER_SVE_VECTOR ) ) ; num_pr = 1 ; } else { scalar_mode elmode = SCALAR_TYPE_MODE ( eltype ) ; unsigned int elbytes = GET_MODE_SIZE ( elmode ) ; poly_uint64 nunits = exact_div ( BYTES_PER_SVE_VECTOR , elbytes ) ; machine_mode mode = aarch64_sve_data_mode ( elmode , nunits ) . require ( ) ; vectype = build_vector_type_for_mode ( eltype , mode ) ; gcc_assert ( VECTOR_MODE_P ( TYPE_MODE ( vectype ) ) && TYPE_MODE ( vectype ) == mode && TYPE_MODE_RAW ( vectype ) == mode && TYPE_ALIGN ( vectype ) == 128 && known_eq ( wi :: to_poly_offset ( TYPE_SIZE ( vectype ) ) , BITS_PER_SVE_VECTOR ) ) ; num_zr = 1 ; } vectype = build_distinct_type_copy ( vectype ) ; gcc_assert ( vectype == TYPE_MAIN_VARIANT ( vectype ) ) ; SET_TYPE_STRUCTURAL_EQUALITY ( vectype ) ; TYPE_ARTIFICIAL ( vectype ) = 1 ; TYPE_INDIVISIBLE_P ( vectype ) = 1 ; add_sve_type_attribute ( vectype , num_zr , num_pr , vector_types [ i ] . mangled_name , vector_types [ i ] . acle_name ) ; make_type_sizeless ( vectype ) ; abi_vector_types [ i ] = vectype ; lang_hooks . types . register_builtin_type ( vectype , vector_types [ i ] . abi_name ) ; } } </s>

Register the built-in RVV ABI types , such as __rvv_int32m1_t .


<s> void rs6000_cost_data :: update_target_cost_per_stmt ( vect_cost_for_stmt kind , stmt_vec_info stmt_info , vect_cost_model_location where , unsigned int orig_count ) { if ( kind == vec_to_scalar || kind == vec_perm || kind == vec_promote_demote || kind == vec_construct || kind == scalar_to_vec || ( where == vect_body && kind == vector_stmt ) ) m_vect_nonmem = true ; if ( ! m_costing_for_scalar && is_a < loop_vec_info > ( m_vinfo ) && where == vect_body ) { m_nstmts += orig_count ; if ( kind == scalar_load || kind == vector_load || kind == unaligned_load || kind == vector_gather_load ) { m_nloads += orig_count ; if ( stmt_info && STMT_VINFO_GATHER_SCATTER_P ( stmt_info ) ) m_gather_load = true ; } else if ( kind == scalar_store || kind == vector_store || kind == unaligned_store || kind == vector_scatter_store ) m_nstores += orig_count ; else if ( ( kind == scalar_stmt || kind == vector_stmt || kind == vec_to_scalar ) && stmt_info && vect_is_reduction ( stmt_info ) ) { tree lhs = gimple_get_lhs ( stmt_info -> stmt ) ; bool is_float = FLOAT_TYPE_P ( TREE_TYPE ( lhs ) ) ; unsigned int basic_cost = is_float ? 2 : 1 ; m_reduc_factor = MAX ( basic_cost * orig_count , m_reduc_factor ) ; } if ( kind == vec_construct && stmt_info && STMT_VINFO_TYPE ( stmt_info ) == load_vec_info_type && ( STMT_VINFO_MEMORY_ACCESS_TYPE ( stmt_info ) == VMAT_ELEMENTWISE || STMT_VINFO_MEMORY_ACCESS_TYPE ( stmt_info ) == VMAT_STRIDED_SLP ) ) { tree vectype = STMT_VINFO_VECTYPE ( stmt_info ) ; unsigned int nunits = vect_nunits_for_cost ( vectype ) ; if ( nunits == 1 ) return ; unsigned int adjusted_cost = ( nunits == 2 ) ? 2 : 1 ; unsigned int extra_cost = nunits * adjusted_cost ; m_extra_ctor_cost += extra_cost ; } } } </s>

Helper function for add_stmt_cost . Check each statement cost entry , gather information and update the target_cost fields accordingly .


<s> void Thumb2InstrInfo :: 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 == ARM :: GPRRegisterClass ) { MachineFunction & MF = * MBB . getParent ( ) ; MachineFrameInfo & MFI = * MF . getFrameInfo ( ) ; MachineMemOperand * MMO = MF . getMachineMemOperand ( PseudoSourceValue :: getFixedStack ( FI ) , MachineMemOperand :: MOStore , 0 , MFI . getObjectSize ( FI ) , MFI . getObjectAlignment ( FI ) ) ; AddDefaultPred ( BuildMI ( MBB , I , DL , get ( ARM :: t2STRi12 ) ) . addReg ( SrcReg , getKillRegState ( isKill ) ) . addFrameIndex ( FI ) . addImm ( 0 ) . addMemOperand ( MMO ) ) ; return ; } ARMBaseInstrInfo :: storeRegToStackSlot ( MBB , I , SrcReg , isKill , FI , RC ) ; } </s>

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


<s> Value * ARMTargetLowering :: emitStoreConditional ( IRBuilder < > & Builder , Value * Val , Value * Addr , AtomicOrdering Ord ) const { Module * M = Builder . GetInsertBlock ( ) -> getParent ( ) -> getParent ( ) ; bool IsRelease = Ord == Release || Ord == AcquireRelease || Ord == SequentiallyConsistent ; if ( Val -> getType ( ) -> getPrimitiveSizeInBits ( ) == 64 ) { Intrinsic :: ID Int = IsRelease ? Intrinsic :: arm_stlexd : Intrinsic :: arm_strexd ; Function * Strex = Intrinsic :: getDeclaration ( M , Int ) ; Type * Int32Ty = Type :: getInt32Ty ( M -> getContext ( ) ) ; Value * Lo = Builder . CreateTrunc ( Val , Int32Ty , "lo" ) ; Value * Hi = Builder . CreateTrunc ( Builder . CreateLShr ( Val , 32 ) , Int32Ty , "hi" ) ; Addr = Builder . CreateBitCast ( Addr , Type :: getInt8PtrTy ( M -> getContext ( ) ) ) ; return Builder . CreateCall3 ( Strex , Lo , Hi , Addr ) ; } Intrinsic :: ID Int = IsRelease ? Intrinsic :: arm_stlex : Intrinsic :: arm_strex ; Type * Tys [ ] = { Addr -> getType ( ) } ; Function * Strex = Intrinsic :: getDeclaration ( M , Int , Tys ) ; return Builder . CreateCall2 ( Strex , Builder . CreateZExtOrBitCast ( Val , Strex -> getFunctionType ( ) -> getParamType ( 0 ) ) , Addr ) ; } </s>

Perform a store-conditional operation to Addr .


<s> static void seh_frame_related_expr ( FILE * f , struct seh_frame_state * seh , rtx pat ) { rtx dest , src ; HOST_WIDE_INT addend ; if ( GET_CODE ( pat ) == PARALLEL || GET_CODE ( pat ) == SEQUENCE ) { int i , n = XVECLEN ( pat , 0 ) , pass , npass ; npass = ( GET_CODE ( pat ) == PARALLEL ? 2 : 1 ) ; for ( pass = 0 ; pass < npass ; ++ pass ) for ( i = 0 ; i < n ; ++ i ) { rtx ele = XVECEXP ( pat , 0 , i ) ; if ( GET_CODE ( ele ) != SET ) continue ; dest = SET_DEST ( ele ) ; if ( i == 0 || RTX_FRAME_RELATED_P ( ele ) ) { if ( ( MEM_P ( dest ) ^ pass ) || npass == 1 ) seh_frame_related_expr ( f , seh , ele ) ; } } return ; } dest = SET_DEST ( pat ) ; src = SET_SRC ( pat ) ; switch ( GET_CODE ( dest ) ) { case REG : switch ( GET_CODE ( src ) ) { case REG : gcc_assert ( src == stack_pointer_rtx ) ; gcc_assert ( dest == hard_frame_pointer_rtx ) ; seh_cfa_adjust_cfa ( f , seh , pat ) ; break ; case PLUS : addend = INTVAL ( XEXP ( src , 1 ) ) ; src = XEXP ( src , 0 ) ; if ( dest == hard_frame_pointer_rtx ) seh_cfa_adjust_cfa ( f , seh , pat ) ; else if ( dest == stack_pointer_rtx ) { gcc_assert ( src == stack_pointer_rtx ) ; seh_emit_stackalloc ( f , seh , addend ) ; } else gcc_unreachable ( ) ; break ; default : gcc_unreachable ( ) ; } break ; case MEM : dest = XEXP ( dest , 0 ) ; if ( GET_CODE ( dest ) == PRE_DEC ) { gcc_checking_assert ( GET_MODE ( src ) == Pmode ) ; gcc_checking_assert ( REG_P ( src ) ) ; seh_emit_push ( f , seh , src ) ; } else seh_cfa_offset ( f , seh , pat ) ; break ; default : gcc_unreachable ( ) ; } } </s>


"Can only insert epilog into returning blocks"

"Expected to see callee-save register restore code"


<s> HOST_WIDE_INT compute_frame_size ( HOST_WIDE_INT size ) { int regno ; HOST_WIDE_INT total_size ; HOST_WIDE_INT var_size ; HOST_WIDE_INT args_size ; HOST_WIDE_INT extra_size ; HOST_WIDE_INT gp_reg_rounded ; HOST_WIDE_INT gp_reg_size ; HOST_WIDE_INT fp_reg_size ; long mask ; gp_reg_size = 0 ; fp_reg_size = 0 ; mask = 0 ; extra_size = IQ2000_STACK_ALIGN ( ( 0 ) ) ; var_size = IQ2000_STACK_ALIGN ( size ) ; args_size = IQ2000_STACK_ALIGN ( crtl -> outgoing_args_size ) ; if ( args_size == 0 && cfun -> calls_alloca ) args_size = 4 * UNITS_PER_WORD ; total_size = var_size + args_size + extra_size ; for ( regno = GP_REG_FIRST ; regno <= GP_REG_LAST ; regno ++ ) { if ( MUST_SAVE_REGISTER ( regno ) ) { gp_reg_size += GET_MODE_SIZE ( gpr_mode ) ; mask |= 1L << ( regno - GP_REG_FIRST ) ; } } if ( crtl -> calls_eh_return ) { unsigned int i ; for ( i = 0 ; ; ++ i ) { regno = EH_RETURN_DATA_REGNO ( i ) ; if ( regno == ( int ) INVALID_REGNUM ) break ; gp_reg_size += GET_MODE_SIZE ( gpr_mode ) ; mask |= 1L << ( regno - GP_REG_FIRST ) ; } } gp_reg_rounded = IQ2000_STACK_ALIGN ( gp_reg_size ) ; total_size += gp_reg_rounded + IQ2000_STACK_ALIGN ( fp_reg_size ) ; if ( total_size == extra_size && ! profile_flag ) total_size = extra_size = 0 ; total_size += IQ2000_STACK_ALIGN ( crtl -> args . pretend_args_size ) ; cfun -> machine -> total_size = total_size ; cfun -> machine -> var_size = var_size ; cfun -> machine -> args_size = args_size ; cfun -> machine -> extra_size = extra_size ; cfun -> machine -> gp_reg_size = gp_reg_size ; cfun -> machine -> fp_reg_size = fp_reg_size ; cfun -> machine -> mask = mask ; cfun -> machine -> initialized = reload_completed ; cfun -> machine -> num_gp = gp_reg_size / UNITS_PER_WORD ; if ( mask ) { unsigned long offset ; offset = ( args_size + extra_size + var_size + gp_reg_size - GET_MODE_SIZE ( gpr_mode ) ) ; cfun -> machine -> gp_sp_offset = offset ; cfun -> machine -> gp_save_offset = offset - total_size ; } else { cfun -> machine -> gp_sp_offset = 0 ; cfun -> machine -> gp_save_offset = 0 ; } cfun -> machine -> fp_sp_offset = 0 ; cfun -> machine -> fp_save_offset = 0 ; return total_size ; } </s>

Typical stack layout should looks like this after the function 's prologue : | | -- ^ | | \ | | | arguments saved | Increasing | | on the stack | addresses PARENT arg pointer - > | | / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | - space for argument split between regs & stack -- CHILD | | \ < -- ( return address here ) | | other call | | saved registers | | / -- frame pointer - > | | \ ___ | | local | | | variables |f | | / |r -- |a | | \ |m | | outgoing |e | | arguments | | Decreasing ( hard ) frame pointer | | / | | addresses and stack pointer - > | | / _|_ | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- V


<s> bool SystemZPassConfig :: addInstSelector ( ) { addPass ( createSystemZISelDag ( getSystemZTargetMachine ( ) , getOptLevel ( ) ) ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) addPass ( createSystemZLDCleanupPass ( getSystemZTargetMachine ( ) ) ) ; return false ; } </s>

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

SystemZ SystemZ SystemZ SystemZ SystemZ SystemZ


<s> Value * X86TargetLowering :: getSafeStackPointerLocation ( IRBuilder < > & IRB ) const { if ( ! Subtarget -> isTargetAndroid ( ) ) return TargetLowering :: getSafeStackPointerLocation ( IRB ) ; unsigned AddressSpace , Offset ; if ( Subtarget -> is64Bit ( ) ) { Offset = 0x48 ; if ( getTargetMachine ( ) . getCodeModel ( ) == CodeModel :: Kernel ) AddressSpace = 256 ; else AddressSpace = 257 ; } else { Offset = 0x24 ; AddressSpace = 256 ; } return ConstantExpr :: getIntToPtr ( ConstantInt :: get ( Type :: getInt32Ty ( IRB . getContext ( ) ) , Offset ) , Type :: getInt8PtrTy ( IRB . getContext ( ) ) -> getPointerTo ( AddressSpace ) ) ; } </s>

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


<s> void SparcRegisterInfo :: eliminateFrameIndex ( MachineBasicBlock :: iterator II , int SPAdj , unsigned FIOperandNum , RegScavenger * RS ) const { assert ( SPAdj == 0 && "Unexpected" ) ; MachineInstr & MI = * II ; DebugLoc dl = MI . getDebugLoc ( ) ; int FrameIndex = MI . getOperand ( FIOperandNum ) . getIndex ( ) ; MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; const SparcSubtarget & Subtarget = MF . getSubtarget < SparcSubtarget > ( ) ; const SparcFrameLowering * TFI = getFrameLowering ( MF ) ; unsigned FrameReg ; int Offset ; Offset = TFI -> getFrameIndexReference ( MF , FrameIndex , FrameReg ) ; Offset += MI . getOperand ( FIOperandNum + 1 ) . getImm ( ) ; if ( ! Subtarget . isV9 ( ) || ! Subtarget . hasHardQuad ( ) ) { if ( MI . getOpcode ( ) == SP :: STQFri ) { const TargetInstrInfo & TII = * Subtarget . getInstrInfo ( ) ; unsigned SrcReg = MI . getOperand ( 2 ) . getReg ( ) ; unsigned SrcEvenReg = getSubReg ( SrcReg , SP :: sub_even64 ) ; unsigned SrcOddReg = getSubReg ( SrcReg , SP :: sub_odd64 ) ; MachineInstr * StMI = BuildMI ( * MI . getParent ( ) , II , dl , TII . get ( SP :: STDFri ) ) . addReg ( FrameReg ) . addImm ( 0 ) . addReg ( SrcEvenReg ) ; replaceFI ( MF , * StMI , * StMI , dl , 0 , Offset , FrameReg ) ; MI . setDesc ( TII . get ( SP :: STDFri ) ) ; MI . getOperand ( 2 ) . setReg ( SrcOddReg ) ; Offset += 8 ; } else if ( MI . getOpcode ( ) == SP :: LDQFri ) { const TargetInstrInfo & TII = * Subtarget . getInstrInfo ( ) ; unsigned DestReg = MI . getOperand ( 0 ) . getReg ( ) ; unsigned DestEvenReg = getSubReg ( DestReg , SP :: sub_even64 ) ; unsigned DestOddReg = getSubReg ( DestReg , SP :: sub_odd64 ) ; MachineInstr * StMI = BuildMI ( * MI . getParent ( ) , II , dl , TII . get ( SP :: LDDFri ) , DestEvenReg ) . addReg ( FrameReg ) . addImm ( 0 ) ; replaceFI ( MF , * StMI , * StMI , dl , 1 , Offset , FrameReg ) ; MI . setDesc ( TII . get ( SP :: LDDFri ) ) ; MI . getOperand ( 0 ) . setReg ( DestOddReg ) ; Offset += 8 ; } } replaceFI ( MF , II , MI , dl , FIOperandNum , Offset , FrameReg ) ; } </s>

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


<s> BitVector AArch64RegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; Reserved . set ( AArch64 :: XSP ) ; Reserved . set ( AArch64 :: WSP ) ; Reserved . set ( AArch64 :: XZR ) ; Reserved . set ( AArch64 :: WZR ) ; if ( TFI -> hasFP ( MF ) ) { Reserved . set ( AArch64 :: X29 ) ; Reserved . set ( AArch64 :: W29 ) ; } 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> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const override { return createSystemZObjectWriter ( OS , OSABI ) ; } </s>

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


<s> void ix86_expand_copysign ( rtx operands [ ] ) { machine_mode mode , vmode ; rtx dest , op0 , op1 , mask , nmask ; dest = operands [ 0 ] ; op0 = operands [ 1 ] ; op1 = operands [ 2 ] ; mode = GET_MODE ( dest ) ; if ( mode == SFmode ) vmode = V4SFmode ; else if ( mode == DFmode ) vmode = V2DFmode ; else vmode = mode ; if ( GET_CODE ( op0 ) == CONST_DOUBLE ) { rtx ( * copysign_insn ) ( rtx , rtx , rtx , rtx ) ; if ( real_isneg ( CONST_DOUBLE_REAL_VALUE ( op0 ) ) ) op0 = simplify_unary_operation ( ABS , mode , op0 , mode ) ; if ( mode == SFmode || mode == DFmode ) { if ( op0 == CONST0_RTX ( mode ) ) op0 = CONST0_RTX ( vmode ) ; else { rtx v = ix86_build_const_vector ( vmode , false , op0 ) ; op0 = force_reg ( vmode , v ) ; } } else if ( op0 != CONST0_RTX ( mode ) ) op0 = force_reg ( mode , op0 ) ; mask = ix86_build_signbit_mask ( vmode , 0 , 0 ) ; if ( mode == SFmode ) copysign_insn = gen_copysignsf3_const ; else if ( mode == DFmode ) copysign_insn = gen_copysigndf3_const ; else copysign_insn = gen_copysigntf3_const ; emit_insn ( copysign_insn ( dest , op0 , op1 , mask ) ) ; } else { rtx ( * copysign_insn ) ( rtx , rtx , rtx , rtx , rtx , rtx ) ; nmask = ix86_build_signbit_mask ( vmode , 0 , 1 ) ; mask = ix86_build_signbit_mask ( vmode , 0 , 0 ) ; if ( mode == SFmode ) copysign_insn = gen_copysignsf3_var ; else if ( mode == DFmode ) copysign_insn = gen_copysigndf3_var ; else copysign_insn = gen_copysigntf3_var ; emit_insn ( copysign_insn ( dest , NULL_RTX , op0 , op1 , nmask , mask ) ) ; } } </s>

Expand a copysign operation . Special case operand 0 being a constant .


<s> unsigned get213Opcode ( ) const { return Opcodes [ Form213 ] ; } </s>


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


<s> unsigned Cpu0SEInstrInfo :: loadImmediate ( int64_t Imm , MachineBasicBlock & MBB , MachineBasicBlock :: iterator II , const DebugLoc & DL , unsigned * NewImm ) const { Cpu0AnalyzeImmediate AnalyzeImm ; unsigned Size = 32 ; unsigned LUi = Cpu0 :: LUi ; unsigned ZEROReg = Cpu0 :: ZERO ; unsigned ATReg = Cpu0 :: AT ; bool LastInstrIsADDiu = NewImm ; const Cpu0AnalyzeImmediate :: InstSeq & Seq = AnalyzeImm . Analyze ( Imm , Size , LastInstrIsADDiu ) ; Cpu0AnalyzeImmediate :: InstSeq :: const_iterator Inst = Seq . begin ( ) ; assert ( Seq . size ( ) && ( ! LastInstrIsADDiu || ( Seq . size ( ) > 1 ) ) ) ; if ( Inst -> Opc == LUi ) BuildMI ( MBB , II , DL , get ( LUi ) , ATReg ) . addImm ( SignExtend64 < 16 > ( Inst -> ImmOperand ) ) ; else BuildMI ( MBB , II , DL , get ( Inst -> Opc ) , ATReg ) . addReg ( ZEROReg ) . addImm ( SignExtend64 < 16 > ( Inst -> ImmOperand ) ) ; for ( ++ Inst ; Inst != Seq . end ( ) - LastInstrIsADDiu ; ++ Inst ) BuildMI ( MBB , II , DL , get ( Inst -> Opc ) , ATReg ) . addReg ( ATReg ) . addImm ( SignExtend64 < 16 > ( Inst -> ImmOperand ) ) ; if ( LastInstrIsADDiu ) * NewImm = Inst -> ImmOperand ; return ATReg ; } </s>

Emit a series of instructions to load an immediate .


<s> void X86IntelInstPrinter :: printInst ( const MCInst * MI , raw_ostream & OS ) { printInstruction ( MI , OS ) ; if ( CommentStream ) EmitAnyX86InstComments ( MI , * CommentStream , getRegisterName ) ; } </s>

Print the specified MCInst to the specified raw_ostream .


<s>
bool
AArch64A53Fix835769
::
runOnMachineFunction
(
MachineFunction
&
F
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"***** AArch64A53Fix835769 *****\n"
)
;
auto
&
STI
=
F
.
getSubtarget
<
AArch64Subtarget
>
(
)
;
if
(
!
STI
.
fixCortexA53_835769
(
)
)
return
false
;
bool
Changed
=
false
;
TII
=
STI
.
getInstrInfo
(
)
;
for
(
auto
&
MBB
:
F
)
{
Changed
|=
runOnBasicBlock
(
MBB
)
;
}
return
Changed
;
}
</s>

runOnMachineFunction - Emit the function body .