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


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

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


<s>
unsigned
getReg
(
)
const
override
{
assert
(
isReg
(
)
&&
"Invalid type access!"
)
;
return
Reg
.
RegNo
;
}
</s>

Returns the register associated with this edge .


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

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


<s> bool isImm ( int64_t MinValue , int64_t MaxValue ) const { return Kind == OpKind_Imm && inRange ( Imm , MinValue , MaxValue ) ; } </s>


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


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


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


"Instruction use requires option to be enabled"

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


<s> bool M88kAsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getIdentifier ( ) ; if ( IDVal == ".requires_88110" ) { MCSubtargetInfo & STI = copySTI ( ) ; STI . setDefaultFeatures ( "m88110" , "m88110" , "" ) ; setAvailableFeatures ( ComputeAvailableFeatures ( STI . getFeatureBits ( ) ) ) ; getTargetStreamer ( ) . emitDirectiveRequires881100 ( ) ; return false ; } return true ; } </s>

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


<s>
bool
M88kAsmParser
::
ParseInstruction
(
ParseInstructionInfo
&
Info
,
StringRef
Name
,
SMLoc
NameLoc
,
OperandVector
&
Operands
)
{
Operands
.
push_back
(
M88kOperand
::
createToken
(
Name
,
NameLoc
)
)
;
if
(
getLexer
(
)
.
isNot
(
AsmToken
::
EndOfStatement
)
)
{
if
(
parseOperand
(
Operands
,
Name
)
)
{
return
Error
(
getLexer
(
)
.
getLoc
(
)
,
"expected operand"
)
;
}
if
(
getLexer
(
)
.
is
(
AsmToken
::
Comma
)
)
{
Parser
.
Lex
(
)
;
if
(
parseOperand
(
Operands
,
Name
)
)
{
return
Error
(
getLexer
(
)
.
getLoc
(
)
,
"expected operand"
)
;
}
if
(
getLexer
(
)
.
is
(
AsmToken
::
Comma
)
)
{
Parser
.
Lex
(
)
;
if
(
parseOperand
(
Operands
,
Name
)
)
{
return
Error
(
getLexer
(
)
.
getLoc
(
)
,
"expected operand"
)
;
}
}
else
if
(
getLexer
(
)
.
is
(
AsmToken
::
LBrac
)
)
{
if
(
parseScaledRegister
(
Operands
)
)
return
Error
(
getLexer
(
)
.
getLoc
(
)
,
"expected scaled register operand"
)
;
}
}
if
(
getLexer
(
)
.
isNot
(
AsmToken
::
EndOfStatement
)
)
return
Error
(
getLexer
(
)
.
getLoc
(
)
,
"unexpected token in argument list"
)
;
}
Parser
.
Lex
(
)
;
return
false
;
}
</s>

ParseInstruction - Parse one assembly instruction .


<s>
void
print
(
raw_ostream
&
OS
)
const
override
{
switch
(
Kind
)
{
case
OpKind_Imm
:
OS
<<
"Imm: "
<<
getImm
(
)
<<
"\n"
;
break
;
case
OpKind_Token
:
OS
<<
"Token: "
<<
getToken
(
)
<<
"\n"
;
break
;
case
OpKind_Reg
:
OS
<<
"Reg: "
;
OS
<<
"%r"
;
OS
<<
"\n"
;
break
;
}
}
</s>

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


<s> OperandMatchResultTy M88kAsmParser :: tryParseRegister ( unsigned & RegNo , SMLoc & StartLoc , SMLoc & EndLoc ) { bool Result = parseRegister ( RegNo , StartLoc , EndLoc , true ) ; bool PendingErrors = getParser ( ) . hasPendingError ( ) ; getParser ( ) . clearPendingErrors ( ) ; if ( PendingErrors ) return MatchOperand_ParseFail ; if ( Result ) return MatchOperand_NoMatch ; return MatchOperand_Success ; } </s>

tryParseRegister - parse one register if possible


<s> unsigned M88kAsmParser :: validateTargetOperandClass ( MCParsedAsmOperand & AsmOp , unsigned Kind ) { if ( Kind == MCK_GPR64RC && AsmOp . isReg ( ) ) { switch ( AsmOp . getReg ( ) ) { case M88k :: R0 : case M88k :: R2 : case M88k :: R4 : case M88k :: R6 : case M88k :: R8 : case M88k :: R10 : case M88k :: R12 : case M88k :: R14 : case M88k :: R16 : case M88k :: R18 : case M88k :: R20 : case M88k :: R22 : case M88k :: R24 : case M88k :: R26 : case M88k :: R28 : case M88k :: R30 : return Match_Success ; case M88k :: R1 : case M88k :: R3 : case M88k :: R5 : case M88k :: R7 : case M88k :: R9 : case M88k :: R11 : case M88k :: R13 : case M88k :: R15 : case M88k :: R17 : case M88k :: R19 : case M88k :: R21 : case M88k :: R23 : case M88k :: R25 : case M88k :: R27 : case M88k :: R29 : case M88k :: R31 : return Match_Success ; default : return Match_InvalidOperand ; } } return Match_InvalidOperand ; } </s>

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


<s> void M88kAsmPrinter :: emitInstruction ( const MachineInstr * MI ) { MachineBasicBlock :: const_instr_iterator I = MI -> getIterator ( ) ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; do { if ( I -> isBundle ( ) ) continue ; MCInst LoweredMI ; switch ( I -> getOpcode ( ) ) { case M88k :: RET : LoweredMI = MCInstBuilder ( M88k :: JMP ) . addReg ( M88k :: R1 ) ; break ; case M88k :: RETn : LoweredMI = MCInstBuilder ( M88k :: JMPn ) . addReg ( M88k :: R1 ) ; break ; default : M88kMCInstLower Lower ( MF -> getContext ( ) , * this ) ; Lower . lower ( & * I , LoweredMI ) ; break ; } EmitToStreamer ( * OutStreamer , LoweredMI ) ; } while ( ( ++ I != E ) && I -> isInsideBundle ( ) ) ; } </s>

Targets should implement this to emit instructions .


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

getPassName - Return a nice clean name for a pass .


<s> bool M88kAsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , const char * ExtraCode , raw_ostream & OS ) { if ( ExtraCode ) return AsmPrinter :: PrintAsmOperand ( MI , OpNo , ExtraCode , OS ) ; M88kMCInstLower Lower ( MF -> getContext ( ) , * this ) ; MCOperand MO ( Lower . lowerOperand ( MI -> getOperand ( OpNo ) ) ) ; M88kInstPrinter :: printOperand ( MO , MAI , OS ) ; return false ; } </s>

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


<s>
unsigned
M88kIncomingValueHandler
::
assignCustomValue
(
CallLowering
::
ArgInfo
&
Arg
,
ArrayRef
<
CCValAssign
>
VAs
,
std
::
function
<
void
(
)
>
*
Thunk
)
{
assert
(
Arg
.
Regs
.
size
(
)
==
1
&&
"Can't handle multple regs yet"
)
;
CCValAssign
VA
=
VAs
[
0
]
;
assert
(
VA
.
needsCustom
(
)
&&
"Value doesn't need custom handling"
)
;
if
(
VA
.
getValVT
(
)
!=
MVT
::
f64
)
return
0
;
CCValAssign
NextVA
=
VAs
[
1
]
;
assert
(
NextVA
.
needsCustom
(
)
&&
"Value doesn't need custom handling"
)
;
assert
(
NextVA
.
getValVT
(
)
==
MVT
::
f64
&&
"Unsupported type"
)
;
assert
(
VA
.
getValNo
(
)
==
NextVA
.
getValNo
(
)
&&
"Values belong to different arguments"
)
;
assert
(
VA
.
isRegLoc
(
)
&&
"Value should be in reg"
)
;
assert
(
NextVA
.
isRegLoc
(
)
&&
"Value should be in reg"
)
;
Register
NewRegs
[
]
=
{
MRI
.
createGenericVirtualRegister
(
LLT
::
scalar
(
32
)
)
,
MRI
.
createGenericVirtualRegister
(
LLT
::
scalar
(
32
)
)
}
;
assignValueToReg
(
NewRegs
[
0
]
,
VA
.
getLocReg
(
)
,
VA
)
;
assignValueToReg
(
NewRegs
[
1
]
,
NextVA
.
getLocReg
(
)
,
NextVA
)
;
MIRBuilder
.
buildMerge
(
Arg
.
Regs
[
0
]
,
NewRegs
)
;
return
1
;
}
</s>

Handle custom values , which may be passed into one or more of VAs .


<s> void M88kIncomingValueHandler :: assignValueToAddress ( Register ValVReg , Register Addr , LLT MemTy , MachinePointerInfo & MPO , CCValAssign & VA ) { MachineFunction & MF = MIRBuilder . getMF ( ) ; auto * MMO = MF . getMachineMemOperand ( MPO , MachineMemOperand :: MOLoad , MemTy , inferAlignFromPtrInfo ( MF , MPO ) ) ; MIRBuilder . buildLoad ( ValVReg , Addr , * MMO ) ; } </s>

An overload which takes an ArgInfo if additional information about the arg is needed .


<s>
void
M88kIncomingValueHandler
::
assignValueToReg
(
Register
ValVReg
,
Register
PhysReg
,
CCValAssign
VA
)
{
assert
(
VA
.
isRegLoc
(
)
&&
"Value shouldn't be assigned to reg"
)
;
assert
(
VA
.
getLocReg
(
)
==
PhysReg
&&
"Assigning to the wrong reg?"
)
;
uint64_t
ValSize
=
VA
.
getValVT
(
)
.
getFixedSizeInBits
(
)
;
uint64_t
LocSize
=
VA
.
getLocVT
(
)
.
getFixedSizeInBits
(
)
;
assert
(
ValSize
<=
64
&&
"Unsupported value size"
)
;
assert
(
LocSize
<=
64
&&
"Unsupported location size"
)
;
markPhysRegUsed
(
PhysReg
)
;
if
(
ValSize
==
LocSize
)
{
MIRBuilder
.
buildCopy
(
ValVReg
,
PhysReg
)
;
}
else
{
assert
(
ValSize
<
LocSize
&&
"Extensions not supported"
)
;
auto
PhysRegToVReg
=
MIRBuilder
.
buildCopy
(
LLT
::
scalar
(
LocSize
)
,
PhysReg
)
;
MIRBuilder
.
buildTrunc
(
ValVReg
,
PhysRegToVReg
)
;
}
}
</s>

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


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

For targets which want to use big-endian can enable it with enableBigEndian ( ) hook .


<s> Register M88kIncomingValueHandler :: getStackAddress ( uint64_t Size , int64_t Offset , MachinePointerInfo & MPO , ISD :: ArgFlagsTy Flags ) { auto & MFI = MIRBuilder . getMF ( ) . getFrameInfo ( ) ; const bool IsImmutable = ! Flags . isByVal ( ) ; int FI = MFI . CreateFixedObject ( Size , Offset , IsImmutable ) ; MPO = MachinePointerInfo :: getFixedStack ( MIRBuilder . getMF ( ) , FI ) ; llvm :: LLT FramePtr = LLT :: pointer ( 0 , 32 ) ; MachineInstrBuilder AddrReg = MIRBuilder . buildFrameIndex ( FramePtr , FI ) ; return AddrReg . getReg ( 0 ) ; } </s>

Materialize a VReg containing the address of the specified stack-based object .


<s> bool M88kCallLowering :: lowerCall ( MachineIRBuilder & MIRBuilder , CallLoweringInfo & Info ) const { MachineFunction & MF = MIRBuilder . getMF ( ) ; const Function & F = MF . getFunction ( ) ; MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; auto & DL = F . getParent ( ) -> getDataLayout ( ) ; SmallVector < ArgInfo , 8 > OutArgs ; for ( auto & OrigArg : Info . OrigArgs ) { splitToValueTypes ( OrigArg , OutArgs , DL , Info . CallConv ) ; } SmallVector < ArgInfo , 8 > InArgs ; if ( ! Info . OrigRet . Ty -> isVoidTy ( ) ) splitToValueTypes ( Info . OrigRet , InArgs , DL , Info . CallConv ) ; MachineInstrBuilder CallSeqStart ; CallSeqStart = MIRBuilder . buildInstr ( M88k :: ADJCALLSTACKDOWN ) ; unsigned Opc = Info . Callee . isReg ( ) ? M88k :: JSR : M88k :: BSR ; auto MIB = MIRBuilder . buildInstrNoInsert ( Opc ) ; MIB . add ( Info . Callee ) ; const uint32_t * Mask ; const M88kSubtarget & Subtarget = MF . getSubtarget < M88kSubtarget > ( ) ; const auto * TRI = Subtarget . getRegisterInfo ( ) ; OutgoingValueAssigner ArgAssigner ( CC_M88k ) ; OutgoingArgHandler Handler ( MIRBuilder , MRI , MIB ) ; if ( ! determineAndHandleAssignments ( Handler , ArgAssigner , OutArgs , MIRBuilder , Info . CallConv , Info . IsVarArg ) ) return false ; Mask = TRI -> getCallPreservedMask ( MF , Info . CallConv ) ; MIB . addRegMask ( Mask ) ; MIRBuilder . insertInstr ( MIB ) ; if ( Info . Callee . isReg ( ) ) constrainOperandRegClass ( MF , * TRI , MRI , * Subtarget . getInstrInfo ( ) , * Subtarget . getRegBankInfo ( ) , * MIB , MIB -> getDesc ( ) , Info . Callee , 0 ) ; if ( ! Info . OrigRet . Ty -> isVoidTy ( ) ) { OutgoingValueAssigner ArgAssigner ( RetCC_M88k ) ; CallReturnHandler ReturnedArgHandler ( MIRBuilder , MRI , MIB ) ; if ( ! determineAndHandleAssignments ( ReturnedArgHandler , ArgAssigner , InArgs , MIRBuilder , Info . CallConv , Info . IsVarArg , OutArgs [ 0 ] . Regs [ 0 ] ) ) return false ; } CallSeqStart . addImm ( ArgAssigner . StackOffset ) . addImm ( 0 ) ; MIRBuilder . buildInstr ( M88k :: ADJCALLSTACKUP ) . addImm ( ArgAssigner . StackOffset ) . addImm ( 0 ) ; return true ; } </s>

This hook must be implemented to lower the given call instruction , including argument and return value marshalling .


<s> bool M88kCallLowering :: lowerFormalArguments ( MachineIRBuilder & MIRBuilder , const Function & F , ArrayRef < ArrayRef < Register >> VRegs , FunctionLoweringInfo & FLI ) const { MachineFunction & MF = MIRBuilder . getMF ( ) ; MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; const auto & DL = F . getParent ( ) -> getDataLayout ( ) ; SmallVector < ArgInfo , 8 > SplitArgs ; unsigned I = 0 ; for ( const auto & Arg : F . args ( ) ) { ArgInfo OrigArg { VRegs [ I ] , Arg . getType ( ) , I } ; setArgFlags ( OrigArg , I + AttributeList :: FirstArgIndex , DL , F ) ; splitToValueTypes ( OrigArg , SplitArgs , DL , F . getCallingConv ( ) ) ; ++ I ; } IncomingValueAssigner ArgAssigner ( CC_M88k ) ; FormalArgHandler ArgHandler ( MIRBuilder , MRI ) ; return determineAndHandleAssignments ( ArgHandler , ArgAssigner , SplitArgs , MIRBuilder , F . getCallingConv ( ) , F . isVarArg ( ) ) ; } </s>

This hook must be implemented to lower the incoming ( formal ) arguments , described by VRegs , for GlobalISel .


<s> bool M88kCallLowering :: lowerReturn ( MachineIRBuilder & MIRBuilder , const Value * Val , ArrayRef < Register > VRegs , FunctionLoweringInfo & FLI , Register SwiftErrorVReg ) const { MachineFunction & MF = MIRBuilder . getMF ( ) ; const Function & F = MF . getFunction ( ) ; MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; const M88kSubtarget & STI = MF . getSubtarget < M88kSubtarget > ( ) ; const M88kInstrInfo & TII = * STI . getInstrInfo ( ) ; auto & DL = F . getParent ( ) -> getDataLayout ( ) ; Register ReturnAddrVReg = getFunctionLiveInPhysReg ( MF , TII , M88k :: R1 , M88k :: GPRRCRegClass , MIRBuilder . getDebugLoc ( ) ) ; MRI . setType ( ReturnAddrVReg , LLT :: pointer ( 0 , 32 ) ) ; auto MIB = MIRBuilder . buildInstrNoInsert ( M88k :: RET ) ; bool Success = true ; if ( ! VRegs . empty ( ) ) { SmallVector < ArgInfo , 8 > SplitArgs ; ArgInfo OrigArg { VRegs , Val -> getType ( ) , 0 } ; setArgFlags ( OrigArg , AttributeList :: ReturnIndex , DL , F ) ; splitToValueTypes ( OrigArg , SplitArgs , DL , F . getCallingConv ( ) ) ; OutgoingValueAssigner ArgAssigner ( RetCC_M88k ) ; OutgoingArgHandler ArgHandler ( MIRBuilder , MRI , MIB ) ; Success = determineAndHandleAssignments ( ArgHandler , ArgAssigner , SplitArgs , MIRBuilder , F . getCallingConv ( ) , F . isVarArg ( ) ) ; } MIRBuilder . buildCopy ( M88k :: R1 , ReturnAddrVReg ) ; MIRBuilder . insertInstr ( MIB ) ; return Success ; } </s>

This hook behaves as the extended lowerReturn function , but for targets that do not support swifterror value promotion .


<s> bool M88kDelaySlotFiller :: runOnMachineFunction ( MachineFunction & MF ) { const M88kSubtarget & Subtarget = MF . getSubtarget < M88kSubtarget > ( ) ; TII = Subtarget . getInstrInfo ( ) ; TRI = Subtarget . getRegisterInfo ( ) ; bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) Changed |= runOnMachineBasicBlock ( MBB ) ; return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s> DecodeStatus M88kDisassembler :: getInstruction ( MCInst & MI , uint64_t & Size , ArrayRef < uint8_t > Bytes , uint64_t Address , raw_ostream & CS ) const { if ( Bytes . size ( ) < 4 ) { Size = 0 ; return MCDisassembler :: Fail ; } Size = 4 ; uint32_t Inst = 0 ; for ( uint32_t I = 0 ; I < Size ; ++ I ) Inst = ( Inst << 8 ) | Bytes [ I ] ; return decodeInstruction ( DecoderTableM88k32 , MI , Inst , Address , this , STI ) ; } </s>

Returns the disassembly of a single instruction .


<s> bool M88kFrameLowering :: assignCalleeSavedSpillSlots ( MachineFunction & MF , const TargetRegisterInfo * TRI , std :: vector < CalleeSavedInfo > & CSI ) const { MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; int64_t CurOffset = - 4 ; for ( auto & CS : CSI ) { Register Reg = CS . getReg ( ) ; if ( M88k :: GPRRCRegClass . contains ( Reg ) ) { CS . setFrameIdx ( MFI . CreateFixedSpillStackObject ( 4 , CurOffset ) ) ; CurOffset -= 4 ; } else { const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( Reg ) ; Align Alignment = TRI -> getSpillAlign ( * RC ) ; unsigned Size = TRI -> getSpillSize ( * RC ) ; Alignment = std :: min ( Alignment , getStackAlign ( ) ) ; CS . setFrameIdx ( MFI . CreateSpillStackObject ( Size , Alignment ) ) ; } } return true ; } </s>

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


<s> void M88kFrameLowering :: determineCalleeSaves ( MachineFunction & MF , BitVector & SavedRegs , RegScavenger * RS ) const { TargetFrameLowering :: determineCalleeSaves ( MF , SavedRegs , RS ) ; MachineFrameInfo & MFFrame = MF . getFrameInfo ( ) ; if ( MFFrame . hasCalls ( ) ) SavedRegs . set ( M88k :: R1 ) ; if ( hasFP ( MF ) ) SavedRegs . set ( M88k :: R30 ) ; } </s>

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


<s> MachineBasicBlock :: iterator M88kFrameLowering :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { return 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 ) .


<s> void M88kFrameLowering :: emitEpilogue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const M88kInstrInfo & LII = * static_cast < const M88kInstrInfo * > ( STI . getInstrInfo ( ) ) ; MachineBasicBlock :: iterator MBBI = MBB . getLastNonDebugInstr ( ) ; DebugLoc DL = MBBI -> getDebugLoc ( ) ; unsigned StackSize = MFI . getStackSize ( ) ; if ( StackSize ) { BuildMI ( MBB , MBBI , DL , LII . get ( M88k :: ADDUri ) ) . addReg ( M88k :: R31 , RegState :: Define ) . addReg ( M88k :: R31 ) . addImm ( StackSize ) . setMIFlag ( MachineInstr :: FrameDestroy ) ; } } </s>


"Larger stack frame not yet implemented"

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


<s> StackOffset M88kFrameLowering :: getFrameIndexReference ( const MachineFunction & MF , int FI , Register & FrameReg ) const { return StackOffset :: getFixed ( resolveFrameIndexReference ( MF , FI , FrameReg ) ) ; } </s>

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


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

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


<s> bool M88kFrameLowering :: hasReservedCallFrame ( const MachineFunction & MF ) const { return true ; } </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>
void
M88kFrameLowering
::
processFunctionBeforeFrameFinalized
(
MachineFunction
&
MF
,
RegScavenger
*
RS
)
const
{
MachineFrameInfo
&
MFI
=
MF
.
getFrameInfo
(
)
;
assert
(
MFI
.
isMaxCallFrameSizeComputed
(
)
&&
"MaxCallFrame not computed"
)
;
unsigned
MaxCallFrameSize
=
MFI
.
getMaxCallFrameSize
(
)
;
MaxCallFrameSize
=
alignTo
(
MaxCallFrameSize
,
getStackAlign
(
)
)
;
MFI
.
setMaxCallFrameSize
(
MaxCallFrameSize
)
;
}
</s>

processFunctionBeforeFrameFinalized - This method is called immediately before the specified function 's frame layout ( MF.getFrameInfo ( ) ) is finalized .


<s> bool M88kFrameLowering :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , MutableArrayRef < CalleeSavedInfo > CSI , const TargetRegisterInfo * TRI ) const { return false ; } </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 M88kFrameLowering :: spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , ArrayRef < CalleeSavedInfo > CSI , const TargetRegisterInfo * TRI ) const { MachineFunction * MF = MBB . getParent ( ) ; const TargetSubtargetInfo & STI = MF -> getSubtarget ( ) ; const TargetInstrInfo * TII = STI . getInstrInfo ( ) ; const Register RAReg = STI . getRegisterInfo ( ) -> getRARegister ( ) ; for ( auto & CS : CSI ) { Register Reg = CS . getReg ( ) ; if ( ! MBB . isLiveIn ( Reg ) ) MBB . addLiveIn ( Reg ) ; if ( Reg != M88k :: R1 && Reg != M88k :: R30 ) { const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( Reg ) ; TII -> storeRegToStackSlot ( MBB , MBBI , Reg , true , CS . getFrameIdx ( ) , RC , TRI ) ; } } 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> inline bool isShiftedMask ( uint64_t I , uint64_t & Width , uint64_t & Offset ) { if ( ! isShiftedMask_64 ( I ) ) return false ; Width = countPopulation ( I ) ; Offset = countTrailingZeros ( I ) ; return true ; } </s>

Return true if this APInt value contains a non-empty sequence of ones with the remainder zero .


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

Print the specified MCInst to the specified raw_ostream .


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

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


<s>
void
M88kInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MBBI
,
const
DebugLoc
&
DL
,
MCRegister
DestReg
,
MCRegister
SrcReg
,
bool
KillSrc
)
const
{
if
(
M88k
::
GPR64RCRegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
copyPhysReg
(
MBB
,
MBBI
,
DL
,
RI
.
getSubReg
(
DestReg
,
M88k
::
sub_hi
)
,
RI
.
getSubReg
(
SrcReg
,
M88k
::
sub_hi
)
,
KillSrc
)
;
MachineInstrBuilder
(
*
MBB
.
getParent
(
)
,
std
::
prev
(
MBBI
)
)
.
addReg
(
SrcReg
,
RegState
::
Implicit
)
;
copyPhysReg
(
MBB
,
MBBI
,
DL
,
RI
.
getSubReg
(
DestReg
,
M88k
::
sub_lo
)
,
RI
.
getSubReg
(
SrcReg
,
M88k
::
sub_lo
)
,
KillSrc
)
;
MachineInstrBuilder
(
*
MBB
.
getParent
(
)
,
std
::
prev
(
MBBI
)
)
.
addReg
(
SrcReg
,
(
getKillRegState
(
KillSrc
)
|
RegState
::
Implicit
)
)
;
return
;
}
if
(
M88k
::
GPRRCRegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
M88k
::
ORrr
)
,
DestReg
)
.
addReg
(
M88k
::
R0
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
return
;
}
unsigned
Opc
;
if
(
M88k
::
XRRCRegClass
.
contains
(
DestReg
,
SrcReg
)
)
Opc
=
M88k
::
MOVxx
;
else
if
(
M88k
::
GPRRCRegClass
.
contains
(
DestReg
)
&&
M88k
::
XRRCRegClass
.
contains
(
SrcReg
)
)
Opc
=
M88k
::
MOVrxs
;
else
if
(
M88k
::
GPR64RCRegClass
.
contains
(
DestReg
)
&&
M88k
::
XRRCRegClass
.
contains
(
SrcReg
)
)
Opc
=
M88k
::
MOVrxd
;
else
if
(
M88k
::
XRRCRegClass
.
contains
(
DestReg
)
&&
M88k
::
GPRRCRegClass
.
contains
(
SrcReg
)
)
Opc
=
M88k
::
MOVxrs
;
else
if
(
M88k
::
XRRCRegClass
.
contains
(
DestReg
)
&&
M88k
::
GPR64RCRegClass
.
contains
(
SrcReg
)
)
Opc
=
M88k
::
MOVxrd
;
else
llvm_unreachable
(
"m88: Impossible reg-to-reg copy"
)
;
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
Opc
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
</s>


<s> std :: pair < unsigned , unsigned > M88kInstrInfo :: 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> unsigned M88kInstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { if ( MI . isInlineAsm ( ) ) { const MachineFunction * MF = MI . getParent ( ) -> getParent ( ) ; const char * AsmStr = MI . getOperand ( 0 ) . getSymbolName ( ) ; return getInlineAsmLength ( AsmStr , * MF -> getTarget ( ) . getMCAsmInfo ( ) ) ; } return MI . getDesc ( ) . getSize ( ) ; } </s>

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


<s> static MachineMemOperand * getMachineMemOperand ( MachineBasicBlock & MBB , int FI , MachineMemOperand :: Flags Flags ) { MachineFunction & MF = * MBB . getParent ( ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; return MF . getMachineMemOperand ( MachinePointerInfo :: getFixedStack ( MF , FI ) , Flags , MFI . getObjectSize ( FI ) , MFI . getObjectAlign ( FI ) ) ; } </s>

Allocate a new MachineMemOperand by copying an existing one , replacing the flags .


<s> MCInst M88kInstrInfo :: getNop ( ) const { return MCInstBuilder ( M88k :: ORrr ) . addReg ( M88k :: R0 ) . addReg ( M88k :: R0 ) . addReg ( M88k :: R0 ) ; } </s>

Return the noop instruction to use for a noop .


<s> const M88kRegisterInfo & 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 .


"insertBranch must not be told to insert a fallthrough"

"wrong number of m88k branch conditions"

Insert branch code into the end of the specified MachineBasicBlock .


"RegScavenger required for long branching"

"new block should be inserted for expanding unconditional branch"

Insert an unconditional indirect branch at the end of MBB to NewDestBB .


<s> void M88kInstrInfo :: insertNoop ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI ) const { DebugLoc DL ; BuildMI ( MBB , MI , DL , get ( M88k :: ORrr ) , M88k :: R0 ) . addReg ( M88k :: R0 ) . addReg ( M88k :: R0 ) ; } </s>

Insert a noop into the instruction stream at the specified point .


<s>
bool
M88kInstrInfo
::
isBranchOffsetInRange
(
unsigned
BranchOpc
,
int64_t
BrOffset
)
const
{
assert
(
isAnalyzableBranchOpc
(
BranchOpc
)
&&
"Unexpected branch opcode"
)
;
int
Bits
=
(
BranchOpc
==
M88k
::
BR
||
BranchOpc
==
M88k
::
BSR
)
26
:
16
;
return
isIntN
(
Bits
,
BrOffset
/
4
)
;
}
</s>

Determine if the branch target is in range .


<s> Optional < DestSourcePair > M88kInstrInfo :: isCopyInstrImpl ( const MachineInstr & MI ) const { if ( MI . isMoveReg ( ) || ( MI . getOpcode ( ) == M88k :: ORri && MI . getOperand ( 2 ) . getImm ( ) == 0 ) ) return DestSourcePair { MI . getOperand ( 0 ) , MI . getOperand ( 1 ) } ; if ( MI . getOpcode ( ) == M88k :: ORrr ) { if ( MI . getOperand ( 2 ) . getReg ( ) == M88k :: R0 ) return DestSourcePair { MI . getOperand ( 0 ) , MI . getOperand ( 1 ) } ; if ( MI . getOperand ( 1 ) . getReg ( ) == M88k :: R0 ) return DestSourcePair { MI . getOperand ( 0 ) , MI . getOperand ( 2 ) } ; } return None ; } </s>

If the specific machine instruction is a instruction that moves/copies value from one register to another register return destination and source registers as machine operands .


<s> unsigned M88kInstrInfo :: isLoadFromStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { case M88k :: LDrib : case M88k :: LDrih : case M88k :: LDriw : case M88k :: LDrid : case M88k :: LDrrsb : case M88k :: LDrrsbu : case M88k :: LDrrsd : case M88k :: LDrrsdu : case M88k :: LDrrsh : case M88k :: LDrrshu : case M88k :: LDrrsw : case M88k :: LDrrswu : case M88k :: LDrrub : case M88k :: LDrrubu : case M88k :: LDrrud : case M88k :: LDrrudu : case M88k :: LDrruh : case M88k :: LDrruhu : case M88k :: LDrruw : case M88k :: LDrruwu : if ( MI . getOperand ( 1 ) . isFI ( ) ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

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


<s> unsigned M88kInstrInfo :: isStoreToStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { case M88k :: STrib : case M88k :: STrih : case M88k :: STriw : case M88k :: STrid : case M88k :: STrrsb : case M88k :: STrrsbt : case M88k :: STrrsbu : case M88k :: STrrsbut : case M88k :: STrrsd : case M88k :: STrrsdt : case M88k :: STrrsdu : case M88k :: STrrsdut : case M88k :: STrrsh : case M88k :: STrrsht : case M88k :: STrrshu : case M88k :: STrrshut : case M88k :: STrrsw : case M88k :: STrrswt : case M88k :: STrrswu : case M88k :: STrrswut : case M88k :: STrrub : case M88k :: STrrubt : case M88k :: STrrubu : case M88k :: STrrubut : case M88k :: STrrud : case M88k :: STrrudt : case M88k :: STrrudu : case M88k :: STrrudut : case M88k :: STrruh : case M88k :: STrruht : case M88k :: STrruhu : case M88k :: STrruhut : case M88k :: STrruw : case M88k :: STrruwt : case M88k :: STrruwu : case M88k :: STrruwut : case M88k :: STxid : case M88k :: STxis : case M88k :: STxix : case M88k :: STxrd : case M88k :: STxrdt : case M88k :: STxrdu : case M88k :: STxrdut : case M88k :: STxrss : case M88k :: STxrsst : case M88k :: STxrssu : case M88k :: STxrssut : case M88k :: STxrsx : case M88k :: STxrsxt : case M88k :: STxrsxu : case M88k :: STxrsxut : case M88k :: STxrud : case M88k :: STxrudt : case M88k :: STxrudu : case M88k :: STxrudut : case M88k :: STxrus : case M88k :: STxrust : case M88k :: STxrusu : case M88k :: STxrusut : case M88k :: STxrux : case M88k :: STxruxt : case M88k :: STxruxu : case M88k :: STxruxut : if ( MI . getOperand ( 1 ) . isFI ( ) ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } 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 M88kInstrInfo :: loadRegFromStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , Register DestReg , int FrameIndex , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { DebugLoc DL ; MachineMemOperand * MMO = getMachineMemOperand ( MBB , FrameIndex , MachineMemOperand :: MOLoad ) ; BuildMI ( MBB , MBBI , DL , get ( M88k :: LDriw ) ) . addReg ( DestReg , RegState :: Define ) . addFrameIndex ( FrameIndex ) . addImm ( 0 ) . addMemOperand ( MMO ) ; } </s>

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


<s> unsigned M88kInstrInfo :: removeBranch ( MachineBasicBlock & MBB , int * BytesRemoved ) const { if ( BytesRemoved ) * BytesRemoved = 0 ; MachineBasicBlock :: iterator I = MBB . getLastNonDebugInstr ( ) ; if ( I == MBB . end ( ) ) return 0 ; if ( ! I -> getDesc ( ) . isUnconditionalBranch ( ) && ! I -> getDesc ( ) . isConditionalBranch ( ) ) return 0 ; if ( BytesRemoved ) * BytesRemoved += getInstSizeInBytes ( * I ) ; I -> eraseFromParent ( ) ; I = MBB . end ( ) ; if ( I == MBB . begin ( ) ) return 1 ; -- I ; if ( ! I -> getDesc ( ) . isConditionalBranch ( ) ) return 1 ; if ( BytesRemoved ) * BytesRemoved += getInstSizeInBytes ( * I ) ; I -> eraseFromParent ( ) ; return 2 ; } </s>

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


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


<s> void M88kInstrInfo :: storeRegToStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , Register SrcReg , bool isKill , int FrameIndex , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { DebugLoc DL ; MachineMemOperand * MMO = getMachineMemOperand ( MBB , FrameIndex , MachineMemOperand :: MOStore ) ; BuildMI ( MBB , MBBI , DL , get ( M88k :: STriw ) ) . addReg ( SrcReg , getKillRegState ( isKill ) ) . addFrameIndex ( FrameIndex ) . addImm ( 0 ) . addMemOperand ( MMO ) ; } </s>

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


<s> static const char * getName ( ) { return DEBUG_TYPE ; } </s>

Return a string with the name of the plan and the applicable VFs and UFs .


"Instruction should be in a basic block!"

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


<s> void M88kMCAsmBackend :: applyFixup ( const MCAssembler & Asm , const MCFixup & Fixup , const MCValue & Target , MutableArrayRef < char > Data , uint64_t Value , bool IsResolved , const MCSubtargetInfo * STI ) const { MCFixupKind Kind = Fixup . getKind ( ) ; unsigned Offset = Fixup . getOffset ( ) ; unsigned NumBytes = ( getFixupKindInfo ( Kind ) . TargetSize + 7 ) / 8 ; unsigned FullSize = 4 ; uint64_t CurVal = 0 ; for ( unsigned i = 0 ; i != NumBytes ; ++ i ) { unsigned Idx = ( FullSize - 1 - i ) ; CurVal |= static_cast < uint64_t > ( static_cast < uint8_t > ( Data [ Offset + Idx ] ) ) << ( i * 8 ) ; } uint64_t Mask = ( static_cast < uint64_t > ( - 1 ) >> ( 64 - getFixupKindInfo ( Kind ) . TargetSize ) ) ; CurVal |= Value & Mask ; for ( unsigned i = 0 ; i != NumBytes ; ++ i ) { unsigned Idx = ( FullSize - 1 - i ) ; Data [ Offset + Idx ] = static_cast < uint8_t > ( ( CurVal >> ( i * 8 ) ) & 0xff ) ; } } </s>

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


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

Simple predicate for targets where ! Resolved implies requiring relaxation .


<s> Optional < MCFixupKind > M88kMCAsmBackend :: getFixupKind ( StringRef Name ) const { unsigned Type = llvm :: StringSwitch < unsigned > ( Name ) . Default ( - 1u ) ; if ( Type != - 1u ) return static_cast < MCFixupKind > ( FirstLiteralRelocationKind + Type ) ; return None ; } </s>

getFixupKind - Get the fixup kind of this expression .


<s>
const
MCFixupKindInfo
&
M88kMCAsmBackend
::
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
static
const
MCFixupKindInfo
Infos
[
M88k
::
NumTargetFixupKinds
]
=
{
{
"FK_88K_NONE"
,
0
,
32
,
0
}
,
{
"FK_88K_DISP16"
,
16
,
16
,
0
}
,
{
"FK_88K_DISP26"
,
6
,
26
,
0
}
,
{
"FK_88K_HI"
,
16
,
16
,
0
}
,
{
"FK_88K_LO"
,
16
,
16
,
0
}
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s> unsigned M88kMCAsmBackend :: getNumFixupKinds ( ) const { return M88k :: NumTargetFixupKinds ; } </s>

Get the number of target specific fixup kinds .


<s> bool M88kMCAsmBackend :: mayNeedRelaxation ( const MCInst & Inst , const MCSubtargetInfo & STI ) const { return false ; } </s>

Check whether the given instruction may need relaxation .


<s> bool M88kMCAsmBackend :: shouldForceRelocation ( const MCAssembler & Asm , const MCFixup & Fixup , const MCValue & Target ) { return Fixup . getKind ( ) == M88k :: FK_88K_DISP16 || Fixup . getKind ( ) == M88k :: FK_88K_DISP26 ; } </s>

Hook to check if a relocation is needed for some target specific reason .


<s> bool M88kMCAsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count , const MCSubtargetInfo * STI ) const { if ( ( Count % 4 ) != 0 ) return false ; for ( uint64_t I = 0 ; I != Count ; ++ I ) OS << "\xf4\x00\x58\x00" ; return true ; } </s>

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


<s>
void
M88kMCCodeEmitter
::
encodeInstruction
(
const
MCInst
&
MI
,
raw_ostream
&
OS
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
uint64_t
Bits
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
assert
(
MCII
.
get
(
MI
.
getOpcode
(
)
)
.
getSize
(
)
==
4
&&
"Unexpected instr length"
)
;
for
(
int
I
=
(
4
1
)
*
8
;
I
>=
0
;
I
-=
8
)
OS
<<
static_cast
<
uint8_t
>
(
(
Bits
>>
I
)
&
0xff
)
;
}
</s>

Encode the given Inst to bytes and append to CB .


<s>
unsigned
M88kMCCodeEmitter
::
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
<
uint64_t
>
(
MO
.
getImm
(
)
)
;
assert
(
MO
.
isExpr
(
)
&&
"Expected MCExpr"
)
;
const
MCExpr
*
Expr
=
MO
.
getExpr
(
)
;
assert
(
isa
<
M88kMCExpr
>
(
Expr
)
&&
"Expected M88kMCExpr"
)
;
const
uint32_t
Offset
=
2
;
Fixups
.
push_back
(
MCFixup
::
create
(
Offset
,
Expr
,
MCFixupKind
(
FixupKind
(
Expr
)
)
)
)
;
return
0
;
}
</s>

getMachineOpValue - Return binary encoding of operand .


<s> static bool classof ( const MCExpr * E ) { return E -> getKind ( ) == MCExpr :: Target ; } </s>

Methods for support type inquiry through isa , cast , and dyn_cast :


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


<s> MCFragment * findAssociatedFragment ( ) const override { return getSubExpr ( ) -> findAssociatedFragment ( ) ; } </s>

Find the `` associated section '' for this expression , which is currently defined as the absolute section for constants , or otherwise the section associated with the first defined symbol in the expression .


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


<s> const MCExpr * getSubExpr ( ) const { return Expr ; } </s>

getSubExpr - Get the child of this expression .


<s> void M88kMCInstLower :: lower ( const MachineInstr * MI , MCInst & OutMI ) const { OutMI . setOpcode ( MI -> getOpcode ( ) ) ; for ( unsigned I = 0 , E = MI -> getNumOperands ( ) ; I != E ; ++ I ) { const MachineOperand & MO = MI -> getOperand ( I ) ; if ( ( ! MO . isReg ( ) || ! MO . isImplicit ( ) ) && ! MO . isRegMask ( ) ) OutMI . addOperand ( lowerOperand ( MO ) ) ; } } </s>


<s>
MCOperand
M88kMCInstLower
::
lowerOperand
(
const
MachineOperand
&
MO
)
const
{
switch
(
MO
.
getType
(
)
)
{
case
MachineOperand
::
MO_Register
:
return
MCOperand
::
createReg
(
MO
.
getReg
(
)
)
;
case
MachineOperand
::
MO_Immediate
:
return
MCOperand
::
createImm
(
MO
.
getImm
(
)
)
;
case
MachineOperand
::
MO_MachineBasicBlock
:
case
MachineOperand
::
MO_GlobalAddress
:
case
MachineOperand
::
MO_ExternalSymbol
:
case
MachineOperand
::
MO_MCSymbol
:
case
MachineOperand
::
MO_JumpTableIndex
:
case
MachineOperand
::
MO_ConstantPoolIndex
:
case
MachineOperand
::
MO_BlockAddress
:
return
lowerSymbolOperand
(
MO
)
;
default
:
report_fatal_error
(
"Unexpected MachineOperand type."
)
;
}
}
</s>

Wrapper for MCInstLowering.lowerOperand ( ) for the tblgen'erated pseudo lowering .


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


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

getPassName - Return a nice clean name for a pass .


<s>
bool
M88kPostLegalizerLowering
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
MF
.
getProperties
(
)
.
hasProperty
(
MachineFunctionProperties
::
Property
::
FailedISel
)
)
return
false
;
assert
(
MF
.
getProperties
(
)
.
hasProperty
(
MachineFunctionProperties
::
Property
::
Legalized
)
&&
"Expected a legalized function?"
)
;
auto
*
TPC
=
&
getAnalysis
<
TargetPassConfig
>
(
)
;
const
Function
&
F
=
MF
.
getFunction
(
)
;
M88kPostLegalizerLoweringInfo
PCInfo
(
F
.
hasOptSize
(
)
,
F
.
hasMinSize
(
)
)
;
Combiner
C
(
PCInfo
,
TPC
)
;
return
C
.
combineMachineInstrs
(
MF
,
nullptr
)
;
}
</s>

runOnMachineFunction - Emit the function body .


<s> void M88kPreLegalizerCombiner :: getAnalysisUsage ( AnalysisUsage & AU ) const { AU . addRequired < TargetPassConfig > ( ) ; AU . setPreservesCFG ( ) ; getSelectionDAGFallbackAnalysisUsage ( AU ) ; AU . addRequired < GISelKnownBitsAnalysis > ( ) ; AU . addPreserved < GISelKnownBitsAnalysis > ( ) ; AU . addRequired < MachineDominatorTree > ( ) ; AU . addPreserved < MachineDominatorTree > ( ) ; AU . addRequired < GISelCSEAnalysisWrapperPass > ( ) ; AU . addPreserved < GISelCSEAnalysisWrapperPass > ( ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ; } </s>


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


<s> bool M88kPreLegalizerCombiner :: runOnMachineFunction ( MachineFunction & MF ) { if ( MF . getProperties ( ) . hasProperty ( MachineFunctionProperties :: Property :: FailedISel ) ) return false ; auto & TPC = getAnalysis < TargetPassConfig > ( ) ; GISelCSEAnalysisWrapper & Wrapper = getAnalysis < GISelCSEAnalysisWrapperPass > ( ) . getCSEWrapper ( ) ; auto * CSEInfo = & Wrapper . get ( TPC . getCSEConfig ( ) ) ; const Function & F = MF . getFunction ( ) ; bool EnableOpt = MF . getTarget ( ) . getOptLevel ( ) != CodeGenOpt :: None && ! skipFunction ( F ) ; GISelKnownBits * KB = & getAnalysis < GISelKnownBitsAnalysis > ( ) . get ( MF ) ; MachineDominatorTree * MDT = & getAnalysis < MachineDominatorTree > ( ) ; M88kPreLegalizerCombinerInfo PCInfo ( EnableOpt , F . hasOptSize ( ) , F . hasMinSize ( ) , KB , MDT ) ; Combiner C ( PCInfo , & TPC ) ; return C . combineMachineInstrs ( MF , CSEInfo ) ; } </s>


<s> void M88kRegisterBankInfo :: applyMappingImpl ( const OperandsMapper & OpdMapper ) const { return applyDefaultMapping ( OpdMapper ) ; } </s>


"This code is for instructions with 3 or less operands"


<s>
const
RegisterBank
&
M88kRegisterBankInfo
::
getRegBankFromRegClass
(
const
TargetRegisterClass
&
RC
,
LLT
Ty
)
const
{
switch
(
RC
.
getID
(
)
)
{
case
M88k
::
GPRRCRegClassID
:
case
M88k
::
GPR64RCRegClassID
:
return
getRegBank
(
M88k
::
GRRegBankID
)
;
case
M88k
::
XRRCRegClassID
:
return
getRegBank
(
M88k
::
XRRegBankID
)
;
default
:
llvm_unreachable
(
"Unexpected register class"
)
;
}
}
</s>


"m88k: Larger offsets not yet supported."

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


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


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

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


<s> Register M88kRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { if ( getFrameLowering ( MF ) -> hasFP ( MF ) ) return M88k :: R30 ; return M88k :: R31 ; } </s>


<s> const TargetRegisterClass * M88kRegisterInfo :: getPointerRegClass ( const MachineFunction & MF , unsigned Kind ) const { return & M88k :: GPRRCRegClass ; } </s>

getPointerRegClass - Returns a TargetRegisterClass used for pointer values .


<s> BitVector M88kRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( M88k :: R0 ) ; Reserved . set ( M88k :: R28 ) ; Reserved . set ( M88k :: R29 ) ; Reserved . set ( M88k :: R31 ) ; if ( getFrameLowering ( MF ) -> hasFP ( MF ) ) Reserved . set ( M88k :: R30 ) ; return Reserved ; } </s>

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


<s> const CallLowering * getCallLowering ( ) const override { return CallLoweringInfo . get ( ) ; } </s>


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


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

Expose LegalizerInfo so the clients can re-use .


<s> const RegisterBankInfo * getRegBankInfo ( ) const override { return RegBankInfo . get ( ) ; } </s>

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


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

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


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

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


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

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


<s> bool M88kPassConfig :: addLegalizeMachineIR ( ) { addPass ( new Legalizer ( ) ) ; return false ; } </s>

This method should install a legalize pass , which converts the instruction sequence into one that can be selected by the target .


<s> void M88kPassConfig :: addPreEmitPass ( ) { if ( BranchRelaxation ) addPass ( & BranchRelaxationPassID ) ; if ( ! DisableDelaySlotFiller ) addPass ( createM88kDelaySlotFiller ( ) ) ; } </s>

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


<s> void M88kPassConfig :: addPreLegalizeMachineIR ( ) { addPass ( createM88kPreLegalizerCombiner ( ) ) ; } </s>

This method may be implemented by targets that want to run passes immediately before legalization .


<s> void M88kPassConfig :: addPreRegBankSelect ( ) { addPass ( createM88kPostLegalizerLowering ( ) ) ; } </s>

This method may be implemented by targets that want to run passes immediately before the register bank selection .


<s> bool M88kPassConfig :: addRegBankSelect ( ) { addPass ( new RegBankSelect ( ) ) ; return false ; } </s>

This method should install a register bank selector pass , which assigns register banks to virtual registers without a register class or register banks .


<s> TargetPassConfig * M88kTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new M88kPassConfig ( * 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 M88kSubtarget * M88kTargetMachine :: getSubtargetImpl ( const Function & F ) const { Attribute CPUAttr = F . getFnAttribute ( "target-cpu" ) ; Attribute FSAttr = F . getFnAttribute ( "target-features" ) ; std :: string CPU = ! CPUAttr . hasAttribute ( Attribute :: None ) ? CPUAttr . getValueAsString ( ) . str ( ) : TargetCPU ; std :: string FS = ! FSAttr . hasAttribute ( Attribute :: None ) ? FSAttr . getValueAsString ( ) . str ( ) : TargetFS ; auto & I = SubtargetMap [ CPU + FS ] ; if ( ! I ) { resetTargetOptions ( F ) ; I = std :: make_unique < M88kSubtarget > ( TargetTriple , CPU , FS , * this ) ; } return I . get ( ) ; } </s>

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


<s> void M88kTargetELFStreamer :: finish ( ) { MCAssembler & MCA = getStreamer ( ) . getAssembler ( ) ; unsigned EFlags = MCA . getELFHeaderEFlags ( ) ; if ( Requires88110 ) EFlags |= ELF :: EF_88K_M88110 ; MCA . setELFHeaderEFlags ( EFlags ) ; } </s>

finish - after all the new live ranges have been created , compute the remaining live range , and rewrite instructions to use the new registers .


<s> MCELFStreamer & M88kTargetELFStreamer :: getStreamer ( ) { return static_cast < MCELFStreamer & > ( Streamer ) ; } </s>

Return the output streamer for the assembler .