<s>
void
FISCAsmBackend
::
applyFixup
(
const
MCFixup
&
Fixup
,
char
*
Data
,
unsigned
DataSize
,
uint64_t
Value
,
bool
isPCRel
)
const
{
unsigned
NumBytes
=
4
;
Value
=
adjustFixupValue
(
Fixup
,
Value
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
DataSize
&&
"Invalid fixup offset!"
)
;
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
Data
[
Offset
+
i
]
|=
uint8_t
(
(
Value
>>
(
(
NumBytes
i
1
)
*
8
)
)
&
0xff
)
;
}
</s>

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


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

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


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

Simple predicate for targets where ! Resolved implies requiring relaxation .


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
override
{
const
static
MCFixupKindInfo
Infos
[
FISC
::
NumTargetFixupKinds
]
=
{
{
"fixup_fisc_mov_q1_pcrel"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_mov_q2_pcrel"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_mov_q3_pcrel"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_mov_q4_pcrel"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_call26_pcrel"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_call19_pcrel"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_9bit_address"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_6bit_shamt"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_12bit_imm"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_fisc_movrz_pcrel"
,
0
,
64
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


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

Get the number of target specific fixup kinds .


<s> unsigned getPointerSize ( ) const { return 8 ; } </s>

Layout pointer size in bytes , rounded up to a whole number of bytes .


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

Check whether the given instruction may need relaxation .


<s> void relaxInstruction ( const MCInst & Inst , MCInst & Res ) const override { } </s>

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


<s> bool writeNopData ( uint64_t Count , MCObjectWriter * OW ) const override { if ( Count == 0 ) return true ; return false ; } </s>

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


<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 std :: unique_ptr < FISCOperand > CreateMem ( unsigned Base , const MCExpr * Off , SMLoc S , SMLoc E ) { auto Op = make_unique < FISCOperand > ( k_Memory ) ; Op -> Mem . Base = Base ; Op -> Mem . Off = Off ; Op -> StartLoc = S ; Op -> EndLoc = E ; return Op ; } </s>


<s> static std :: unique_ptr < FISCOperand > CreateReg ( unsigned RegNum , SMLoc S , SMLoc E ) { auto Op = make_unique < FISCOperand > ( k_Register ) ; Op -> Reg . RegNum = RegNum ; Op -> StartLoc = S ; Op -> EndLoc = E ; return Op ; } </s>

CreateReg - Allocate a single virtual register for the given type .


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

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


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

Returns the register associated with this edge .


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

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


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


<s> bool isMem ( ) const { return Kind == k_Memory ; } </s>


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


<s> bool isToken ( ) const { return Kind == k_Token ; } </s>


"instruction requires a CPU feature not currently enabled"

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


<s> bool FISCAsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getString ( ) ; if ( IDVal == ".ent" ) { Parser . Lex ( ) ; return false ; } if ( IDVal == ".end" ) { Parser . Lex ( ) ; return false ; } if ( IDVal == ".frame" ) { Parser . eatToEndOfStatement ( ) ; return false ; } if ( IDVal == ".set" ) { return parseDirectiveSet ( ) ; } if ( IDVal == ".fmask" ) { Parser . eatToEndOfStatement ( ) ; return false ; } if ( IDVal == ".mask" ) { Parser . eatToEndOfStatement ( ) ; return false ; } if ( IDVal == ".gpword" ) { Parser . eatToEndOfStatement ( ) ; return false ; } if ( IDVal == ".byte" ) return parseDirectiveWord ( 1 , DirectiveID . getLoc ( ) ) ; if ( IDVal == ".half" ) return parseDirectiveWord ( 2 , DirectiveID . getLoc ( ) ) ; if ( IDVal == ".word" ) return parseDirectiveWord ( 4 , DirectiveID . getLoc ( ) ) ; if ( IDVal == ".nword" ) return parseDirectiveWord ( 8 , DirectiveID . getLoc ( ) ) ; if ( IDVal == ".xword" ) return parseDirectiveWord ( 8 , DirectiveID . getLoc ( ) ) ; return true ; } </s>

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


<s> virtual void print ( raw_ostream & OS ) const { llvm_unreachable ( "unimplemented!" ) ; } </s>

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


<s> void FISCAsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { MCInst TmpInst ; MCInstLowering . Lower ( MI , TmpInst ) ; EmitToStreamer ( * OutStreamer , TmpInst ) ; } </s>

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


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

getPassName - Return a nice clean name for a pass .


<s>
bool
FISCAsmPrinter
::
PrintAsmMemoryOperand
(
const
MachineInstr
*
MI
,
unsigned
OpNum
,
unsigned
AsmVariant
,
const
char
*
ExtraCode
,
raw_ostream
&
O
)
{
int
Offset
=
0
;
if
(
ExtraCode
)
return
true
;
const
MachineOperand
&
MO
=
MI
->
getOperand
(
OpNum
)
;
assert
(
MO
.
isReg
(
)
&&
"unexpected inline asm memory operand"
)
;
O
<<
"["
<<
FISCInstPrinter
::
getRegisterName
(
MO
.
getReg
(
)
)
<<
", "
<<
Offset
<<
"]"
;
return
false
;
}
</s>

Print the specified operand of MI , an INLINEASM instruction , using the specified assembler variant as an address .

FISC
FISC
0
"unexpected inline asm memory operand"
"["
FISC
", "
"]"


<s> bool FISCAsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , unsigned AsmVariant , const char * ExtraCode , raw_ostream & O ) { if ( ExtraCode && ExtraCode [ 0 ] ) { if ( ExtraCode [ 1 ] != 0 ) return true ; const MachineOperand & MO = MI -> getOperand ( OpNo ) ; switch ( ExtraCode [ 0 ] ) { default : return AsmPrinter :: PrintAsmOperand ( MI , OpNo , AsmVariant , ExtraCode , O ) ; case 'X' : if ( ( MO . getType ( ) ) != MachineOperand :: MO_Immediate ) return true ; O << "0x" << StringRef ( utohexstr ( MO . getImm ( ) ) ) . lower ( ) ; return false ; case 'x' : if ( ( MO . getType ( ) ) != MachineOperand :: MO_Immediate ) return true ; O << "0x" << StringRef ( utohexstr ( MO . getImm ( ) & 0xffff ) ) . lower ( ) ; return false ; case 'd' : if ( ( MO . getType ( ) ) != MachineOperand :: MO_Immediate ) return true ; O << MO . getImm ( ) ; return false ; case 'm' : if ( ( MO . getType ( ) ) != MachineOperand :: MO_Immediate ) return true ; O << MO . getImm ( ) - 1 ; return false ; case 'z' : { if ( MO . getType ( ) != MachineOperand :: MO_Immediate ) return true ; int64_t Val = MO . getImm ( ) ; if ( Val ) O << Val ; else O << "xzr" ; return false ; } } } printOperand ( MI , OpNo , O ) ; return false ; } </s>

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


<s>
const
char
*
getPassName
(
)
const
override
{
return
"FISC Delay Slot Filler"
;
}
</s>


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

runOnMachineFunction - Emit the function body .


<s> DecodeStatus FISCDisassembler :: getInstruction ( MCInst & Instr , uint64_t & Size , ArrayRef < uint8_t > Bytes , uint64_t Address , raw_ostream & VStream , raw_ostream & CStream ) const { uint32_t Insn ; DecodeStatus Result = readInstruction32 ( Bytes , Address , Size , Insn ) ; if ( Result == MCDisassembler :: Fail ) return Result ; Result = decodeInstruction ( DecoderTableFISC32 , Instr , Insn , Address , this , STI ) ; if ( Result != MCDisassembler :: Fail ) { Size = 4 ; return Result ; } return MCDisassembler :: Fail ; } </s>

Returns the disassembly of a single instruction .


<s> void FISCFrameLowering :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { if ( I -> getOpcode ( ) == FISC :: ADJCALLSTACKUP || I -> getOpcode ( ) == FISC :: ADJCALLSTACKDOWN ) MBB . erase ( I ) ; } </s>

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

FISC FISC FISC::ADJCALLSTACKUP FISC::ADJCALLSTACKDOWN


<s> void FISCFrameLowering :: emitEpilogue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; MachineBasicBlock :: iterator MBBI = MBB . getLastNonDebugInstr ( ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; uint64_t StackSize = computeStackSize ( MF ) ; if ( ! StackSize ) return ; unsigned StackReg = FISC :: SP ; unsigned OffsetReg = materializeOffset ( MF , MBB , MBBI , ( unsigned ) StackSize ) ; if ( OffsetReg ) { BuildMI ( MBB , MBBI , dl , TII . get ( FISC :: ADDrr ) , StackReg ) . addReg ( StackReg ) . addReg ( OffsetReg ) . setMIFlag ( MachineInstr :: FrameSetup ) ; } else { BuildMI ( MBB , MBBI , dl , TII . get ( FISC :: ADDri ) , StackReg ) . addReg ( StackReg ) . addImm ( StackSize ) . setMIFlag ( MachineInstr :: FrameSetup ) ; } } </s>

FISC FISC FISC::SP FISC::ADDrr FISC::ADDri


<s> void FISCFrameLowering :: emitPrologue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; MachineBasicBlock :: iterator MBBI = MBB . begin ( ) ; DebugLoc dl = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; uint64_t StackSize = computeStackSize ( MF ) ; if ( ! StackSize ) return ; unsigned StackReg = FISC :: SP ; unsigned OffsetReg = materializeOffset ( MF , MBB , MBBI , ( unsigned ) StackSize ) ; if ( OffsetReg ) { BuildMI ( MBB , MBBI , dl , TII . get ( FISC :: SUBrr ) , StackReg ) . addReg ( StackReg ) . addReg ( OffsetReg ) . setMIFlag ( MachineInstr :: FrameSetup ) ; } else { BuildMI ( MBB , MBBI , dl , TII . get ( FISC :: SUBri ) , StackReg ) . addReg ( StackReg ) . addImm ( StackSize ) . setMIFlag ( MachineInstr :: FrameSetup ) ; } } </s>

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

FISC FISC FISC::SP FISC::SUBrr FISC::SUBri


<s> bool FISCFrameLowering :: hasFP ( const MachineFunction & MF ) const { return MF . getTarget ( ) . Options . DisableFramePointerElim ( MF ) || MF . getFrameInfo ( ) -> hasVarSizedObjects ( ) ; } </s>

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


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


<s> void FISCInstPrinter :: printInst ( const MCInst * MI , raw_ostream & O , StringRef Annot , const MCSubtargetInfo & STI ) { printInstruction ( MI , O ) ; printAnnotation ( O , Annot ) ; } </s>

Print the specified MCInst to the specified raw_ostream .


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


<s> void FISCInstrInfo :: copyPhysReg ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , DebugLoc DL , unsigned DestReg , unsigned SrcReg , bool KillSrc ) const { BuildMI ( MBB , I , I -> getDebugLoc ( ) , get ( FISC :: MOVrr ) , DestReg ) . addReg ( SrcReg , getKillRegState ( KillSrc ) ) ; } </s>


<s> bool FISCInstrInfo :: expandPostRAPseudo ( MachineBasicBlock :: iterator MI ) const { switch ( MI -> getOpcode ( ) ) { default : return false ; case FISC :: MOVi64 : { DebugLoc DL = MI -> getDebugLoc ( ) ; MachineBasicBlock & MBB = * MI -> getParent ( ) ; const unsigned DstReg = MI -> getOperand ( 0 ) . getReg ( ) ; const bool DstIsDead = MI -> getOperand ( 0 ) . isDead ( ) ; const MachineOperand & MO = MI -> getOperand ( 1 ) ; auto Q1 = BuildMI ( MBB , MI , DL , get ( FISC :: MOVZ ) , DstReg ) ; auto Q2 = BuildMI ( MBB , MI , DL , get ( FISC :: MOVK ) ) . addReg ( DstReg , RegState :: Define | getDeadRegState ( DstIsDead ) ) . addReg ( DstReg ) ; auto Q3 = BuildMI ( MBB , MI , DL , get ( FISC :: MOVK ) ) . addReg ( DstReg , RegState :: Define | getDeadRegState ( DstIsDead ) ) . addReg ( DstReg ) ; auto Q4 = BuildMI ( MBB , MI , DL , get ( FISC :: MOVK ) ) . addReg ( DstReg , RegState :: Define | getDeadRegState ( DstIsDead ) ) . addReg ( DstReg ) ; if ( MO . isImm ( ) ) { const uint64_t Imm = MO . getImm ( ) ; Q1 = Q1 . addImm ( Imm & 0xffff ) . addImm ( 0 ) ; Q2 = Q2 . addImm ( ( Imm >> 16 ) & 0xffff ) . addImm ( 1 ) ; Q3 = Q3 . addImm ( ( Imm >> 32 ) & 0xffff ) . addImm ( 2 ) ; Q4 = Q4 . addImm ( ( Imm >> 48 ) & 0xffff ) . addImm ( 3 ) ; } else { const GlobalValue * GV = MO . getGlobal ( ) ; const unsigned TF = MO . getTargetFlags ( ) ; Q1 = Q1 . addGlobalAddress ( GV , MO . getOffset ( ) , FISCII :: MO_Q1 ) . addImm ( 0 ) ; Q2 = Q2 . addGlobalAddress ( GV , MO . getOffset ( ) , FISCII :: MO_Q2 ) . addImm ( 1 ) ; Q3 = Q3 . addGlobalAddress ( GV , MO . getOffset ( ) , FISCII :: MO_Q3 ) . addImm ( 2 ) ; Q4 = Q4 . addGlobalAddress ( GV , MO . getOffset ( ) , FISCII :: MO_Q4 ) . addImm ( 3 ) ; } MBB . erase ( MI ) ; return true ; } } } </s>

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


<s> const FISCRegisterInfo & getRegisterInfo ( ) const { return RI ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> unsigned FISCInstrInfo :: isLoadFromStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { 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> unsigned FISCInstrInfo :: isStoreToStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { 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> void FISCInstrInfo :: loadRegFromStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , unsigned DestReg , int FrameIndex , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { BuildMI ( MBB , I , I -> getDebugLoc ( ) , get ( FISC :: LDR ) , DestReg ) . addFrameIndex ( FrameIndex ) . addImm ( 0 ) ; } </s>

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


<s> void FISCInstrInfo :: storeRegToStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , unsigned SrcReg , bool isKill , int FrameIndex , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { BuildMI ( MBB , I , I -> getDebugLoc ( ) , get ( FISC :: STR ) ) . addReg ( SrcReg , getKillRegState ( isKill ) ) . addFrameIndex ( FrameIndex ) . addImm ( 0 ) ; } </s>

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


"FISC DAG->DAG Pattern Instruction Selection"


<s>
SDNode
*
FISCDAGToDAGISel
::
Select
(
SDNode
*
N
)
{
DEBUG
(
errs
(
)
<<
">>>>>> Selecting Node: "
;
N
->
dump
(
CurDAG
)
;
errs
(
)
<<
"\n"
)
;
switch
(
N
->
getOpcode
(
)
)
{
case
ISD
::
LOAD
:
return
SelectIndexedLoad
(
N
)
;
case
ISD
::
STORE
:
return
SelectIndexedStore
(
N
)
;
case
ISD
::
FrameIndex
:
return
SelectFrameIndex
(
N
)
;
case
ISD
::
Constant
:
return
ConstantToRegisterExpand
(
N
,
SDValue
(
N
,
0
)
)
.
getNode
(
)
;
case
ISD
::
ADD
:
if
(
N
->
getOperand
(
0
)
.
getOpcode
(
)
==
ISD
::
TargetGlobalAddress
)
return
SelectTargetGlobalAddressforADD
(
N
,
N
->
getOperand
(
0
)
.
getNode
(
)
)
;
break
;
case
FISCISD
::
CMP
:
return
SelectCompare
(
N
)
;
case
ISD
::
BR_CC
:
return
SelectConditionalBranch
(
N
)
;
case
ISD
::
CopyToReg
:
if
(
N
->
getOperand
(
2
)
.
getOpcode
(
)
==
ISD
::
TargetGlobalAddress
)
{
GlobalAddressSDNode
*
GA
=
dyn_cast
<
GlobalAddressSDNode
>
(
N
->
getOperand
(
2
)
)
;
const
GlobalValue
*
GV
=
GA
->
getGlobal
(
)
;
unsigned
char
TargetFlags
=
FISCII
::
MO_MOVRZ
;
if
(
GV
->
getValueID
(
)
==
Value
::
FunctionVal
)
TargetFlags
=
FISCII
::
MO_Q1
;
SDValue
TargetGlobalAddr
=
CurDAG
->
getTargetGlobalAddress
(
GV
,
SDLoc
(
N
)
,
MVT
::
i64
,
GA
->
getOffset
(
)
,
TargetFlags
)
;
MachineSDNode
*
Move
=
CurDAG
->
getMachineNode
(
FISC
::
MOVRZ
,
N
,
MVT
::
i64
,
TargetGlobalAddr
,
CurDAG
->
getTargetConstant
(
0
,
N
,
MVT
::
i64
)
)
;
CurDAG
->
ReplaceAllUsesWith
(
N
->
getOperand
(
2
)
,
SDValue
(
Move
,
0
)
)
;
}
break
;
case
FISCISD
::
CALL
:
{
unsigned
int
operand2Opc
=
N
->
getOperand
(
1
)
.
getOpcode
(
)
;
if
(
operand2Opc
==
ISD
::
LOAD
||
operand2Opc
==
ISD
::
CopyFromReg
)
{
return
SelectCallFunctionPointer
(
N
)
;
}
break
;
}
case
ISD
::
SRL
:
return
SelectShifts
(
N
)
;
case
ISD
::
MULHU
:
case
ISD
::
MULHS
:
return
SelectMUL
(
N
)
;
}
return
SelectCode
(
N
)
;
}
</s>

Main hook for targets to transform nodes into machine nodes .


<s>
bool
FISCDAGToDAGISel
::
SelectInlineAsmMemoryOperand
(
const
SDValue
&
Op
,
unsigned
ConstraintID
,
std
::
vector
<
SDValue
>
&
OutOps
)
{
switch
(
ConstraintID
)
{
default
:
llvm_unreachable
(
"Unexpected asm memory constraint"
)
;
case
InlineAsm
::
Constraint_m
:
OutOps
.
push_back
(
Op
)
;
return
false
;
}
return
true
;
}
</s>

SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode , according to the specified constraint .

FISC
FISC
"Unexpected asm memory constraint"


<s> static void AnalyzeArguments ( CCState & State , SmallVectorImpl < CCValAssign > & ArgLocs , const SmallVectorImpl < ArgT > & Args ) { static const MCPhysReg RegList [ ] = { FISC :: X10 , FISC :: X11 , FISC :: X12 , FISC :: X13 , FISC :: X14 , FISC :: X15 , FISC :: X26 , FISC :: X27 , FISC :: X18 } ; static const unsigned NbRegs = array_lengthof ( RegList ) ; SmallVector < unsigned , 4 > ArgsParts ; ParseFunctionArgs ( Args , ArgsParts ) ; if ( State . isVarArg ( ) ) { unsigned ValNo = 0 ; for ( unsigned i = 0 , e = ArgsParts . size ( ) ; i != e ; i ++ ) { MVT ArgVT = Args [ ValNo ] . VT ; MVT LocVT = ArgVT ; CCValAssign :: LocInfo LocInfo = CCValAssign :: Full ; for ( unsigned j = 0 ; j < ArgsParts [ i ] ; j ++ ) { if ( i == 0 && j == 0 ) State . addLoc ( CCValAssign :: getCustomMem ( ValNo ++ , ArgVT , State . AllocateStack ( 8 , 8 ) , LocVT , LocInfo ) ) ; else State . addLoc ( CCValAssign :: getCustomMem ( ValNo ++ , ArgVT , State . AllocateStack ( 8 , 8 ) , LocVT , LocInfo ) ) ; } } return ; } unsigned RegsLeft = NbRegs ; bool UseStack = false ; unsigned ValNo = 0 ; for ( unsigned i = 0 , e = ArgsParts . size ( ) ; i != e ; i ++ ) { MVT ArgVT = Args [ ValNo ] . VT ; ISD :: ArgFlagsTy ArgFlags = Args [ ValNo ] . Flags ; MVT LocVT = ArgVT ; CCValAssign :: LocInfo LocInfo = CCValAssign :: Full ; if ( ArgFlags . isByVal ( ) ) { State . HandleByVal ( ValNo ++ , ArgVT , LocVT , LocInfo , 8 , 8 , ArgFlags ) ; continue ; } unsigned Parts = ArgsParts [ i ] ; if ( ! UseStack && Parts <= RegsLeft ) { unsigned FirstVal = ValNo ; for ( unsigned j = 0 ; j < Parts ; j ++ ) { unsigned Reg = State . AllocateReg ( RegList ) ; State . addLoc ( CCValAssign :: getReg ( ValNo ++ , ArgVT , Reg , LocVT , LocInfo ) ) ; RegsLeft -- ; } SmallVectorImpl < CCValAssign > :: iterator B = ArgLocs . begin ( ) + FirstVal ; std :: reverse ( B , B + Parts ) ; } else { UseStack = true ; for ( unsigned j = 0 ; j < Parts ; j ++ ) CC_FISC ( ValNo ++ , ArgVT , LocVT , LocInfo , ArgFlags , State ) ; } } } </s>

The function will invoke AnalyzeCallOperands .


<s> bool FISCTargetLowering :: 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 ) ; if ( ! CCInfo . CheckReturn ( Outs , RetCC_FISC ) ) return false ; if ( CCInfo . getNextStackOffset ( ) != 0 && isVarArg ) 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 .


<s>
MachineBasicBlock
*
FISCTargetLowering
::
EmitInstrWithCustomInserter
(
MachineInstr
*
MI
,
MachineBasicBlock
*
BB
)
const
{
const
TargetInstrInfo
&
TII
=
*
BB
->
getParent
(
)
->
getSubtarget
(
)
.
getInstrInfo
(
)
;
DebugLoc
DL
=
MI
->
getDebugLoc
(
)
;
assert
(
MI
->
getOpcode
(
)
==
FISC
::
Select
&&
"Unexpected instr type to insert"
)
;
const
BasicBlock
*
LLVM_BB
=
BB
->
getBasicBlock
(
)
;
MachineFunction
::
iterator
I
=
++
BB
->
getIterator
(
)
;
MachineBasicBlock
*
ThisMBB
=
BB
;
MachineFunction
*
F
=
BB
->
getParent
(
)
;
MachineBasicBlock
*
Copy0MBB
=
F
->
CreateMachineBasicBlock
(
LLVM_BB
)
;
MachineBasicBlock
*
Copy1MBB
=
F
->
CreateMachineBasicBlock
(
LLVM_BB
)
;
F
->
insert
(
I
,
Copy0MBB
)
;
F
->
insert
(
I
,
Copy1MBB
)
;
Copy1MBB
->
splice
(
Copy1MBB
->
begin
(
)
,
BB
,
std
::
next
(
MachineBasicBlock
::
iterator
(
MI
)
)
,
BB
->
end
(
)
)
;
Copy1MBB
->
transferSuccessorsAndUpdatePHIs
(
BB
)
;
BB
->
addSuccessor
(
Copy0MBB
)
;
BB
->
addSuccessor
(
Copy1MBB
)
;
BuildMI
(
BB
,
DL
,
TII
.
get
(
FISC
::
Bcc
)
)
.
addOperand
(
MI
->
getOperand
(
3
)
)
.
addMBB
(
Copy1MBB
,
FISCII
::
MO_CALL19
)
;
BB
=
Copy0MBB
;
BB
->
addSuccessor
(
Copy1MBB
)
;
BB
=
Copy1MBB
;
BuildMI
(
*
BB
,
BB
->
begin
(
)
,
DL
,
TII
.
get
(
FISC
::
PHI
)
,
MI
->
getOperand
(
0
)
.
getReg
(
)
)
.
addReg
(
MI
->
getOperand
(
2
)
.
getReg
(
)
)
.
addMBB
(
Copy0MBB
)
.
addReg
(
MI
->
getOperand
(
1
)
.
getReg
(
)
)
.
addMBB
(
ThisMBB
)
;
MI
->
eraseFromParent
(
)
;
return
BB
;
}
</s>

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


<s> FISCTargetLowering :: ConstraintType FISCTargetLowering :: getConstraintType ( StringRef Constraint ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { default : break ; case 'c' : return C_RegisterClass ; case 'R' : return C_Memory ; } } return TargetLowering :: getConstraintType ( Constraint ) ; } </s>

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


<s>
std
::
pair
<
unsigned
,
const
TargetRegisterClass
*
>
FISCTargetLowering
::
getRegForInlineAsmConstraint
(
const
TargetRegisterInfo
*
TRI
,
StringRef
Constraint
,
MVT
VT
)
const
{
if
(
Constraint
.
size
(
)
==
1
)
{
switch
(
Constraint
[
0
]
)
{
case
'r'
:
if
(
VT
==
MVT
::
i8
||
VT
==
MVT
::
i16
||
VT
==
MVT
::
i32
||
VT
==
MVT
::
i64
)
return
std
::
make_pair
(
0U
,
&
FISC
::
GRRegsRegClass
)
;
return
std
::
make_pair
(
0u
,
static_cast
<
const
TargetRegisterClass
*
>
(
0
)
)
;
case
'c'
:
if
(
VT
==
MVT
::
i64
)
return
std
::
make_pair
(
(
unsigned
)
FISC
::
X19
,
&
FISC
::
GRRegsRegClass
)
;
assert
(
"Unexpected type."
)
;
}
}
std
::
pair
<
unsigned
,
const
TargetRegisterClass
*
>
R
;
R
=
parseRegForInlineAsmConstraint
(
Constraint
,
VT
)
;
if
(
R
.
second
)
return
R
;
return
TargetLowering
::
getRegForInlineAsmConstraint
(
TRI
,
Constraint
,
VT
)
;
}
</s>

Given a physical register constraint ( e.g .


<s> TargetLowering :: ConstraintWeight FISCTargetLowering :: getSingleConstraintMatchWeight ( AsmOperandInfo & info , const char * constraint ) const { ConstraintWeight weight = CW_Invalid ; Value * CallOperandVal = info . CallOperandVal ; if ( ! CallOperandVal ) return CW_Default ; Type * type = CallOperandVal -> getType ( ) ; switch ( * constraint ) { default : weight = TargetLowering :: getSingleConstraintMatchWeight ( info , constraint ) ; break ; case 'c' : 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> const char * FISCTargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( Opcode ) { default : return NULL ; case FISCISD :: RET_FLAG : return "RetFlag" ; case FISCISD :: LOAD_SYM : return "LOAD_SYM" ; case FISCISD :: MOVEi64 : return "MOVEi64" ; case FISCISD :: CALL : return "CALL" ; case FISCISD :: SELECT_CC : return "SELECT_CC" ; case FISCISD :: CMP : return "CMP" ; } } </s>

getTargetNodeName - This method returns the name of a target specific


<s> bool FISCTargetLowering :: isLegalAddressingMode ( const DataLayout & DL , const AddrMode & AM , Type * Ty , unsigned AS ) const { if ( AM . BaseGV ) return false ; switch ( AM . Scale ) { case 0 : break ; case 1 : if ( ! AM . HasBaseReg ) break ; return false ; default : return false ; } return true ; } </s>

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


<s> SDValue FISCTargetLowering :: LowerCallResult ( SDValue Chain , SDValue InGlue , CallingConv :: ID CallConv , bool isVarArg , const SmallVectorImpl < ISD :: InputArg > & Ins , SDLoc dl , SelectionDAG & DAG , SmallVectorImpl < SDValue > & InVals ) const { SmallVector < CCValAssign , 16 > RVLocs ; CCState CCInfo ( CallConv , isVarArg , DAG . getMachineFunction ( ) , RVLocs , * DAG . getContext ( ) ) ; AnalyzeReturnValues ( CCInfo , RVLocs , Ins ) ; for ( unsigned i = 0 ; i != RVLocs . size ( ) ; ++ i ) { Chain = DAG . getCopyFromReg ( Chain , dl , RVLocs [ i ] . getLocReg ( ) , RVLocs [ i ] . getValVT ( ) , InGlue ) . getValue ( 1 ) ; InGlue = Chain . getValue ( 2 ) ; InVals . push_back ( Chain . getValue ( 0 ) ) ; } return Chain ; } </s>

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


<s>
SDValue
FISCTargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Unimplemented operand"
)
;
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
SELECT_CC
:
return
LowerSelectCC
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
LowerVASTART
(
Op
,
DAG
)
;
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .

FISC
FISC
"Unimplemented operand"
ISD::GlobalAddress
ISD::SELECT_CC
ISD::VASTART


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

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


<s>
void
FISCMCCodeEmitter
::
encodeInstruction
(
const
MCInst
&
MI
,
raw_ostream
&
OS
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
const
MCInstrDesc
&
Desc
=
MCII
.
get
(
MI
.
getOpcode
(
)
)
;
if
(
Desc
.
getSize
(
)
!=
4
)
{
llvm_unreachable
(
"Unexpected instruction size!"
)
;
}
const
uint32_t
Binary
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
EmitConstant
(
Binary
,
Desc
.
getSize
(
)
,
OS
)
;
++
MCNumEmitted
;
}
</s>

Encode the given Inst to bytes and append to CB .

FISC
FISC
4
"Unexpected instruction size!"


<s>
unsigned
FISCMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
if
(
MO
.
isReg
(
)
)
return
CTX
.
getRegisterInfo
(
)
->
getEncodingValue
(
MO
.
getReg
(
)
)
;
if
(
MO
.
isImm
(
)
)
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
assert
(
MO
.
isExpr
(
)
&&
"unknown operand kind in printOperand"
)
;
const
MCExpr
*
Expr
=
MO
.
getExpr
(
)
;
MCExpr
::
ExprKind
Kind
=
Expr
->
getKind
(
)
;
if
(
Kind
==
MCExpr
::
Binary
)
{
Expr
=
static_cast
<
const
MCBinaryExpr
*
>
(
Expr
)
->
getLHS
(
)
;
Kind
=
Expr
->
getKind
(
)
;
}
if
(
Kind
==
MCExpr
::
Constant
)
return
cast
<
MCConstantExpr
>
(
Expr
)
->
getValue
(
)
;
assert
(
Kind
==
MCExpr
::
SymbolRef
)
;
unsigned
FixupKind
;
unsigned
VKind
=
cast
<
MCSymbolRefExpr
>
(
Expr
)
->
getKind
(
)
;
switch
(
VKind
)
{
case
MCSymbolRefExpr
::
VK_None
:
return
0
;
default
:
{
std
::
string
msg
=
"Unknown fixup kind! ("
+
std
::
to_string
(
VKind
)
+
")"
;
llvm_unreachable
(
msg
.
c_str
(
)
)
;
}
case
MCSymbolRefExpr
::
VK_FISC_Q1
:
FixupKind
=
FISC
::
fixup_fisc_mov_q1_pcrel
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_Q2
:
FixupKind
=
FISC
::
fixup_fisc_mov_q2_pcrel
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_Q3
:
FixupKind
=
FISC
::
fixup_fisc_mov_q3_pcrel
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_Q4
:
FixupKind
=
FISC
::
fixup_fisc_mov_q4_pcrel
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_CALL26
:
FixupKind
=
FISC
::
fixup_fisc_call26_pcrel
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_CALL19
:
FixupKind
=
FISC
::
fixup_fisc_call19_pcrel
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_9BIT
:
FixupKind
=
FISC
::
fixup_fisc_9bit_address
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_6BIT
:
FixupKind
=
FISC
::
fixup_fisc_6bit_shamt
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_12BIT
:
FixupKind
=
FISC
::
fixup_fisc_12bit_imm
;
break
;
case
MCSymbolRefExpr
::
VK_FISC_MOVRZ
:
FixupKind
=
FISC
::
fixup_fisc_movrz_pcrel
;
break
;
}
Fixups
.
push_back
(
MCFixup
::
create
(
0
,
MO
.
getExpr
(
)
,
MCFixupKind
(
FixupKind
)
)
)
;
return
0
;
}
</s>

getMachineOpValue - Return binary encoding of operand .


<s> void FISCMCInstLower :: Initialize ( Mangler * M , MCContext * C ) { Mang = M ; Ctx = C ; } </s>

This method must be called before any actual lowering is done .


<s> void FISCRegisterInfo :: eliminateFrameIndex ( MachineBasicBlock :: iterator II , int SPAdj , unsigned FIOperandNum , RegScavenger * RS ) const { MachineInstr & MI = * II ; const MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; MachineOperand & FIOp = MI . getOperand ( FIOperandNum ) ; unsigned FI = FIOp . getIndex ( ) ; unsigned ImmOpIdx = 0 ; switch ( MI . getOpcode ( ) ) { default : return ; case FISC :: ADDri : case FISC :: LDR : case FISC :: LDRB : case FISC :: LDRH : case FISC :: LDRSW : case FISC :: LDRXR : case FISC :: LDRR : case FISC :: LDRBR : case FISC :: LDRHR : case FISC :: LDRSWR : case FISC :: LDRXRR : case FISC :: STR : case FISC :: STRB : case FISC :: STRH : case FISC :: STRW : case FISC :: STRXR : case FISC :: STRR : case FISC :: STRBR : case FISC :: STRHR : case FISC :: STRWR : case FISC :: STRXRR : ImmOpIdx = FIOperandNum + 1 ; break ; } MachineOperand & ImmOp = MI . getOperand ( ImmOpIdx ) ; int Offset = MFI -> getObjectOffset ( FI ) + MFI -> getStackSize ( ) + ImmOp . getImm ( ) ; FIOp . ChangeToRegister ( FISC :: SP , false ) ; ImmOp . setImm ( Offset ) ; } </s>

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

FISC FISC 0 FISC::ADDri FISC::LDR FISC::LDRB FISC::LDRH FISC::LDRSW FISC::LDRXR FISC::LDRR FISC::LDRBR FISC::LDRHR FISC::LDRSWR FISC::LDRXRR FISC::STR FISC::STRB FISC::STRH FISC::STRW FISC::STRXR FISC::STRR FISC::STRBR FISC::STRHR FISC::STRWR FISC::STRXRR 1 FISC::SP


<s> const uint16_t * FISCRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { static const uint16_t CalleeSavedRegs [ ] = { FISC :: LR , FISC :: X19 , FISC :: X20 , FISC :: X21 , FISC :: X22 , FISC :: X23 , FISC :: X24 , FISC :: X25 , FISC :: X26 , FISC :: X27 , 0 } ; return CalleeSavedRegs ; } </s>


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

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


<s> unsigned FISCRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { return FISC :: SP ; } </s>


<s> BitVector FISCRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( FISC :: SP ) ; Reserved . set ( FISC :: LR ) ; return Reserved ; } </s>

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


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

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


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

Returns true if the live-ins should be tracked after register allocation .


<s> bool FISCRegisterInfo :: useFPForScavengingIndex ( const MachineFunction & MF ) const { return false ; } </s>

Returns true if the target wants to use frame pointer based accesses to spill to the scavenger emergency spill slot .


<s> const FISCInstrInfo * getInstrInfo ( ) const override { return & InstrInfo ; } </s>


<s> const InstrItineraryData * getInstrItineraryData ( ) const override { return & InstrItins ; } </s>

getInstrItineraryData - Returns instruction itinerary data for the target or specific subtarget .


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

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> bool FISCPassConfig :: addInstSelector ( ) { addPass ( createFISCISelDag ( getFISCTargetMachine ( ) , getOptLevel ( ) ) ) ; return false ; } </s>

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


<s> void FISCPassConfig :: addPreEmitPass ( ) { addPass ( createFISCDelaySlotFillerPass ( getFISCTargetMachine ( ) ) ) ; } </s>

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


<s> bool FISCPassConfig :: addPreISel ( ) { return false ; } </s>


<s> TargetPassConfig * FISCTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new FISCPassConfig ( this , PM ) ; } </s>

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


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

Return information about object file lowering .


<s> virtual const TargetSubtargetInfo * getSubtargetImpl ( const Function & ) const override { return & Subtarget ; } </s>

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