<s> RISCVSubtarget & RISCVSubtarget :: initializeSubtargetDependencies ( const Triple & TT , StringRef CPU , StringRef FS , StringRef ABIName ) { bool Is64Bit = TT . isArch64Bit ( ) ; std :: string CPUName = std :: string ( CPU ) ; if ( CPUName . empty ( ) ) CPUName = Is64Bit ? "generic-rv64" : "generic-rv32" ; ParseSubtargetFeatures ( CPUName , CPUName , FS ) ; if ( Is64Bit ) { XLenVT = MVT :: i64 ; XLen = 64 ; } TargetABI = RISCVABI :: computeTargetABI ( TT , getFeatureBits ( ) , ABIName ) ; RISCVFeatures :: validate ( TT , getFeatureBits ( ) ) ; return * this ; } </s>

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


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

Return true if the target supports masked scatter .


"Can't store this register to stack slot"

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


<s> static void riscv_expand_conditional_move_onesided ( rtx dest , rtx cons , rtx alt , rtx_code code , rtx op0 , rtx op1 ) { machine_mode mode = GET_MODE ( dest ) ; gcc_assert ( GET_MODE_CLASS ( mode ) == MODE_INT ) ; gcc_assert ( reg_or_0_operand ( cons , mode ) ) ; gcc_assert ( reg_or_0_operand ( alt , mode ) ) ; riscv_emit_int_compare ( & code , & op0 , & op1 , true ) ; rtx cond = gen_rtx_fmt_ee ( code , mode , op0 , op1 ) ; rtx tmp1 = gen_reg_rtx ( mode ) ; rtx tmp2 = gen_reg_rtx ( mode ) ; emit_insn ( gen_rtx_SET ( tmp1 , gen_rtx_IF_THEN_ELSE ( mode , cond , cons , const0_rtx ) ) ) ; cond = gen_rtx_fmt_ee ( ( code == EQ ) ? NE : EQ , mode , op0 , op1 ) ; emit_insn ( gen_rtx_SET ( tmp2 , gen_rtx_IF_THEN_ELSE ( mode , cond , alt , const0_rtx ) ) ) ; emit_insn ( gen_rtx_SET ( dest , gen_rtx_IOR ( mode , tmp1 , tmp2 ) ) ) ; } </s>

Helper to emit two one-sided conditional moves for the movecc .


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

Return the vector type associated with type suffix TYPE .


<s> bool apply_mask_policy_p ( ) const override { return false ; } </s>

We choose to apply mask policy operand by default since most of the intrinsics has mask policy operand .


<s>
const
uint32_t
*
RISCVRegisterInfo
::
getCallPreservedMask
(
const
MachineFunction
&
MF
,
CallingConv
::
ID
CC
)
const
{
auto
&
Subtarget
=
MF
.
getSubtarget
<
RISCVSubtarget
>
(
)
;
if
(
CC
==
CallingConv
::
GHC
)
return
CSR_NoRegs_RegMask
;
switch
(
Subtarget
.
getTargetABI
(
)
)
{
default
:
llvm_unreachable
(
"Unrecognized ABI"
)
;
case
RISCVABI
::
ABI_ILP32
:
case
RISCVABI
::
ABI_LP64
:
return
CSR_ILP32_LP64_RegMask
;
case
RISCVABI
::
ABI_ILP32F
:
case
RISCVABI
::
ABI_LP64F
:
return
CSR_ILP32F_LP64F_RegMask
;
case
RISCVABI
::
ABI_ILP32D
:
case
RISCVABI
::
ABI_LP64D
:
return
CSR_ILP32D_LP64D_RegMask
;
}
}
</s>

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


<s> rtx riscv_gen_gpr_save_insn ( struct riscv_frame_info * frame ) { unsigned count = riscv_save_libcall_count ( frame -> mask ) ; unsigned veclen = 1 + 2 + 1 + count ; rtvec vec = rtvec_alloc ( veclen ) ; gcc_assert ( veclen <= ARRAY_SIZE ( gpr_save_reg_order ) ) ; RTVEC_ELT ( vec , 0 ) = gen_rtx_UNSPEC_VOLATILE ( VOIDmode , gen_rtvec ( 1 , GEN_INT ( count ) ) , UNSPECV_GPR_SAVE ) ; for ( unsigned i = 1 ; i < veclen ; ++ i ) { unsigned regno = gpr_save_reg_order [ i ] ; rtx reg = gen_rtx_REG ( Pmode , regno ) ; rtx elt ; if ( i < 3 ) elt = gen_rtx_CLOBBER ( Pmode , reg ) ; else elt = gen_rtx_USE ( Pmode , reg ) ; RTVEC_ELT ( vec , i ) = elt ; } gcc_assert ( ( count == 0 ) || BITSET_P ( frame -> mask , gpr_save_reg_order [ veclen - 1 ] ) ) ; return gen_rtx_PARALLEL ( VOIDmode , vec ) ; } </s>

Helper function for generating gpr_save pattern .


<s> const char * RISCVTargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( ( RISCVISD :: NodeType ) Opcode ) { case RISCVISD :: FIRST_NUMBER : break ; case RISCVISD :: RET_FLAG : return "RISCVISD::RET_FLAG" ; case RISCVISD :: URET_FLAG : return "RISCVISD::URET_FLAG" ; case RISCVISD :: SRET_FLAG : return "RISCVISD::SRET_FLAG" ; case RISCVISD :: MRET_FLAG : return "RISCVISD::MRET_FLAG" ; case RISCVISD :: CALL : return "RISCVISD::CALL" ; case RISCVISD :: SELECT_CC : return "RISCVISD::SELECT_CC" ; case RISCVISD :: BuildPairF64 : return "RISCVISD::BuildPairF64" ; case RISCVISD :: SplitF64 : return "RISCVISD::SplitF64" ; case RISCVISD :: TAIL : return "RISCVISD::TAIL" ; case RISCVISD :: SLLW : return "RISCVISD::SLLW" ; case RISCVISD :: SRAW : return "RISCVISD::SRAW" ; case RISCVISD :: SRLW : return "RISCVISD::SRLW" ; case RISCVISD :: DIVW : return "RISCVISD::DIVW" ; case RISCVISD :: DIVUW : return "RISCVISD::DIVUW" ; case RISCVISD :: REMUW : return "RISCVISD::REMUW" ; case RISCVISD :: FMV_W_X_RV64 : return "RISCVISD::FMV_W_X_RV64" ; case RISCVISD :: FMV_X_ANYEXTW_RV64 : return "RISCVISD::FMV_X_ANYEXTW_RV64" ; case RISCVISD :: READ_CYCLE_WIDE : return "RISCVISD::READ_CYCLE_WIDE" ; } return nullptr ; } </s>

getTargetNodeName - This method returns the name of a target specific


<s> bool RISCVPassConfig :: addPreISel ( ) { if ( TM -> getOptLevel ( ) != CodeGenOpt :: None ) { addPass ( createBarrierNoopPass ( ) ) ; } return false ; } </s>


<s> bool RISCVFrameLowering :: hasReservedCallFrame ( const MachineFunction & MF ) const { return ! MF . getFrameInfo ( ) . hasVarSizedObjects ( ) && ! ( hasFP ( MF ) && hasRVVFrameObject ( MF ) ) ; } </s>

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


<s> int riscv_address_insns ( rtx x , machine_mode mode , bool might_split_p ) { struct riscv_address_info addr ; int n = 1 ; if ( ! riscv_classify_address ( & addr , x , mode , false ) ) { return 3 ; } if ( mode != BLKmode && might_split_p ) n += ( GET_MODE_SIZE ( mode ) + UNITS_PER_WORD - 1 ) / UNITS_PER_WORD ; if ( addr . type == ADDRESS_LO_SUM ) n += riscv_symbol_insns ( addr . symbol_type ) - 1 ; return n ; } </s>

Return the number of instructions needed to load or store a value of mode MODE at address X . Return 0 if X is n't valid for MODE . Assume that multiword moves may need to be split into word moves if MIGHT_SPLIT_P , otherwise assume that a single load or store is enough .


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


<s> static SDValue getTargetNode ( ConstantPoolSDNode * N , SDLoc DL , EVT Ty , SelectionDAG & DAG , unsigned Flags ) { return DAG . getTargetConstantPool ( N -> getConstVal ( ) , Ty , N -> getAlignment ( ) , N -> getOffset ( ) , Flags ) ; } </s>

Retrieve the target node this edge connects to .


<s> void function_builder :: append_sew ( int sew ) { switch ( sew ) { case 8 : append_name ( "8" ) ; break ; case 16 : append_name ( "16" ) ; break ; case 32 : append_name ( "32" ) ; break ; case 64 : append_name ( "64" ) ; break ; default : gcc_unreachable ( ) ; } } </s>


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

Return information about object file lowering .


<s>
void
RISCVMCCodeEmitter
::
encodeInstruction
(
const
MCInst
&
MI
,
raw_ostream
&
OS
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
const
MCInstrDesc
&
Desc
=
MCII
.
get
(
MI
.
getOpcode
(
)
)
;
unsigned
Size
=
Desc
.
getSize
(
)
;
if
(
MI
.
getOpcode
(
)
==
RISCV
::
PseudoCALLReg
||
MI
.
getOpcode
(
)
==
RISCV
::
PseudoCALL
||
MI
.
getOpcode
(
)
==
RISCV
::
PseudoTAIL
)
{
expandFunctionCall
(
MI
,
OS
,
Fixups
,
STI
)
;
MCNumEmitted
+=
2
;
return
;
}
if
(
MI
.
getOpcode
(
)
==
RISCV
::
PseudoAddTPRel
)
{
expandAddTPRel
(
MI
,
OS
,
Fixups
,
STI
)
;
MCNumEmitted
+=
1
;
return
;
}
switch
(
Size
)
{
default
:
llvm_unreachable
(
"Unhandled encodeInstruction length!"
)
;
case
2
:
{
uint16_t
Bits
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
support
::
endian
::
write
<
uint16_t
>
(
OS
,
Bits
,
support
::
little
)
;
break
;
}
case
4
:
{
uint32_t
Bits
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
support
::
endian
::
write
(
OS
,
Bits
,
support
::
little
)
;
break
;
}
}
++
MCNumEmitted
;
}
</s>

Encode the given Inst to bytes and append to CB .

RISCV
RISCV
RISCV::PseudoCALLReg
RISCV::PseudoCALL
RISCV::PseudoTAIL
2
RISCV::PseudoAddTPRel
1
"Unhandled encodeInstruction length!"
2
support::endian
support::little
4
support::endian
support::little


<s> yaml :: MachineFunctionInfo * RISCVTargetMachine :: convertFuncInfoToYAML ( const MachineFunction & MF ) const { const auto * MFI = MF . getInfo < RISCVMachineFunctionInfo > ( ) ; return new yaml :: RISCVMachineFunctionInfo ( * MFI ) ; } </s>

Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo .


<s> bool RISCVRegisterInfo :: isAsmClobberable ( const MachineFunction & MF , unsigned PhysReg ) const { return ! MF . getSubtarget < RISCVSubtarget > ( ) . isRegisterReservedByUser ( PhysReg ) ; } </s>

Returns false if we ca n't guarantee that Physreg , specified as an IR asm clobber constraint , will be preserved across the statement .


<s> static void riscv_unique_section ( tree decl , int reloc ) { const char * prefix = NULL ; bool one_only = DECL_ONE_ONLY ( decl ) && ! HAVE_COMDAT_GROUP ; switch ( categorize_decl_for_section ( decl , reloc ) ) { case SECCAT_SRODATA : prefix = one_only ? ".sr" : ".srodata" ; break ; default : break ; } if ( prefix ) { const char * name , * linkonce ; char * string ; name = IDENTIFIER_POINTER ( DECL_ASSEMBLER_NAME ( decl ) ) ; name = targetm . strip_name_encoding ( name ) ; linkonce = one_only ? ".gnu.linkonce" : "" ; string = ACONCAT ( ( linkonce , prefix , "." , name , NULL ) ) ; set_decl_section_name ( decl , string ) ; return ; } default_unique_section ( decl , reloc ) ; } </s>

Switch to the appropriate section for output of DECL .


<s> static bool riscv_classify_address ( struct riscv_address_info * info , rtx x , machine_mode mode , bool strict_p ) { switch ( GET_CODE ( x ) ) { case REG : case SUBREG : info -> type = ADDRESS_REG ; info -> reg = x ; info -> offset = const0_rtx ; return riscv_valid_base_register_p ( info -> reg , mode , strict_p ) ; case PLUS : info -> type = ADDRESS_REG ; info -> reg = XEXP ( x , 0 ) ; info -> offset = XEXP ( x , 1 ) ; return ( riscv_valid_base_register_p ( info -> reg , mode , strict_p ) && riscv_valid_offset_p ( info -> offset , mode ) ) ; case LO_SUM : info -> type = ADDRESS_LO_SUM ; info -> reg = XEXP ( x , 0 ) ; info -> offset = XEXP ( x , 1 ) ; info -> symbol_type = riscv_classify_symbolic_expression ( info -> offset ) ; return ( riscv_valid_base_register_p ( info -> reg , mode , strict_p ) && riscv_valid_lo_sum_p ( info -> symbol_type , mode , info -> offset ) ) ; case CONST_INT : info -> type = ADDRESS_CONST_INT ; return SMALL_OPERAND ( INTVAL ( x ) ) ; default : return false ; } } </s>

Return true if X is a valid address for machine mode MODE . If it is , fill in INFO appropriately . STRICT_P is true if REG_OK_STRICT is in effect .


<s> bool RISCVInstrInfo :: isFunctionSafeToOutlineFrom ( MachineFunction & MF , bool OutlineFromLinkOnceODRs ) const { const Function & F = MF . getFunction ( ) ; if ( ! OutlineFromLinkOnceODRs && F . hasLinkOnceODRLinkage ( ) ) return false ; if ( F . hasSection ( ) ) return false ; return true ; } </s>

Return true if the function can safely be outlined from .


<s>
SDValue
RISCVTargetLowering
::
getAddr
(
NodeTy
*
N
,
EVT
Ty
,
SelectionDAG
&
DAG
,
bool
IsLocal
,
bool
CanDeriveFromPcc
)
const
{
SDLoc
DL
(
N
)
;
if
(
RISCVABI
::
isCheriPureCapABI
(
Subtarget
.
getTargetABI
(
)
)
)
{
SDValue
Addr
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
0
)
;
if
(
IsLocal
&&
CanDeriveFromPcc
)
{
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoCLLC
,
DL
,
Ty
,
Addr
)
,
0
)
;
}
SDValue
Load
=
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoCLGC
,
DL
,
Ty
,
Addr
)
,
0
)
;
MachineFunction
&
MF
=
DAG
.
getMachineFunction
(
)
;
MachineMemOperand
*
MemOp
=
MF
.
getMachineMemOperand
(
MachinePointerInfo
::
getGOT
(
MF
)
,
MachineMemOperand
::
MOLoad
|
MachineMemOperand
::
MODereferenceable
|
MachineMemOperand
::
MOInvariant
,
LLT
(
Ty
.
getSimpleVT
(
)
)
,
Align
(
Ty
.
getFixedSizeInBits
(
)
/
8
)
)
;
DAG
.
setNodeMemRefs
(
cast
<
MachineSDNode
>
(
Load
.
getNode
(
)
)
,
{
MemOp
}
)
;
return
Load
;
}
if
(
isPositionIndependent
(
)
)
{
SDValue
Addr
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
0
)
;
if
(
IsLocal
)
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoLLA
,
DL
,
Ty
,
Addr
)
,
0
)
;
SDValue
Load
=
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoLA
,
DL
,
Ty
,
Addr
)
,
0
)
;
MachineFunction
&
MF
=
DAG
.
getMachineFunction
(
)
;
MachineMemOperand
*
MemOp
=
MF
.
getMachineMemOperand
(
MachinePointerInfo
::
getGOT
(
MF
)
,
MachineMemOperand
::
MOLoad
|
MachineMemOperand
::
MODereferenceable
|
MachineMemOperand
::
MOInvariant
,
LLT
(
Ty
.
getSimpleVT
(
)
)
,
Align
(
Ty
.
getFixedSizeInBits
(
)
/
8
)
)
;
DAG
.
setNodeMemRefs
(
cast
<
MachineSDNode
>
(
Load
.
getNode
(
)
)
,
{
MemOp
}
)
;
return
Load
;
}
switch
(
getTargetMachine
(
)
.
getCodeModel
(
)
)
{
default
:
report_fatal_error
(
"Unsupported code model for lowering"
)
;
case
CodeModel
::
Small
:
{
SDValue
AddrHi
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
RISCVII
::
MO_HI
)
;
SDValue
AddrLo
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
RISCVII
::
MO_LO
)
;
SDValue
MNHi
=
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
LUI
,
DL
,
Ty
,
AddrHi
)
,
0
)
;
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
ADDI
,
DL
,
Ty
,
MNHi
,
AddrLo
)
,
0
)
;
}
case
CodeModel
::
Medium
:
{
SDValue
Addr
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
0
)
;
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoLLA
,
DL
,
Ty
,
Addr
)
,
0
)
;
}
}
}
</s>

Return the address accessed by this recipe .


<s> static int riscv_build_integer ( struct riscv_integer_op * codes , HOST_WIDE_INT value , machine_mode mode ) { int cost = riscv_build_integer_1 ( codes , value , mode ) ; if ( value > 0 && cost > 2 ) { struct riscv_integer_op alt_codes [ RISCV_MAX_INTEGER_OPS ] ; int alt_cost , shift = clz_hwi ( value ) ; HOST_WIDE_INT shifted_val ; shifted_val = ( value << shift ) | ( ( ( ( HOST_WIDE_INT ) 1 ) << shift ) - 1 ) ; alt_cost = 1 + riscv_build_integer_1 ( alt_codes , shifted_val , mode ) ; if ( alt_cost < cost ) { alt_codes [ alt_cost - 1 ] . code = LSHIFTRT ; alt_codes [ alt_cost - 1 ] . value = shift ; memcpy ( codes , alt_codes , sizeof ( alt_codes ) ) ; cost = alt_cost ; } shifted_val = value << shift ; alt_cost = 1 + riscv_build_integer_1 ( alt_codes , shifted_val , mode ) ; if ( alt_cost < cost ) { alt_codes [ alt_cost - 1 ] . code = LSHIFTRT ; alt_codes [ alt_cost - 1 ] . value = shift ; memcpy ( codes , alt_codes , sizeof ( alt_codes ) ) ; cost = alt_cost ; } } return cost ; } </s>

Fill CODES with a sequence of rtl operations to load VALUE . Return the number of operations needed .


<s> rtx riscv_legitimize_call_address ( rtx addr ) { if ( ! call_insn_operand ( addr , VOIDmode ) ) { rtx reg = RISCV_CALL_ADDRESS_TEMP ( Pmode ) ; riscv_emit_move ( reg , addr ) ; return reg ; } return addr ; } </s>

Make ADDR suitable for use as a call or sibcall target .


"Trying to obtain non-reserved register \""

Return the register ID of the name passed in .


<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 :: FSH : case RISCV :: FSW : case RISCV :: SD : case RISCV :: FSD : case RISCV :: SC_64 : case RISCV :: SC_128 : case RISCV :: CSB : case RISCV :: CSH : case RISCV :: CSW : case RISCV :: CFSW : case RISCV :: CSD : case RISCV :: CFSD : case RISCV :: CSC_64 : case RISCV :: CSC_128 : 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> bool RISCVFrameLowering :: hasFP ( const MachineFunction & MF ) const { const TargetRegisterInfo * RegInfo = MF . getSubtarget ( ) . getRegisterInfo ( ) ; auto * RVFI = MF . getInfo < RISCVMachineFunctionInfo > ( ) ; const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; return MF . getTarget ( ) . Options . DisableFramePointerElim ( MF ) || RegInfo -> needsStackRealignment ( MF ) || MFI . hasVarSizedObjects ( ) || MFI . isFrameAddressTaken ( ) || RVFI -> hasSpillVRs ( ) ; } </s>

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


<s> bool RISCVAsmBackend :: shouldInsertFixupForCodeAlign ( MCAssembler & Asm , const MCAsmLayout & Layout , MCAlignFragment & AF ) { if ( ! STI . getFeatureBits ( ) [ RISCV :: FeatureRelax ] ) return false ; unsigned Count ; if ( ! shouldInsertExtraNopBytesForCodeAlign ( AF , Count ) || ( Count == 0 ) ) return false ; MCContext & Ctx = Asm . getContext ( ) ; const MCExpr * Dummy = MCConstantExpr :: create ( 0 , Ctx ) ; MCFixup Fixup = MCFixup :: create ( 0 , Dummy , MCFixupKind ( RISCV :: fixup_riscv_align ) , SMLoc ( ) ) ; uint64_t FixedValue = 0 ; MCValue NopBytes = MCValue :: get ( Count ) ; Asm . getWriter ( ) . recordRelocation ( Asm , Layout , & AF , Fixup , NopBytes , FixedValue ) ; return true ; } </s>

Hook which indicates if the target requires a fixup to be generated when handling an align directive in an executable section .


"getIntImmCost can only estimate cost of materialising integers"

Return the expected cost of materialization for the given integer immediate of the specified type for a given instruction .


"frame pointer should not have been eliminated"

"SecondSPAdjustAmount should be greater than zero"


<s> void riscv_expand_int_scc ( rtx target , enum rtx_code code , rtx op0 , rtx op1 ) { riscv_extend_comparands ( code , & op0 , & op1 ) ; op0 = force_reg ( word_mode , op0 ) ; if ( code == EQ || code == NE ) { rtx zie = riscv_zero_if_equal ( op0 , op1 ) ; riscv_emit_binary ( code , target , zie , const0_rtx ) ; } else riscv_emit_int_order_test ( code , 0 , target , op0 , op1 ) ; } </s>

CODE-compare OP0 and OP1 . Store the result in TARGET .


<s> static machine_mode riscv_promote_function_mode ( const_tree type ATTRIBUTE_UNUSED , machine_mode mode , int * punsignedp ATTRIBUTE_UNUSED , const_tree fntype ATTRIBUTE_UNUSED , int for_return ATTRIBUTE_UNUSED ) { int unsignedp ; if ( type != NULL_TREE ) return promote_mode ( type , mode , punsignedp ) ; unsignedp = * punsignedp ; PROMOTE_MODE ( as_a < scalar_mode > ( mode ) , unsignedp , type ) ; * punsignedp = unsignedp ; return mode ; } </s>


<s> void RISCVFrameLowering :: determineCalleeSaves ( MachineFunction & MF , BitVector & SavedRegs , RegScavenger * RS ) const { TargetFrameLowering :: determineCalleeSaves ( MF , SavedRegs , RS ) ; if ( hasFP ( MF ) ) { SavedRegs . set ( RISCV :: X1 ) ; SavedRegs . set ( RISCV :: X8 ) ; } if ( hasBP ( MF ) ) SavedRegs . set ( RISCVABI :: getBPReg ( ) ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; if ( MF . getFunction ( ) . hasFnAttribute ( "interrupt" ) && MFI . hasCalls ( ) ) { static const MCPhysReg CSRegs [ ] = { RISCV :: X1 , RISCV :: X5 , RISCV :: X6 , RISCV :: X7 , RISCV :: X10 , RISCV :: X11 , RISCV :: X12 , RISCV :: X13 , RISCV :: X14 , RISCV :: X15 , RISCV :: X16 , RISCV :: X17 , RISCV :: X28 , RISCV :: X29 , RISCV :: X30 , RISCV :: X31 , 0 } ; for ( unsigned i = 0 ; CSRegs [ i ] ; ++ i ) SavedRegs . set ( CSRegs [ i ] ) ; if ( MF . getSubtarget < RISCVSubtarget > ( ) . hasStdExtF ( ) ) { const MCPhysReg * Regs = MF . getRegInfo ( ) . getCalleeSavedRegs ( ) ; for ( unsigned i = 0 ; Regs [ i ] ; ++ i ) if ( RISCV :: FPR16RegClass . contains ( Regs [ i ] ) || RISCV :: FPR32RegClass . contains ( Regs [ i ] ) || RISCV :: FPR64RegClass . contains ( Regs [ i ] ) ) SavedRegs . set ( Regs [ i ] ) ; } } } </s>

This method determines which of the registers reported by TargetRegisterInfo : :getCalleeSavedRegs ( ) should actually get saved .


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
override
{
const
static
MCFixupKindInfo
Infos
[
RISCV
::
NumTargetFixupKinds
]
=
{
{
"fixup_riscv_hi20"
,
12
,
20
,
0
}
,
{
"fixup_riscv_lo12_i"
,
20
,
12
,
0
}
,
{
"fixup_riscv_lo12_s"
,
0
,
32
,
0
}
,
{
"fixup_riscv_pcrel_hi20"
,
12
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_riscv_jal"
,
12
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_riscv_branch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_riscv_rvc_jump"
,
2
,
11
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_riscv_rvc_branch"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s>
SDValue
RISCVTargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
default
:
report_fatal_error
(
"unimplemented operand"
)
;
case
ISD
::
GlobalAddress
:
return
lowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
BlockAddress
:
return
lowerBlockAddress
(
Op
,
DAG
)
;
case
ISD
::
ConstantPool
:
return
lowerConstantPool
(
Op
,
DAG
)
;
case
ISD
::
SELECT
:
return
lowerSELECT
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
lowerVASTART
(
Op
,
DAG
)
;
case
ISD
::
FRAMEADDR
:
return
lowerFRAMEADDR
(
Op
,
DAG
)
;
case
ISD
::
RETURNADDR
:
return
lowerRETURNADDR
(
Op
,
DAG
)
;
case
ISD
::
BITCAST
:
{
assert
(
Subtarget
.
is64Bit
(
)
&&
Subtarget
.
hasStdExtF
(
)
&&
"Unexpected custom legalisation"
)
;
SDLoc
DL
(
Op
)
;
SDValue
Op0
=
Op
.
getOperand
(
0
)
;
if
(
Op
.
getValueType
(
)
!=
MVT
::
f32
||
Op0
.
getValueType
(
)
!=
MVT
::
i32
)
return
SDValue
(
)
;
SDValue
NewOp0
=
DAG
.
getNode
(
ISD
::
ANY_EXTEND
,
DL
,
MVT
::
i64
,
Op0
)
;
SDValue
FPConv
=
DAG
.
getNode
(
RISCVISD
::
FMV_W_X_RV64
,
DL
,
MVT
::
f32
,
NewOp0
)
;
return
FPConv
;
}
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .


<s> VSETVLIInfo intersect ( const VSETVLIInfo & Other ) const { if ( ! Other . isValid ( ) ) return * this ; if ( ! isValid ( ) ) return Other ; if ( * this == Other ) return * this ; return VSETVLIInfo :: getUnknown ( ) ; } </s>

Intersect this set with a temporary other set in place .


<s> bool isFMAFasterThanFMulAndFAdd ( EVT ) const override { return true ; } </s>

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


<s> rtx get_avl ( ) const { return m_avl . get_value ( ) ; } </s>


<s> static bool get_default_ma ( ) { return ( bool ) ( get_prefer_mask_policy ( ) & 0x1 || ( get_prefer_mask_policy ( ) >> 1 & 0x1 ) ) ; } </s>


<s>
void
RISCVDAGToDAGISel
::
Select
(
SDNode
*
Node
)
{
unsigned
Opcode
=
Node
->
getOpcode
(
)
;
MVT
XLenVT
=
Subtarget
->
getXLenVT
(
)
;
if
(
Node
->
isMachineOpcode
(
)
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"== "
;
Node
->
dump
(
CurDAG
)
;
dbgs
(
)
<<
"\n"
)
;
Node
->
setNodeId
(
1
)
;
return
;
}
EVT
VT
=
Node
->
getValueType
(
0
)
;
if
(
Opcode
==
ISD
::
Constant
&&
VT
==
XLenVT
)
{
auto
*
ConstNode
=
cast
<
ConstantSDNode
>
(
Node
)
;
if
(
ConstNode
->
isNullValue
(
)
)
{
SDValue
New
=
CurDAG
->
getCopyFromReg
(
CurDAG
->
getEntryNode
(
)
,
SDLoc
(
Node
)
,
RISCV
::
X0
,
XLenVT
)
;
ReplaceNode
(
Node
,
New
.
getNode
(
)
)
;
return
;
}
}
if
(
Opcode
==
ISD
::
FrameIndex
)
{
SDLoc
DL
(
Node
)
;
SDValue
Imm
=
CurDAG
->
getTargetConstant
(
0
,
DL
,
XLenVT
)
;
int
FI
=
cast
<
FrameIndexSDNode
>
(
Node
)
->
getIndex
(
)
;
EVT
VT
=
Node
->
getValueType
(
0
)
;
SDValue
TFI
=
CurDAG
->
getTargetFrameIndex
(
FI
,
VT
)
;
ReplaceNode
(
Node
,
CurDAG
->
getMachineNode
(
RISCV
::
ADDI
,
DL
,
VT
,
TFI
,
Imm
)
)
;
return
;
}
SelectCode
(
Node
)
;
}
</s>

Main hook for targets to transform nodes into machine nodes .


<s> const MCFixup * RISCVMCExpr :: getPCRelHiFixup ( const MCFragment * * DFOut ) const { MCValue AUIPCLoc ; if ( ! getSubExpr ( ) -> evaluateAsRelocatable ( AUIPCLoc , nullptr , nullptr ) ) return nullptr ; const MCSymbolRefExpr * AUIPCSRE = AUIPCLoc . getSymA ( ) ; if ( ! AUIPCSRE ) return nullptr ; const MCSymbol * AUIPCSymbol = & AUIPCSRE -> getSymbol ( ) ; const auto * DF = dyn_cast_or_null < MCDataFragment > ( AUIPCSymbol -> getFragment ( ) ) ; if ( ! DF ) return nullptr ; uint64_t Offset = AUIPCSymbol -> getOffset ( ) ; if ( DF -> getContents ( ) . size ( ) == Offset ) { DF = dyn_cast_or_null < MCDataFragment > ( DF -> getNextNode ( ) ) ; if ( ! DF ) return nullptr ; Offset = 0 ; } for ( const MCFixup & F : DF -> getFixups ( ) ) { if ( F . getOffset ( ) != Offset ) continue ; switch ( ( unsigned ) F . getKind ( ) ) { default : continue ; case RISCV :: fixup_riscv_got_hi20 : case RISCV :: fixup_riscv_tls_got_hi20 : case RISCV :: fixup_riscv_tls_gd_hi20 : case RISCV :: fixup_riscv_pcrel_hi20 : if ( DFOut ) * DFOut = DF ; return & F ; } } return nullptr ; } </s>

Get the corresponding PC-relative HI fixup that a VK_RISCV_PCREL_LO points to , and optionally the fragment containing it .


<s> const uint32_t * RISCVRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID ) const { auto & Subtarget = MF . getSubtarget < RISCVSubtarget > ( ) ; if ( MF . getFunction ( ) . hasFnAttribute ( "interrupt" ) ) { if ( Subtarget . hasStdExtD ( ) ) return CSR_XLEN_F64_Interrupt_RegMask ; if ( Subtarget . hasStdExtF ( ) ) return CSR_XLEN_F32_Interrupt_RegMask ; return CSR_Interrupt_RegMask ; } return CSR_ILP32_LP64_RegMask ; } </s>

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


<s> static section * riscv_elf_select_rtx_section ( machine_mode mode , rtx x , unsigned HOST_WIDE_INT align ) { section * s = default_elf_select_rtx_section ( mode , x , align ) ; if ( riscv_size_ok_for_small_data_p ( GET_MODE_SIZE ( mode ) . to_constant ( ) ) ) { if ( startswith ( s -> named . name , ".rodata.cst" ) ) { char * name = ( char * ) alloca ( strlen ( s -> named . name ) + 2 ) ; sprintf ( name , ".s%s" , s -> named . name + 1 ) ; return get_section ( name , s -> named . common . flags , NULL ) ; } if ( s == data_section ) return sdata_section ; } return s ; } </s>

Return a section for X , handling small data .


<s> bool RISCVAsmParser :: processInstruction ( MCInst & Inst , SMLoc IDLoc , MCStreamer & Out ) { Inst . setLoc ( IDLoc ) ; if ( Inst . getOpcode ( ) == RISCV :: PseudoLI ) { auto Reg = Inst . getOperand ( 0 ) . getReg ( ) ; int64_t Imm = Inst . getOperand ( 1 ) . getImm ( ) ; if ( ! isRV64 ( ) ) Imm = SignExtend64 < 32 > ( Imm ) ; emitLoadImm ( Reg , Imm , Out ) ; return false ; } emitToStreamer ( Out , Inst ) ; return false ; } </s>

Process a single instruction and collect debug info anchors .


"RVV type %qT does not have a fixed size"

"RVV type %qT does not have a defined alignment"

"variables of type %qT cannot have thread-local"

"member variables cannot have RVV type %qT"

"array elements cannot have RVV type %qT"

"cannot allocate objects with RVV type %qT"

"cannot delete objects with RVV type %qT"

Implement TARGET_VERIFY_TYPE_CONTEXT for RVV types .


<s> const char * riscv_output_gpr_save ( unsigned mask ) { static char s [ 32 ] ; unsigned n = riscv_save_libcall_count ( mask ) ; ssize_t bytes = snprintf ( s , sizeof ( s ) , "call\tt0,__riscv_save_%u" , n ) ; gcc_assert ( ( size_t ) bytes < sizeof ( s ) ) ; return s ; } </s>

Return the code to invoke the GPR save routine .


<s> void addExpr ( MCInst & Inst , const MCExpr * Expr ) const { if ( Expr == 0 ) Inst . addOperand ( MCOperand :: createImm ( 0 ) ) ; else if ( const MCConstantExpr * CE = dyn_cast < MCConstantExpr > ( Expr ) ) Inst . addOperand ( MCOperand :: createImm ( CE -> getValue ( ) ) ) ; else Inst . addOperand ( MCOperand :: createExpr ( Expr ) ) ; } </s>


<s> static rtx riscv_strip_unspec_address ( rtx op ) { rtx base , offset ; split_const ( op , & base , & offset ) ; if ( UNSPEC_ADDRESS_P ( base ) ) op = plus_constant ( Pmode , UNSPEC_ADDRESS ( base ) , INTVAL ( offset ) ) ; return op ; } </s>

If OP is an UNSPEC address , return the address to which it refers , otherwise return OP itself .


<s> const RISCVMCExpr * RISCVMCExpr :: create ( RISCVMCExpr :: VariantKind Kind , const MCExpr * Expr , MCContext & Ctx ) { return new ( Ctx ) RISCVMCExpr ( Kind , Expr ) ; } </s>


<s> static enum riscv_symbol_type riscv_classify_symbol ( const_rtx x ) { if ( riscv_tls_symbol_p ( x ) ) return SYMBOL_TLS ; if ( GET_CODE ( x ) == SYMBOL_REF && flag_pic && ! riscv_symbol_binds_local_p ( x ) ) return SYMBOL_GOT_DISP ; return riscv_cmodel == CM_MEDLOW ? SYMBOL_ABSOLUTE : SYMBOL_PCREL ; } </s>

Return the method that should be used to access SYMBOL_REF or LABEL_REF X .


<s> static bool backward_propagate_worthwhile_p ( const basic_block cfg_bb , const vector_block_info block_info ) { if ( loop_basic_block_p ( cfg_bb ) ) { if ( block_info . reaching_out . valid_or_dirty_p ( ) ) { if ( block_info . local_dem . compatible_p ( block_info . reaching_out ) ) { return true ; } else { if ( support_relaxed_compatible_p ( block_info . reaching_out , block_info . local_dem ) ) return true ; return false ; } } else { gcc_assert ( block_info . reaching_out . unknown_p ( ) ) ; return false ; } } return true ; } </s>

Return true if the block is worthwhile backward propagation .


<s> BitVector RISCVRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const RISCVFrameLowering * TFI = getFrameLowering ( MF ) ; BitVector Reserved ( getNumRegs ( ) ) ; for ( size_t Reg = 0 ; Reg < getNumRegs ( ) ; Reg ++ ) { if ( MF . getSubtarget < RISCVSubtarget > ( ) . isRegisterReservedByUser ( Reg ) ) markSuperRegs ( Reserved , Reg ) ; } markSuperRegs ( Reserved , RISCV :: X0 ) ; markSuperRegs ( Reserved , RISCV :: X2 ) ; markSuperRegs ( Reserved , RISCV :: X3 ) ; markSuperRegs ( Reserved , RISCV :: X4 ) ; auto & Subtarget = MF . getSubtarget < RISCVSubtarget > ( ) ; if ( Subtarget . hasStdExtV ( ) || TFI -> hasFP ( MF ) ) markSuperRegs ( Reserved , RISCV :: X8 ) ; if ( TFI -> hasBP ( MF ) ) markSuperRegs ( Reserved , RISCVABI :: getBPReg ( ) ) ; assert ( checkAllSuperRegsMarked ( Reserved ) ) ; return Reserved ; } </s>

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


<s> const char * RISCVTargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( ( RISCVISD :: NodeType ) Opcode ) { case RISCVISD :: FIRST_NUMBER : break ; case RISCVISD :: RET_FLAG : return "RISCVISD::RET_FLAG" ; case RISCVISD :: URET_FLAG : return "RISCVISD::URET_FLAG" ; case RISCVISD :: SRET_FLAG : return "RISCVISD::SRET_FLAG" ; case RISCVISD :: MRET_FLAG : return "RISCVISD::MRET_FLAG" ; case RISCVISD :: CALL : return "RISCVISD::CALL" ; case RISCVISD :: SELECT_CC : return "RISCVISD::SELECT_CC" ; case RISCVISD :: BuildPairF64 : return "RISCVISD::BuildPairF64" ; case RISCVISD :: SplitF64 : return "RISCVISD::SplitF64" ; case RISCVISD :: TAIL : return "RISCVISD::TAIL" ; case RISCVISD :: SLLW : return "RISCVISD::SLLW" ; case RISCVISD :: SRAW : return "RISCVISD::SRAW" ; case RISCVISD :: SRLW : return "RISCVISD::SRLW" ; case RISCVISD :: DIVW : return "RISCVISD::DIVW" ; case RISCVISD :: DIVUW : return "RISCVISD::DIVUW" ; case RISCVISD :: REMUW : return "RISCVISD::REMUW" ; case RISCVISD :: FMV_W_X_RV64 : return "RISCVISD::FMV_W_X_RV64" ; case RISCVISD :: FMV_H_X_RV32 : return "RISCVISD::FMV_H_X_RV32" ; case RISCVISD :: FMV_H_X_RV64 : return "RISCVISD::FMV_H_X_RV64" ; case RISCVISD :: FMV_X_ANYEXTW_RV64 : return "RISCVISD::FMV_X_ANYEXTW_RV64" ; case RISCVISD :: FMV_X_ANYEXTH_RV64 : return "RISCVISD::FMV_X_ANYEXTH_RV64" ; case RISCVISD :: FMV_X_ANYEXTH_RV32 : return "RISCVISD::FMV_X_ANYEXTH_RV32" ; case RISCVISD :: READ_CYCLE_WIDE : return "RISCVISD::READ_CYCLE_WIDE" ; } return nullptr ; } </s>

getTargetNodeName - This method returns the name of a target specific


<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 . hasStdExtV ( ) ) preAssignMask ( Outs , FirstMaskArgument , CCInfo ) ; 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> static unsigned char riscv_class_max_nregs ( reg_class_t rclass , enum machine_mode mode ) { if ( reg_class_subset_p ( FP_REGS , rclass ) ) return riscv_hard_regno_nregs ( FP_REG_FIRST , mode ) ; if ( reg_class_subset_p ( GR_REGS , rclass ) ) return riscv_hard_regno_nregs ( GP_REG_FIRST , mode ) ; return 0 ; } </s>


<s>
SDValue
RISCVTargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
default
:
report_fatal_error
(
"unimplemented operand"
)
;
case
ISD
::
GlobalAddress
:
return
lowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
BlockAddress
:
return
lowerBlockAddress
(
Op
,
DAG
)
;
case
ISD
::
ConstantPool
:
return
lowerConstantPool
(
Op
,
DAG
)
;
case
ISD
::
GlobalTLSAddress
:
return
lowerGlobalTLSAddress
(
Op
,
DAG
)
;
case
ISD
::
SELECT
:
return
lowerSELECT
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
lowerVASTART
(
Op
,
DAG
)
;
case
ISD
::
FRAMEADDR
:
return
lowerFRAMEADDR
(
Op
,
DAG
)
;
case
ISD
::
RETURNADDR
:
return
lowerRETURNADDR
(
Op
,
DAG
)
;
case
ISD
::
SHL_PARTS
:
return
lowerShiftLeftParts
(
Op
,
DAG
)
;
case
ISD
::
SRA_PARTS
:
return
lowerShiftRightParts
(
Op
,
DAG
,
true
)
;
case
ISD
::
SRL_PARTS
:
return
lowerShiftRightParts
(
Op
,
DAG
,
false
)
;
case
ISD
::
BITCAST
:
{
assert
(
Subtarget
.
is64Bit
(
)
&&
Subtarget
.
hasStdExtF
(
)
&&
"Unexpected custom legalisation"
)
;
SDLoc
DL
(
Op
)
;
SDValue
Op0
=
Op
.
getOperand
(
0
)
;
if
(
Op
.
getValueType
(
)
!=
MVT
::
f32
||
Op0
.
getValueType
(
)
!=
MVT
::
i32
)
return
SDValue
(
)
;
SDValue
NewOp0
=
DAG
.
getNode
(
ISD
::
ANY_EXTEND
,
DL
,
MVT
::
i64
,
Op0
)
;
SDValue
FPConv
=
DAG
.
getNode
(
RISCVISD
::
FMV_W_X_RV64
,
DL
,
MVT
::
f32
,
NewOp0
)
;
return
FPConv
;
}
case
ISD
::
INTRINSIC_WO_CHAIN
:
return
LowerINTRINSIC_WO_CHAIN
(
Op
,
DAG
)
;
case
ISD
::
INTRINSIC_W_CHAIN
:
return
SDValue
(
)
;
}
}
</s>


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

getPassName - Return a nice clean name for a pass .


<s> static bool riscv_pass_by_reference ( cumulative_args_t cum_v , machine_mode mode , const_tree type , bool named ) { HOST_WIDE_INT size = type ? int_size_in_bytes ( type ) : GET_MODE_SIZE ( mode ) ; struct riscv_arg_info info ; CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; if ( cum != NULL ) { riscv_get_arg_info ( & info , cum , mode , type , named , false ) ; if ( info . num_fprs ) return false ; } return ! IN_RANGE ( size , 0 , 2 * UNITS_PER_WORD ) ; } </s>


<s> const uint32_t * RISCVRegisterInfo :: getCallPreservedMask ( const MachineFunction & , CallingConv :: ID ) const { return CSR_RegMask ; } </s>


<s>
void
print
(
raw_ostream
&
OS
)
const
override
{
switch
(
Kind
)
{
case
Immediate
:
OS
<<
*
getImm
(
)
;
break
;
case
Register
:
OS
<<
"<register x"
;
OS
<<
getReg
(
)
<<
">"
;
break
;
case
Token
:
OS
<<
"'"
<<
getToken
(
)
<<
"'"
;
break
;
}
}
</s>

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


<s> static unsigned int riscv_dwarf_poly_indeterminate_value ( unsigned int i , unsigned int * factor , int * offset ) { gcc_assert ( i == 1 ) ; * factor = riscv_bytes_per_vector_chunk ; * offset = 1 ; return RISCV_DWARF_VLENB ; } </s>

Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook .


<s>
void
print
(
raw_ostream
&
OS
)
const
override
{
auto
RegName
=
[
]
(
unsigned
Reg
)
{
if
(
Reg
)
return
RISCVInstPrinter
::
getRegisterName
(
Reg
)
;
else
return
"noreg"
;
}
;
switch
(
Kind
)
{
case
KindTy
::
Immediate
:
OS
<<
*
getImm
(
)
;
break
;
case
KindTy
::
Register
:
OS
<<
"<register "
<<
RegName
(
getReg
(
)
)
<<
">"
;
break
;
case
KindTy
::
Token
:
OS
<<
"'"
<<
getToken
(
)
<<
"'"
;
break
;
case
KindTy
::
SystemRegister
:
OS
<<
"<sysreg: "
<<
getSysReg
(
)
<<
'>'
;
break
;
case
KindTy
::
SpecialCapRegister
:
OS
<<
"<specialcapreg: "
<<
getSpecialCapReg
(
)
<<
'>'
;
break
;
case
KindTy
::
VType
:
OS
<<
"<vtype: "
;
RISCVVType
::
printVType
(
getVType
(
)
,
OS
)
;
OS
<<
'>'
;
break
;
}
}
</s>

RISCV
RISCV
"noreg"
"<register "
">"
"'"
"'"
"<sysreg: "
"<specialcapreg: "
"<vtype: "
RISCV


<s> InstructionCost RISCVTTIImpl :: getGatherScatterOpCost ( unsigned Opcode , Type * DataTy , const Value * Ptr , bool VariableMask , Align Alignment , TTI :: TargetCostKind CostKind , const Instruction * I ) { if ( CostKind != TTI :: TCK_RecipThroughput ) return BaseT :: getGatherScatterOpCost ( Opcode , DataTy , Ptr , VariableMask , Alignment , CostKind , I ) ; if ( ( Opcode == Instruction :: Load && ! isLegalMaskedGather ( DataTy , Align ( Alignment ) ) ) || ( Opcode == Instruction :: Store && ! isLegalMaskedScatter ( DataTy , Align ( Alignment ) ) ) ) return BaseT :: getGatherScatterOpCost ( Opcode , DataTy , Ptr , VariableMask , Alignment , CostKind , I ) ; if ( ! isa < FixedVectorType > ( DataTy ) ) return BaseT :: getGatherScatterOpCost ( Opcode , DataTy , Ptr , VariableMask , Alignment , CostKind , I ) ; auto * VTy = cast < FixedVectorType > ( DataTy ) ; unsigned NumLoads = VTy -> getNumElements ( ) ; InstructionCost MemOpCost = getMemoryOpCost ( Opcode , VTy -> getElementType ( ) , Alignment , 0 , CostKind , I ) ; return NumLoads * MemOpCost ; } </s>

Calculate the cost of Gather / Scatter operation .


<s> static bool riscv_secondary_memory_needed ( machine_mode mode , reg_class_t class1 , reg_class_t class2 ) { return ( ! riscv_v_ext_vector_mode_p ( mode ) && GET_MODE_SIZE ( mode ) . to_constant ( ) > UNITS_PER_WORD && ( class1 == FP_REGS ) != ( class2 == FP_REGS ) && ! TARGET_XTHEADFMV ) ; } </s>

Implement TARGET_SECONDARY_MEMORY_NEEDED . When floating-point registers are wider than integer ones , moves between them must go through memory .


<s> unsigned getNumberOfRegisters ( unsigned ClassID ) const { bool Vector = ( ClassID == 1 ) ; if ( Vector ) { if ( ST -> hasVInstructions ( ) ) return 32 ; return 0 ; } return 31 ; } </s>


<s> bool RISCVRI5CYIR :: runOnFunction ( Function & F ) { errs ( ) << "runOnFunction(" << F . getName ( ) . str ( ) << ")\n" ; this -> transformBitManipulation ( F ) ; return false ; } </s>

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


<s> void pass_vsetvl :: transfer_after ( vector_insn_info & info , insn_info * insn ) const { if ( vector_config_insn_p ( insn -> rtl ( ) ) ) { info = m_vector_manager -> vector_insn_infos [ insn -> uid ( ) ] ; return ; } if ( fault_first_load_p ( insn -> rtl ( ) ) && info . update_fault_first_load_avl ( insn ) ) return ; if ( insn -> is_call ( ) || insn -> is_asm ( ) || find_access ( insn -> defs ( ) , VL_REGNUM ) || find_access ( insn -> defs ( ) , VTYPE_REGNUM ) ) info = vector_insn_info :: get_unknown ( ) ; } </s>

Given a state with which we evaluated insn ( see transfer_before above for why this might be different that the state insn requested ) , modify the state to reflect the changes insn might make .


"-mdiv requires -march to subsume the %<M%> extension"

"requested ABI requires -march to subsume the %qc extension"


<s>
void
print
(
raw_ostream
&
OS
)
const
{
OS
<<
"{"
;
if
(
!
isValid
(
)
)
OS
<<
"Uninitialized"
;
if
(
isUnknown
(
)
)
OS
<<
"unknown"
;
;
if
(
hasAVLReg
(
)
)
OS
<<
"AVLReg="
<<
(
unsigned
)
AVLReg
;
if
(
hasAVLImm
(
)
)
OS
<<
"AVLImm="
<<
(
unsigned
)
AVLImm
;
OS
<<
", "
<<
"VLMul="
<<
(
unsigned
)
VLMul
<<
", "
<<
"SEW="
<<
(
unsigned
)
SEW
<<
", "
<<
"TailAgnostic="
<<
(
bool
)
TailAgnostic
<<
", "
<<
"MaskAgnostic="
<<
(
bool
)
MaskAgnostic
<<
", "
<<
"MaskRegOp="
<<
(
bool
)
MaskRegOp
<<
", "
<<
"StoreOp="
<<
(
bool
)
StoreOp
<<
", "
<<
"ScalarMovOp="
<<
(
bool
)
ScalarMovOp
<<
", "
<<
"SEWLMULRatioOnly="
<<
(
bool
)
SEWLMULRatioOnly
<<
"}"
;
}
</s>

RISCV
"{"
"Uninitialized"
"unknown"
"AVLReg="
"AVLImm="
", "
"VLMul="
", "
"SEW="
", "
"TailAgnostic="
", "
"MaskAgnostic="
", "
"MaskRegOp="
", "
"StoreOp="
", "
"ScalarMovOp="
", "
"SEWLMULRatioOnly="
"}"


<s> void RISCVFrameLowering :: determineCalleeSaves ( MachineFunction & MF , BitVector & SavedRegs , RegScavenger * RS ) const { TargetFrameLowering :: determineCalleeSaves ( MF , SavedRegs , RS ) ; MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; RISCVFunctionInfo * RISCVFI = MF . getInfo < RISCVFunctionInfo > ( ) ; const RISCVSubtarget & STI = MF . getSubtarget < RISCVSubtarget > ( ) ; unsigned FP = STI . isRV64 ( ) ? RISCV :: fp_64 : RISCV :: fp ; if ( hasFP ( MF ) ) SavedRegs . set ( FP ) ; if ( RISCVFI -> getCallsEhReturn ( ) ) RISCVFI -> createEhDataRegsFI ( ) ; uint64_t MaxSPOffset = MF . getInfo < RISCVFunctionInfo > ( ) -> getIncomingArgSize ( ) + MFI -> estimateStackSize ( MF ) ; if ( isInt < 12 > ( MaxSPOffset ) ) return ; const TargetRegisterClass * RC = & RISCV :: GR32BitRegClass ; int FI = MF . getFrameInfo ( ) -> CreateStackObject ( RC -> getSize ( ) , RC -> getAlignment ( ) , false ) ; RS -> addScavengingFrameIndex ( FI ) ; } </s>

This method determines which of the registers reported by TargetRegisterInfo : :getCalleeSavedRegs ( ) should actually get saved .

RISCV RISCV RISCV RISCV RISCV RISCV RISCV RISCV::fp_64 RISCV::fp RISCV RISCV RISCV 12 RISCV::GR32BitRegClass


<s> DecodeStatus RISCVDisassembler :: getInstruction ( MCInst & MI , uint64_t & Size , ArrayRef < uint8_t > Bytes , uint64_t Address , raw_ostream & OS , raw_ostream & CS ) const { Size = 4 ; if ( Bytes . size ( ) < 4 ) { Size = 0 ; return MCDisassembler :: Fail ; } uint32_t Inst = support :: endian :: read32le ( Bytes . data ( ) ) ; return decodeInstruction ( DecoderTable32 , MI , Inst , Address , this , STI ) ; } </s>

Returns the disassembly of a single instruction .


<s> void riscv_set_return_address ( rtx address , rtx scratch ) { rtx slot_address ; gcc_assert ( BITSET_P ( cfun -> machine -> frame . mask , RETURN_ADDR_REGNUM ) ) ; slot_address = riscv_add_offset ( scratch , stack_pointer_rtx , cfun -> machine -> frame . gp_sp_offset . to_constant ( ) ) ; riscv_emit_move ( gen_frame_mem ( GET_MODE ( address ) , slot_address ) , address ) ; } </s>

Emit code to change the current function 's return address to ADDRESS . SCRATCH is available as a scratch register , if needed . ADDRESS and SCRATCH are both word-mode GPRs .


<s>
SDValue
RISCVTargetLowering
::
getAddr
(
NodeTy
*
N
,
SelectionDAG
&
DAG
)
const
{
SDLoc
DL
(
N
)
;
EVT
Ty
=
getPointerTy
(
DAG
.
getDataLayout
(
)
)
;
switch
(
getTargetMachine
(
)
.
getCodeModel
(
)
)
{
default
:
report_fatal_error
(
"Unsupported code model for lowering"
)
;
case
CodeModel
::
Small
:
{
SDValue
AddrHi
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
RISCVII
::
MO_HI
)
;
SDValue
AddrLo
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
RISCVII
::
MO_LO
)
;
SDValue
MNHi
=
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
LUI
,
DL
,
Ty
,
AddrHi
)
,
0
)
;
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
ADDI
,
DL
,
Ty
,
MNHi
,
AddrLo
)
,
0
)
;
}
case
CodeModel
::
Medium
:
{
SDValue
Addr
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
0
)
;
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoLLA
,
DL
,
Ty
,
Addr
)
,
0
)
;
}
}
}
</s>

Return the address accessed by this recipe .


<s> bool RISCVPassConfig :: addGlobalInstructionSelect ( ) { addPass ( new InstructionSelect ( ) ) ; 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> bool RISCVAsmParser :: processInstruction ( MCInst & Inst , SMLoc IDLoc , MCStreamer & Out ) { Inst . setLoc ( IDLoc ) ; if ( Inst . getOpcode ( ) == RISCV :: PseudoLI ) { auto Reg = Inst . getOperand ( 0 ) . getReg ( ) ; int64_t Imm = Inst . getOperand ( 1 ) . getImm ( ) ; if ( ! isRV64 ( ) ) Imm = SignExtend64 < 32 > ( Imm ) ; emitLoadImm ( Reg , Imm , Out ) ; return false ; } else if ( Inst . getOpcode ( ) == RISCV :: PseudoLLA ) { emitLoadLocalAddress ( Inst , IDLoc , Out ) ; return false ; } emitToStreamer ( Out , Inst ) ; return false ; } </s>

Process a single instruction and collect debug info anchors .


<s> static unsigned char riscv_class_max_nregs ( reg_class_t rclass , machine_mode mode ) { if ( reg_class_subset_p ( rclass , FP_REGS ) ) return riscv_hard_regno_nregs ( FP_REG_FIRST , mode ) ; if ( reg_class_subset_p ( rclass , GR_REGS ) ) return riscv_hard_regno_nregs ( GP_REG_FIRST , mode ) ; if ( reg_class_subset_p ( rclass , V_REGS ) ) return riscv_hard_regno_nregs ( V_REG_FIRST , mode ) ; return 0 ; } </s>


<s> void riscv_init_builtins ( void ) { riscv_init_builtin_types ( ) ; riscv_vector :: init_builtins ( ) ; for ( size_t i = 0 ; i < ARRAY_SIZE ( riscv_builtins ) ; i ++ ) { const struct riscv_builtin_description * d = & riscv_builtins [ i ] ; if ( d -> avail ( ) ) { tree type = riscv_build_function_type ( d -> prototype ) ; riscv_builtin_decls [ i ] = add_builtin_function ( d -> name , type , ( i << RISCV_BUILTIN_SHIFT ) + RISCV_BUILTIN_GENERAL , BUILT_IN_MD , NULL , NULL ) ; riscv_builtin_decl_index [ d -> icode ] = i ; } } } </s>


"Not all fixup kinds added to Infos array"


<s> static void riscv_prepare_builtin_arg ( struct expand_operand * op , tree exp , unsigned argno ) { tree arg = CALL_EXPR_ARG ( exp , argno ) ; create_input_operand ( op , expand_normal ( arg ) , TYPE_MODE ( TREE_TYPE ( arg ) ) ) ; } </s>

Take argument ARGNO from EXP 's argument list and convert it into an expand operand . Store the operand in * OP .


"  Found lowered global address with one use: "

runOnMachineFunction - Emit the function body .


<s> static void riscv_set_frame_expr ( rtx frame_pattern ) { rtx insn ; insn = get_last_insn ( ) ; RTX_FRAME_RELATED_P ( insn ) = 1 ; REG_NOTES ( insn ) = alloc_EXPR_LIST ( REG_FRAME_RELATED_EXPR , frame_pattern , REG_NOTES ( insn ) ) ; } </s>

Make the last instruction frame-related and note that it performs the operation described by FRAME_PATTERN .


<s> bool RISCVTargetLowering :: isMulAddWithConstProfitable ( const SDValue & AddNode , const SDValue & ConstNode ) const { EVT VT = AddNode . getValueType ( ) ; if ( VT . isVector ( ) ) return true ; if ( VT . getScalarSizeInBits ( ) > Subtarget . getXLen ( ) ) return true ; ConstantSDNode * C1Node = cast < ConstantSDNode > ( AddNode . getOperand ( 1 ) ) ; ConstantSDNode * C2Node = cast < ConstantSDNode > ( ConstNode ) ; const APInt & C1 = C1Node -> getAPIntValue ( ) ; const APInt & C2 = C2Node -> getAPIntValue ( ) ; if ( C1 . isSignedIntN ( 12 ) && ! ( C1 * C2 ) . isSignedIntN ( 12 ) ) return false ; return true ; } </s>

Return true if it may be profitable to transform ( mul ( add x , c1 ) , c2 ) - > ( add ( mul x , c2 ) , c1 * c2 ) .


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

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


<s> unsigned RISCVInstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { unsigned Opcode = MI . getOpcode ( ) ; switch ( Opcode ) { default : { return get ( Opcode ) . getSize ( ) ; } case TargetOpcode :: EH_LABEL : case TargetOpcode :: IMPLICIT_DEF : case TargetOpcode :: KILL : case TargetOpcode :: DBG_VALUE : return 0 ; case RISCV :: PseudoCALL : case RISCV :: PseudoTAIL : case RISCV :: PseudoLLA : case RISCV :: PseudoLA : case RISCV :: PseudoLA_TLS_IE : case RISCV :: PseudoLA_TLS_GD : return 8 ; case TargetOpcode :: INLINEASM : case TargetOpcode :: INLINEASM_BR : { const MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; const auto & TM = static_cast < const RISCVTargetMachine & > ( MF . getTarget ( ) ) ; return getInlineAsmLength ( MI . getOperand ( 0 ) . getSymbolName ( ) , * TM . getMCAsmInfo ( ) ) ; } } } </s>

Returns the size in bytes of the specified MachineInstr , or ~0U when this function is not implemented by a target .


<s>
static
void
riscv_emit_attribute
(
)
{
fprintf
(
asm_out_file
,
"\t.attribute arch, \"%s\"\n"
,
riscv_arch_str
(
)
.
c_str
(
)
)
;
fprintf
(
asm_out_file
,
"\t.attribute unaligned_access, %d\n"
,
TARGET_STRICT_ALIGN
0
:
1
)
;
fprintf
(
asm_out_file
,
"\t.attribute stack_align, %d\n"
,
riscv_stack_boundary
/
8
)
;
}
</s>

Auxiliary function to emit RISC-V ELF attribute .


<s> void RISCVPassConfig :: addPostRegAlloc ( ) { if ( TM -> getOptLevel ( ) != CodeGenOpt :: None && EnableRedundantCopyElimination ) addPass ( createRISCVRedundantCopyEliminationPass ( ) ) ; } </s>

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


<s> std :: pair < unsigned , const TargetRegisterClass * > RISCVTargetLowering :: getRegForInlineAsmConstraint ( const TargetRegisterInfo * TRI , StringRef Constraint , MVT VT ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { case 'r' : return std :: make_pair ( 0U , & RISCV :: GPRRegClass ) ; case 'f' : if ( Subtarget . hasStdExtF ( ) && VT == MVT :: f32 ) return std :: make_pair ( 0U , & RISCV :: FPR32RegClass ) ; if ( Subtarget . hasStdExtD ( ) && VT == MVT :: f64 ) return std :: make_pair ( 0U , & RISCV :: FPR64RegClass ) ; break ; default : break ; } } return TargetLowering :: getRegForInlineAsmConstraint ( TRI , Constraint , VT ) ; } </s>

Given a physical register constraint ( e.g .


<s> Register RISCVTargetLowering :: getExceptionSelectorRegister ( const Constant * PersonalityFn ) const { return RISCV :: X11 ; } </s>

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


<s> rtx riscv_function_value ( const_tree type , const_tree func , machine_mode mode ) { struct riscv_arg_info info ; CUMULATIVE_ARGS args ; if ( type ) { int unsigned_p = TYPE_UNSIGNED ( type ) ; mode = TYPE_MODE ( type ) ; mode = promote_function_mode ( type , mode , & unsigned_p , func , 1 ) ; } memset ( & args , 0 , sizeof args ) ; return riscv_get_arg_info ( & info , & args , mode , type , true , true ) ; } </s>

Implement FUNCTION_VALUE and LIBCALL_VALUE . For normal calls , VALTYPE is the return type and MODE is VOIDmode . For libcalls , VALTYPE is null and MODE is the mode of the return value .


<s> static void riscv_function_arg_advance ( cumulative_args_t cum_v , enum machine_mode mode , const_tree type , bool named ) { CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; struct riscv_arg_info info ; riscv_get_arg_info ( & info , cum , mode , type , named , false ) ; cum -> num_fprs = info . fpr_offset + info . num_fprs ; cum -> num_gprs = info . gpr_offset + info . num_gprs ; } </s>


<s> bool pass_vsetvl :: can_refine_vsetvl_p ( const basic_block cfg_bb , const vector_insn_info & info ) const { if ( ! m_vector_manager -> all_same_ratio_p ( m_vector_manager -> vector_avin [ cfg_bb -> index ] ) ) return false ; if ( ! m_vector_manager -> all_same_avl_p ( cfg_bb , m_vector_manager -> vector_avin [ cfg_bb -> index ] ) ) return false ; size_t expr_id = bitmap_first_set_bit ( m_vector_manager -> vector_avin [ cfg_bb -> index ] ) ; if ( ! m_vector_manager -> vector_exprs [ expr_id ] -> same_vlmax_p ( info ) ) return false ; if ( ! m_vector_manager -> vector_exprs [ expr_id ] -> compatible_avl_p ( info ) ) return false ; edge e ; edge_iterator ei ; bool all_valid_p = true ; FOR_EACH_EDGE ( e , ei , cfg_bb -> preds ) { if ( bitmap_empty_p ( m_vector_manager -> vector_avout [ e -> src -> index ] ) ) { all_valid_p = false ; break ; } } if ( ! all_valid_p ) return false ; return true ; } </s>

Return true if VSETVL in the block can be refined as vsetvl zero , zero .


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

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


<s> static rtx riscv_pass_fpr_single ( enum machine_mode type_mode , unsigned regno , enum machine_mode value_mode ) { rtx x = gen_rtx_REG ( value_mode , regno ) ; if ( type_mode != value_mode ) { x = gen_rtx_EXPR_LIST ( VOIDmode , x , const0_rtx ) ; x = gen_rtx_PARALLEL ( type_mode , gen_rtvec ( 1 , x ) ) ; } return x ; } </s>

Return the representation of an argument passed or returned in an FPR when the value has mode VALUE_MODE and the type has TYPE_MODE . The two modes may be different for structures like : struct __attribute__ ( ( packed ) ) foo { float f ; } where the SFmode value `` f '' is passed in REGNO but the struct itself has mode BLKmode .


<s> bool RISCVInstrInfo :: analyzeBranch ( MachineBasicBlock & MBB , MachineBasicBlock * & TBB , MachineBasicBlock * & FBB , SmallVectorImpl < MachineOperand > & Cond , bool AllowModify ) const { TBB = FBB = nullptr ; Cond . clear ( ) ; MachineBasicBlock :: iterator I = MBB . getLastNonDebugInstr ( ) ; if ( I == MBB . end ( ) || ! isUnpredicatedTerminator ( * I ) ) return false ; MachineBasicBlock :: iterator FirstUncondOrIndirectBr = MBB . end ( ) ; int NumTerminators = 0 ; for ( auto J = I . getReverse ( ) ; J != MBB . rend ( ) && isUnpredicatedTerminator ( * J ) ; J ++ ) { NumTerminators ++ ; if ( J -> getDesc ( ) . isUnconditionalBranch ( ) || J -> getDesc ( ) . isIndirectBranch ( ) ) { FirstUncondOrIndirectBr = J . getReverse ( ) ; } } if ( AllowModify && FirstUncondOrIndirectBr != MBB . end ( ) ) { while ( std :: next ( FirstUncondOrIndirectBr ) != MBB . end ( ) ) { std :: next ( FirstUncondOrIndirectBr ) -> eraseFromParent ( ) ; NumTerminators -- ; } I = FirstUncondOrIndirectBr ; } if ( I -> getDesc ( ) . isIndirectBranch ( ) ) return true ; if ( NumTerminators > 2 ) return true ; if ( NumTerminators == 1 && I -> getDesc ( ) . isUnconditionalBranch ( ) ) { TBB = getBranchDestBlock ( * I ) ; return false ; } if ( NumTerminators == 1 && I -> getDesc ( ) . isConditionalBranch ( ) ) { parseCondBranch ( * I , TBB , Cond ) ; return false ; } if ( NumTerminators == 2 && std :: prev ( I ) -> getDesc ( ) . isConditionalBranch ( ) && I -> getDesc ( ) . isUnconditionalBranch ( ) ) { parseCondBranch ( * std :: prev ( I ) , TBB , Cond ) ; FBB = getBranchDestBlock ( * I ) ; return false ; } return true ; } </s>

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


<s> static bool riscv_valid_lo_sum_p ( enum riscv_symbol_type sym_type , machine_mode mode ) { if ( riscv_symbol_insns ( sym_type ) == 0 ) return false ; if ( ! riscv_split_symbol_type ( sym_type ) ) return false ; if ( GET_MODE_SIZE ( mode ) > UNITS_PER_WORD && ( ! TARGET_STRICT_ALIGN || GET_MODE_BITSIZE ( mode ) > GET_MODE_ALIGNMENT ( mode ) ) ) return false ; return true ; } </s>

Return true if a LO_SUM can address a value of mode MODE when the LO_SUM symbol has type SYM_TYPE .


<s> void RISCVFrameLowering :: determineFrameLayout ( MachineFunction & MF ) const { MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const RISCVRegisterInfo * RI = STI . getRegisterInfo ( ) ; uint64_t FrameSize = MFI . getStackSize ( ) ; uint64_t StackAlign = RI -> needsStackRealignment ( MF ) ? MFI . getMaxAlignment ( ) : getStackAlignment ( ) ; uint64_t MaxCallFrameSize = MFI . getMaxCallFrameSize ( ) ; if ( MFI . hasVarSizedObjects ( ) ) MaxCallFrameSize = alignTo ( MaxCallFrameSize , StackAlign ) ; MFI . setMaxCallFrameSize ( MaxCallFrameSize ) ; if ( ! ( hasReservedCallFrame ( MF ) && MFI . adjustsStack ( ) ) ) FrameSize += MaxCallFrameSize ; FrameSize = alignTo ( FrameSize , StackAlign ) ; MFI . setStackSize ( FrameSize ) ; } </s>

Determine the frame layout but do not update the machine function .


<s> bool RISCVFrameLowering :: canUseAsPrologue ( const MachineBasicBlock & MBB ) const { MachineBasicBlock * TmpMBB = const_cast < MachineBasicBlock * > ( & MBB ) ; const auto * RVFI = MBB . getParent ( ) -> getInfo < RISCVMachineFunctionInfo > ( ) ; if ( ! RVFI -> useSaveRestoreLibCalls ( ) ) return true ; RegScavenger RS ; RS . enterBasicBlock ( * TmpMBB ) ; return ! RS . isRegUsed ( RISCV :: X5 ) ; } </s>

Check whether or not the given MBB can be used as a prologue for the target .


<s> static bool riscv_compressed_reg_p ( int regno ) { return ( TARGET_RVC && ( IN_RANGE ( regno , GP_REG_FIRST + 8 , GP_REG_FIRST + 15 ) || IN_RANGE ( regno , FP_REG_FIRST + 8 , FP_REG_FIRST + 15 ) ) ) ; } </s>

Return true if hard reg REGNO can be used in compressed instructions .


<s> BitVector RISCVRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const RISCVFrameLowering * TFI = getFrameLowering ( MF ) ; BitVector Reserved ( getNumRegs ( ) ) ; for ( size_t Reg = 0 ; Reg < getNumRegs ( ) ; Reg ++ ) { if ( MF . getSubtarget < RISCVSubtarget > ( ) . isRegisterReservedByUser ( Reg ) ) markSuperRegs ( Reserved , Reg ) ; } markSuperRegs ( Reserved , RISCV :: X0 ) ; markSuperRegs ( Reserved , RISCV :: X2 ) ; markSuperRegs ( Reserved , RISCV :: X3 ) ; markSuperRegs ( Reserved , RISCV :: X4 ) ; if ( TFI -> hasFP ( MF ) ) markSuperRegs ( Reserved , RISCV :: X8 ) ; if ( TFI -> hasBP ( MF ) ) markSuperRegs ( Reserved , RISCVABI :: getBPReg ( ) ) ; markSuperRegs ( Reserved , RISCV :: VL ) ; markSuperRegs ( Reserved , RISCV :: VTYPE ) ; markSuperRegs ( Reserved , RISCV :: VXSAT ) ; markSuperRegs ( Reserved , RISCV :: VXRM ) ; markSuperRegs ( Reserved , RISCV :: VLENB ) ; markSuperRegs ( Reserved , RISCV :: FRM ) ; markSuperRegs ( Reserved , RISCV :: FFLAGS ) ; assert ( checkAllSuperRegsMarked ( Reserved ) ) ; return Reserved ; } </s>

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

RISCV RISCV RISCV 0 RISCV RISCV::X0 RISCV::X2 RISCV::X3 RISCV::X4 RISCV::X8 RISCVABI::getBPReg RISCV::VL RISCV::VTYPE RISCV::VXSAT RISCV::VXRM RISCV::VLENB RISCV::FRM RISCV::FFLAGS


<s> static int riscv_build_integer ( struct riscv_integer_op * codes , HOST_WIDE_INT value , machine_mode mode ) { int cost = riscv_build_integer_1 ( codes , value , mode ) ; if ( value > 0 && cost > 2 ) { struct riscv_integer_op alt_codes [ RISCV_MAX_INTEGER_OPS ] ; int alt_cost , shift = clz_hwi ( value ) ; HOST_WIDE_INT shifted_val ; shifted_val = ( value << shift ) | ( ( ( ( HOST_WIDE_INT ) 1 ) << shift ) - 1 ) ; alt_cost = 1 + riscv_build_integer_1 ( alt_codes , shifted_val , mode ) ; if ( alt_cost < cost ) { alt_codes [ alt_cost - 1 ] . code = LSHIFTRT ; alt_codes [ alt_cost - 1 ] . value = shift ; memcpy ( codes , alt_codes , sizeof ( alt_codes ) ) ; cost = alt_cost ; } shifted_val = value << shift ; alt_cost = 1 + riscv_build_integer_1 ( alt_codes , shifted_val , mode ) ; if ( alt_cost < cost ) { alt_codes [ alt_cost - 1 ] . code = LSHIFTRT ; alt_codes [ alt_cost - 1 ] . value = shift ; memcpy ( codes , alt_codes , sizeof ( alt_codes ) ) ; cost = alt_cost ; } } if ( ! TARGET_64BIT && ( value > INT32_MAX || value < INT32_MIN ) ) { unsigned HOST_WIDE_INT loval = sext_hwi ( value , 32 ) ; unsigned HOST_WIDE_INT hival = sext_hwi ( ( value - loval ) >> 32 , 32 ) ; struct riscv_integer_op alt_codes [ RISCV_MAX_INTEGER_OPS ] ; struct riscv_integer_op hicode [ RISCV_MAX_INTEGER_OPS ] ; int hi_cost , lo_cost ; hi_cost = riscv_build_integer_1 ( hicode , hival , mode ) ; if ( hi_cost < cost ) { lo_cost = riscv_build_integer_1 ( alt_codes , loval , mode ) ; if ( lo_cost + hi_cost < cost ) { memcpy ( codes , alt_codes , lo_cost * sizeof ( struct riscv_integer_op ) ) ; memcpy ( codes + lo_cost , hicode , hi_cost * sizeof ( struct riscv_integer_op ) ) ; cost = lo_cost + hi_cost ; } } } return cost ; } </s>

Fill CODES with a sequence of rtl operations to load VALUE . Return the number of operations needed .


<s> bool RISCVInstructionSelector :: select ( MachineInstr & I ) { if ( ! isPreISelGenericOpcode ( I . getOpcode ( ) ) ) { return true ; } if ( selectImpl ( I , * CoverageInfo ) ) return true ; return false ; } </s>

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


<s> static int riscv_arg_partial_bytes ( cumulative_args_t cum , machine_mode mode , tree type , bool named ) { struct riscv_arg_info arg ; riscv_get_arg_info ( & arg , get_cumulative_args ( cum ) , mode , type , named , false ) ; return arg . stack_p ? arg . num_gprs * UNITS_PER_WORD : 0 ; } </s>


<s> const LegalizerInfo * RISCVSubtarget :: getLegalizerInfo ( ) const { return Legalizer . get ( ) ; } </s>

Expose LegalizerInfo so the clients can re-use .


<s>
unsigned
getReg
(
)
const
override
{
assert
(
Kind
==
Register
&&
"Invalid type access!"
)
;
return
Reg
.
RegNum
;
}
</s>

Returns the register associated with this edge .


<s> ISD :: NodeType getExtendForAtomicCmpSwapArg ( ) const override { return ISD :: SIGN_EXTEND ; } </s>

Returns how the platform 's atomic compare and swap expects its comparison value to be extended ( ZERO_EXTEND , SIGN_EXTEND , or ANY_EXTEND ) .


<s> bool RISCVTargetLowering :: isOffsetFoldingLegal ( const GlobalAddressSDNode * GA ) const { return false ; } </s>

Return true if folding a constant offset with the given GlobalAddress is legal .


<s> static void i386_solaris_elf_named_section ( const char * name , unsigned int flags , tree decl ) { if ( TARGET_64BIT && strcmp ( name , ".eh_frame" ) == 0 ) { fprintf ( asm_out_file , "\t.section\t%s,\"%s\",@unwind\n" , name , flags & SECTION_WRITE ? "aw" : "a" ) ; return ; } default_elf_asm_named_section ( name , flags , decl ) ; } </s>

Solaris named-section hook . Parameters are as for named_section_real .


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

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


"  Preloading operand for insn %d into r%d\n"

Convert operand OP in INSN . We should handle memory operands and uninitialized registers . All other register uses are converted during registers conversion .


<s> static scalar_int_mode rs6000_abi_word_mode ( void ) { return TARGET_32BIT ? SImode : DImode ; } </s>

The mode the ABI uses for a word . This is not the same as word_mode for -m32 -mpowerpc64 . This is used to implement various target hooks .


<s> void PPCXCOFFStreamer :: emitInstruction ( const MCInst & Inst , const MCSubtargetInfo & STI ) { PPCMCCodeEmitter * Emitter = static_cast < PPCMCCodeEmitter * > ( getAssembler ( ) . getEmitterPtr ( ) ) ; if ( ! Emitter -> isPrefixedInstruction ( Inst ) ) { MCXCOFFStreamer :: emitInstruction ( Inst , STI ) ; return ; } emitPrefixedInstruction ( Inst , STI ) ; } </s>

Targets should implement this to emit instructions .


<s>
CCAssignFn
*
AArch64TargetLowering
::
CCAssignFnForCall
(
CallingConv
::
ID
CC
,
bool
IsVarArg
)
const
{
switch
(
CC
)
{
default
:
report_fatal_error
(
"Unsupported calling convention."
)
;
case
CallingConv
::
WebKit_JS
:
return
CC_AArch64_WebKit_JS
;
case
CallingConv
::
GHC
:
return
CC_AArch64_GHC
;
case
CallingConv
::
C
:
case
CallingConv
::
Fast
:
case
CallingConv
::
PreserveMost
:
case
CallingConv
::
CXX_FAST_TLS
:
case
CallingConv
::
Swift
:
case
CallingConv
::
SwiftTail
:
case
CallingConv
::
Tail
:
if
(
Subtarget
->
isTargetWindows
(
)
&&
IsVarArg
)
return
CC_AArch64_Win64_VarArg
;
if
(
!
Subtarget
->
isTargetDarwin
(
)
)
return
CC_AArch64_AAPCS
;
if
(
!
IsVarArg
)
return
CC_AArch64_DarwinPCS
;
return
Subtarget
->
isTargetILP32
(
)
CC_AArch64_DarwinPCS_ILP32_VarArg
:
CC_AArch64_DarwinPCS_VarArg
;
case
CallingConv
::
Win64
:
return
IsVarArg
CC_AArch64_Win64_VarArg
:
CC_AArch64_AAPCS
;
case
CallingConv
::
CFGuard_Check
:
return
CC_AArch64_Win64_CFGuard_Check
;
case
CallingConv
::
AArch64_VectorCall
:
case
CallingConv
::
AArch64_SVE_VectorCall
:
return
CC_AArch64_AAPCS
;
}
}
</s>

Selects the correct CCAssignFn for a given CallingConvention value .


<s> outliner :: OutlinedFunction X86InstrInfo :: getOutliningCandidateInfo ( std :: vector < outliner :: Candidate > & RepeatedSequenceLocs ) const { unsigned SequenceSize = std :: accumulate ( RepeatedSequenceLocs [ 0 ] . front ( ) , std :: next ( RepeatedSequenceLocs [ 0 ] . back ( ) ) , 0 , [ ] ( unsigned Sum , const MachineInstr & MI ) { if ( MI . isDebugInstr ( ) || MI . isKill ( ) ) return Sum ; return Sum + 1 ; } ) ; unsigned CFICount = 0 ; MachineBasicBlock :: iterator MBBI = RepeatedSequenceLocs [ 0 ] . front ( ) ; for ( unsigned Loc = RepeatedSequenceLocs [ 0 ] . getStartIdx ( ) ; Loc < RepeatedSequenceLocs [ 0 ] . getEndIdx ( ) + 1 ; Loc ++ ) { if ( MBBI -> isCFIInstruction ( ) ) CFICount ++ ; MBBI ++ ; } for ( outliner :: Candidate & C : RepeatedSequenceLocs ) { std :: vector < MCCFIInstruction > CFIInstructions = C . getMF ( ) -> getFrameInstructions ( ) ; if ( CFICount > 0 && CFICount != CFIInstructions . size ( ) ) return outliner :: OutlinedFunction ( ) ; } if ( RepeatedSequenceLocs [ 0 ] . back ( ) -> isTerminator ( ) ) { for ( outliner :: Candidate & C : RepeatedSequenceLocs ) C . setCallInfo ( MachineOutlinerTailCall , 1 ) ; return outliner :: OutlinedFunction ( RepeatedSequenceLocs , SequenceSize , 0 , MachineOutlinerTailCall ) ; } if ( CFICount > 0 ) return outliner :: OutlinedFunction ( ) ; for ( outliner :: Candidate & C : RepeatedSequenceLocs ) C . setCallInfo ( MachineOutlinerDefault , 1 ) ; return outliner :: OutlinedFunction ( RepeatedSequenceLocs , SequenceSize , 1 , MachineOutlinerDefault ) ; } </s>

Returns a outliner : :OutlinedFunction struct containing target-specific information for a set of outlining candidates .


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> PPCSubtarget :: PPCSubtarget ( const std :: string & TT , const std :: string & CPU , const std :: string & FS , bool is64Bit , CodeGenOpt :: Level OptLevel ) : PPCGenSubtargetInfo ( TT , CPU , FS ) , IsPPC64 ( is64Bit ) , TargetTriple ( TT ) { initializeEnvironment ( ) ; std :: string FullFS = FS ; if ( OptLevel >= CodeGenOpt :: Default ) { if ( ! FullFS . empty ( ) ) FullFS = "+crbits," + FullFS ; else FullFS = "+crbits" ; } resetSubtargetFeatures ( CPU , FullFS ) ; } </s>

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

PowerPC PPC PPC PPC PPC "+crbits," "+crbits"


<s> bool Thumb1RegisterInfo :: saveScavengerRegister ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , MachineBasicBlock :: iterator & UseMI , const TargetRegisterClass * RC , unsigned Reg ) const { DebugLoc DL ; AddDefaultPred ( BuildMI ( MBB , I , DL , TII . get ( ARM :: tMOVr ) ) . addReg ( ARM :: R12 , RegState :: Define ) . addReg ( Reg , RegState :: Kill ) ) ; bool done = false ; for ( MachineBasicBlock :: iterator II = I ; ! done && II != UseMI ; ++ II ) { if ( II -> isDebugValue ( ) ) continue ; for ( unsigned i = 0 , e = II -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = II -> getOperand ( i ) ; if ( MO . isRegMask ( ) && MO . clobbersPhysReg ( ARM :: R12 ) ) { UseMI = II ; done = true ; break ; } if ( ! MO . isReg ( ) || MO . isUndef ( ) || ! MO . getReg ( ) || TargetRegisterInfo :: isVirtualRegister ( MO . getReg ( ) ) ) continue ; if ( MO . getReg ( ) == ARM :: R12 ) { UseMI = II ; done = true ; break ; } } } AddDefaultPred ( BuildMI ( MBB , UseMI , DL , TII . get ( ARM :: tMOVr ) ) . addReg ( Reg , RegState :: Define ) . addReg ( ARM :: R12 , RegState :: Kill ) ) ; return true ; } </s>

Spill the register so it can be used by the register scavenger .


<s> void Thumb2InstrInfo :: storeRegToStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , Register SrcReg , bool isKill , int FI , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { DebugLoc DL ; if ( I != MBB . end ( ) ) DL = I -> getDebugLoc ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; MachineMemOperand * MMO = MF . getMachineMemOperand ( MachinePointerInfo :: getFixedStack ( MF , FI ) , MachineMemOperand :: MOStore , MFI . getObjectSize ( FI ) , MFI . getObjectAlignment ( FI ) ) ; if ( ARM :: GPRRegClass . hasSubClassEq ( RC ) ) { BuildMI ( MBB , I , DL , get ( ARM :: t2STRi12 ) ) . addReg ( SrcReg , getKillRegState ( isKill ) ) . addFrameIndex ( FI ) . addImm ( 0 ) . addMemOperand ( MMO ) . add ( predOps ( ARMCC :: AL ) ) ; return ; } if ( ARM :: GPRPairRegClass . hasSubClassEq ( RC ) ) { if ( Register :: isVirtualRegister ( SrcReg ) ) { MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; MRI -> constrainRegClass ( SrcReg , & ARM :: GPRPairnospRegClass ) ; } MachineInstrBuilder MIB = BuildMI ( MBB , I , DL , get ( ARM :: t2STRDi8 ) ) ; AddDReg ( MIB , SrcReg , ARM :: gsub_0 , getKillRegState ( isKill ) , TRI ) ; AddDReg ( MIB , SrcReg , ARM :: gsub_1 , 0 , TRI ) ; MIB . addFrameIndex ( FI ) . addImm ( 0 ) . addMemOperand ( MMO ) . add ( predOps ( ARMCC :: AL ) ) ; return ; } ARMBaseInstrInfo :: storeRegToStackSlot ( MBB , I , SrcReg , isKill , FI , RC , TRI ) ; } </s>

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


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

runOnMachineFunction - Emit the function body .

Mips Mips Mips Mips Mips Mips Mips16HardFloatInfo::FuncSignature Mips Mips Mips16HardFloatInfo::FuncSignature


<s>
void
final_prescan_insn
(
rtx
insn
,
rtx
*
opvec
ATTRIBUTE_UNUSED
,
int
noperands
ATTRIBUTE_UNUSED
)
{
if
(
TARGET_DUMPISIZE
)
fprintf
(
asm_out_file
,
"\n! at %04x\n"
,
INSN_ADDRESSES
(
INSN_UID
(
insn
)
)
)
;
if
(
TARGET_RELAX
)
{
rtx
note
;
note
=
find_reg_note
(
insn
,
REG_LABEL
,
NULL_RTX
)
;
if
(
note
)
{
rtx
pattern
;
pattern
=
PATTERN
(
insn
)
;
if
(
GET_CODE
(
pattern
)
==
PARALLEL
)
pattern
=
XVECEXP
(
pattern
,
0
,
0
)
;
switch
(
GET_CODE
(
pattern
)
)
{
case
SET
:
if
(
GET_CODE
(
SET_SRC
(
pattern
)
)
!=
CALL
&&
get_attr_type
(
insn
)
!=
TYPE_SFUNC
)
{
targetm
.
asm_out
.
internal_label
(
asm_out_file
,
"L"
,
CODE_LABEL_NUMBER
(
XEXP
(
note
,
0
)
)
)
;
break
;
}
case
CALL
:
asm_fprintf
(
asm_out_file
,
"\t.uses %LL%d\n"
,
CODE_LABEL_NUMBER
(
XEXP
(
note
,
0
)
)
)
;
break
;
default
:
gcc_unreachable
(
)
;
}
}
}
}
</s>

If defined , a C statement to be executed just prior to the output of assembler code for INSN , to modify the extracted operands so they will be output differently . Here the argument OPVEC is the vector containing the operands extracted from INSN , and NOPERANDS is the number of elements of the vector which contain meaningful data for this insn . The contents of this vector are what will be used to convert the insn template into assembler code , so you can change the assembler output by changing the contents of the vector . We use it to check if the current insn needs a nop in front of it because of load delays , and also to update the delay slot statistics .


<s> InstructionCost ARMTTIImpl :: getIntImmCostInst ( unsigned Opcode , unsigned Idx , const APInt & Imm , Type * Ty , TTI :: TargetCostKind CostKind , Instruction * Inst ) { if ( ( Opcode == Instruction :: SDiv || Opcode == Instruction :: UDiv || Opcode == Instruction :: SRem || Opcode == Instruction :: URem ) && Idx == 1 ) return 0 ; if ( Opcode == Instruction :: And ) { if ( Imm == 255 || Imm == 65535 ) return 0 ; return std :: min ( getIntImmCost ( Imm , Ty , CostKind ) , getIntImmCost ( ~ Imm , Ty , CostKind ) ) ; } if ( Opcode == Instruction :: Add ) return std :: min ( getIntImmCost ( Imm , Ty , CostKind ) , getIntImmCost ( - Imm , Ty , CostKind ) ) ; if ( Opcode == Instruction :: ICmp && Imm . isNegative ( ) && Ty -> getIntegerBitWidth ( ) == 32 ) { int64_t NegImm = - Imm . getSExtValue ( ) ; if ( ST -> isThumb2 ( ) && NegImm < 1 << 12 ) return 0 ; if ( ST -> isThumb ( ) && NegImm < 1 << 8 ) return 0 ; } if ( Opcode == Instruction :: Xor && Imm . isAllOnesValue ( ) ) return 0 ; if ( Inst && ( ( ST -> hasV6Ops ( ) && ! ST -> isThumb ( ) ) || ST -> isThumb2 ( ) ) && Ty -> getIntegerBitWidth ( ) <= 32 ) { if ( isSSATMinMaxPattern ( Inst , Imm ) || ( isa < ICmpInst > ( Inst ) && Inst -> hasOneUse ( ) && isSSATMinMaxPattern ( cast < Instruction > ( * Inst -> user_begin ( ) ) , Imm ) ) ) return 0 ; } return getIntImmCost ( Imm , Ty , CostKind ) ; } </s>

Return the expected cost of materialization for the given integer immediate of the specified type for a given instruction .


<s> unsigned MipsSEInstrInfo :: loadImmediate ( int64_t Imm , MachineBasicBlock & MBB , MachineBasicBlock :: iterator II , DebugLoc DL , unsigned * NewImm ) const { MipsAnalyzeImmediate AnalyzeImm ; const MipsSubtarget & STI = TM . getSubtarget < MipsSubtarget > ( ) ; MachineRegisterInfo & RegInfo = MBB . getParent ( ) -> getRegInfo ( ) ; unsigned Size = STI . isABI_N64 ( ) ? 64 : 32 ; unsigned LUi = STI . isABI_N64 ( ) ? Mips :: LUi64 : Mips :: LUi ; unsigned ZEROReg = STI . isABI_N64 ( ) ? Mips :: ZERO_64 : Mips :: ZERO ; const TargetRegisterClass * RC = STI . isABI_N64 ( ) ? & Mips :: CPU64RegsRegClass : & Mips :: CPURegsRegClass ; bool LastInstrIsADDiu = NewImm ; const MipsAnalyzeImmediate :: InstSeq & Seq = AnalyzeImm . Analyze ( Imm , Size , LastInstrIsADDiu ) ; MipsAnalyzeImmediate :: InstSeq :: const_iterator Inst = Seq . begin ( ) ; assert ( Seq . size ( ) && ( ! LastInstrIsADDiu || ( Seq . size ( ) > 1 ) ) ) ; unsigned Reg = RegInfo . createVirtualRegister ( RC ) ; if ( Inst -> Opc == LUi ) BuildMI ( MBB , II , DL , get ( LUi ) , Reg ) . addImm ( SignExtend64 < 16 > ( Inst -> ImmOpnd ) ) ; else BuildMI ( MBB , II , DL , get ( Inst -> Opc ) , Reg ) . addReg ( ZEROReg ) . addImm ( SignExtend64 < 16 > ( Inst -> ImmOpnd ) ) ; for ( ++ Inst ; Inst != Seq . end ( ) - LastInstrIsADDiu ; ++ Inst ) BuildMI ( MBB , II , DL , get ( Inst -> Opc ) , Reg ) . addReg ( Reg , RegState :: Kill ) . addImm ( SignExtend64 < 16 > ( Inst -> ImmOpnd ) ) ; if ( LastInstrIsADDiu ) * NewImm = Inst -> ImmOpnd ; return Reg ; } </s>

Emit a series of instructions to load an immediate .


<s> EVT ARMTargetLowering :: getSetCCResultType ( const DataLayout & DL , LLVMContext & , EVT VT ) const { if ( ! VT . isVector ( ) ) return getPointerTy ( DL ) ; if ( ( Subtarget -> hasMVEIntegerOps ( ) && ( VT == MVT :: v4i32 || VT == MVT :: v8i16 || VT == MVT :: v16i8 ) ) || ( Subtarget -> hasMVEFloatOps ( ) && ( VT == MVT :: v4f32 || VT == MVT :: v8f16 ) ) ) return MVT :: getVectorVT ( MVT :: i1 , VT . getVectorElementCount ( ) ) ; return VT . changeVectorElementTypeToInteger ( ) ; } </s>

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


"Unexpected register class in CSRsViaCopy!"

"Function should be nounwind in insertCopiesSplitCSR!"

Insert explicit copies in entry and exit blocks .


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } </s>


Relax the instruction in the given fragment to the next wider instruction .


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

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


<s> bool isImm ( ) const { return Kind == Immediate || Kind == Expression ; } </s>


<s> bool Cpu0AsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count ) const { OS . write_zeros ( Count ) ; return true ; } </s>

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


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


<s>
static
char
*
describe_cache
(
unsigned
l1_sizekb
,
unsigned
l1_line
,
unsigned
l1_assoc
ATTRIBUTE_UNUSED
,
unsigned
l2_sizekb
)
{
char
l1size
[
1000
]
,
line
[
1000
]
,
l2size
[
1000
]
;
sprintf
(
l1size
,
"--param l1-cache-size=%u"
,
l1_sizekb
)
;
sprintf
(
line
,
"--param l1-cache-line-size=%u"
,
l1_line
)
;
sprintf
(
l2size
,
"--param l2-cache-size=%u"
,
l2_sizekb
)
;
return
concat
(
l1size
,
" "
,
line
,
" "
,
l2size
,
" "
,
)
;
}
</s>

Returns parameters that describe L1_ASSOC associative cache of size L1_SIZEKB with lines of size L1_LINE , and L2_SIZEKB .


<s> TargetTransformInfo X86TargetMachine :: getTargetTransformInfo ( const Function & F ) { return TargetTransformInfo ( X86TTIImpl ( this , F ) ) ; } </s>

Get a TargetTransformInfo implementation for the target .


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getSubtarget ( ) . getDataLayout ( ) ; TII = Fn . getSubtarget ( ) . getInstrInfo ( ) ; TRI = Fn . getSubtarget ( ) . getRegisterInfo ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


<s> static void ia64_emit_insn_before ( rtx insn , rtx_insn * before ) { emit_insn_before ( insn , before ) ; } </s>

Like emit_insn_before , but skip cycle_display insns . This makes the assembly output a bit prettier .


<s> static rtx sh_struct_value_rtx ( tree fndecl , int incoming ATTRIBUTE_UNUSED ) { if ( TARGET_HITACHI || sh_attr_renesas_p ( fndecl ) ) return 0 ; return gen_rtx_REG ( Pmode , 2 ) ; } </s>

The Renesas calling convention does n't quite fit into this scheme since the address is passed like an invisible argument , but one that is always passed in memory .


<s> bool enableIndirectBrExpand ( ) const override { return useRetpoline ( ) ; } </s>

If we are using indirect thunks , we need to expand indirectbr to avoid it lowering to an actual indirect jump .


<s>
bool
MipsAsmParser
::
ParseInstruction
(
ParseInstructionInfo
&
Info
,
StringRef
Name
,
SMLoc
NameLoc
,
SmallVectorImpl
<
MCParsedAsmOperand
*
>
&
Operands
)
{
StringRef
Mnemonic
;
if
(
requestsDoubleOperand
(
Name
)
)
{
setFpFormat
(
FP_FORMAT_D
)
;
Operands
.
push_back
(
MipsOperand
::
CreateToken
(
Name
,
NameLoc
)
)
;
Mnemonic
=
Name
;
}
else
{
setDefaultFpFormat
(
)
;
size_t
Start
=
0
,
Next
=
Name
.
find
(
'.'
)
;
Mnemonic
=
Name
.
slice
(
Start
,
Next
)
;
Operands
.
push_back
(
MipsOperand
::
CreateToken
(
Mnemonic
,
NameLoc
)
)
;
if
(
Next
!=
StringRef
::
npos
)
{
size_t
Dot
=
Name
.
find
(
'.'
,
Next
+
1
)
;
StringRef
Format
=
Name
.
slice
(
Next
,
Dot
)
;
if
(
Dot
==
StringRef
::
npos
)
Operands
.
push_back
(
MipsOperand
::
CreateToken
(
Format
,
NameLoc
)
)
;
else
{
if
(
Name
.
startswith
(
"c."
)
)
{
Operands
.
push_back
(
MipsOperand
::
CreateToken
(
"."
,
NameLoc
)
)
;
int
Cc
=
ConvertCcString
(
Format
)
;
if
(
Cc
==
1
)
{
return
Error
(
NameLoc
,
"Invalid conditional code"
)
;
}
SMLoc
E
=
SMLoc
::
getFromPointer
(
Parser
.
getTok
(
)
.
getLoc
(
)
.
getPointer
(
)
1
)
;
Operands
.
push_back
(
MipsOperand
::
CreateImm
(
MCConstantExpr
::
Create
(
Cc
,
getContext
(
)
)
,
NameLoc
,
E
)
)
;
}
else
{
return
parseMathOperation
(
Name
,
NameLoc
,
Operands
)
;
}
Format
=
Name
.
slice
(
Dot
,
StringRef
::
npos
)
;
Operands
.
push_back
(
MipsOperand
::
CreateToken
(
Format
,
NameLoc
)
)
;
}
setFpFormat
(
Format
)
;
}
}
if
(
getLexer
(
)
.
isNot
(
AsmToken
::
EndOfStatement
)
)
{
if
(
ParseOperand
(
Operands
,
Mnemonic
)
)
{
SMLoc
Loc
=
getLexer
(
)
.
getLoc
(
)
;
Parser
.
eatToEndOfStatement
(
)
;
return
Error
(
Loc
,
"unexpected token in argument list"
)
;
}
while
(
getLexer
(
)
.
is
(
AsmToken
::
Comma
)
)
{
Parser
.
Lex
(
)
;
if
(
ParseOperand
(
Operands
,
Name
)
)
{
SMLoc
Loc
=
getLexer
(
)
.
getLoc
(
)
;
Parser
.
eatToEndOfStatement
(
)
;
return
Error
(
Loc
,
"unexpected token in argument list"
)
;
}
}
}
if
(
getLexer
(
)
.
isNot
(
AsmToken
::
EndOfStatement
)
)
{
SMLoc
Loc
=
getLexer
(
)
.
getLoc
(
)
;
Parser
.
eatToEndOfStatement
(
)
;
return
Error
(
Loc
,
"unexpected token in argument list"
)
;
}
Parser
.
Lex
(
)
;
return
false
;
}
</s>

ParseInstruction - Parse one assembly instruction .

Mips
Mips
MipsOperand::CreateToken
0
MipsOperand::CreateToken
1
MipsOperand::CreateToken
"c."
MipsOperand::CreateToken
"."
1
"Invalid conditional code"
1
MipsOperand::CreateImm
MipsOperand::CreateToken
"unexpected token in argument list"
"unexpected token in argument list"
"unexpected token in argument list"


<s> int tls_symbolic_operand ( rtx op , enum machine_mode mode ATTRIBUTE_UNUSED ) { if ( GET_CODE ( op ) != SYMBOL_REF ) return 0 ; return SYMBOL_REF_TLS_MODEL ( op ) ; } </s>

Return the TLS type for TLS symbols , 0 for otherwise .


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : break ; case ARM :: LDRrs : case ARM :: t2LDRs : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isReg ( ) && MI . getOperand ( 3 ) . isImm ( ) && MI . getOperand ( 2 ) . getReg ( ) == 0 && MI . getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: LDRi12 : case ARM :: t2LDRi12 : case ARM :: tLDRspi : case ARM :: VLDRD : case ARM :: VLDRS : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLD1q64 : case ARM :: VLD1d8TPseudo : case ARM :: VLD1d16TPseudo : case ARM :: VLD1d32TPseudo : case ARM :: VLD1d64TPseudo : case ARM :: VLD1d8QPseudo : case ARM :: VLD1d16QPseudo : case ARM :: VLD1d32QPseudo : case ARM :: VLD1d64QPseudo : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLDMQIA : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot , return the virtual or physical register number of the destination along with the FrameIndex of the loaded stack slot .


<s> static rtx pa_trampoline_adjust_address ( rtx addr ) { if ( ! TARGET_64BIT ) addr = memory_address ( Pmode , plus_constant ( Pmode , addr , 58 ) ) ; return addr ; } </s>

Perform any machine-specific adjustment in the address of the trampoline . ADDR contains the address that was passed to pa_trampoline_init . Adjust the trampoline address to point to the plabel at offset 44 .


<s> bool aarch64_sve_dup_immediate_p ( rtx x ) { rtx elt ; if ( ! const_vec_duplicate_p ( x , & elt ) || ! CONST_INT_P ( elt ) ) return false ; HOST_WIDE_INT val = INTVAL ( elt ) ; if ( val & 0xff ) return IN_RANGE ( val , - 0x80 , 0x7f ) ; return IN_RANGE ( val , - 0x8000 , 0x7f00 ) ; } </s>

Return true if X is a valid immediate for the SVE DUP and CPY instructions .


<s> unsigned X86TTIImpl :: getScalarizationOverhead ( VectorType * Ty , const APInt & DemandedElts , bool Insert , bool Extract ) { unsigned Cost = 0 ; if ( Insert ) { std :: pair < int , MVT > LT = TLI -> getTypeLegalizationCost ( DL , Ty ) ; MVT MScalarTy = LT . second . getScalarType ( ) ; if ( ( MScalarTy == MVT :: i16 && ST -> hasSSE2 ( ) ) || ( MScalarTy . isInteger ( ) && ST -> hasSSE41 ( ) ) || ( MScalarTy == MVT :: f32 && ST -> hasSSE41 ( ) ) ) { if ( LT . second . getSizeInBits ( ) <= 128 ) { Cost += BaseT :: getScalarizationOverhead ( Ty , DemandedElts , Insert , false ) ; } else { unsigned NumSubVecs = LT . second . getSizeInBits ( ) / 128 ; Cost += ( PowerOf2Ceil ( NumSubVecs ) - 1 ) * LT . first ; Cost += DemandedElts . countPopulation ( ) ; if ( MScalarTy == MVT :: f32 ) for ( unsigned i = 0 , e = Ty -> getNumElements ( ) ; i < e ; i += 4 ) if ( DemandedElts [ i ] ) Cost -- ; } } else if ( LT . second . isVector ( ) ) { if ( Ty -> isIntOrIntVectorTy ( ) ) Cost += DemandedElts . countPopulation ( ) ; unsigned NumElts = LT . second . getVectorNumElements ( ) ; unsigned Pow2Elts = PowerOf2Ceil ( Ty -> getNumElements ( ) ) ; Cost += ( std :: min < unsigned > ( NumElts , Pow2Elts ) - 1 ) * LT . first ; } } if ( Extract ) Cost += BaseT :: getScalarizationOverhead ( Ty , DemandedElts , false , Extract ) ; return Cost ; } </s>

Estimate the overhead of scalarizing an instruction .


<s>
void
ARMTargetLowering
::
ReplaceNodeResults
(
SDNode
*
N
,
SmallVectorImpl
<
SDValue
>
&
Results
,
SelectionDAG
&
DAG
)
const
{
SDValue
Res
;
switch
(
N
->
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Don't know how to custom expand this!"
)
;
case
ISD
::
BITCAST
:
Res
=
ExpandBITCAST
(
N
,
DAG
)
;
break
;
case
ISD
::
SIGN_EXTEND
:
case
ISD
::
ZERO_EXTEND
:
Res
=
ExpandVectorExtension
(
N
,
DAG
)
;
break
;
case
ISD
::
SRL
:
case
ISD
::
SRA
:
Res
=
Expand64BitShift
(
N
,
DAG
,
Subtarget
)
;
break
;
case
ISD
::
ATOMIC_LOAD_ADD
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMADD64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_AND
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMAND64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_NAND
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMNAND64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_OR
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMOR64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_SUB
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMSUB64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_XOR
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMXOR64_DAG
)
;
return
;
case
ISD
::
ATOMIC_SWAP
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMSWAP64_DAG
)
;
return
;
case
ISD
::
ATOMIC_CMP_SWAP
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMCMPXCHG64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_MIN
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMMIN64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_UMIN
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMUMIN64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_MAX
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMMAX64_DAG
)
;
return
;
case
ISD
::
ATOMIC_LOAD_UMAX
:
ReplaceATOMIC_OP_64
(
N
,
Results
,
DAG
,
ARMISD
::
ATOMUMAX64_DAG
)
;
return
;
}
if
(
Res
.
getNode
(
)
)
Results
.
push_back
(
Res
)
;
}
</s>

ReplaceNodeResults - Replace the results of node with an illegal result type with new values built out of custom code .


<s> Value * X86TargetLowering :: getSafeStackPointerLocation ( IRBuilder < > & IRB ) const { if ( Subtarget . getTargetTriple ( ) . isOSContiki ( ) ) return getDefaultSafeStackPointerLocation ( IRB , false ) ; if ( ! Subtarget . isTargetAndroid ( ) ) return TargetLowering :: getSafeStackPointerLocation ( IRB ) ; unsigned AddressSpace , Offset ; Offset = ( Subtarget . is64Bit ( ) ) ? 0x48 : 0x24 ; AddressSpace = getAddressSpace ( ) ; 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> static bool alg_usable_p ( enum stringop_alg alg , bool memset ) { if ( alg == no_stringop ) return false ; if ( alg == vector_loop ) return TARGET_SSE || TARGET_AVX ; if ( alg == rep_prefix_1_byte || alg == rep_prefix_4_byte || alg == rep_prefix_8_byte ) return ! ( fixed_regs [ CX_REG ] || fixed_regs [ DI_REG ] || ( memset ? fixed_regs [ AX_REG ] : fixed_regs [ SI_REG ] ) ) ; return true ; } </s>

Return true if ALG can be used in current context . Assume we expand memset if MEMSET is true .


<s> void X86InstructionSelector :: beginFunction ( const MachineFunction & MF ) { OptForSize = MF . getFunction ( ) -> optForSize ( ) ; OptForMinSize = MF . getFunction ( ) -> optForMinSize ( ) ; AvailableFeatures = computeAvailableFeatures ( & MF , & STI ) ; } </s>

Gather pre-function exception information .


"  group = %s, path = %d, byte_len = %d\n"

"  num_imm = %d, num_imm_32 = %d, num_imm_64 = %d, imm_size = %d\n"

Print INSN dispatch information to FILE .


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

Simple predicate for targets where ! Resolved implies requiring relaxation .


<s> TargetLowering :: ConstraintWeight MipsTargetLowering :: getSingleConstraintMatchWeight ( AsmOperandInfo & info , const char * constraint ) const { ConstraintWeight weight = CW_Invalid ; Value * CallOperandVal = info . CallOperandVal ; if ( CallOperandVal == NULL ) return CW_Default ; Type * type = CallOperandVal -> getType ( ) ; switch ( * constraint ) { default : weight = TargetLowering :: getSingleConstraintMatchWeight ( info , constraint ) ; break ; case 'd' : case 'y' : if ( type -> isIntegerTy ( ) ) weight = CW_Register ; break ; case 'f' : if ( type -> isFloatTy ( ) ) weight = CW_Register ; break ; case 'c' : case 'l' : case 'x' : if ( type -> isIntegerTy ( ) ) weight = CW_SpecificReg ; break ; case 'I' : case 'J' : case 'K' : case 'L' : case 'N' : case 'O' : case 'P' : if ( isa < ConstantInt > ( CallOperandVal ) ) weight = CW_Constant ; break ; case 'R' : weight = CW_Memory ; break ; } return weight ; } </s>

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


<s> bool loongarch_split_move_p ( rtx dest , rtx src ) { unsigned int size = GET_MODE_SIZE ( GET_MODE ( dest ) ) ; if ( size == 8 && FP_REG_RTX_P ( src ) && FP_REG_RTX_P ( dest ) ) return false ; if ( size == 8 ) { if ( FP_REG_RTX_P ( dest ) && MEM_P ( src ) ) return false ; if ( FP_REG_RTX_P ( src ) && MEM_P ( dest ) ) return false ; } return size > UNITS_PER_WORD ; } </s>

Return true if a move from SRC to DEST should be split into two . SPLIT_TYPE describes the split condition .


<s> unsigned getNumFixupKinds ( ) const override { return SIC :: NumTargetFixupKinds ; } </s>

Get the number of target specific fixup kinds .


<s> Register getFramePtr ( ) const { return FramePtr ; } </s>

Returns physical register used as frame pointer .


<s> DecodeStatus MipsDisassembler :: getInstruction ( MCInst & instr , uint64_t & Size , const MemoryObject & Region , uint64_t Address , raw_ostream & vStream , raw_ostream & cStream ) const { uint32_t Insn ; DecodeStatus Result = readInstruction32 ( Region , Address , Size , Insn , isBigEndian , IsMicroMips ) ; if ( Result == MCDisassembler :: Fail ) return MCDisassembler :: Fail ; if ( IsMicroMips ) { Result = decodeInstruction ( DecoderTableMicroMips32 , instr , Insn , Address , this , STI ) ; if ( Result != MCDisassembler :: Fail ) { Size = 4 ; return Result ; } return MCDisassembler :: Fail ; } if ( isMips32r6 ( ) ) { Result = decodeInstruction ( DecoderTableMips32r6_64r632 , instr , Insn , Address , this , STI ) ; if ( Result != MCDisassembler :: Fail ) { Size = 4 ; return Result ; } } Result = decodeInstruction ( DecoderTableMips32 , instr , Insn , Address , this , STI ) ; if ( Result != MCDisassembler :: Fail ) { Size = 4 ; return Result ; } return MCDisassembler :: Fail ; } </s>

Returns the disassembly of a single instruction .

Mips Mips Mips Mips Mips 4 Mips Mips 4 Mips 4


<s> bool X86TargetLowering :: shouldSinkOperands ( Instruction * I , SmallVectorImpl < Use * > & Ops ) const { using namespace llvm :: PatternMatch ; FixedVectorType * VTy = dyn_cast < FixedVectorType > ( I -> getType ( ) ) ; if ( ! VTy ) return false ; if ( I -> getOpcode ( ) == Instruction :: Mul && VTy -> getElementType ( ) -> isIntegerTy ( 64 ) ) { for ( auto & Op : I -> operands ( ) ) { if ( any_of ( Ops , [ & ] ( Use * U ) { return U -> get ( ) == Op ; } ) ) continue ; if ( Subtarget . hasSSE41 ( ) && match ( Op . get ( ) , m_AShr ( m_Shl ( m_Value ( ) , m_SpecificInt ( 32 ) ) , m_SpecificInt ( 32 ) ) ) ) { Ops . push_back ( & cast < Instruction > ( Op ) -> getOperandUse ( 0 ) ) ; Ops . push_back ( & Op ) ; } else if ( Subtarget . hasSSE2 ( ) && match ( Op . get ( ) , m_And ( m_Value ( ) , m_SpecificInt ( UINT64_C ( 0xffffffff ) ) ) ) ) { Ops . push_back ( & Op ) ; } } return ! Ops . empty ( ) ; } int ShiftAmountOpNum = - 1 ; if ( I -> isShift ( ) ) ShiftAmountOpNum = 1 ; else if ( auto * II = dyn_cast < IntrinsicInst > ( I ) ) { if ( II -> getIntrinsicID ( ) == Intrinsic :: fshl || II -> getIntrinsicID ( ) == Intrinsic :: fshr ) ShiftAmountOpNum = 2 ; } if ( ShiftAmountOpNum == - 1 ) return false ; auto * Shuf = dyn_cast < ShuffleVectorInst > ( I -> getOperand ( ShiftAmountOpNum ) ) ; if ( Shuf && getSplatIndex ( Shuf -> getShuffleMask ( ) ) >= 0 && isVectorShiftByScalarCheap ( I -> getType ( ) ) ) { Ops . push_back ( & I -> getOperandUse ( ShiftAmountOpNum ) ) ; return true ; } return false ; } </s>

Return true if sinking I 's operands to the same basic block as I is profitable , e.g .


<s> bool ARMFrameInfo :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; MachineFunction & MF = * MBB . getParent ( ) ; ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; bool isVarArg = AFI -> getVarArgsRegSaveSize ( ) > 0 ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned PopOpc = AFI -> isThumbFunction ( ) ? ARM :: t2LDMIA_UPD : ARM :: LDMIA_UPD ; unsigned LdrOpc = AFI -> isThumbFunction ( ) ? ARM :: t2LDR_POST : ARM :: LDR_POST ; unsigned FltOpc = ARM :: VLDMDIA_UPD ; emitPopInst ( MBB , MI , CSI , FltOpc , 0 , isVarArg , true , & isARMArea3Register ) ; emitPopInst ( MBB , MI , CSI , PopOpc , LdrOpc , isVarArg , false , & isARMArea2Register ) ; emitPopInst ( MBB , MI , CSI , PopOpc , LdrOpc , isVarArg , false , & isARMArea1Register ) ; return true ; } </s>

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


<s> static bool is_prefetch ( rtx insn ) { return NONJUMP_INSN_P ( insn ) && GET_CODE ( PATTERN ( insn ) ) == PREFETCH ; } </s>

Return true if insn is a prefetch instruction .


<s> void PPCDispatchGroupSBHazardRecognizer :: EmitNoop ( ) { unsigned Directive = DAG -> MF . getSubtarget < PPCSubtarget > ( ) . getMcpu ( ) ; if ( Directive == PPC :: MCPU_PWR6 || Directive == PPC :: MCPU_PWR7 || Directive == PPC :: MCPU_PWR8 || Directive == PPC :: MCPU_PWR9 || CurSlots == 6 ) { CurGroup . clear ( ) ; CurSlots = CurBranches = 0 ; } else { CurGroup . push_back ( nullptr ) ; ++ CurSlots ; } } </s>

EmitNoop - This callback is invoked when a noop was added to the instruction stream .