<s> void GBZ80AsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { GBZ80MCInstLower MCInstLowering ( OutContext , * this ) ; MCInst I ; MCInstLowering . lowerInstruction ( * MI , I ) ; EmitToStreamer ( * OutStreamer , I ) ; } </s>

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


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

getPassName - Return a nice clean name for a pass .


"Wrong register class for memory operand."

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


<s> bool GBZ80AsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNum , unsigned AsmVariant , const char * ExtraCode , raw_ostream & O ) { bool Error = AsmPrinter :: PrintAsmOperand ( MI , OpNum , AsmVariant , ExtraCode , O ) ; if ( Error ) printOperand ( MI , OpNum , O ) ; return false ; } </s>

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


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

Return the output streamer for the assembler .


"Cannot handle this call frame pseudo instruction"

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 ) .


"Can only insert epilog into returning blocks"


<s> void GBZ80FrameLowering :: emitPrologue ( MachineFunction & MF ) const { MachineBasicBlock & MBB = MF . front ( ) ; MachineBasicBlock :: iterator MBBI = MBB . begin ( ) ; MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; GBZ80MachineFunctionInfo * GBZ80FI = MF . getInfo < GBZ80MachineFunctionInfo > ( ) ; const GBZ80InstrInfo & TII = * static_cast < const GBZ80InstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; DebugLoc dl = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; uint64_t StackSize = MFI -> getStackSize ( ) ; uint64_t CallFrameSize = MFI -> getMaxCallFrameSize ( ) ; uint64_t FrameSize = GBZ80FI -> getCalleeSavedFrameSize ( ) ; uint64_t NumBytes = StackSize + CallFrameSize - FrameSize ; while ( MBBI != MBB . end ( ) && ( MBBI -> getOpcode ( ) == GBZ80 :: PUSH16r ) ) MBBI ++ ; if ( NumBytes || GBZ80FI -> isNeedFP ( ) ) { unsigned FP = TII . getRegisterInfo ( ) . getFrameRegister ( MF ) ; BuildMI ( MBB , MBBI , dl , TII . get ( GBZ80 :: LD16ri ) , FP ) . addImm ( - NumBytes ) ; BuildMI ( MBB , MBBI , dl , TII . get ( GBZ80 :: ADD16rSP ) , FP ) ; BuildMI ( MBB , MBBI , dl , TII . get ( GBZ80 :: LD16SPr ) ) . addReg ( FP ) ; } } </s>

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


<s> bool GBZ80FrameLowering :: hasFP ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; return ( MFI -> getMaxCallFrameSize ( ) > 0 || ( MFI -> getNumObjects ( ) > 0 ) ) ; } </s>

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


<s> bool GBZ80FrameLowering :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; DebugLoc dl ; if ( MI != MBB . end ( ) ) dl = MI -> getDebugLoc ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; for ( unsigned i = 0 , e = CSI . size ( ) ; i != e ; i ++ ) BuildMI ( MBB , MI , dl , TII . get ( GBZ80 :: POP16r ) , CSI [ i ] . getReg ( ) ) ; 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 GBZ80FrameLowering :: spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; DebugLoc dl ; if ( MI != MBB . end ( ) ) dl = MI -> getDebugLoc ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; GBZ80MachineFunctionInfo * MFI = MF . getInfo < GBZ80MachineFunctionInfo > ( ) ; MFI -> setCalleeSavedFrameSize ( CSI . size ( ) * 2 ) ; for ( unsigned i = CSI . size ( ) ; i != 0 ; i -- ) { unsigned Reg = CSI [ i - 1 ] . getReg ( ) ; MBB . addLiveIn ( Reg ) ; BuildMI ( MBB , MI , dl , TII . get ( GBZ80 :: PUSH16r ) ) . addReg ( Reg , RegState :: Kill ) ; } 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> bool GBZ80FrameLowering :: canSimplifyCallFramePseudos ( const MachineFunction & MF ) const { return false ; } </s>

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


<s> void GBZ80FrameLowering :: determineCalleeSaves ( MachineFunction & MF , BitVector & SavedRegs , RegScavenger * RS ) const { TargetFrameLowering :: determineCalleeSaves ( MF , SavedRegs , RS ) ; } </s>

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


"call frame with stack not yet implemented!"


<s> void GBZ80FrameLowering :: emitPrologue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { MachineBasicBlock :: iterator MBBI = MBB . begin ( ) ; CallingConv :: ID CallConv = MF . getFunction ( ) . getCallingConv ( ) ; DebugLoc DL = ( MBBI != MBB . end ( ) ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; const GBZ80Subtarget & STI = MF . getSubtarget < GBZ80Subtarget > ( ) ; const GBZ80InstrInfo & TII = * STI . getInstrInfo ( ) ; bool HasFP = hasFP ( MF ) ; const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const GBZ80MachineFunctionInfo * AFI = MF . getInfo < GBZ80MachineFunctionInfo > ( ) ; int FrameSize = MFI . getStackSize ( ) - AFI -> getCalleeSavedFrameSize ( ) ; while ( ( MBBI != MBB . end ( ) ) && MBBI -> getFlag ( MachineInstr :: FrameSetup ) && ( MBBI -> getOpcode ( ) == GB :: PUSH ) ) { ++ MBBI ; } if ( ! FrameSize ) { return ; } while ( FrameSize != 0 ) { int ToSubtract = std :: min ( 128 , FrameSize ) ; MachineInstr * MI = BuildMI ( MBB , MBBI , DL , TII . get ( GB :: ADD_SP_e ) ) . addImm ( - ToSubtract ) . setMIFlag ( MachineInstr :: FrameSetup ) ; MI -> findRegisterDefOperand ( GB :: RF ) -> setIsDead ( ) ; FrameSize -= ToSubtract ; } } </s>

GBZ80 GB GB GB GB GB GB GB::PUSH 0 128 GB::ADD_SP_e GB::RF


"GBZ80 dynalloca stack pointer save/restore"


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


<s> bool GBZ80FrameLowering :: hasReservedCallFrame ( const MachineFunction & MF ) const { return false ; } </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>
bool
GBZ80FrameLowering
::
restoreCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
if
(
CSI
.
empty
(
)
)
{
return
false
;
}
DebugLoc
DL
=
MBB
.
findDebugLoc
(
MI
)
;
const
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
const
GBZ80Subtarget
&
STI
=
MF
.
getSubtarget
<
GBZ80Subtarget
>
(
)
;
const
TargetInstrInfo
&
TII
=
*
STI
.
getInstrInfo
(
)
;
for
(
const
CalleeSavedInfo
&
CCSI
:
CSI
)
{
unsigned
Reg
=
CCSI
.
getReg
(
)
;
assert
(
TRI
->
getRegSizeInBits
(
*
TRI
->
getMinimalPhysRegClass
(
Reg
)
)
==
16
&&
"Invalid register size"
)
;
BuildMI
(
MBB
,
MI
,
DL
,
TII
.
get
(
GB
::
POP
)
,
Reg
)
.
setMIFlag
(
MachineInstr
::
FrameDestroy
)
;
}
return
true
;
}
</s>

GBZ80
GB
GB
GB
16
"Invalid register size"
GB::POP


<s> bool runOnMachineFunction ( MachineFunction & MF ) { if ( ! MF . getFrameInfo ( ) . hasVarSizedObjects ( ) ) { return false ; } const GBZ80Subtarget & STI = MF . getSubtarget < GBZ80Subtarget > ( ) ; const TargetInstrInfo & TII = * STI . getInstrInfo ( ) ; MachineBasicBlock & EntryMBB = MF . front ( ) ; MachineBasicBlock :: iterator MBBI = EntryMBB . begin ( ) ; DebugLoc DL = EntryMBB . findDebugLoc ( MBBI ) ; unsigned SPCopy = MF . getRegInfo ( ) . createVirtualRegister ( & GB :: DREGSRegClass ) ; BuildMI ( EntryMBB , MBBI , DL , TII . get ( GB :: COPY ) , SPCopy ) . addReg ( GB :: SP ) ; for ( MachineBasicBlock & MBB : MF ) { if ( ! MBB . empty ( ) && MBB . back ( ) . isReturn ( ) ) { MBBI = MBB . getLastNonDebugInstr ( ) ; DL = MBBI -> getDebugLoc ( ) ; BuildMI ( MBB , MBBI , DL , TII . get ( GB :: COPY ) , GB :: SP ) . addReg ( SPCopy , RegState :: Kill ) ; } } return true ; } </s>

runOnMachineFunction - Emit the function body .

GBZ80 GB GB GB::DREGSRegClass GB::COPY GB::SP GB::COPY GB::SP


<s>
bool
GBZ80FrameLowering
::
spillCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
const
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
if
(
CSI
.
empty
(
)
)
{
return
false
;
}
unsigned
CalleeFrameSize
=
0
;
DebugLoc
DL
=
MBB
.
findDebugLoc
(
MI
)
;
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
const
GBZ80Subtarget
&
STI
=
MF
.
getSubtarget
<
GBZ80Subtarget
>
(
)
;
const
TargetInstrInfo
&
TII
=
*
STI
.
getInstrInfo
(
)
;
GBZ80MachineFunctionInfo
*
GBZ80FI
=
MF
.
getInfo
<
GBZ80MachineFunctionInfo
>
(
)
;
for
(
const
CalleeSavedInfo
&
CCSI
:
reverse
(
CSI
)
)
{
unsigned
Reg
=
CCSI
.
getReg
(
)
;
bool
IsNotLiveIn
=
!
MBB
.
isLiveIn
(
Reg
)
;
assert
(
TRI
->
getRegSizeInBits
(
*
TRI
->
getMinimalPhysRegClass
(
Reg
)
)
==
16
&&
"Invalid register size"
)
;
if
(
IsNotLiveIn
)
{
MBB
.
addLiveIn
(
Reg
)
;
}
BuildMI
(
MBB
,
MI
,
DL
,
TII
.
get
(
GB
::
PUSH
)
)
.
addReg
(
Reg
,
getKillRegState
(
IsNotLiveIn
)
)
.
setMIFlag
(
MachineInstr
::
FrameSetup
)
;
CalleeFrameSize
+=
2
;
}
GBZ80FI
->
setCalleeSavedFrameSize
(
CalleeFrameSize
)
;
return
true
;
}
</s>

GBZ80
GB
0
GB
GB
GB
GB
GB
16
"Invalid register size"
GB::PUSH
2
GB


<s> void GBZ80InstPrinter :: printInst ( const MCInst * MI , raw_ostream & O , StringRef Annot , const MCSubtargetInfo & STI ) { unsigned Opcode = MI -> getOpcode ( ) ; switch ( Opcode ) { default : if ( ! printAliasInstr ( MI , O ) ) printInstruction ( MI , O ) ; printAnnotation ( O , Annot ) ; break ; } } </s>

Print the specified MCInst to the specified raw_ostream .


<s>
void
GBZ80InstPrinter
::
printPCRelImm
(
const
MCInst
*
MI
,
unsigned
OpNo
,
raw_ostream
&
O
)
{
const
MCOperand
&
Op
=
MI
->
getOperand
(
OpNo
)
;
if
(
Op
.
isImm
(
)
)
{
int64_t
Imm
=
Op
.
getImm
(
)
;
if
(
Imm
>=
0
)
O
<<
'+'
;
O
<<
Imm
;
}
else
{
assert
(
Op
.
isExpr
(
)
&&
"Unknown pcrel immediate operand"
)
;
O
<<
*
Op
.
getExpr
(
)
;
}
}
</s>


<s>
MachineInstr
*
GBZ80InstrInfo
::
commuteInstruction
(
MachineInstr
*
MI
,
bool
NewMI
)
const
{
switch
(
MI
->
getOpcode
(
)
)
{
default
:
return
TargetInstrInfo
::
commuteInstruction
(
MI
,
NewMI
)
;
case
GBZ80
::
ADD8r
:
case
GBZ80
::
ADD16r
:
case
GBZ80
::
ADC8r
:
case
GBZ80
::
ADC16r
:
case
GBZ80
::
AND8r
:
case
GBZ80
::
XOR8r
:
case
GBZ80
::
OR8r
:
break
;
case
GBZ80
::
ADD8i
:
case
GBZ80
::
ADC8i
:
case
GBZ80
::
AND8i
:
case
GBZ80
::
XOR8i
:
case
GBZ80
::
OR8i
:
return
;
}
assert
(
!
NewMI
&&
"Not implemented yet!"
)
;
MachineBasicBlock
&
MBB
=
*
MI
->
getParent
(
)
;
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
unsigned
reg
[
2
]
,
arg
[
]
=
{
0
,
0
}
;
MachineInstr
*
MILoadReg
=
MI
->
getPrevNode
(
)
;
if
(
MILoadReg
==
||
MILoadReg
->
getOpcode
(
)
!=
GBZ80
::
COPY
)
return
;
MachineOperand
&
MO0
=
MI
->
getOperand
(
0
)
;
MachineOperand
&
MO1
=
MILoadReg
->
getOperand
(
1
)
;
reg
[
0
]
=
MO0
.
getReg
(
)
;
reg
[
1
]
=
MO1
.
getReg
(
)
;
unsigned
PreferArg
=
1
;
for
(
MachineFunction
::
iterator
MFI
=
MF
.
begin
(
)
,
MFE
=
MF
.
end
(
)
;
MFI
!=
MFE
;
MFI
++
)
{
MachineBasicBlock
::
iterator
MBBI
=
MFI
->
begin
(
)
;
while
(
MBBI
!=
MFI
->
end
(
)
)
{
if
(
MBBI
->
getOpcode
(
)
==
TargetOpcode
::
COPY
)
{
if
(
MBBI
->
findRegisterDefOperand
(
reg
[
0
]
)
)
{
arg
[
0
]
=
MBBI
->
getOperand
(
1
)
.
getReg
(
)
;
if
(
RI
.
isPhysicalRegister
(
arg
[
0
]
)
)
PreferArg
=
0
;
}
if
(
MBBI
->
findRegisterDefOperand
(
reg
[
1
]
)
)
{
arg
[
1
]
=
MBBI
->
getOperand
(
1
)
.
getReg
(
)
;
if
(
RI
.
isPhysicalRegister
(
arg
[
0
]
)
)
PreferArg
=
1
;
}
if
(
arg
[
0
]
&&
arg
[
1
]
)
break
;
}
MBBI
++
;
}
if
(
arg
[
0
]
&&
arg
[
1
]
)
break
;
}
if
(
arg
[
0
]
==
0
||
arg
[
1
]
==
0
)
{
return
;
}
if
(
PreferArg
==
0
)
{
MO0
.
setReg
(
reg
[
1
]
)
;
MO1
.
setReg
(
reg
[
0
]
)
;
}
else
{
}
return
;
}
</s>

This method commutes the operands of the given machine instruction MI .


<s>
void
GBZ80InstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
DebugLoc
DL
,
unsigned
DestReg
,
unsigned
SrcReg
,
bool
KillSrc
)
const
{
if
(
GBZ80
::
GR8RegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
I
,
DL
,
get
(
GBZ80
::
LD8rr
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
return
;
}
else
if
(
GBZ80
::
GR16RegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
unsigned
DestSubReg
,
SrcSubReg
;
DestSubReg
=
RI
.
getSubReg
(
DestReg
,
GBZ80
::
subreg_hi
)
;
SrcSubReg
=
RI
.
getSubReg
(
SrcReg
,
GBZ80
::
subreg_hi
)
;
BuildMI
(
MBB
,
I
,
DL
,
get
(
GBZ80
::
LD8rr
)
,
DestSubReg
)
.
addReg
(
SrcSubReg
)
;
DestSubReg
=
RI
.
getSubReg
(
DestReg
,
GBZ80
::
subreg_lo
)
;
SrcSubReg
=
RI
.
getSubReg
(
SrcReg
,
GBZ80
::
subreg_lo
)
;
BuildMI
(
MBB
,
I
,
DL
,
get
(
GBZ80
::
LD8rr
)
,
DestSubReg
)
.
addReg
(
SrcSubReg
)
;
if
(
KillSrc
)
BuildMI
(
MBB
,
I
,
DL
,
get
(
GBZ80
::
KILL
)
)
.
addReg
(
SrcReg
)
;
return
;
}
else
if
(
GBZ80
::
GR16RegClass
.
contains
(
DestReg
)
||
GBZ80
::
GR16RegClass
.
contains
(
SrcReg
)
)
{
BuildMI
(
MBB
,
I
,
DL
,
get
(
GBZ80
::
PUSH16r
)
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
BuildMI
(
MBB
,
I
,
DL
,
get
(
GBZ80
::
POP16r
)
,
DestReg
)
;
return
;
}
llvm_unreachable
(
"Imposible reg-to-reg copy"
)
;
}
</s>


<s> bool GBZ80InstrInfo :: expandPostRAPseudo ( MachineBasicBlock :: iterator MI ) const { MachineBasicBlock & MBB = * MI -> getParent ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; const TargetRegisterInfo & RI = * MF . getSubtarget ( ) . getRegisterInfo ( ) ; DebugLoc dl = MI -> getDebugLoc ( ) ; unsigned Opc , Reg , Imm , FPReg , Idx ; switch ( MI -> getOpcode ( ) ) { default : return false ; } unsigned Lo , Hi ; Lo = RI . getSubReg ( Reg , GBZ80 :: subreg_lo ) ; Hi = RI . getSubReg ( Reg , GBZ80 :: subreg_hi ) ; MI -> eraseFromParent ( ) ; return true ; } </s>

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


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

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


"Can't load this register from stack slot"

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


"Can't store this register to stack slot"

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


<s> bool GBZ80InstrInfo :: analyzeBranchPredicate ( MachineBasicBlock & MBB , MachineBranchPredicate & MBP , bool AllowModify ) const { SmallVector < MachineOperand , 4 > Cond ; MachineBasicBlock * FBB = nullptr , * TBB = nullptr ; if ( analyzeBranch ( MBB , TBB , FBB , Cond , AllowModify ) ) return true ; return true ; } </s>

Analyze the branching code at the end of MBB and parse it into the MachineBranchPredicate structure if possible .


<s> MachineInstr * GBZ80InstrInfo :: commuteInstructionImpl ( MachineInstr & MI , bool NewMI , unsigned OpIdx1 , unsigned OpIdx2 ) const { MachineRegisterInfo & MRI = MI . getParent ( ) -> getParent ( ) -> getRegInfo ( ) ; if ( MRI . getRegClass ( MI . getOperand ( OpIdx2 ) . getReg ( ) ) -> hasSuperClassEq ( & GB :: R8RegClass ) ) { if ( ! safeToCommute ( MI , OpIdx1 , OpIdx2 ) ) return nullptr ; } return TargetInstrInfo :: commuteInstructionImpl ( MI , NewMI , OpIdx1 , OpIdx2 ) ; } </s>

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


<s>
void
GBZ80InstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
const
DebugLoc
&
DL
,
unsigned
DestReg
,
unsigned
SrcReg
,
bool
KillSrc
)
const
{
const
GBZ80Subtarget
&
STI
=
MBB
.
getParent
(
)
->
getSubtarget
<
GBZ80Subtarget
>
(
)
;
const
GBZ80RegisterInfo
&
TRI
=
*
STI
.
getRegisterInfo
(
)
;
unsigned
Opc
;
if
(
GB
::
R16RegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
unsigned
DestLo
,
DestHi
,
SrcLo
,
SrcHi
;
TRI
.
splitReg
(
DestReg
,
DestLo
,
DestHi
)
;
TRI
.
splitReg
(
SrcReg
,
SrcLo
,
SrcHi
)
;
BuildMI
(
MBB
,
MI
,
DL
,
get
(
GB
::
LD_r_r
)
,
DestLo
)
.
addReg
(
SrcLo
,
getKillRegState
(
KillSrc
)
)
;
BuildMI
(
MBB
,
MI
,
DL
,
get
(
GB
::
LD_r_r
)
,
DestHi
)
.
addReg
(
SrcHi
,
getKillRegState
(
KillSrc
)
)
;
}
else
if
(
GB
::
R8RegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
MI
,
DL
,
get
(
GB
::
LD_r_r
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
else
if
(
DestReg
==
GB
::
SP
&&
SrcReg
==
GB
::
RHL
)
{
BuildMI
(
MBB
,
MI
,
DL
,
get
(
GB
::
LD_SP_HL
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
else
{
llvm_unreachable
(
"Impossible reg-to-reg copy"
)
;
}
}
</s>


<s> unsigned GBZ80InstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { unsigned Opcode = MI . getOpcode ( ) ; switch ( Opcode ) { default : { const MCInstrDesc & Desc = get ( Opcode ) ; return Desc . getSize ( ) ; } case TargetOpcode :: EH_LABEL : case TargetOpcode :: IMPLICIT_DEF : case TargetOpcode :: KILL : case TargetOpcode :: DBG_VALUE : return 0 ; case TargetOpcode :: INLINEASM : { const MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; const GBZ80TargetMachine & TM = static_cast < const GBZ80TargetMachine & > ( MF . getTarget ( ) ) ; const GBZ80Subtarget & STI = MF . getSubtarget < GBZ80Subtarget > ( ) ; const TargetInstrInfo & TII = * STI . getInstrInfo ( ) ; return TII . getInlineAsmLength ( MI . getOperand ( 0 ) . getSymbolName ( ) , * TM . getMCAsmInfo ( ) ) ; } } } </s>

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


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


<s> int GBZ80InstrInfo :: getSPAdjust ( const MachineInstr & MI ) const { switch ( MI . getOpcode ( ) ) { case GB :: PUSH : return - 2 ; case GB :: POP : return 2 ; case GB :: ADD_SP_e : return ( int8_t ) MI . getOperand ( 0 ) . getImm ( ) ; } return TargetInstrInfo :: getSPAdjust ( MI ) ; } </s>

getSPAdjust - This returns the stack pointer adjustment made by this instruction .


"insertBranch must not be told to insert a fallthrough"

"GBZ80 branch conditions must have a multiple of two components!"

"Unconditional branch with multiple successors!"

Insert branch code into the end of the specified MachineBasicBlock .


<s> unsigned GBZ80InstrInfo :: insertIndirectBranch ( MachineBasicBlock & MBB , MachineBasicBlock & NewDestBB , const DebugLoc & DL , int64_t BrOffset , RegScavenger * RS ) const { auto & MI = * BuildMI ( & MBB , DL , get ( GB :: JP_nn ) ) . addMBB ( & NewDestBB ) ; return getInstSizeInBytes ( MI ) ; } </s>

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


<s>
bool
GBZ80InstrInfo
::
isBranchOffsetInRange
(
unsigned
BranchOp
,
int64_t
BrOffset
)
const
{
switch
(
BranchOp
)
{
default
:
llvm_unreachable
(
"unexpected opcode!"
)
;
case
GB
::
CALL_cc_nn
:
case
GB
::
CALL_nn
:
case
GB
::
JP_cc_nn
:
case
GB
::
JP_nn
:
return
true
;
case
GB
::
JR_cc_e
:
case
GB
::
JR_e
:
return
BrOffset
>=
127
&&
BrOffset
<=
129
;
}
}
</s>

Determine if the branch target is in range .


<s> bool GBZ80InstrInfo :: isConditionalBranch ( const MachineInstr & I ) const { return I . getOpcode ( ) == GB :: JP_cc_nn || I . getOpcode ( ) == GB :: JR_cc_e ; } </s>

Return true if this is a branch which may fall through to the next instruction or may transfer control flow to some other block .


<s> unsigned GBZ80InstrInfo :: isLoadFromStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { case GB :: LD8_FI : { if ( MI . getOperand ( 1 ) . isFI ( ) ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } default : 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> bool GBZ80InstrInfo :: isReallyTriviallyReMaterializable ( const MachineInstr & MI , AliasAnalysis * AI ) const { switch ( MI . getOpcode ( ) ) { default : return false ; case GB :: LD_r_n : case GB :: LD_dd_nn : return true ; } } </s>

For instructions with opcodes for which the M_REMATERIALIZABLE flag is set , this hook lets the target specify whether the instruction is actually trivially rematerializable , taking into consideration its operands .


<s> unsigned GBZ80InstrInfo :: isStoreToStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { case GB :: ST8_FI : { if ( MI . getOperand ( 1 ) . isFI ( ) ) { FrameIndex = MI . getOperand ( 0 ) . getIndex ( ) ; return MI . getOperand ( 1 ) . getReg ( ) ; } break ; } default : 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> bool GBZ80InstrInfo :: isUnconditionalBranch ( const MachineInstr & I ) const { return I . getOpcode ( ) == GB :: JP_nn || I . getOpcode ( ) == GB :: JR_e ; } </s>

Return true if this is a branch which always transfers control flow to some other block .


"Cannot load this register from a stack slot!"


<s> void GBZ80InstrInfo :: reMaterialize ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , unsigned DestReg , unsigned SubIdx , const MachineInstr & Orig , const TargetRegisterInfo & TRI ) const { MachineInstr * MI = MBB . getParent ( ) -> CloneMachineInstr ( & Orig ) ; MBB . insert ( I , MI ) ; MachineInstr & NewMI = * std :: prev ( I ) ; NewMI . substituteRegister ( Orig . getOperand ( 0 ) . getReg ( ) , DestReg , SubIdx , TRI ) ; } </s>

Re-issue the specified 'original ' instruction at the specific location targeting a new destination register .


<s> unsigned GBZ80InstrInfo :: removeBranch ( MachineBasicBlock & MBB , int * BytesRemoved ) const { if ( BytesRemoved ) * BytesRemoved = 0 ; MachineBasicBlock :: iterator I = MBB . end ( ) ; unsigned Count = 0 ; while ( I != MBB . begin ( ) ) { -- I ; if ( I -> isDebugValue ( ) ) { continue ; } if ( ! isUnconditionalBranch ( * I ) && ! isConditionalBranch ( * I ) ) { break ; } if ( BytesRemoved ) * BytesRemoved += getInstSizeInBytes ( * I ) ; I -> eraseFromParent ( ) ; I = MBB . end ( ) ; ++ Count ; } return Count ; } </s>

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


<s>
bool
GBZ80InstrInfo
::
reverseBranchCondition
(
SmallVectorImpl
<
MachineOperand
>
&
Cond
)
const
{
assert
(
(
Cond
.
size
(
)
%
2
==
0
)
&&
"Invalid GBZ80 branch condition!"
)
;
return
!
invertCondition
(
Cond
)
;
}
</s>

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


"Cannot store this register into a stack slot!"


<s> SDNode * GBZ80DAGToDAGISel :: Select ( SDNode * Node ) { DebugLoc dl = Node -> getDebugLoc ( ) ; switch ( Node -> getOpcode ( ) ) { default : break ; } SDNode * ResNode = SelectCode ( Node ) ; return ResNode ; } </s>

Main hook for targets to transform nodes into machine nodes .


<s>
StringRef
getPassName
(
)
const
override
{
return
"GBZ80 DAG->DAG Instruction Selection"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> bool GBZ80DAGToDAGISel :: runOnMachineFunction ( MachineFunction & MF ) { Subtarget = & MF . getSubtarget < GBZ80Subtarget > ( ) ; return SelectionDAGISel :: runOnMachineFunction ( MF ) ; } </s>

runOnMachineFunction - Emit the function body .


<s>
void
GBZ80DAGToDAGISel
::
Select
(
SDNode
*
N
)
{
LLVM_DEBUG
(
errs
(
)
<<
"Selecting: "
;
N
->
dump
(
CurDAG
)
;
errs
(
)
<<
"\n"
)
;
if
(
N
->
isMachineOpcode
(
)
)
{
LLVM_DEBUG
(
errs
(
)
<<
"== "
;
N
->
dump
(
CurDAG
)
;
errs
(
)
<<
"\n"
)
;
N
->
setNodeId
(
1
)
;
return
;
}
if
(
trySelect
(
N
)
)
return
;
SelectCode
(
N
)
;
}
</s>

GBZ80
GB
"Selecting: "
"\n"
"== "
"\n"
1


<s>
MachineBasicBlock
*
GBZ80TargetLowering
::
EmitInstrWithCustomInserter
(
MachineInstr
*
MI
,
MachineBasicBlock
*
MBB
)
const
{
unsigned
Opc
=
MI
->
getOpcode
(
)
;
switch
(
Opc
)
{
case
GBZ80
::
SELECT8
:
case
GBZ80
::
SELECT16
:
return
EmitSelectInstr
(
MI
,
MBB
)
;
case
GBZ80
::
SHL8
:
case
GBZ80
::
LSHR8
:
case
GBZ80
::
ASHR8
:
case
GBZ80
::
SHL16
:
case
GBZ80
::
LSHR16
:
case
GBZ80
::
ASHR16
:
return
EmitShiftInstr
(
MI
,
MBB
)
;
default
:
llvm_unreachable
(
"Invalid Custom Inserter Instruction"
)
;
}
}
</s>

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


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

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


<s> const char * GBZ80TargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( Opcode ) { default : return NULL ; case GBZ80ISD :: WRAPPER : return "GBZ80ISD::WRAPPER" ; case GBZ80ISD :: SCF : return "GBZ80ISD::SCF" ; case GBZ80ISD :: CCF : return "GBZ80ISD::CCF" ; case GBZ80ISD :: RLC : return "GBZ80ISD::RLC" ; case GBZ80ISD :: RRC : return "GBZ80ISD::RRC" ; case GBZ80ISD :: RL : return "GBZ80ISD::RL" ; case GBZ80ISD :: RR : return "GBZ80ISD::RR" ; case GBZ80ISD :: SLA : return "GBZ80ISD::SLA" ; case GBZ80ISD :: SRA : return "GBZ80ISD::SRA" ; case GBZ80ISD :: SLL : return "GBZ80ISD::SLL" ; case GBZ80ISD :: SRL : return "GBZ80ISD::SRL" ; case GBZ80ISD :: SHL : return "GBZ80ISD::SHL" ; case GBZ80ISD :: LSHR : return "GBZ80ISD::LSHR" ; case GBZ80ISD :: ASHR : return "GBZ80ISD::ASHR" ; case GBZ80ISD :: CP : return "GBZ80ISD::CP" ; case GBZ80ISD :: SELECT_CC : return "GBZ80ISD::SELECT_CC" ; case GBZ80ISD :: BR_CC : return "GBZ80ISD::BR_CC" ; case GBZ80ISD :: CALL : return "GBZ80ISD::CALL" ; case GBZ80ISD :: RET : return "GBZ80ISD::RET" ; } } </s>

getTargetNodeName - This method returns the name of a target specific


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

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


"LowerFormalArguments Unhandled argument type: "

"LowerFormalArguments unhandled argument type: "

This hook must be implemented to lower the incoming ( formal ) arguments , described by the Ins array , into the specified DAG .


<s>
SDValue
GBZ80TargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
case
ISD
::
ZERO_EXTEND
:
return
LowerZExt
(
Op
,
DAG
)
;
case
ISD
::
SIGN_EXTEND
:
return
LowerSExt
(
Op
,
DAG
)
;
case
ISD
::
SUB
:
case
ISD
::
SUBC
:
return
LowerSUB
(
Op
,
DAG
)
;
case
ISD
::
SRL
:
case
ISD
::
SHL
:
case
ISD
::
SRA
:
case
ISD
::
ROTL
:
case
ISD
::
ROTR
:
return
LowerShifts
(
Op
,
DAG
)
;
case
ISD
::
AND
:
case
ISD
::
OR
:
case
ISD
::
XOR
:
return
LowerBinaryOp
(
Op
,
DAG
)
;
case
ISD
::
SELECT_CC
:
return
LowerSelectCC
(
Op
,
DAG
)
;
case
ISD
::
BR_CC
:
return
LowerBrCC
(
Op
,
DAG
)
;
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
STORE
:
return
LowerStore
(
Op
,
DAG
)
;
case
ISD
::
LOAD
:
return
LowerLoad
(
Op
,
DAG
)
;
default
:
llvm_unreachable
(
"unimplemented operation"
)
;
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .

GBZ80
GB
ISD::ZERO_EXTEND
ISD::SIGN_EXTEND
ISD::SUB
ISD::SUBC
ISD::SRL
ISD::SHL
ISD::SRA
ISD::ROTL
ISD::ROTR
ISD::AND
ISD::OR
ISD::XOR
ISD::SELECT_CC
ISD::BR_CC
ISD::GlobalAddress
ISD::STORE
ISD::LOAD
"unimplemented operation"


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

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


<s> bool GBZ80TargetLowering :: CanLowerReturn ( CallingConv :: ID CallConv , MachineFunction & MF , bool isVarArg , const SmallVectorImpl < ISD :: OutputArg > & Outs , LLVMContext & Context ) const { SmallVector < CCValAssign , 16 > RVLocs ; CCState CCInfo ( CallConv , isVarArg , MF , RVLocs , Context ) ; auto CCFunction = CCAssignFnForReturn ( CallConv ) ; return CCInfo . CheckReturn ( Outs , CCFunction ) ; } </s>

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


<s> CCAssignFn * GBZ80TargetLowering :: CCAssignFnForReturn ( CallingConv :: ID CC ) const { switch ( CC ) { default : return RetCC_GBZ80 ; } } </s>

Selects the correct CCAssignFn for a given CallingConvention value .


<s>
MachineBasicBlock
*
GBZ80TargetLowering
::
EmitInstrWithCustomInserter
(
MachineInstr
&
MI
,
MachineBasicBlock
*
MBB
)
const
{
llvm_unreachable
(
"Custom inserters are disabled."
)
;
return
nullptr
;
}
</s>

GBZ80
GB
"Custom inserters are disabled."


<s> MVT :: SimpleValueType getCmpLibcallReturnType ( ) const override { return MVT :: i8 ; } </s>

Return the ValueType for comparison libcalls .


"don't know how to get the name for this callee"


<s> bool GBZ80TargetLowering :: getPostIndexedAddressParts ( SDNode * N , SDNode * Op , SDValue & Base , SDValue & Offset , ISD :: MemIndexedMode & AM , SelectionDAG & DAG ) const { EVT VT ; SDLoc DL ( N ) ; if ( const LoadSDNode * LD = dyn_cast < LoadSDNode > ( N ) ) { VT = LD -> getMemoryVT ( ) ; if ( LD -> getExtensionType ( ) != ISD :: NON_EXTLOAD ) return false ; } else if ( const StoreSDNode * ST = dyn_cast < StoreSDNode > ( N ) ) { VT = ST -> getMemoryVT ( ) ; } else { return false ; } if ( VT != MVT :: i8 ) { return false ; } if ( Op -> getOpcode ( ) != ISD :: ADD && Op -> getOpcode ( ) != ISD :: SUB ) { return false ; } if ( const ConstantSDNode * RHS = dyn_cast < ConstantSDNode > ( Op -> getOperand ( 1 ) ) ) { int RHSC = RHS -> getSExtValue ( ) ; if ( Op -> getOpcode ( ) == ISD :: SUB ) RHSC = - RHSC ; if ( RHSC == 1 ) { Base = Op -> getOperand ( 0 ) ; Offset = DAG . getConstant ( RHSC , DL , MVT :: i16 ) ; AM = ISD :: POST_INC ; return true ; } else if ( RHSC == - 1 ) { Base = Op -> getOperand ( 0 ) ; Offset = DAG . getConstant ( RHSC , DL , MVT :: i16 ) ; AM = ISD :: POST_DEC ; return true ; } } return false ; } </s>

Returns true by value , base pointer and offset pointer and addressing mode by reference if this node can be combined with a load / store to form a post-indexed load / store .


<s> MVT getScalarShiftAmountTy ( const DataLayout & , EVT LHSTy ) const override { return MVT :: i8 ; } </s>


<s>
EVT
GBZ80TargetLowering
::
getSetCCResultType
(
const
DataLayout
&
DL
,
LLVMContext
&
,
EVT
VT
)
const
{
assert
(
!
VT
.
isVector
(
)
&&
"No GBZ80 SetCC type for vectors!"
)
;
return
MVT
::
i8
;
}
</s>

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


<s> const char * GBZ80TargetLowering :: getTargetNodeName ( unsigned Opcode ) const { case GBISD :: name : \ return # name switch ( Opcode ) { default : return nullptr ; NODE ( RET_FLAG ) ; NODE ( RETI_FLAG ) ; NODE ( CALL ) ; NODE ( WRAPPER ) ; NODE ( FI ) ; NODE ( LSL ) ; NODE ( LSR ) ; NODE ( ROL ) ; NODE ( ROR ) ; NODE ( ASR ) ; NODE ( LSLLOOP ) ; NODE ( LSRLOOP ) ; NODE ( ASRLOOP ) ; NODE ( BRCOND ) ; NODE ( CMP ) ; NODE ( CMPC ) ; NODE ( TST ) ; NODE ( SELECT_CC ) ; NODE ( SELECT_BR ) ; NODE ( BR16 ) ; } </s>


<s> bool GBZ80TargetLowering :: isLegalAddressingMode ( const DataLayout & DL , const AddrMode & AM , Type * Ty , unsigned AS , Instruction * I ) const { int64_t Offs = AM . BaseOffs ; if ( AM . BaseGV && ! AM . HasBaseReg && AM . Scale == 0 && Offs == 0 ) { return true ; } if ( ! AM . BaseGV && AM . HasBaseReg && AM . Scale == 0 && Offs == 0 ) { return true ; } if ( ! AM . BaseGV && ! AM . HasBaseReg && AM . Scale == 1 && Offs == 0 ) { return true ; } if ( ! AM . BaseGV && ! AM . HasBaseReg && Offs >= 0xFF00 ) { return ( AM . Scale == 1 && Offs == 0xFF00 ) || ( AM . Scale == 0 && Offs <= 0xFFFF ) ; } return false ; } </s>

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


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

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


<s> SDValue GBZ80TargetLowering :: 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 ( ) ) ; auto CCFunction = CCAssignFnForReturn ( CallConv ) ; CCInfo . AnalyzeCallResult ( Ins , CCFunction ) ; if ( RVLocs . size ( ) > 1 ) { std :: reverse ( RVLocs . begin ( ) , RVLocs . end ( ) ) ; } for ( CCValAssign const & RVLoc : RVLocs ) { Chain = DAG . getCopyFromReg ( Chain , dl , RVLoc . getLocReg ( ) , RVLoc . getValVT ( ) , InFlag ) . getValue ( 1 ) ; InFlag = Chain . getValue ( 2 ) ; InVals . push_back ( Chain . getValue ( 0 ) ) ; } return Chain ; } </s>


<s>
SDValue
GBZ80TargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Don't know how to custom lower this!"
)
;
case
ISD
::
SHL
:
case
ISD
::
SRA
:
case
ISD
::
SRL
:
case
ISD
::
ROTL
:
case
ISD
::
ROTR
:
return
LowerShifts
(
Op
,
DAG
)
;
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
BlockAddress
:
return
LowerBlockAddress
(
Op
,
DAG
)
;
case
ISD
::
FrameIndex
:
return
LowerFrameIndex
(
Op
,
DAG
)
;
case
ISD
::
BR_CC
:
return
LowerBR_CC
(
Op
,
DAG
)
;
case
ISD
::
SELECT_CC
:
return
LowerSELECT_CC
(
Op
,
DAG
)
;
case
ISD
::
SETCC
:
return
LowerSETCC
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
LowerVASTART
(
Op
,
DAG
)
;
case
ISD
::
SDIVREM
:
case
ISD
::
UDIVREM
:
return
LowerDivRem
(
Op
,
DAG
)
;
case
ISD
::
LOAD
:
return
LowerLOAD
(
Op
,
DAG
)
;
}
return
SDValue
(
)
;
}
</s>

GBZ80
GB
"Don't know how to custom lower this!"
ISD::SHL
ISD::SRA
ISD::SRL
ISD::ROTL
ISD::ROTR
ISD::GlobalAddress
ISD::BlockAddress
ISD::FrameIndex
ISD::BR_CC
ISD::SELECT_CC
ISD::SETCC
ISD::VASTART
ISD::SDIVREM
ISD::UDIVREM
ISD::LOAD


<s>
SDValue
GBZ80TargetLowering
::
LowerReturn
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
isVarArg
,
const
SmallVectorImpl
<
ISD
::
OutputArg
>
&
Outs
,
const
SmallVectorImpl
<
SDValue
>
&
OutVals
,
const
SDLoc
&
dl
,
SelectionDAG
&
DAG
)
const
{
SmallVector
<
CCValAssign
,
16
>
RVLocs
;
CCState
CCInfo
(
CallConv
,
isVarArg
,
DAG
.
getMachineFunction
(
)
,
RVLocs
,
*
DAG
.
getContext
(
)
)
;
auto
CCFunction
=
CCAssignFnForReturn
(
CallConv
)
;
CCInfo
.
AnalyzeReturn
(
Outs
,
CCFunction
)
;
MachineFunction
&
MF
=
DAG
.
getMachineFunction
(
)
;
unsigned
e
=
RVLocs
.
size
(
)
;
if
(
e
>
1
)
{
std
::
reverse
(
RVLocs
.
begin
(
)
,
RVLocs
.
end
(
)
)
;
}
SDValue
Flag
;
SmallVector
<
SDValue
,
4
>
RetOps
(
1
,
Chain
)
;
for
(
unsigned
i
=
0
;
i
!=
e
;
++
i
)
{
CCValAssign
&
VA
=
RVLocs
[
i
]
;
assert
(
VA
.
isRegLoc
(
)
&&
"Can only return in registers!"
)
;
Chain
=
DAG
.
getCopyToReg
(
Chain
,
dl
,
VA
.
getLocReg
(
)
,
OutVals
[
i
]
,
Flag
)
;
Flag
=
Chain
.
getValue
(
1
)
;
RetOps
.
push_back
(
DAG
.
getRegister
(
VA
.
getLocReg
(
)
,
VA
.
getLocVT
(
)
)
)
;
}
if
(
MF
.
getFunction
(
)
.
getAttributes
(
)
.
hasAttribute
(
AttributeList
::
FunctionIndex
,
Attribute
::
Naked
)
)
{
return
Chain
;
}
unsigned
RetOpc
=
GBISD
::
RET_FLAG
;
RetOps
[
0
]
=
Chain
;
if
(
Flag
.
getNode
(
)
)
{
RetOps
.
push_back
(
Flag
)
;
}
return
DAG
.
getNode
(
RetOpc
,
dl
,
MVT
::
Other
,
RetOps
)
;
}
</s>


<s> SDValue GBZ80TargetLowering :: PerformDAGCombine ( SDNode * N , DAGCombinerInfo & DCI ) const { switch ( N -> getOpcode ( ) ) { default : break ; case ISD :: ADD : return PerformADDCombine ( N , DCI ) ; } 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> void GBZ80TargetLowering :: ReplaceNodeResults ( SDNode * N , SmallVectorImpl < SDValue > & Results , SelectionDAG & DAG ) const { SDLoc DL ( N ) ; switch ( N -> getOpcode ( ) ) { case ISD :: ADD : { if ( const ConstantSDNode * C = dyn_cast < ConstantSDNode > ( N -> getOperand ( 1 ) ) ) { SDValue Sub = DAG . getNode ( ISD :: SUB , DL , N -> getValueType ( 0 ) , N -> getOperand ( 0 ) , DAG . getConstant ( - C -> getAPIntValue ( ) , DL , C -> getValueType ( 0 ) ) ) ; Results . push_back ( Sub ) ; } break ; } default : { SDValue Res = LowerOperation ( SDValue ( N , 0 ) , DAG ) ; for ( unsigned I = 0 , E = Res -> getNumValues ( ) ; I != E ; ++ I ) Results . push_back ( Res . getValue ( I ) ) ; break ; } } } </s>

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


<s> void GBZ80MCCodeEmitter :: emitInstruction ( uint64_t Val , unsigned Size , const MCSubtargetInfo & STI , raw_ostream & OS ) const { const uint16_t * Words = reinterpret_cast < uint16_t const * > ( & Val ) ; size_t WordCount = Size / 2 ; for ( int64_t i = WordCount - 1 ; i >= 0 ; -- i ) { uint16_t Word = Words [ i ] ; OS << ( uint8_t ) ( ( Word & 0x00ff ) >> 0 ) ; OS << ( uint8_t ) ( ( Word & 0xff00 ) >> 8 ) ; } } </s>

Targets should implement this to emit instructions .


<s>
void
GBZ80MCCodeEmitter
::
encodeInstruction
(
const
MCInst
&
MI
,
raw_ostream
&
OS
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
const
MCInstrDesc
&
Desc
=
MCII
.
get
(
MI
.
getOpcode
(
)
)
;
unsigned
Size
=
Desc
.
getSize
(
)
;
assert
(
Size
>
0
&&
"Instruction size cannot be zero"
)
;
uint64_t
BinaryOpCode
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
emitInstruction
(
BinaryOpCode
,
Size
,
STI
,
OS
)
;
}
</s>

Encode the given Inst to bytes and append to CB .


<s> unsigned GBZ80MCCodeEmitter :: getMachineOpValue ( const MCInst & MI , const MCOperand & MO , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { if ( MO . isReg ( ) ) return Ctx . getRegisterInfo ( ) -> getEncodingValue ( MO . getReg ( ) ) ; if ( MO . isImm ( ) ) return static_cast < unsigned > ( MO . getImm ( ) ) ; if ( MO . isFPImm ( ) ) return static_cast < unsigned > ( APFloat ( MO . getFPImm ( ) ) . bitcastToAPInt ( ) . getHiBits ( 32 ) . getLimitedValue ( ) ) ; assert ( MO . isExpr ( ) ) ; return getExprOpValue ( MO . getExpr ( ) , Fixups , STI ) ; } </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 GBZ80MCExpr * GBZ80MCExpr :: create ( VariantKind Kind , const MCExpr * Expr , bool Negated , MCContext & Ctx ) { return new ( Ctx ) GBZ80MCExpr ( Kind , Expr , Negated ) ; } </s>


<s> bool GBZ80MCExpr :: evaluateAsConstant ( int64_t & Result ) const { MCValue Value ; bool isRelocatable = getSubExpr ( ) -> evaluateAsRelocatable ( Value , nullptr , nullptr ) ; if ( ! isRelocatable ) return false ; if ( Value . isAbsolute ( ) ) { Result = evaluateAsInt64 ( Value . getConstant ( ) ) ; return true ; } return false ; } </s>

Evaluates the fixup as a constant value .


<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>
GB
::
Fixups
GBZ80MCExpr
::
getFixupKind
(
)
const
{
GB
::
Fixups
Kind
=
GB
::
Fixups
::
LastTargetFixupKind
;
switch
(
getKind
(
)
)
{
case
VK_GBZ80_LO8
:
Kind
=
isNegated
(
)
GB
::
fixup_lo8_ldi_neg
:
GB
::
fixup_lo8_ldi
;
break
;
case
VK_GBZ80_HI8
:
Kind
=
isNegated
(
)
GB
::
fixup_hi8_ldi_neg
:
GB
::
fixup_hi8_ldi
;
break
;
case
VK_GBZ80_HH8
:
Kind
=
isNegated
(
)
GB
::
fixup_hh8_ldi_neg
:
GB
::
fixup_hh8_ldi
;
break
;
case
VK_GBZ80_HHI8
:
Kind
=
isNegated
(
)
GB
::
fixup_ms8_ldi_neg
:
GB
::
fixup_ms8_ldi
;
break
;
case
VK_GBZ80_PM_LO8
:
Kind
=
isNegated
(
)
GB
::
fixup_lo8_ldi_pm_neg
:
GB
::
fixup_lo8_ldi_pm
;
break
;
case
VK_GBZ80_PM_HI8
:
Kind
=
isNegated
(
)
GB
::
fixup_hi8_ldi_pm_neg
:
GB
::
fixup_hi8_ldi_pm
;
break
;
case
VK_GBZ80_PM_HH8
:
Kind
=
isNegated
(
)
GB
::
fixup_hh8_ldi_pm_neg
:
GB
::
fixup_hh8_ldi_pm
;
break
;
case
VK_GBZ80_None
:
llvm_unreachable
(
"Uninitialized expression"
)
;
}
return
Kind
;
}
</s>

getFixupKind - Get the fixup kind of this expression .


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


<s> const char * GBZ80MCExpr :: getName ( ) const { const auto & Modifier = std :: find_if ( std :: begin ( ModifierNames ) , std :: end ( ModifierNames ) , [ this ] ( ModifierEntry const & Mod ) { return Mod . VariantKind == Kind ; } ) ; if ( Modifier != std :: end ( ModifierNames ) ) { return Modifier -> Spelling ; } return nullptr ; } </s>

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


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

getSubExpr - Get the child of this expression .


<s>
void
GBZ80MCInstLower
::
lowerInstruction
(
const
MachineInstr
&
MI
,
MCInst
&
OutMI
)
const
{
OutMI
.
setOpcode
(
MI
.
getOpcode
(
)
)
;
for
(
MachineOperand
const
&
MO
:
MI
.
operands
(
)
)
{
MCOperand
MCOp
;
switch
(
MO
.
getType
(
)
)
{
default
:
MI
.
print
(
errs
(
)
)
;
llvm_unreachable
(
"unknown operand type"
)
;
case
MachineOperand
::
MO_Register
:
if
(
MO
.
isImplicit
(
)
)
continue
;
MCOp
=
MCOperand
::
createReg
(
MO
.
getReg
(
)
)
;
break
;
case
MachineOperand
::
MO_Immediate
:
MCOp
=
MCOperand
::
createImm
(
MO
.
getImm
(
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
MCOp
=
lowerSymbolOperand
(
MO
,
Printer
.
getSymbol
(
MO
.
getGlobal
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ExternalSymbol
:
MCOp
=
lowerSymbolOperand
(
MO
,
Printer
.
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
)
;
break
;
case
MachineOperand
::
MO_MachineBasicBlock
:
MCOp
=
MCOperand
::
createExpr
(
MCSymbolRefExpr
::
create
(
MO
.
getMBB
(
)
->
getSymbol
(
)
,
Ctx
)
)
;
break
;
case
MachineOperand
::
MO_RegisterMask
:
continue
;
case
MachineOperand
::
MO_BlockAddress
:
MCOp
=
lowerSymbolOperand
(
MO
,
Printer
.
GetBlockAddressSymbol
(
MO
.
getBlockAddress
(
)
)
)
;
break
;
case
MachineOperand
::
MO_JumpTableIndex
:
MCOp
=
lowerSymbolOperand
(
MO
,
Printer
.
GetJTISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
MCOp
=
lowerSymbolOperand
(
MO
,
Printer
.
GetCPISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
}
OutMI
.
addOperand
(
MCOp
)
;
}
}
</s>


<s> void canonicalize ( ) { if ( ! isLHSReg ( ) && isRHSReg ( ) ) { std :: swap ( LHSReg , RHSReg ) ; std :: swap ( LHSImm , RHSImm ) ; CC = ISD :: getSetCCSwappedOperands ( CC ) ; } } </s>

Form a canonical key for the specified mangling .


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

getPassName - Return a nice clean name for a pass .


<s> void initialize ( unsigned LHS , unsigned RHS ) { MachineRegisterInfo & MRI = True -> getParent ( ) -> getRegInfo ( ) ; LHSReg = LHS ; RHSReg = RHS ; if ( ! TargetRegisterInfo :: isPhysicalRegister ( LHS ) ) { MachineInstr * DefI = MRI . getVRegDef ( LHS ) ; if ( DefI -> getOpcode ( ) == GB :: LD_dd_nn ) { LHSReg = 0 ; LHSImm = DefI -> getOperand ( 1 ) . getImm ( ) ; } } if ( ! TargetRegisterInfo :: isPhysicalRegister ( RHSReg ) ) { MachineInstr * DefI = MRI . getVRegDef ( RHSReg ) ; if ( DefI -> getOpcode ( ) == GB :: LD_dd_nn ) { RHSReg = 0 ; RHSImm = DefI -> getOperand ( 1 ) . getImm ( ) ; } } canonicalize ( ) ; } </s>

Initialize the strategy after building the DAG for a new region .


<s> bool GBZ80PostISel :: runOnMachineFunction ( MachineFunction & MF ) { bool Modified = false ; this -> MF = & MF ; const GBZ80Subtarget & STI = MF . getSubtarget < GBZ80Subtarget > ( ) ; TRI = STI . getRegisterInfo ( ) ; TII = STI . getInstrInfo ( ) ; MRI = & MF . getRegInfo ( ) ; Modified |= expandShiftLoop16 ( ) ; Modified |= expandPseudos ( ) ; Modified |= expandBranch16 ( ) ; Modified |= optimizeCP ( ) ; return Modified ; } </s>

runOnMachineFunction - Emit the function body .


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s>
bool
GBZ80PostPEI
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
bool
Modified
=
false
;
this
->
MF
=
&
MF
;
const
GBZ80Subtarget
&
STI
=
MF
.
getSubtarget
<
GBZ80Subtarget
>
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
TII
=
STI
.
getInstrInfo
(
)
;
LI
=
&
getAnalysis
<
LiveIntervals
>
(
)
;
RS
=
new
RegScavenger
(
)
;
Accesses
.
clear
(
)
;
OutgoingAdjustments
.
clear
(
)
;
CollectFrameAccesses
(
)
;
for
(
auto
&
A
:
Accesses
)
{
A
.
MI
->
dump
(
)
;
errs
(
)
<<
"Stack adj: "
<<
A
.
StackAdjustment
<<
"\n"
;
errs
(
)
<<
"Must save: "
<<
A
.
MustSaveHL
<<
"\n\n"
;
}
TransformFrameAccesses
(
)
;
delete
RS
;
return
!
Accesses
.
empty
(
)
;
}
</s>

GBZ80
GB
GB
GB
"Stack adj: "
"\n"
"Must save: "
"\n\n"


<s> bool GBZ80PostRA :: runOnMachineFunction ( MachineFunction & MF ) { bool Modified = false ; this -> MF = & MF ; const GBZ80Subtarget & STI = MF . getSubtarget < GBZ80Subtarget > ( ) ; TRI = STI . getRegisterInfo ( ) ; TII = STI . getInstrInfo ( ) ; MRI = & MF . getRegInfo ( ) ; Modified |= expandPostRAPseudos ( ) ; return Modified ; } </s>


<s> bool GBZ80PreEmit :: runOnMachineFunction ( MachineFunction & MF ) { bool Modified = false ; const GBZ80Subtarget & STI = MF . getSubtarget < GBZ80Subtarget > ( ) ; TRI = STI . getRegisterInfo ( ) ; TII = STI . getInstrInfo ( ) ; return Modified ; } </s>


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


<s> bool GBZ80PreRA :: runOnMachineFunction ( MachineFunction & MF ) { bool Modified = false ; this -> MF = & MF ; const GBZ80Subtarget & STI = MF . getSubtarget < GBZ80Subtarget > ( ) ; TRI = STI . getRegisterInfo ( ) ; TII = STI . getInstrInfo ( ) ; MRI = & MF . getRegInfo ( ) ; DT = & getAnalysis < MachineDominatorTree > ( ) ; Modified |= combinePostIncMemAccs ( ) ; if ( WidenRegClasses ) Modified |= widenConstrainedRegClasses ( ) ; return Modified ; } </s>


<s> const uint16_t * GBZ80RegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { static const uint16_t CalleeSavedRegs [ ] = { GBZ80 :: BC , GBZ80 :: DE , 0 } ; return CalleeSavedRegs ; } </s>


<s> const uint32_t * GBZ80RegisterInfo :: getCallPreservedMask ( CallingConv :: ID CallConv ) const { return CSR_16_RegMask ; } </s>

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


<s> BitVector GBZ80RegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( GBZ80 :: PC ) ; Reserved . set ( GBZ80 :: SP ) ; Reserved . set ( GBZ80 :: FLAGS ) ; Reserved . set ( getFrameRegister ( MF ) ) ; 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>
void
GBZ80RegisterInfo
::
eliminateFrameIndex
(
MachineBasicBlock
::
iterator
II
,
int
SPAdj
,
unsigned
FIOperandNum
,
RegScavenger
*
RS
)
const
{
assert
(
SPAdj
==
0
&&
"Unexpected SPAdj value"
)
;
MachineInstr
&
MI
=
*
II
;
DebugLoc
dl
=
MI
.
getDebugLoc
(
)
;
MachineBasicBlock
&
MBB
=
*
MI
.
getParent
(
)
;
const
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
const
GBZ80TargetMachine
&
TM
=
(
const
GBZ80TargetMachine
&
)
MF
.
getTarget
(
)
;
const
TargetInstrInfo
&
TII
=
*
TM
.
getSubtargetImpl
(
)
->
getInstrInfo
(
)
;
const
MachineFrameInfo
&
MFI
=
MF
.
getFrameInfo
(
)
;
const
TargetFrameLowering
*
TFI
=
TM
.
getSubtargetImpl
(
)
->
getFrameLowering
(
)
;
int
FrameIndex
=
MI
.
getOperand
(
FIOperandNum
)
.
getIndex
(
)
;
int
Offset
=
MFI
.
getObjectOffset
(
FrameIndex
)
;
Offset
+=
MFI
.
getStackSize
(
)
TFI
->
getOffsetOfLocalArea
(
)
;
assert
(
MI
.
getOpcode
(
)
==
GB
::
FRMIDX
||
MI
.
getOpcode
(
)
==
GB
::
LD8_FI
||
MI
.
getOpcode
(
)
==
GB
::
ST8_FI
)
;
MI
.
getOperand
(
FIOperandNum
)
.
ChangeToImmediate
(
Offset
)
;
}
</s>

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


<s> const uint16_t * GBZ80RegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { if ( MF -> getFunction ( ) . getFunctionType ( ) -> getNumParams ( ) <= 1 ) return CSR_0_1_SaveList ; else return CSR_2_SaveList ; } </s>


<s> const uint32_t * GBZ80RegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { if ( MF . getFunction ( ) . getFunctionType ( ) -> getNumParams ( ) <= 1 ) return CSR_0_1_RegMask ; else return CSR_2_RegMask ; } </s>


<s> const TargetRegisterClass * GBZ80RegisterInfo :: getCrossCopyRegClass ( const TargetRegisterClass * RC ) const { if ( RC == & GB :: R8_GPRRegClass ) return & GB :: R8RegClass ; else if ( RC == & GB :: R16_HLRegClass || RC == & GB :: R16_BCDERegClass ) return & GB :: R16RegClass ; return RC ; } </s>

getCrossCopyRegClass - Returns a legal register class to copy a register in the specified class to or from .


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


<s> const TargetRegisterClass * GBZ80RegisterInfo :: getLargestLegalSuperClass ( const TargetRegisterClass * RC , const MachineFunction & MF ) const { const TargetRegisterInfo * TRI = MF . getSubtarget ( ) . getRegisterInfo ( ) ; if ( RC == & GB :: R8_GPRRegClass || RC == & GB :: R8RegClass ) { return & GB :: R8RegClass ; } if ( RC == & GB :: R16_HLRegClass || RC == & GB :: R16_BCDERegClass || RC == & GB :: R16RegClass ) { return & GB :: R16RegClass ; } return RC ; } </s>

Returns the largest super class of RC that is legal to use in the current sub-target and has the same spill size .


<s> const TargetRegisterClass * GBZ80RegisterInfo :: getPointerRegClass ( const MachineFunction & MF , unsigned Kind ) const { return & GB :: R16RegClass ; } </s>

getPointerRegClass - Returns a TargetRegisterClass used for pointer values .


<s> BitVector GBZ80RegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( GB :: SP ) ; Reserved . set ( GB :: IME ) ; return Reserved ; } </s>


<s> bool GBZ80RegisterInfo :: shouldCoalesce ( MachineInstr * MI , const TargetRegisterClass * SrcRC , unsigned SubReg , const TargetRegisterClass * DstRC , unsigned DstSubReg , const TargetRegisterClass * NewRC , LiveIntervals & LIS ) const { return true ; } </s>


<s>
void
GBZ80RegisterInfo
::
splitReg
(
unsigned
Reg
,
unsigned
&
LoReg
,
unsigned
&
HiReg
)
const
{
assert
(
GB
::
R16RegClass
.
contains
(
Reg
)
&&
"can only split 16-bit registers"
)
;
LoReg
=
getSubReg
(
Reg
,
GB
::
sub_lo
)
;
HiReg
=
getSubReg
(
Reg
,
GB
::
sub_hi
)
;
}
</s>

Splits a 16-bit DREGS register into the lo/hi register pair .


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

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


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

Enable tracking of subregister liveness in register allocator .


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


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

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> bool GBZ80PassConfig :: addInstSelector ( ) { addPass ( createGBZ80ISelDAG ( getGBZ80TargetMachine ( ) , getOptLevel ( ) ) ) ; return false ; } </s>

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


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

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


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

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


<s> virtual const GBZ80InstrInfo * getInstrInfo ( ) const { return & InstrInfo ; } </s>


<s> virtual const GBZ80RegisterInfo * getRegisterInfo ( ) const { return & getInstrInfo ( ) -> getRegisterInfo ( ) ; } </s>


<s> bool GBZ80PassConfig :: addInstSelector ( ) { addPass ( createGBZ80ISelDag ( getGBZ80TargetMachine ( ) , getOptLevel ( ) ) ) ; addPass ( createGBZ80PostISelPass ( ) ) ; return false ; } </s>


<s> void GBZ80PassConfig :: addPostRegAlloc ( ) { addPass ( createGBZ80PostRAPass ( ) ) ; } </s>

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


<s> void GBZ80PassConfig :: addPreEmitPass ( ) { addPass ( createGBZ80PreEmitPass ( ) ) ; addPass ( & BranchRelaxationPassID ) ; } </s>

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


<s> void GBZ80PassConfig :: addPreRegAlloc ( ) { addPass ( createGBZ80PreRAPass ( ) ) ; } </s>

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


<s> void GBZ80PassConfig :: addPreSched2 ( ) { addPass ( createGBZ80PostPEIPass ( ) ) ; } </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 * GBZ80TargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new GBZ80PassConfig ( * this , PM ) ; } </s>


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

Return information about object file lowering .


<s> const GBZ80Subtarget * GBZ80TargetMachine :: getSubtargetImpl ( const Function & ) const { return & SubTarget ; } </s>

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


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

Returns true if the target is expected to pass all machine verifier checks .


<s> static bool classof ( const MCSection * S ) { return S -> getVariant ( ) == SV_GBZ80 ; } </s>

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


<s> bool GBZ80SectionData :: get ( StringRef Specifier , GBZ80SectionData & Data ) { Data . Type = ST_NONE ; Data . Address = 0 ; Data . Bank = ~ 0U ; Data . Alignment = 1 ; return false ; } </s>

Get the generated Value for a given VPValue and given Part and Lane .


<s> uint16_t getAddress ( ) const { return Address ; } </s>

Returns the address of this pointer in this block .


<s> unsigned getAlignment ( ) const { return Alignment ; } </s>

getAlignment - Return the alignment of the function .


<s>
void
GBZ80SectionData
::
getAsString
(
SmallVectorImpl
<
char
>
&
Str
)
const
{
raw_svector_ostream
O
(
Str
)
;
if
(
SectionName
.
empty
(
)
)
O
<<
"SECTION @,"
;
else
O
<<
"SECTION \""
<<
SectionName
<<
"\","
;
switch
(
Type
)
{
case
ST_ROM0
:
O
<<
"ROM0"
;
break
;
case
ST_ROMX
:
O
<<
"ROMX"
;
break
;
case
ST_VRAM
:
O
<<
"VRAM"
;
break
;
case
ST_SRAM
:
O
<<
"SRAM"
;
break
;
case
ST_WRAM0
:
O
<<
"WRAM0"
;
break
;
case
ST_WRAMX
:
O
<<
"WRAMX"
;
break
;
case
ST_OAM
:
O
<<
"OAM"
;
break
;
case
ST_HRAM
:
O
<<
"HRAM"
;
break
;
default
:
llvm_unreachable
(
"Tried to print an invalid section!"
)
;
}
if
(
hasAddress
(
)
)
O
<<
"[$"
<<
format
(
"%04x"
,
Address
)
<<
"]"
;
if
(
hasBank
(
)
)
O
<<
",BANK["
<<
Bank
<<
"]"
;
if
(
hasAlignment
(
)
)
O
<<
",ALIGN["
<<
Log2_32_Ceil
(
Alignment
)
<<
"]"
;
}
</s>

Retrieve a string representation of the version number .

GBZ80
GB
"SECTION @,"
"SECTION \""
"\","
"ROM0"
"ROMX"
"VRAM"
"SRAM"
"WRAM0"
"WRAMX"
"OAM"
"HRAM"
"Tried to print an invalid section!"
"[$"
"%04x"
"]"
",BANK["
"]"
",ALIGN["
"]"


"getExplicitSectionGlobal not yet implemented!"

Targets should implement this method to assign a section to globals with an explicit section specfied .


<s> StringRef getName ( ) const { return SectionName ; } </s>

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


<s> MCSectionGBZ80 * GBZ80TargetObjectFile :: getSection ( SectionKind Kind , StringRef N , GBSectionType T , uint16_t A , unsigned B , unsigned Align , const GlobalObject * GO ) const { GBZ80SectionData Data ( N , T , A , B , Align , GO ) ; if ( Sections . count ( Data ) ) return Sections [ Data ] ; MCSectionGBZ80 * Section = new MCSectionGBZ80 ( Kind , Data , nullptr ) ; Sections [ Data ] = Section ; return Section ; } </s>

Get the section associated with a defined , non-absolute symbol .


<s>
MCSection
*
GBZ80TargetObjectFile
::
getSectionForConstant
(
const
DataLayout
&
DL
,
SectionKind
Kind
,
const
Constant
*
C
,
unsigned
&
Align
)
const
{
assert
(
Kind
.
isReadOnly
(
)
&&
"Writeable constant?"
)
;
return
getSection
(
Kind
,
StringRef
(
)
,
ST_ROM0
,
0
,
~
0U
,
Align
,
nullptr
)
;
}
</s>

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


<s> GBSectionType getType ( ) const { return Type ; } </s>

Overload to return most specific vector type .


<s> void GBZ80TargetObjectFile :: Initialize ( MCContext & Ctx , const TargetMachine & TM ) { Base :: Initialize ( Ctx , TM ) ; TextSection = getSection ( SectionKind :: getText ( ) , StringRef ( ".text" ) , GBSectionType :: ST_ROM0 , 0 , ~ 0U , 1 , nullptr ) ; DataSection = getSection ( SectionKind :: getText ( ) , StringRef ( ".data" ) , GBSectionType :: ST_WRAM0 , 0 , ~ 0U , 1 , nullptr ) ; BSSSection = getSection ( SectionKind :: getText ( ) , StringRef ( ".bss" ) , GBSectionType :: ST_WRAM0 , 0 , ~ 0U , 1 , nullptr ) ; ReadOnlySection = getSection ( SectionKind :: getText ( ) , StringRef ( ".readonly" ) , GBSectionType :: ST_ROM0 , 0 , ~ 0U , 1 , nullptr ) ; } </s>

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


<s> bool MCSectionGBZ80 :: isVirtualSection ( ) const { return false ; } </s>

Check whether this section is `` virtual '' , that is has no actual object file contents .


<s> void setAlignment ( unsigned Align ) { Alignment = Align ; } </s>

setAlignment - Set the alignment of the function .


<s> void setName ( StringRef N ) { SectionName = N ; } </s>

Change the name of this type to the specified name , or to a name with a suffix if there is a collision .


<s> void setType ( GBSectionType T ) { Type = T ; } </s>


<s> void GBZ80TargetStreamer :: finish ( ) { } </s>

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