<s>
void
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
,
const
MCSubtargetInfo
*
STI
)
const
override
{
unsigned
Size
=
1
<<
getFixupKindLog2Size
(
Fixup
.
getKind
(
)
)
;
assert
(
Fixup
.
getOffset
(
)
+
Size
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
assert
(
isIntN
(
Size
*
8
+
1
,
Value
)
&&
"Value does not fit in the Fixup field"
)
;
for
(
unsigned
i
=
0
;
i
!=
Size
;
++
i
)
Data
[
Fixup
.
getOffset
(
)
+
i
]
=
uint8_t
(
Value
>>
(
(
Size
i
1
)
*
8
)
)
;
}
</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 .


"Cannot relax the instruction, value does not fit"

Simple predicate for targets where ! Resolved implies requiring relaxation .


<s> unsigned getMinimumNopSize ( ) const override { return 2 ; } </s>

Returns the minimum size of a nop in bytes on this target .


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

Get the number of target specific fixup kinds .


<s> bool M680x0AsmBackend :: mayNeedRelaxation ( const MCInst & Inst , const MCSubtargetInfo & STI ) const { if ( getRelaxedOpcodeBranch ( Inst ) != Inst . getOpcode ( ) ) return true ; if ( getRelaxedOpcodeArith ( Inst ) == Inst . getOpcode ( ) ) return false ; unsigned RelaxableOp = Inst . getNumOperands ( ) - 1 ; if ( Inst . getOperand ( RelaxableOp ) . isExpr ( ) ) return true ; return false ; } </s>

Check whether the given instruction may need relaxation .


<s>
void
M680x0AsmBackend
::
relaxInstruction
(
const
MCInst
&
Inst
,
const
MCSubtargetInfo
&
STI
,
MCInst
&
Res
)
const
{
unsigned
RelaxedOp
=
getRelaxedOpcode
(
Inst
)
;
if
(
RelaxedOp
==
Inst
.
getOpcode
(
)
)
{
SmallString
<
256
>
Tmp
;
raw_svector_ostream
OS
(
Tmp
)
;
Inst
.
dump_pretty
(
OS
)
;
OS
<<
"\n"
;
report_fatal_error
(
"unexpected instruction to relax: "
+
OS
.
str
(
)
)
;
}
Res
=
Inst
;
Res
.
setOpcode
(
RelaxedOp
)
;
}
</s>

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


<s> bool M680x0AsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count ) const { if ( Count % 2 != 0 ) return false ; uint64_t NumNops = Count / 2 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) { OS << "\x4E\x71" ; } return true ; } </s>

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


<s>
void
M680x0AsmPrinter
::
EmitInstruction
(
const
MachineInstr
*
MI
)
{
switch
(
MI
->
getOpcode
(
)
)
{
default
:
{
if
(
MI
->
isPseudo
(
)
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Pseudo opcode("
<<
MI
->
getOpcode
(
)
<<
") found in EmitInstruction()\n"
)
;
llvm_unreachable
(
"Cannot proceed"
)
;
}
break
;
}
case
M680x0
::
TAILJMPj
:
case
M680x0
::
TAILJMPq
:
OutStreamer
->
AddComment
(
"TAILCALL"
)
;
break
;
}
MCInst
TmpInst0
;
MCInstLowering
->
Lower
(
MI
,
TmpInst0
)
;
OutStreamer
->
EmitInstruction
(
TmpInst0
,
getSubtargetInfo
(
)
)
;
}
</s>

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


<s>
StringRef
getPassName
(
)
const
override
{
return
"M680x0 Assembly Printer"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> bool M680x0AsmPrinter :: runOnMachineFunction ( MachineFunction & MF ) { MMFI = MF . getInfo < M680x0MachineFunctionInfo > ( ) ; MCInstLowering = make_unique < M680x0MCInstLower > ( MF , * this ) ; AsmPrinter :: runOnMachineFunction ( MF ) ; return true ; } </s>

runOnMachineFunction - Emit the function body .


<s> void Finish ( MachineBasicBlock & MBB , MOVEMState & State ) { auto MI = State . GetBegin ( ) ; auto End = State . GetEnd ( ) ; auto DL = MI -> getDebugLoc ( ) ; if ( std :: next ( MI ) == End ) { State = MOVEMState ( ) ; return ; } while ( MI != End ) { auto Next = std :: next ( MI ) ; MBB . erase ( MI ) ; MI = Next ; } if ( State . IsLoad ( ) ) { BuildMI ( MBB , End , DL , TII -> get ( M680x0 :: MOVM32mp ) ) . addImm ( State . GetMask ( ) ) . addImm ( State . GetFinalOffset ( ) ) . addReg ( State . GetBase ( ) ) ; } else { BuildMI ( MBB , End , DL , TII -> get ( M680x0 :: MOVM32pm ) ) . addImm ( State . GetFinalOffset ( ) ) . addReg ( State . GetBase ( ) ) . addImm ( State . GetMask ( ) ) ; } State = MOVEMState ( ) ; } </s>

Finish - Do final processing and write the object to the output stream .


<s>
StringRef
getPassName
(
)
const
override
{
return
"M680x0 MOVEM collapser pass"
;
}
</s>


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { STI = & static_cast < const M680x0Subtarget & > ( MF . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MFI = MF . getInfo < M680x0MachineFunctionInfo > ( ) ; FL = STI -> getFrameLowering ( ) ; bool Modified = false ; MOVEMState State ; unsigned Mask = 0 ; unsigned Reg = 0 ; int Offset = 0 ; for ( auto & MBB : MF ) { auto MI = MBB . begin ( ) , E = MBB . end ( ) ; while ( MI != E ) { auto NMI = std :: next ( MI ) ; switch ( MI -> getOpcode ( ) ) { default : if ( State . HasBase ( ) ) { State . SetEnd ( MI ) ; Finish ( MBB , State ) ; Modified = true ; } break ; case M680x0 :: MOVM32jm : Mask = MI -> getOperand ( 1 ) . getImm ( ) ; Reg = MI -> getOperand ( 0 ) . getReg ( ) ; Offset = 0 ; Modified |= ProcessMI ( MBB , MI , State , Mask , Offset , Reg , true ) ; break ; case M680x0 :: MOVM32pm : Mask = MI -> getOperand ( 2 ) . getImm ( ) ; Reg = MI -> getOperand ( 1 ) . getReg ( ) ; Offset = MI -> getOperand ( 0 ) . getImm ( ) ; Modified |= ProcessMI ( MBB , MI , State , Mask , Offset , Reg , true ) ; break ; case M680x0 :: MOVM32mj : Mask = MI -> getOperand ( 0 ) . getImm ( ) ; Reg = MI -> getOperand ( 1 ) . getReg ( ) ; Offset = 0 ; Modified |= ProcessMI ( MBB , MI , State , Mask , Offset , Reg , false ) ; break ; case M680x0 :: MOVM32mp : Mask = MI -> getOperand ( 0 ) . getImm ( ) ; Reg = MI -> getOperand ( 2 ) . getReg ( ) ; Offset = MI -> getOperand ( 1 ) . getImm ( ) ; Modified |= ProcessMI ( MBB , MI , State , Mask , Offset , Reg , false ) ; break ; } MI = NMI ; } if ( State . HasBase ( ) ) { State . SetEnd ( MI ) ; Finish ( MBB , State ) ; } } return Modified ; } </s>


<s> static M680x0RelType getType ( unsigned Kind , MCSymbolRefExpr :: VariantKind & Modifier , bool & IsPCRel ) { switch ( Kind ) { default : llvm_unreachable ( "Unimplemented" ) ; case FK_Data_4 : case FK_PCRel_4 : return RT_32 ; case FK_PCRel_2 : case FK_Data_2 : return RT_16 ; case FK_PCRel_1 : case FK_Data_1 : return RT_8 ; } } </s>

Overload to return most specific vector type .


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


"M680x0 pseudo instruction expansion pass"


<s> bool M680x0ExpandPseudo :: runOnMachineFunction ( MachineFunction & MF ) { STI = & static_cast < const M680x0Subtarget & > ( MF . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MFI = MF . getInfo < M680x0MachineFunctionInfo > ( ) ; FL = STI -> getFrameLowering ( ) ; bool Modified = false ; for ( MachineBasicBlock & MBB : MF ) Modified |= ExpandMBB ( MBB ) ; return Modified ; } </s>


<s> bool M680x0FrameLowering :: assignCalleeSavedSpillSlots ( MachineFunction & MF , const TargetRegisterInfo * TRI , std :: vector < CalleeSavedInfo > & CSI ) const { MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; M680x0MachineFunctionInfo * M680x0FI = MF . getInfo < M680x0MachineFunctionInfo > ( ) ; int SpillSlotOffset = getOffsetOfLocalArea ( ) + M680x0FI -> getTCReturnAddrDelta ( ) ; if ( hasFP ( MF ) ) { SpillSlotOffset -= SlotSize ; MFI . CreateFixedSpillStackObject ( SlotSize , SpillSlotOffset ) ; unsigned FPReg = TRI -> getFrameRegister ( MF ) ; for ( unsigned i = 0 ; i < CSI . size ( ) ; ++ i ) { if ( TRI -> regsOverlap ( CSI [ i ] . getReg ( ) , FPReg ) ) { CSI . erase ( CSI . begin ( ) + i ) ; break ; } } } return false ; } </s>

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


<s> void M680x0FrameLowering :: BuildCFI ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , const DebugLoc & DL , const MCCFIInstruction & CFIInst ) const { MachineFunction & MF = * MBB . getParent ( ) ; unsigned CFIIndex = MF . addFrameInst ( CFIInst ) ; BuildMI ( MBB , MBBI , DL , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) ; } </s>

Wraps up getting a CFI index and building a MachineInstr for it .


<s> bool M680x0FrameLowering :: canSimplifyCallFramePseudos ( const MachineFunction & MF ) const { return hasReservedCallFrame ( MF ) || ( hasFP ( MF ) && ! TRI -> needsStackRealignment ( MF ) ) || TRI -> hasBasePointer ( MF ) ; } </s>

canSimplifyCallFramePseudos - If there is a reserved call frame , the call frame pseudos can be simplified .


<s> void M680x0FrameLowering :: determineCalleeSaves ( MachineFunction & MF , BitVector & SavedRegs , RegScavenger * RS ) const { TargetFrameLowering :: determineCalleeSaves ( MF , SavedRegs , RS ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; M680x0MachineFunctionInfo * M680x0FI = MF . getInfo < M680x0MachineFunctionInfo > ( ) ; int64_t TailCallReturnAddrDelta = M680x0FI -> getTCReturnAddrDelta ( ) ; if ( TailCallReturnAddrDelta < 0 ) { MFI . CreateFixedObject ( - TailCallReturnAddrDelta , TailCallReturnAddrDelta - SlotSize , true ) ; } if ( TRI -> hasBasePointer ( MF ) ) { SavedRegs . set ( TRI -> getBaseRegister ( ) ) ; } } </s>

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


<s> MachineBasicBlock :: iterator M680x0FrameLowering :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { bool reserveCallFrame = hasReservedCallFrame ( MF ) ; unsigned Opcode = I -> getOpcode ( ) ; bool isDestroy = Opcode == TII . getCallFrameDestroyOpcode ( ) ; DebugLoc DL = I -> getDebugLoc ( ) ; uint64_t Amount = ! reserveCallFrame ? I -> getOperand ( 0 ) . getImm ( ) : 0 ; uint64_t InternalAmt = ( isDestroy && Amount ) ? I -> getOperand ( 1 ) . getImm ( ) : 0 ; I = MBB . erase ( I ) ; if ( ! reserveCallFrame ) { unsigned StackAlign = getStackAlignment ( ) ; Amount = alignTo ( Amount , StackAlign ) ; MachineModuleInfo & MMI = MF . getMMI ( ) ; const auto & Fn = MF . getFunction ( ) ; bool DwarfCFI = MMI . hasDebugInfo ( ) || Fn . needsUnwindTableEntry ( ) ; bool HasDwarfEHHandlers = ! MF . getLandingPads ( ) . empty ( ) ; if ( HasDwarfEHHandlers && ! isDestroy && MF . getInfo < M680x0MachineFunctionInfo > ( ) -> getHasPushSequences ( ) ) { BuildCFI ( MBB , I , DL , MCCFIInstruction :: createGnuArgsSize ( nullptr , Amount ) ) ; } if ( Amount == 0 ) return I ; Amount -= InternalAmt ; if ( isDestroy && InternalAmt && DwarfCFI && ! hasFP ( MF ) ) BuildCFI ( MBB , I , DL , MCCFIInstruction :: createAdjustCfaOffset ( nullptr , - InternalAmt ) ) ; int64_t StackAdjustment = isDestroy ? Amount : - Amount ; int64_t CfaAdjustment = - StackAdjustment ; if ( StackAdjustment ) { StackAdjustment += mergeSPUpdates ( MBB , I , true ) ; StackAdjustment += mergeSPUpdates ( MBB , I , false ) ; if ( StackAdjustment ) { BuildStackAdjustment ( MBB , I , DL , StackAdjustment , false ) ; } } if ( DwarfCFI && ! hasFP ( MF ) ) { if ( CfaAdjustment ) { BuildCFI ( MBB , I , DL , MCCFIInstruction :: createAdjustCfaOffset ( nullptr , CfaAdjustment ) ) ; } } return I ; } if ( isDestroy && InternalAmt ) { MachineBasicBlock :: iterator CI = I ; MachineBasicBlock :: iterator B = MBB . begin ( ) ; while ( CI != B && ! std :: prev ( CI ) -> isCall ( ) ) -- CI ; BuildStackAdjustment ( MBB , CI , DL , - InternalAmt , false ) ; } return 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 ) .


<s> void M680x0FrameLowering :: emitSPUpdate ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , int64_t NumBytes , bool InEpilogue ) const { bool isSub = NumBytes < 0 ; uint64_t Offset = isSub ? - NumBytes : NumBytes ; uint64_t Chunk = ( 1LL << 31 ) - 1 ; DebugLoc DL = MBB . findDebugLoc ( MBBI ) ; while ( Offset ) { if ( Offset > Chunk ) { unsigned Reg = 0 ; if ( isSub && ! isRegLiveIn ( MBB , M680x0 :: D0 ) ) Reg = ( unsigned ) ( M680x0 :: D0 ) ; else Reg = findDeadCallerSavedReg ( MBB , MBBI , TRI ) ; if ( Reg ) { unsigned Opc = M680x0 :: MOV32ri ; BuildMI ( MBB , MBBI , DL , TII . get ( Opc ) , Reg ) . addImm ( Offset ) ; Opc = isSub ? getSUBrrOpcode ( ) : getADDrrOpcode ( ) ; MachineInstr * MI = BuildMI ( MBB , MBBI , DL , TII . get ( Opc ) , StackPtr ) . addReg ( StackPtr ) . addReg ( Reg ) ; MI -> getOperand ( 3 ) . setIsDead ( ) ; Offset = 0 ; continue ; } } uint64_t ThisVal = std :: min ( Offset , Chunk ) ; MachineInstrBuilder MI = BuildStackAdjustment ( MBB , MBBI , DL , isSub ? - ThisVal : ThisVal , InEpilogue ) ; if ( isSub ) MI . setMIFlag ( MachineInstr :: FrameSetup ) ; else MI . setMIFlag ( MachineInstr :: FrameDestroy ) ; Offset -= ThisVal ; } } </s>

Emit a series of instructions to increment / decrement the stack pointer by a constant value .


<s> static unsigned findDeadCallerSavedReg ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , const M680x0RegisterInfo * TRI ) { const MachineFunction * MF = MBB . getParent ( ) ; if ( MF -> callsEHReturn ( ) ) return 0 ; const TargetRegisterClass & AvailableRegs = * TRI -> getRegsForTailCall ( * MF ) ; if ( MBBI == MBB . end ( ) ) return 0 ; switch ( MBBI -> getOpcode ( ) ) { default : return 0 ; case TargetOpcode :: PATCHABLE_RET : case M680x0 :: RET : { SmallSet < uint16_t , 8 > Uses ; for ( unsigned i = 0 , e = MBBI -> getNumOperands ( ) ; i != e ; ++ i ) { MachineOperand & MO = MBBI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isDef ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( ! Reg ) continue ; for ( MCRegAliasIterator AI ( Reg , TRI , true ) ; AI . isValid ( ) ; ++ AI ) Uses . insert ( * AI ) ; } for ( auto CS : AvailableRegs ) if ( ! Uses . count ( CS ) ) return CS ; } } return 0 ; } </s>

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


"VLAs and dynamic stack realign, but no FP?!"

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


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

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


<s> bool M680x0FrameLowering :: hasReservedCallFrame ( const MachineFunction & MF ) const { return ! MF . getFrameInfo ( ) . hasVarSizedObjects ( ) && ! MF . getInfo < M680x0MachineFunctionInfo > ( ) -> getHasPushSequences ( ) ; } </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 M680x0FrameLowering :: mergeSPUpdates ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , bool doMergeWithPrevious ) const { if ( ( doMergeWithPrevious && MBBI == MBB . begin ( ) ) || ( ! doMergeWithPrevious && MBBI == MBB . end ( ) ) ) return 0 ; MachineBasicBlock :: iterator PI = doMergeWithPrevious ? std :: prev ( MBBI ) : MBBI ; MachineBasicBlock :: iterator NI = doMergeWithPrevious ? nullptr : std :: next ( MBBI ) ; unsigned Opc = PI -> getOpcode ( ) ; int Offset = 0 ; if ( ! doMergeWithPrevious && NI != MBB . end ( ) && NI -> getOpcode ( ) == TargetOpcode :: CFI_INSTRUCTION ) { return Offset ; } if ( Opc == M680x0 :: ADD32ri && PI -> getOperand ( 0 ) . getReg ( ) == StackPtr ) { assert ( PI -> getOperand ( 1 ) . getReg ( ) == StackPtr ) ; Offset += PI -> getOperand ( 2 ) . getImm ( ) ; MBB . erase ( PI ) ; if ( ! doMergeWithPrevious ) MBBI = NI ; } else if ( Opc == M680x0 :: SUB32ri && PI -> getOperand ( 0 ) . getReg ( ) == StackPtr ) { assert ( PI -> getOperand ( 1 ) . getReg ( ) == StackPtr ) ; Offset -= PI -> getOperand ( 2 ) . getImm ( ) ; MBB . erase ( PI ) ; if ( ! doMergeWithPrevious ) MBBI = NI ; } return Offset ; } </s>

Check the instruction before/after the passed instruction .


<s> bool M680x0FrameLowering :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { auto & MRI = * static_cast < const M680x0RegisterInfo * > ( TRI ) ; auto DL = MBB . findDebugLoc ( MI ) ; int FI = 0 ; unsigned Mask = 0 ; for ( size_t i = 0 ; i < CSI . size ( ) ; ++ i ) { FI = std :: max ( FI , CSI [ i ] . getFrameIdx ( ) ) ; unsigned Reg = CSI [ i ] . getReg ( ) ; unsigned Shift = MRI . getSpillRegisterOrder ( Reg ) ; Mask |= 1 << Shift ; } auto I = addFrameReference ( BuildMI ( MBB , MI , DL , TII . get ( M680x0 :: MOVM32mp ) ) . addImm ( Mask ) , FI ) . setMIFlag ( MachineInstr :: FrameDestroy ) ; for ( size_t i = 0 ; i < CSI . size ( ) ; ++ i ) { I . addReg ( CSI [ i ] . getReg ( ) , RegState :: ImplicitDefine ) ; addMemOperand ( I , CSI [ i ] . getFrameIdx ( ) , 0 ) ; } 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> bool M680x0FrameLowering :: spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { auto & MRI = * static_cast < const M680x0RegisterInfo * > ( TRI ) ; auto DL = MBB . findDebugLoc ( MI ) ; int FI = 0 ; unsigned Mask = 0 ; for ( size_t i = 0 ; i < CSI . size ( ) ; ++ i ) { FI = std :: max ( FI , CSI [ i ] . getFrameIdx ( ) ) ; unsigned Reg = CSI [ i ] . getReg ( ) ; unsigned Shift = MRI . getSpillRegisterOrder ( Reg ) ; Mask |= 1 << Shift ; } auto I = addFrameReference ( BuildMI ( MBB , MI , DL , TII . get ( M680x0 :: MOVM32pm ) ) , FI ) . addImm ( Mask ) . setMIFlag ( MachineInstr :: FrameSetup ) ; const MachineFunction & MF = * MBB . getParent ( ) ; const MachineRegisterInfo & RI = MF . getRegInfo ( ) ; for ( size_t i = 0 ; i < CSI . size ( ) ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; bool isLiveIn = RI . isLiveIn ( Reg ) ; if ( ! isLiveIn ) MBB . addLiveIn ( Reg ) ; I . addReg ( Reg , isLiveIn ? RegState :: Implicit : RegState :: ImplicitKill ) ; addMemOperand ( I , CSI [ i ] . getFrameIdx ( ) , 0 ) ; } return true ; } </s>

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


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

Print the specified MCInst to the specified raw_ostream .


<s> void printPCRelImm ( const MCInst * MI , int opNum , raw_ostream & O ) { printOperand ( MI , opNum , O ) ; } </s>


<s> void M680x0InstPrinter :: printRegName ( raw_ostream & OS , unsigned RegNo ) const { OS << "%" << StringRef ( getRegisterName ( RegNo ) ) ; } </s>


<s> static inline const MachineInstrBuilder & addMemOperand ( const MachineInstrBuilder & MIB , int FI , int Offset = 0 ) { MachineInstr * MI = MIB ; MachineFunction & MF = * MI -> getParent ( ) -> getParent ( ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; auto Flags = MachineMemOperand :: MONone ; if ( MCID . mayLoad ( ) ) Flags |= MachineMemOperand :: MOLoad ; if ( MCID . mayStore ( ) ) Flags |= MachineMemOperand :: MOStore ; MachineMemOperand * MMO = MF . getMachineMemOperand ( MachinePointerInfo :: getFixedStack ( MF , FI , Offset ) , Flags , MFI . getObjectSize ( FI ) , MFI . getObjectAlignment ( FI ) ) ; return MIB . addMemOperand ( MMO ) ; } </s>

Add a MachineMemOperand to the machine instruction .


<s>
void
M680x0InstrInfo
::
AddSExt
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
DebugLoc
DL
,
unsigned
Reg
,
MVT
From
,
MVT
To
)
const
{
if
(
From
==
MVT
::
i8
)
{
unsigned
R
=
Reg
;
if
(
To
==
MVT
::
i32
)
{
R
=
RI
.
getSubReg
(
Reg
,
M680x0
::
MxSubRegIndex16Lo
)
;
assert
(
R
&&
"No viable SUB register available"
)
;
}
BuildMI
(
MBB
,
I
,
DL
,
get
(
M680x0
::
EXT16
)
,
R
)
.
addReg
(
R
)
;
}
if
(
To
==
MVT
::
i32
)
{
BuildMI
(
MBB
,
I
,
DL
,
get
(
M680x0
::
EXT32
)
,
Reg
)
.
addReg
(
Reg
)
;
}
}
</s>


<s> void M680x0InstrInfo :: AddZExt ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , DebugLoc DL , unsigned Reg , MVT From , MVT To ) const { unsigned Mask , And ; if ( From == MVT :: i8 ) { Mask = 0xFF ; } else { Mask = 0xFFFF ; } if ( To == MVT :: i16 ) { And = M680x0 :: AND16di ; } else { And = M680x0 :: AND32di ; } BuildMI ( MBB , I , DL , get ( And ) , Reg ) . addReg ( Reg ) . addImm ( Mask ) ; } </s>


<s> bool M680x0InstrInfo :: analyzeBranch ( MachineBasicBlock & MBB , MachineBasicBlock * & TBB , MachineBasicBlock * & FBB , SmallVectorImpl < MachineOperand > & Cond , bool AllowModify ) const { return AnalyzeBranchImpl ( MBB , TBB , FBB , Cond , AllowModify ) ; } </s>

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


<s>
void
M680x0InstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
const
DebugLoc
&
DL
,
unsigned
DstReg
,
unsigned
SrcReg
,
bool
KillSrc
)
const
{
unsigned
Opc
=
0
;
if
(
M680x0
::
XR32RegClass
.
contains
(
DstReg
,
SrcReg
)
)
Opc
=
M680x0
::
MOV32rr
;
else
if
(
M680x0
::
XR16RegClass
.
contains
(
DstReg
,
SrcReg
)
)
Opc
=
M680x0
::
MOV16rr
;
else
if
(
M680x0
::
DR8RegClass
.
contains
(
DstReg
,
SrcReg
)
)
{
Opc
=
M680x0
::
MOV8dd
;
}
if
(
Opc
)
{
BuildMI
(
MBB
,
MI
,
DL
,
get
(
Opc
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
return
;
}
MachineInstrBuilder
MIB
(
*
MBB
.
getParent
(
)
,
MI
)
;
if
(
M680x0
::
DR8RegClass
.
contains
(
SrcReg
)
)
{
if
(
M680x0
::
XR16RegClass
.
contains
(
DstReg
)
)
{
Opc
=
M680x0
::
MOVXd16d8
;
}
else
if
(
M680x0
::
XR32RegClass
.
contains
(
DstReg
)
)
{
Opc
=
M680x0
::
MOVXd32d8
;
}
}
else
if
(
M680x0
::
XR16RegClass
.
contains
(
SrcReg
)
)
{
if
(
M680x0
::
XR32RegClass
.
contains
(
DstReg
)
)
{
Opc
=
M680x0
::
MOVXd32d16
;
}
}
if
(
Opc
)
{
BuildMI
(
MBB
,
MI
,
DL
,
get
(
Opc
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
return
;
}
bool
FromCCR
=
SrcReg
==
M680x0
::
CCR
;
bool
FromSR
=
SrcReg
==
M680x0
::
SR
;
bool
ToCCR
=
DstReg
==
M680x0
::
CCR
;
bool
ToSR
=
DstReg
==
M680x0
::
SR
;
if
(
FromCCR
)
{
assert
(
M680x0
::
DR8RegClass
.
contains
(
DstReg
)
&&
"Need DR8 register to copy CCR"
)
;
Opc
=
M680x0
::
MOV8dc
;
}
else
if
(
ToCCR
)
{
assert
(
M680x0
::
DR8RegClass
.
contains
(
SrcReg
)
&&
"Need DR8 register to copy CCR"
)
;
Opc
=
M680x0
::
MOV8cd
;
}
else
if
(
FromSR
||
ToSR
)
{
llvm_unreachable
(
"Cannot emit SR copy instruction"
)
;
}
if
(
Opc
)
{
BuildMI
(
MBB
,
MI
,
DL
,
get
(
Opc
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
return
;
}
LLVM_DEBUG
(
dbgs
(
)
<<
"Cannot copy "
<<
RI
.
getName
(
SrcReg
)
<<
" to "
<<
RI
.
getName
(
DstReg
)
<<
'\n'
)
;
llvm_unreachable
(
"Cannot emit physreg copy instruction"
)
;
}
</s>


<s> std :: pair < unsigned , unsigned > M680x0InstrInfo :: decomposeMachineOperandsTargetFlags ( unsigned TF ) const { return std :: make_pair ( TF , 0u ) ; } </s>

Decompose the machine operand 's target flags into two values - the direct target flag value and any of bit flags that are applied .


<s> bool M680x0InstrInfo :: ExpandCCR ( MachineInstrBuilder & MIB , bool isToCCR ) const { if ( isToCCR ) { MIB -> setDesc ( get ( M680x0 :: MOV16cd ) ) ; } else { MIB -> setDesc ( get ( M680x0 :: MOV16dc ) ) ; } auto & Opd = MIB -> getOperand ( 1 ) ; Opd . setReg ( getRegisterInfo ( ) . getMatchingSuperReg ( Opd . getReg ( ) , M680x0 :: MxSubRegIndex8Lo , & M680x0 :: DR16RegClass ) ) ; return true ; } </s>


<s>
bool
M680x0InstrInfo
::
ExpandMOVEM
(
MachineInstrBuilder
&
MIB
,
const
MCInstrDesc
&
Desc
,
bool
isRM
)
const
{
int
Reg
=
0
,
Offset
=
0
,
Base
=
0
;
auto
XR32
=
RI
.
getRegClass
(
M680x0
::
XR32RegClassID
)
;
auto
DL
=
MIB
->
getDebugLoc
(
)
;
auto
MI
=
MIB
.
getInstr
(
)
;
auto
&
MBB
=
*
MIB
->
getParent
(
)
;
if
(
isRM
)
{
Reg
=
MIB
->
getOperand
(
0
)
.
getReg
(
)
;
Offset
=
MIB
->
getOperand
(
1
)
.
getImm
(
)
;
Base
=
MIB
->
getOperand
(
2
)
.
getReg
(
)
;
}
else
{
Offset
=
MIB
->
getOperand
(
0
)
.
getImm
(
)
;
Base
=
MIB
->
getOperand
(
1
)
.
getReg
(
)
;
Reg
=
MIB
->
getOperand
(
2
)
.
getReg
(
)
;
}
if
(
!
XR32
->
contains
(
Reg
)
)
{
Reg
=
RI
.
getMatchingMegaReg
(
Reg
,
XR32
)
;
assert
(
Reg
&&
"Has not meaningful MEGA register"
)
;
}
unsigned
Mask
=
1
<<
RI
.
getSpillRegisterOrder
(
Reg
)
;
if
(
isRM
)
{
BuildMI
(
MBB
,
MI
,
DL
,
Desc
)
.
addImm
(
Mask
)
.
addImm
(
Offset
)
.
addReg
(
Base
)
.
addReg
(
Reg
,
RegState
::
ImplicitDefine
)
.
copyImplicitOps
(
*
MIB
)
;
}
else
{
BuildMI
(
MBB
,
MI
,
DL
,
Desc
)
.
addImm
(
Offset
)
.
addReg
(
Base
)
.
addImm
(
Mask
)
.
addReg
(
Reg
,
RegState
::
Implicit
)
.
copyImplicitOps
(
*
MIB
)
;
}
MIB
->
eraseFromParent
(
)
;
return
true
;
}
</s>

Expand all MOVEM pseudos into real MOVEMs .


<s>
bool
M680x0InstrInfo
::
ExpandMOVSZX_RM
(
MachineInstrBuilder
&
MIB
,
bool
isSigned
,
const
MCInstrDesc
&
Desc
,
MVT
MVTDst
,
MVT
MVTSrc
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Expand "
<<
*
MIB
.
getInstr
(
)
<<
" to LOAD and "
)
;
unsigned
Dst
=
MIB
->
getOperand
(
0
)
.
getReg
(
)
;
unsigned
SubDst
=
RI
.
getSubReg
(
Dst
,
MVTSrc
==
MVT
::
i8
M680x0
::
MxSubRegIndex8Lo
:
M680x0
::
MxSubRegIndex16Lo
)
;
assert
(
SubDst
&&
"No viable SUB register available"
)
;
MIB
->
setDesc
(
Desc
)
;
MIB
->
getOperand
(
0
)
.
setReg
(
SubDst
)
;
MachineBasicBlock
::
iterator
I
=
MIB
.
getInstr
(
)
;
I
++
;
MachineBasicBlock
&
MBB
=
*
MIB
->
getParent
(
)
;
DebugLoc
DL
=
MIB
->
getDebugLoc
(
)
;
if
(
isSigned
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Sign Extend"
<<
'\n'
)
;
AddSExt
(
MBB
,
I
,
DL
,
Dst
,
MVTSrc
,
MVTDst
)
;
}
else
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Zero Extend"
<<
'\n'
)
;
AddZExt
(
MBB
,
I
,
DL
,
Dst
,
MVTSrc
,
MVTDst
)
;
}
return
true
;
}
</s>


"You cannot use the same Regs with MOVSX_RR"

"You cannot use the same Reg Classes with MOVSX_RR"


"You cannot use the same Regs with MOVX_RR"

"You cannot use the same Reg Classes with MOVX_RR"

Move across register classes without extension .


<s> bool M680x0InstrInfo :: expandPostRAPseudo ( MachineInstr & MI ) const { MachineInstrBuilder MIB ( * MI . getParent ( ) -> getParent ( ) , MI ) ; switch ( MI . getOpcode ( ) ) { case M680x0 :: PUSH8d : return ExpandPUSH_POP ( MIB , get ( M680x0 :: MOV8ed ) , true ) ; case M680x0 :: PUSH16d : return ExpandPUSH_POP ( MIB , get ( M680x0 :: MOV16er ) , true ) ; case M680x0 :: PUSH32r : return ExpandPUSH_POP ( MIB , get ( M680x0 :: MOV32er ) , true ) ; case M680x0 :: POP8d : return ExpandPUSH_POP ( MIB , get ( M680x0 :: MOV8do ) , false ) ; case M680x0 :: POP16d : return ExpandPUSH_POP ( MIB , get ( M680x0 :: MOV16ro ) , false ) ; case M680x0 :: POP32r : return ExpandPUSH_POP ( MIB , get ( M680x0 :: MOV32ro ) , false ) ; case M680x0 :: SETCS_C8d : return Expand2AddrUndef ( MIB , get ( M680x0 :: SUBX8dd ) ) ; case M680x0 :: SETCS_C16d : return Expand2AddrUndef ( MIB , get ( M680x0 :: SUBX16dd ) ) ; case M680x0 :: SETCS_C32d : return Expand2AddrUndef ( MIB , get ( M680x0 :: SUBX32dd ) ) ; } return false ; } </s>

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


<s> bool M680x0InstrInfo :: ExpandPUSH_POP ( MachineInstrBuilder & MIB , const MCInstrDesc & Desc , bool isPush ) const { MachineBasicBlock :: iterator I = MIB . getInstr ( ) ; I ++ ; MachineBasicBlock & MBB = * MIB -> getParent ( ) ; MachineOperand MO = MIB -> getOperand ( 0 ) ; DebugLoc DL = MIB -> getDebugLoc ( ) ; if ( isPush ) { BuildMI ( MBB , I , DL , Desc ) . addReg ( RI . getStackRegister ( ) ) . add ( MO ) ; } else { BuildMI ( MBB , I , DL , Desc , MO . getReg ( ) ) . addReg ( RI . getStackRegister ( ) ) ; } MIB -> eraseFromParent ( ) ; return true ; } </s>


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> unsigned M680x0InstrInfo :: getGlobalBaseReg ( MachineFunction * MF ) const { M680x0MachineFunctionInfo * MxFI = MF -> getInfo < M680x0MachineFunctionInfo > ( ) ; unsigned GlobalBaseReg = MxFI -> getGlobalBaseReg ( ) ; if ( GlobalBaseReg != 0 ) return GlobalBaseReg ; MachineRegisterInfo & RegInfo = MF -> getRegInfo ( ) ; GlobalBaseReg = RegInfo . createVirtualRegister ( & M680x0 :: AR32_NOSPRegClass ) ; MxFI -> setGlobalBaseReg ( GlobalBaseReg ) ; return GlobalBaseReg ; } </s>

getGlobalBaseReg - Return a virtual register initialized with the the global base register value .


"M680x0 PIC Global Base Reg Initialization"

getPassName - Return a nice clean name for a pass .


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

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


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


<s> bool M680x0InstrInfo :: getStackSlotRange ( const TargetRegisterClass * RC , unsigned SubIdx , unsigned & Size , unsigned & Offset , const MachineFunction & MF ) const { Size = 4 ; Offset = 0 ; return true ; } </s>

Compute the size in bytes and offset within a stack slot of a spilled register or subregister .


"InsertBranch must not be told to insert a fallthrough"

"M680x0 branch conditions have one component!"

"Unconditional branch with multiple successors!"

Insert branch code into the end of the specified MachineBasicBlock .


<s>
void
M680x0InstrInfo
::
loadRegFromStackSlot
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
unsigned
DstReg
,
int
FrameIndex
,
const
TargetRegisterClass
*
RC
,
const
TargetRegisterInfo
*
TRI
)
const
{
const
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
assert
(
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIndex
)
==
4
&&
"Stack slot too small for store"
)
;
unsigned
Opc
=
getLoadRegOpcode
(
DstReg
,
RC
,
TRI
,
Subtarget
)
;
DebugLoc
DL
=
MBB
.
findDebugLoc
(
MI
)
;
addFrameReference
(
BuildMI
(
MBB
,
MI
,
DL
,
get
(
Opc
)
,
DstReg
)
,
FrameIndex
)
;
}
</s>

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


<s>
unsigned
M680x0InstrInfo
::
removeBranch
(
MachineBasicBlock
&
MBB
,
int
*
BytesRemoved
)
const
{
assert
(
!
BytesRemoved
&&
"code size not handled"
)
;
MachineBasicBlock
::
iterator
I
=
MBB
.
end
(
)
;
unsigned
Count
=
0
;
while
(
I
!=
MBB
.
begin
(
)
)
{
I
;
if
(
I
->
isDebugValue
(
)
)
continue
;
if
(
I
->
getOpcode
(
)
!=
M680x0
::
BRA8
&&
getCondFromBranchOpc
(
I
->
getOpcode
(
)
)
==
M680x0
::
COND_INVALID
)
break
;
I
->
eraseFromParent
(
)
;
I
=
MBB
.
end
(
)
;
++
Count
;
}
return
Count
;
}
</s>

Remove the branching code at the end of the specific MBB .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { const M680x0Subtarget & STI = MF . getSubtarget < M680x0Subtarget > ( ) ; M680x0MachineFunctionInfo * MxFI = MF . getInfo < M680x0MachineFunctionInfo > ( ) ; unsigned GlobalBaseReg = MxFI -> getGlobalBaseReg ( ) ; if ( GlobalBaseReg == 0 ) return false ; MachineBasicBlock & FirstMBB = MF . front ( ) ; MachineBasicBlock :: iterator MBBI = FirstMBB . begin ( ) ; DebugLoc DL = FirstMBB . findDebugLoc ( MBBI ) ; const M680x0InstrInfo * TII = STI . getInstrInfo ( ) ; BuildMI ( FirstMBB , MBBI , DL , TII -> get ( M680x0 :: LEA32q ) , GlobalBaseReg ) . addExternalSymbol ( "_GLOBAL_OFFSET_TABLE_" , M680x0II :: MO_GOTPCREL ) ; return true ; } </s>

runOnMachineFunction - Emit the function body .


<s>
void
M680x0InstrInfo
::
storeRegToStackSlot
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
unsigned
SrcReg
,
bool
isKill
,
int
FrameIndex
,
const
TargetRegisterClass
*
RC
,
const
TargetRegisterInfo
*
TRI
)
const
{
const
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
assert
(
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIndex
)
==
4
&&
"Stack slot too small for store"
)
;
unsigned
Opc
=
getStoreRegOpcode
(
SrcReg
,
RC
,
TRI
,
Subtarget
)
;
DebugLoc
DL
=
MBB
.
findDebugLoc
(
MI
)
;
addFrameReference
(
BuildMI
(
MBB
,
MI
,
DL
,
get
(
Opc
)
)
,
FrameIndex
)
.
addReg
(
SrcReg
,
getKillRegState
(
isKill
)
)
;
}
</s>

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


<s>
void
dump
(
)
{
dbgs
(
)
<<
"M680x0ISelAddressMode "
<<
this
;
dbgs
(
)
<<
"\nDisp: "
<<
Disp
;
dbgs
(
)
<<
", BaseReg: "
;
if
(
BaseReg
.
getNode
(
)
)
BaseReg
.
getNode
(
)
->
dump
(
)
;
else
dbgs
(
)
<<
"null"
;
dbgs
(
)
<<
", BaseFI: "
<<
BaseFrameIndex
;
dbgs
(
)
<<
", IndexReg: "
;
if
(
IndexReg
.
getNode
(
)
)
{
IndexReg
.
getNode
(
)
->
dump
(
)
;
}
else
{
dbgs
(
)
<<
"null"
;
dbgs
(
)
<<
", Scale: "
<<
Scale
;
}
dbgs
(
)
<<
'\n'
;
}
</s>

Dump the plan to stderr ( for debugging ) .

M680x0
"M680x0ISelAddressMode "
"\nDisp: "
", BaseReg: "
"null"
", BaseFI: "
", IndexReg: "
"null"
", Scale: "


<s> SDNode * M680x0DAGToDAGISel :: getGlobalBaseReg ( ) { unsigned GlobalBaseReg = getInstrInfo ( ) -> getGlobalBaseReg ( MF ) ; auto & DL = MF -> getDataLayout ( ) ; return CurDAG -> getRegister ( GlobalBaseReg , TLI -> getPointerTy ( DL ) ) . getNode ( ) ; } </s>


<s> const M680x0InstrInfo * getInstrInfo ( ) const { return Subtarget -> getInstrInfo ( ) ; } </s>


"M680X0 DAG->DAG Pattern Instruction Selection"


<s> const M680x0TargetMachine & getTargetMachine ( ) { return static_cast < const M680x0TargetMachine & > ( TM ) ; } </s>

Return the target machine ( if available ) .


<s> bool M680x0DAGToDAGISel :: runOnMachineFunction ( MachineFunction & MF ) { Subtarget = & static_cast < const M680x0Subtarget & > ( MF . getSubtarget ( ) ) ; return SelectionDAGISel :: runOnMachineFunction ( MF ) ; } </s>


<s>
void
M680x0DAGToDAGISel
::
Select
(
SDNode
*
Node
)
{
unsigned
Opcode
=
Node
->
getOpcode
(
)
;
SDLoc
DL
(
Node
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Selecting: "
;
Node
->
dump
(
CurDAG
)
;
dbgs
(
)
<<
'\n'
)
;
if
(
Node
->
isMachineOpcode
(
)
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"== "
;
Node
->
dump
(
CurDAG
)
;
dbgs
(
)
<<
'\n'
)
;
Node
->
setNodeId
(
1
)
;
return
;
}
switch
(
Opcode
)
{
default
:
break
;
case
M680x0ISD
::
GlobalBaseReg
:
ReplaceNode
(
Node
,
getGlobalBaseReg
(
)
)
;
return
;
}
SelectCode
(
Node
)
;
}
</s>

Main hook for targets to transform nodes into machine nodes .


<s>
MachineBasicBlock
*
M680x0TargetLowering
::
EmitInstrWithCustomInserter
(
MachineInstr
&
MI
,
MachineBasicBlock
*
BB
)
const
{
switch
(
MI
.
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Unexpected instr type to insert"
)
;
case
M680x0
::
CMOV8d
:
case
M680x0
::
CMOV16d
:
case
M680x0
::
CMOV32r
:
return
EmitLoweredSelect
(
MI
,
BB
)
;
case
M680x0
::
SALLOCA
:
return
EmitLoweredSegAlloca
(
MI
,
BB
)
;
}
}
</s>

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


<s> unsigned M680x0TargetLowering :: getJumpTableEncoding ( ) const { return Subtarget . getJumpTableEncoding ( ) ; } </s>

Return the entry encoding for a jump table in the current function .


<s> SDValue M680x0TargetLowering :: getPICJumpTableRelocBase ( SDValue Table , SelectionDAG & DAG ) const { if ( getJumpTableEncoding ( ) == MachineJumpTableInfo :: EK_Custom32 ) return DAG . getNode ( M680x0ISD :: GlobalBaseReg , SDLoc ( ) , getPointerTy ( DAG . getDataLayout ( ) ) ) ; return Table ; } </s>

Returns relocation base for the given PIC jumptable .


<s> const MCExpr * M680x0TargetLowering :: getPICJumpTableRelocBaseExpr ( const MachineFunction * MF , unsigned JTI , MCContext & Ctx ) const { return MCSymbolRefExpr :: create ( MF -> getJTISymbol ( JTI , Ctx ) , Ctx ) ; } </s>

This returns the relocation base for the given PIC jumptable , the same as getPICJumpTableRelocBase , but as an MCExpr .


<s> MVT M680x0TargetLowering :: getScalarShiftAmountTy ( const DataLayout & DL , EVT Ty ) const { if ( Ty . isSimple ( ) ) { return Ty . getSimpleVT ( ) ; } return MVT :: getIntegerVT ( 8 * DL . getPointerSize ( 0 ) ) ; } </s>

Return the type to use for a scalar shift opcode , given the shifted amount type .


<s> EVT M680x0TargetLowering :: getSetCCResultType ( const DataLayout & DL , LLVMContext & Context , EVT VT ) const { return MVT :: i8 ; } </s>

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


<s> const char * M680x0TargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( Opcode ) { case M680x0ISD :: CALL : return "M680x0ISD::CALL" ; case M680x0ISD :: TAIL_CALL : return "M680x0ISD::TAIL_CALL" ; case M680x0ISD :: RET : return "M680x0ISD::RET" ; case M680x0ISD :: TC_RETURN : return "M680x0ISD::TC_RETURN" ; case M680x0ISD :: ADD : return "M680x0ISD::ADD" ; case M680x0ISD :: SUB : return "M680x0ISD::SUB" ; case M680x0ISD :: ADDX : return "M680x0ISD::ADDX" ; case M680x0ISD :: SUBX : return "M680x0ISD::SUBX" ; case M680x0ISD :: SMUL : return "M680x0ISD::SMUL" ; case M680x0ISD :: UMUL : return "M680x0ISD::UMUL" ; case M680x0ISD :: OR : return "M680x0ISD::OR" ; case M680x0ISD :: XOR : return "M680x0ISD::XOR" ; case M680x0ISD :: AND : return "M680x0ISD::AND" ; case M680x0ISD :: CMP : return "M680x0ISD::CMP" ; case M680x0ISD :: BT : return "M680x0ISD::BT" ; case M680x0ISD :: SELECT : return "M680x0ISD::SELECT" ; case M680x0ISD :: CMOV : return "M680x0ISD::CMOV" ; case M680x0ISD :: BRCOND : return "M680x0ISD::BRCOND" ; case M680x0ISD :: SETCC : return "M680x0ISD::SETCC" ; case M680x0ISD :: SETCC_CARRY : return "M680x0ISD::SETCC_CARRY" ; case M680x0ISD :: GlobalBaseReg : return "M680x0ISD::GlobalBaseReg" ; case M680x0ISD :: Wrapper : return "M680x0ISD::Wrapper" ; case M680x0ISD :: WrapperPC : return "M680x0ISD::WrapperPC" ; case M680x0ISD :: SEG_ALLOCA : return "M680x0ISD::SEG_ALLOCA" ; default : return NULL ; } } </s>

getTargetNodeName - This method returns the name of a target specific


<s> SDValue M680x0TargetLowering :: LowerCallResult ( SDValue Chain , SDValue InFlag , CallingConv :: ID CallConv , bool isVarArg , const SmallVectorImpl < ISD :: InputArg > & Ins , const SDLoc & DL , SelectionDAG & DAG , SmallVectorImpl < SDValue > & InVals ) const { SmallVector < CCValAssign , 16 > RVLocs ; CCState CCInfo ( CallConv , isVarArg , DAG . getMachineFunction ( ) , RVLocs , * DAG . getContext ( ) ) ; CCInfo . AnalyzeCallResult ( Ins , RetCC_M680x0 ) ; for ( unsigned i = 0 , e = RVLocs . size ( ) ; i != e ; ++ i ) { CCValAssign & VA = RVLocs [ i ] ; EVT CopyVT = VA . getLocVT ( ) ; Chain = DAG . getCopyFromReg ( Chain , DL , VA . getLocReg ( ) , CopyVT , InFlag ) . getValue ( 1 ) ; SDValue Val = Chain . getValue ( 0 ) ; if ( VA . isExtInLoc ( ) && VA . getValVT ( ) . getScalarType ( ) == MVT :: i1 ) Val = DAG . getNode ( ISD :: TRUNCATE , DL , VA . getValVT ( ) , Val ) ; InFlag = Chain . getValue ( 2 ) ; InVals . push_back ( Val ) ; } return Chain ; } </s>

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


<s>
SDValue
M680x0TargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Should not custom lower this!"
)
;
case
ISD
::
MUL
:
return
LowerMUL
(
Op
,
DAG
)
;
case
ISD
::
SADDO
:
case
ISD
::
UADDO
:
case
ISD
::
SSUBO
:
case
ISD
::
USUBO
:
case
ISD
::
SMULO
:
case
ISD
::
UMULO
:
return
LowerXALUO
(
Op
,
DAG
)
;
case
ISD
::
SETCC
:
return
LowerSETCC
(
Op
,
DAG
)
;
case
ISD
::
SETCCCARRY
:
return
LowerSETCCCARRY
(
Op
,
DAG
)
;
case
ISD
::
SELECT
:
return
LowerSELECT
(
Op
,
DAG
)
;
case
ISD
::
BRCOND
:
return
LowerBRCOND
(
Op
,
DAG
)
;
case
ISD
::
ADDC
:
case
ISD
::
ADDE
:
case
ISD
::
SUBC
:
case
ISD
::
SUBE
:
return
LowerADDC_ADDE_SUBC_SUBE
(
Op
,
DAG
)
;
case
ISD
::
ConstantPool
:
return
LowerConstantPool
(
Op
,
DAG
)
;
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
ExternalSymbol
:
return
LowerExternalSymbol
(
Op
,
DAG
)
;
case
ISD
::
BlockAddress
:
return
LowerBlockAddress
(
Op
,
DAG
)
;
case
ISD
::
JumpTable
:
return
LowerJumpTable
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
LowerVASTART
(
Op
,
DAG
)
;
case
ISD
::
DYNAMIC_STACKALLOC
:
return
LowerDYNAMIC_STACKALLOC
(
Op
,
DAG
)
;
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .

M680x0
M680x0
"Should not custom lower this!"
ISD::MUL
ISD::SADDO
ISD::UADDO
ISD::SSUBO
ISD::USUBO
ISD::SMULO
ISD::UMULO
ISD::SETCC
ISD::SETCCCARRY
ISD::SELECT
ISD::BRCOND
ISD::ADDC
ISD::ADDE
ISD::SUBC
ISD::SUBE
ISD::ConstantPool
ISD::GlobalAddress
ISD::ExternalSymbol
ISD::BlockAddress
ISD::JumpTable
ISD::VASTART
ISD::DYNAMIC_STACKALLOC


<s> SDValue M680x0TargetLowering :: PerformDAGCombine ( SDNode * N , DAGCombinerInfo & DCI ) const { SelectionDAG & DAG = DCI . DAG ; switch ( N -> getOpcode ( ) ) { case M680x0ISD :: SUBX : return combineSUBX ( N , DAG ) ; case M680x0ISD :: ADDX : return combineADDX ( N , DAG , DCI ) ; case M680x0ISD :: SETCC : return combineM680x0SetCC ( N , DAG , Subtarget ) ; case M680x0ISD :: BRCOND : return combineM680x0BrCond ( N , DAG , Subtarget ) ; } return SDValue ( ) ; } </s>

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


<s> unsigned getGlobalBaseReg ( ) const { return GlobalBaseReg ; } </s>

getGlobalBaseReg - Return a virtual register initialized with the the global base register value .


"*** Instruction does not have Beads defined"

Encode the given Inst to bytes and append to CB .


<s>
MCSymbol
*
M680x0MCInstLower
::
GetSymbolFromOperand
(
const
MachineOperand
&
MO
)
const
{
assert
(
(
MO
.
isGlobal
(
)
||
MO
.
isSymbol
(
)
||
MO
.
isMBB
(
)
)
&&
"Isn't a symbol reference"
)
;
const
DataLayout
&
DL
=
MF
.
getDataLayout
(
)
;
MCSymbol
*
Sym
=
nullptr
;
SmallString
<
128
>
Name
;
StringRef
Suffix
;
if
(
!
Suffix
.
empty
(
)
)
Name
+=
DL
.
getPrivateGlobalPrefix
(
)
;
if
(
MO
.
isGlobal
(
)
)
{
const
GlobalValue
*
GV
=
MO
.
getGlobal
(
)
;
AsmPrinter
.
getNameWithPrefix
(
Name
,
GV
)
;
}
else
if
(
MO
.
isSymbol
(
)
)
{
Mangler
::
getNameWithPrefix
(
Name
,
MO
.
getSymbolName
(
)
,
DL
)
;
}
else
if
(
MO
.
isMBB
(
)
)
{
assert
(
Suffix
.
empty
(
)
)
;
Sym
=
MO
.
getMBB
(
)
->
getSymbol
(
)
;
}
Name
+=
Suffix
;
if
(
!
Sym
)
Sym
=
Ctx
.
getOrCreateSymbol
(
Name
)
;
return
Sym
;
}
</s>

Lower an MO_GlobalAddress or MO_ExternalSymbol operand to an MCSymbol .


<s> bool M680x0RegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { if ( ! TargetRegisterInfo :: canRealignStack ( MF ) ) return false ; const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; if ( ! MRI -> canReserveReg ( FramePtr ) ) return false ; if ( CantUseSP ( MFI ) ) return MRI -> canReserveReg ( BasePtr ) ; return true ; } </s>

True if the stack can be realigned for the target .


<s> void M680x0RegisterInfo :: eliminateFrameIndex ( MachineBasicBlock :: iterator II , int SPAdj , unsigned FIOperandNum , RegScavenger * RS ) const { MachineInstr & MI = * II ; MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; const M680x0FrameLowering * TFI = getFrameLowering ( MF ) ; MachineOperand & Disp = MI . getOperand ( FIOperandNum - 1 ) ; MachineOperand & Base = MI . getOperand ( FIOperandNum ) ; int Imm = ( int ) ( Disp . getImm ( ) ) ; int FIndex = ( int ) ( Base . getIndex ( ) ) ; bool AfterFPPop = false ; unsigned BasePtr ; if ( hasBasePointer ( MF ) ) BasePtr = ( FIndex < 0 ? FramePtr : getBaseRegister ( ) ) ; else if ( needsStackRealignment ( MF ) ) BasePtr = ( FIndex < 0 ? FramePtr : StackPtr ) ; else if ( AfterFPPop ) BasePtr = StackPtr ; else BasePtr = ( TFI -> hasFP ( MF ) ? FramePtr : StackPtr ) ; Base . ChangeToRegister ( BasePtr , false ) ; int FIOffset ; unsigned IgnoredFrameReg ; if ( AfterFPPop ) { const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; FIOffset = MFI . getObjectOffset ( FIndex ) - TFI -> getOffsetOfLocalArea ( ) ; } else { FIOffset = TFI -> getFrameIndexReference ( MF , FIndex , IgnoredFrameReg ) ; } if ( BasePtr == StackPtr ) FIOffset += SPAdj ; long long Offset = FIOffset + Imm ; Disp . ChangeToImmediate ( Offset ) ; } </s>

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


<s> const MCPhysReg * M680x0RegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return CSR_STD_SaveList ; } </s>


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

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


<s> unsigned M680x0RegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getSubtarget ( ) . getFrameLowering ( ) ; return TFI -> hasFP ( MF ) ? FramePtr : StackPtr ; } </s>


<s> unsigned M680x0RegisterInfo :: getMatchingMegaReg ( unsigned Reg , const TargetRegisterClass * RC ) const { for ( MCSuperRegIterator Super ( Reg , this ) ; Super . isValid ( ) ; ++ Super ) if ( RC -> contains ( * Super ) ) return * Super ; return 0 ; } </s>

Return a mega-register of the specified register Reg so its sub-register of index SubIdx is Reg , its super ( or mega ) Reg .


<s>
const
TargetRegisterClass
*
M680x0RegisterInfo
::
getMaximalPhysRegClass
(
unsigned
reg
,
MVT
VT
)
const
{
assert
(
isPhysicalRegister
(
reg
)
&&
"reg must be a physical register"
)
;
const
TargetRegisterClass
*
BestRC
=
nullptr
;
for
(
regclass_iterator
I
=
regclass_begin
(
)
,
E
=
regclass_end
(
)
;
I
!=
E
;
++
I
)
{
const
TargetRegisterClass
*
RC
=
*
I
;
if
(
(
VT
==
MVT
::
Other
||
isTypeLegalForClass
(
*
RC
,
VT
)
)
&&
RC
->
contains
(
reg
)
&&
(
!
BestRC
||
(
BestRC
->
hasSubClass
(
RC
)
&&
RC
->
getNumRegs
(
)
>
BestRC
->
getNumRegs
(
)
)
)
)
BestRC
=
RC
;
}
assert
(
BestRC
&&
"Couldn't find the register class"
)
;
return
BestRC
;
}
</s>

Returns the Register Class of a physical register of the given type , picking the biggest register class of the right type that contains this physreg .


<s> int M680x0RegisterInfo :: getRegisterOrder ( unsigned Reg , const TargetRegisterClass & TRC ) const { for ( unsigned i = 0 ; i < TRC . getNumRegs ( ) ; ++ i ) { if ( regsOverlap ( Reg , TRC . getRegister ( i ) ) ) { return i ; } } return - 1 ; } </s>

Return index of a register within a register class , otherwise return -1 .


<s> const TargetRegisterClass * M680x0RegisterInfo :: getRegsForTailCall ( const MachineFunction & MF ) const { return & M680x0 :: XR32_TCRegClass ; } </s>

Returns a register class with registers that can be used in forming tail calls .


"Stack realignment in presence of dynamic allocas is "

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>
int
M680x0RegisterInfo
::
getSpillRegisterOrder
(
unsigned
Reg
)
const
{
int
Result
=
getRegisterOrder
(
Reg
,
*
getRegClass
(
M680x0
::
SPILLRegClassID
)
)
;
if
(
Result
<
0
)
{
llvm_unreachable
(
"Cannot determine spill order"
)
;
}
return
Result
;
}
</s>

Return spill order index of a register , if there is none then trap .


<s> unsigned getSpillSize ( const TargetRegisterClass & RC ) const override { return 4 ; } </s>

Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class RC .


<s> const TargetRegisterClass * M680x0RegisterInfo :: intRegClass ( unsigned size ) const { return & M680x0 :: DR32RegClass ; } </s>


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

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


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

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


<s> unsigned char M680x0Subtarget :: classifyBlockAddressReference ( ) const { return M680x0II :: MO_PC_RELATIVE_ADDRESS ; } </s>

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


<s> unsigned char M680x0Subtarget :: classifyExternalReference ( const Module & M ) const { if ( TM . shouldAssumeDSOLocal ( M , nullptr ) ) return classifyLocalReference ( nullptr ) ; if ( isPositionIndependent ( ) ) { return M680x0II :: MO_GOTPCREL ; } else { return M680x0II :: MO_GOT ; } } </s>

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


<s> unsigned char M680x0Subtarget :: classifyGlobalFunctionReference ( const GlobalValue * GV , const Module & M ) const { if ( TM . shouldAssumeDSOLocal ( M , GV ) ) return M680x0II :: MO_NO_FLAG ; auto * F = dyn_cast_or_null < Function > ( GV ) ; if ( F && F -> hasFnAttribute ( Attribute :: NonLazyBind ) ) { return M680x0II :: MO_GOTPCREL ; } return M680x0II :: MO_PLT ; } </s>

Classify a global function reference for the current subtarget .


<s>
unsigned
char
M680x0Subtarget
::
classifyGlobalReference
(
const
GlobalValue
*
GV
,
const
Module
&
M
)
const
{
if
(
TM
.
shouldAssumeDSOLocal
(
M
,
GV
)
)
return
classifyLocalReference
(
GV
)
;
switch
(
TM
.
getCodeModel
(
)
)
{
default
:
llvm_unreachable
(
"Unsupported code model"
)
;
case
CodeModel
::
Small
:
case
CodeModel
::
Kernel
:
{
if
(
isPositionIndependent
(
)
)
{
return
M680x0II
::
MO_GOTPCREL
;
}
else
{
return
M680x0II
::
MO_PC_RELATIVE_ADDRESS
;
}
}
case
CodeModel
::
Medium
:
{
if
(
isPositionIndependent
(
)
)
{
return
M680x0II
::
MO_GOTPCREL
;
}
else
{
if
(
IsM68020
)
{
return
M680x0II
::
MO_PC_RELATIVE_ADDRESS
;
}
return
M680x0II
::
MO_ABSOLUTE_ADDRESS
;
}
}
}
}
</s>

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


<s>
unsigned
char
M680x0Subtarget
::
classifyLocalReference
(
const
GlobalValue
*
GV
)
const
{
switch
(
TM
.
getCodeModel
(
)
)
{
default
:
llvm_unreachable
(
"Unsupported code model"
)
;
case
CodeModel
::
Small
:
case
CodeModel
::
Kernel
:
{
return
M680x0II
::
MO_PC_RELATIVE_ADDRESS
;
}
case
CodeModel
::
Medium
:
{
if
(
isPositionIndependent
(
)
)
{
if
(
IsM68020
)
{
return
M680x0II
::
MO_PC_RELATIVE_ADDRESS
;
}
return
M680x0II
::
MO_GOTOFF
;
}
else
{
if
(
IsM68020
)
{
return
M680x0II
::
MO_PC_RELATIVE_ADDRESS
;
}
return
M680x0II
::
MO_ABSOLUTE_ADDRESS
;
}
}
}
}
</s>


<s> const M680x0InstrInfo * 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> unsigned M680x0Subtarget :: getJumpTableEncoding ( ) const { if ( isPositionIndependent ( ) ) { if ( TM . getCodeModel ( ) == CodeModel :: Medium && ! isM68020 ( ) ) return MachineJumpTableInfo :: EK_Custom32 ; return MachineJumpTableInfo :: EK_LabelDifference32 ; } return MachineJumpTableInfo :: EK_BlockAddress ; } </s>

Return the entry encoding for a jump table in the current function .


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

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> unsigned getSlotSize ( ) const { return 4 ; } </s>

getSlotSize - Stack slot size in bytes .


<s> unsigned getStackAlignment ( ) const { return stackAlignment ; } </s>

Returns the minimum alignment known to hold of the stack frame on entry to the function and which must be maintained by every function for this subtarget .


<s> const Triple & getTargetTriple ( ) const { return TargetTriple ; } </s>

Get the target triple which is a string describing the target host .


<s> M680x0Subtarget & M680x0Subtarget :: initializeSubtargetDependencies ( StringRef CPU , Triple TT , StringRef FS , const M680x0TargetMachine & TM ) { std :: string CPUName = selectM680x0CPU ( TT , CPU ) ; IsM68000 = true ; InstrItins = getInstrItineraryForCPU ( CPUName ) ; stackAlignment = 8 ; 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 M680x0Subtarget :: isLegalToCallImmediateAddr ( ) const { return true ; } </s>

Return true if the subtarget allows calls to immediate address .


<s> bool M680x0PassConfig :: addInstSelector ( ) { addPass ( createM680x0ISelDag ( getM680x0TargetMachine ( ) ) ) ; addPass ( createM680x0GlobalBaseRegPass ( ) ) ; return false ; } </s>

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


<s> void M680x0PassConfig :: addPreEmitPass ( ) { addPass ( createM680x0CollapseMOVEMPass ( ) ) ; } </s>

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


<s> void M680x0PassConfig :: addPreSched2 ( ) { addPass ( createM680x0ExpandPseudoPass ( ) ) ; } </s>

This method may be implemented by targets that want to run passes after prolog-epilog insertion and before the second instruction scheduling pass .


<s> TargetPassConfig * M680x0TargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new M680x0PassConfig ( * 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> const M680x0Subtarget * getSubtargetImpl ( ) const { return & Subtarget ; } </s>

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


<s> void M680x0ELFTargetObjectFile :: Initialize ( MCContext & Ctx , const TargetMachine & TM ) { TargetLoweringObjectFileELF :: Initialize ( Ctx , TM ) ; InitializeELF ( TM . Options . UseInitArray ) ; this -> TM = & static_cast < const M680x0TargetMachine & > ( TM ) ; SmallDataSection = getContext ( ) . getELFSection ( ".sdata" , ELF :: SHT_PROGBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC ) ; SmallBSSSection = getContext ( ) . getELFSection ( ".sbss" , ELF :: SHT_NOBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC ) ; } </s>

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