<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
const
ARMSubtarget
&
STI
=
Fn
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
(
STI
.
isCortexA15
(
)
&&
STI
.
hasNEON
(
)
)
)
return
false
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineFunction
::
iterator
MFI
=
Fn
.
begin
(
)
,
E
=
Fn
.
end
(
)
;
MFI
!=
E
;
++
MFI
)
{
for
(
MachineBasicBlock
::
iterator
MI
=
MFI
->
begin
(
)
,
ME
=
MFI
->
end
(
)
;
MI
!=
ME
;
)
{
Modified
|=
runOnInstruction
(
MI
++
)
;
}
}
for
(
std
::
set
<
MachineInstr
*
>
::
iterator
I
=
DeadInstr
.
begin
(
)
,
E
=
DeadInstr
.
end
(
)
;
I
!=
E
;
++
I
)
{
(
*
I
)
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>

runOnMachineFunction - Emit the function body .


<s>
const
char
*
getPassName
(
)
const
override
{
return
"ARM A15 S->D optimizer"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
Fn
.
getTarget
(
)
.
getInstrInfo
(
)
)
;
TRI
=
Fn
.
getTarget
(
)
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineFunction
::
iterator
MFI
=
Fn
.
begin
(
)
,
E
=
Fn
.
end
(
)
;
MFI
!=
E
;
++
MFI
)
{
for
(
MachineBasicBlock
::
iterator
MI
=
MFI
->
begin
(
)
,
ME
=
MFI
->
end
(
)
;
MI
!=
ME
;
)
{
Modified
|=
runOnInstruction
(
MI
++
)
;
}
}
for
(
std
::
set
<
MachineInstr
*
>
::
iterator
I
=
DeadInstr
.
begin
(
)
,
E
=
DeadInstr
.
end
(
)
;
I
!=
E
;
++
I
)
{
(
*
I
)
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
if
(
skipFunction
(
Fn
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
STI
=
Fn
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
(
STI
.
useSplatVFPToNeon
(
)
&&
STI
.
hasNEON
(
)
)
)
return
false
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineBasicBlock
&
MBB
:
Fn
)
{
for
(
MachineInstr
&
MI
:
MBB
)
{
Modified
|=
runOnInstruction
(
&
MI
)
;
}
}
for
(
MachineInstr
*
MI
:
DeadInstr
)
{
MI
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
if
(
skipFunction
(
*
Fn
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
STI
=
Fn
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
(
STI
.
isCortexA15
(
)
&&
STI
.
hasNEON
(
)
)
)
return
false
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineFunction
::
iterator
MFI
=
Fn
.
begin
(
)
,
E
=
Fn
.
end
(
)
;
MFI
!=
E
;
++
MFI
)
{
for
(
MachineBasicBlock
::
iterator
MI
=
MFI
->
begin
(
)
,
ME
=
MFI
->
end
(
)
;
MI
!=
ME
;
)
{
Modified
|=
runOnInstruction
(
&
*
MI
++
)
;
}
}
for
(
std
::
set
<
MachineInstr
*
>
::
iterator
I
=
DeadInstr
.
begin
(
)
,
E
=
DeadInstr
.
end
(
)
;
I
!=
E
;
++
I
)
{
(
*
I
)
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
if
(
skipFunction
(
*
Fn
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
STI
=
Fn
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
(
STI
.
isCortexA15
(
)
&&
STI
.
hasNEON
(
)
)
)
return
false
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineBasicBlock
&
MBB
:
Fn
)
{
for
(
MachineInstr
&
MI
:
MBB
)
{
Modified
|=
runOnInstruction
(
&
MI
)
;
}
}
for
(
MachineInstr
*
MI
:
DeadInstr
)
{
MI
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
StringRef
getPassName
(
)
const
override
{
return
"ARM A15 S->D optimizer"
;
}
</s>


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
if
(
skipFunction
(
Fn
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
STI
=
Fn
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
(
STI
.
isCortexA15
(
)
&&
STI
.
hasNEON
(
)
)
)
return
false
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineBasicBlock
&
MBB
:
Fn
)
{
for
(
MachineInstr
&
MI
:
MBB
)
{
Modified
|=
runOnInstruction
(
&
MI
)
;
}
}
for
(
MachineInstr
*
MI
:
DeadInstr
)
{
MI
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
if
(
skipFunction
(
*
Fn
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
STI
=
Fn
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
(
STI
.
isCortexA15
(
)
&&
STI
.
hasNEON
(
)
)
)
return
false
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineFunction
::
iterator
MFI
=
Fn
.
begin
(
)
,
E
=
Fn
.
end
(
)
;
MFI
!=
E
;
++
MFI
)
{
for
(
MachineBasicBlock
::
iterator
MI
=
MFI
->
begin
(
)
,
ME
=
MFI
->
end
(
)
;
MI
!=
ME
;
)
{
Modified
|=
runOnInstruction
(
MI
++
)
;
}
}
for
(
std
::
set
<
MachineInstr
*
>
::
iterator
I
=
DeadInstr
.
begin
(
)
,
E
=
DeadInstr
.
end
(
)
;
I
!=
E
;
++
I
)
{
(
*
I
)
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
if
(
skipFunction
(
Fn
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
STI
=
Fn
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
(
STI
.
isCortexA15
(
)
&&
STI
.
hasNEON
(
)
)
)
return
false
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineBasicBlock
&
MBB
:
Fn
)
{
for
(
MachineInstr
&
MI
:
MBB
)
{
Modified
|=
runOnInstruction
(
&
MI
)
;
}
}
for
(
MachineInstr
*
MI
:
DeadInstr
)
{
MI
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
bool
A15SDOptimizer
::
runOnMachineFunction
(
MachineFunction
&
Fn
)
{
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
Fn
.
getSubtarget
(
)
.
getInstrInfo
(
)
)
;
TRI
=
Fn
.
getSubtarget
(
)
.
getRegisterInfo
(
)
;
MRI
=
&
Fn
.
getRegInfo
(
)
;
bool
Modified
=
false
;
DEBUG
(
dbgs
(
)
<<
"Running on function "
<<
Fn
.
getName
(
)
<<
"\n"
)
;
DeadInstr
.
clear
(
)
;
Replacements
.
clear
(
)
;
for
(
MachineFunction
::
iterator
MFI
=
Fn
.
begin
(
)
,
E
=
Fn
.
end
(
)
;
MFI
!=
E
;
++
MFI
)
{
for
(
MachineBasicBlock
::
iterator
MI
=
MFI
->
begin
(
)
,
ME
=
MFI
->
end
(
)
;
MI
!=
ME
;
)
{
Modified
|=
runOnInstruction
(
MI
++
)
;
}
}
for
(
std
::
set
<
MachineInstr
*
>
::
iterator
I
=
DeadInstr
.
begin
(
)
,
E
=
DeadInstr
.
end
(
)
;
I
!=
E
;
++
I
)
{
(
*
I
)
->
eraseFromParent
(
)
;
}
return
Modified
;
}
</s>


<s>
virtual
const
char
*
getPassName
(
)
const
{
return
"ARM A15 S->D optimizer"
;
}
</s>


<s> StringRef ARMALFWriter :: getPassName ( ) const { return "ARMALFWriter" ; } </s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCFixup
&
Fixup
,
char
*
Data
,
unsigned
DataSize
,
uint64_t
Value
,
bool
IsPCRel
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
Value
=
adjustFixupValue
(
Fixup
,
Value
,
IsPCRel
,
nullptr
,
IsLittleEndian
,
true
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
DataSize
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
!
IsLittleEndian
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
DataSize
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
IsLittleEndian
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
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 ARMAsmBackend :: fixupNeedsRelaxation ( const MCFixup & Fixup , uint64_t Value , const MCRelaxableFragment * DF , const MCAsmLayout & Layout ) const { return reasonForFixupRelaxation ( Fixup , Value ) ; } </s>

Simple predicate for targets where ! Resolved implies requiring relaxation .


<s> void ARMAsmBackend :: handleAssemblerFlag ( MCAssemblerFlag Flag ) { switch ( Flag ) { default : break ; case MCAF_Code16 : setIsThumb ( true ) ; break ; case MCAF_Code32 : setIsThumb ( false ) ; break ; } } </s>

Handle any target-specific assembler flags . By default , do nothing .


<s>
void
ARMAsmBackend
::
relaxInstruction
(
const
MCInst
&
Inst
,
MCInst
&
Res
)
const
{
unsigned
RelaxedOp
=
getRelaxedOpcode
(
Inst
.
getOpcode
(
)
)
;
if
(
RelaxedOp
==
Inst
.
getOpcode
(
)
)
{
SmallString
<
256
>
Tmp
;
raw_svector_ostream
OS
(
Tmp
)
;
Inst
.
dump_pretty
(
OS
)
;
OS
<<
"\n"
;
report_fatal_error
(
"unexpected instruction to relax: "
+
OS
.
str
(
)
)
;
}
if
(
(
Inst
.
getOpcode
(
)
==
ARM
::
tCBZ
||
Inst
.
getOpcode
(
)
==
ARM
::
tCBNZ
)
&&
RelaxedOp
==
ARM
::
tHINT
)
{
Res
.
setOpcode
(
RelaxedOp
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
0
)
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
14
)
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
0
)
)
;
return
;
}
Res
=
Inst
;
Res
.
setOpcode
(
RelaxedOp
)
;
}
</s>

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


<s> bool ARMAsmBackend :: writeNopData ( uint64_t Count , MCObjectWriter * OW ) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0 ; const uint16_t Thumb2_16bitNopEncoding = 0xbf00 ; const uint32_t ARMv4_NopEncoding = 0xe1a00000 ; const uint32_t ARMv6T2_NopEncoding = 0xe320f000 ; if ( isThumb ( ) ) { const uint16_t nopEncoding = hasNOP ( ) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding ; uint64_t NumNops = Count / 2 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> write16 ( nopEncoding ) ; if ( Count & 1 ) OW -> write8 ( 0 ) ; return true ; } const uint32_t nopEncoding = hasNOP ( ) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding ; uint64_t NumNops = Count / 4 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> write32 ( nopEncoding ) ; switch ( Count % 4 ) { default : break ; case 1 : OW -> write8 ( 0 ) ; break ; case 2 : OW -> write16 ( 0 ) ; break ; case 3 : OW -> write16 ( 0 ) ; OW -> write8 ( 0xa0 ) ; break ; } return true ; } </s>

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


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
,
const
MCSubtargetInfo
*
STI
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
Value
=
adjustFixupValue
(
Asm
,
Fixup
,
Target
,
Value
,
IsResolved
,
Ctx
,
STI
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
Endian
==
support
::
big
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
Data
.
size
(
)
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
Endian
==
support
::
little
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


<s> bool ARMAsmBackend :: mayNeedRelaxation ( const MCInst & Inst , const MCSubtargetInfo & STI ) const { if ( getRelaxedOpcode ( Inst . getOpcode ( ) , STI ) != Inst . getOpcode ( ) ) return true ; return false ; } </s>

Check whether the given instruction may need relaxation .


<s>
void
ARMAsmBackend
::
relaxInstruction
(
const
MCInst
&
Inst
,
const
MCSubtargetInfo
&
STI
,
MCInst
&
Res
)
const
{
unsigned
RelaxedOp
=
getRelaxedOpcode
(
Inst
.
getOpcode
(
)
,
STI
)
;
if
(
RelaxedOp
==
Inst
.
getOpcode
(
)
)
{
SmallString
<
256
>
Tmp
;
raw_svector_ostream
OS
(
Tmp
)
;
Inst
.
dump_pretty
(
OS
)
;
OS
<<
"\n"
;
report_fatal_error
(
"unexpected instruction to relax: "
+
OS
.
str
(
)
)
;
}
if
(
(
Inst
.
getOpcode
(
)
==
ARM
::
tCBZ
||
Inst
.
getOpcode
(
)
==
ARM
::
tCBNZ
)
&&
RelaxedOp
==
ARM
::
tHINT
)
{
Res
.
setOpcode
(
RelaxedOp
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
0
)
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
14
)
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
0
)
)
;
return
;
}
Res
=
Inst
;
Res
.
setOpcode
(
RelaxedOp
)
;
}
</s>


<s>
bool
ARMAsmBackend
::
shouldForceRelocation
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
)
{
const
MCSymbolRefExpr
*
A
=
Target
.
getSymA
(
)
;
const
MCSymbol
*
Sym
=
A
&
A
->
getSymbol
(
)
:
nullptr
;
const
unsigned
FixupKind
=
Fixup
.
getKind
(
)
;
if
(
(
unsigned
)
Fixup
.
getKind
(
)
==
ARM
::
fixup_arm_thumb_bl
)
{
assert
(
Sym
&&
"How did we resolve this?"
)
;
if
(
Sym
->
isExternal
(
)
)
return
true
;
}
if
(
Sym
&&
Sym
->
isELF
(
)
)
{
unsigned
Type
=
cast
<
MCSymbolELF
>
(
Sym
)
->
getType
(
)
;
if
(
(
Type
==
ELF
::
STT_FUNC
||
Type
==
ELF
::
STT_GNU_IFUNC
)
)
{
if
(
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_uncondbranch
)
)
return
true
;
if
(
!
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_br
||
FixupKind
==
ARM
::
fixup_arm_thumb_bl
||
FixupKind
==
ARM
::
fixup_t2_condbranch
||
FixupKind
==
ARM
::
fixup_t2_uncondbranch
)
)
return
true
;
}
}
if
(
A
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_blx
||
FixupKind
==
ARM
::
fixup_arm_blx
||
FixupKind
==
ARM
::
fixup_arm_uncondbl
||
FixupKind
==
ARM
::
fixup_arm_condbl
)
)
return
true
;
return
false
;
}
</s>

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


<s> bool ARMAsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count ) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0 ; const uint16_t Thumb2_16bitNopEncoding = 0xbf00 ; const uint32_t ARMv4_NopEncoding = 0xe1a00000 ; const uint32_t ARMv6T2_NopEncoding = 0xe320f000 ; if ( isThumb ( ) ) { const uint16_t nopEncoding = hasNOP ( ) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding ; uint64_t NumNops = Count / 2 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) support :: endian :: write ( OS , nopEncoding , Endian ) ; if ( Count & 1 ) OS << '\0' ; return true ; } const uint32_t nopEncoding = hasNOP ( ) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding ; uint64_t NumNops = Count / 4 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) support :: endian :: write ( OS , nopEncoding , Endian ) ; switch ( Count % 4 ) { default : break ; case 1 : OS << '\0' ; break ; case 2 : OS . write ( "\0\0" , 2 ) ; break ; case 3 : OS . write ( "\0\0\xa0" , 3 ) ; break ; } return true ; } </s>


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


<s> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const { return createARMMachObjectWriter ( OS , false , object :: mach :: CTM_ARM , Subtype ) ; } </s>

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


"Unexpected fixup kind in fixupNeedsRelaxation()!"


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10_unscaled"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbl"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_condbl"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_blx"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_thumb_bcc"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


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

Get the number of target specific fixup kinds .


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

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


<s> void handleAssemblerFlag ( MCAssemblerFlag Flag ) { switch ( Flag ) { default : break ; case MCAF_Code16 : setIsThumb ( true ) ; break ; case MCAF_Code32 : setIsThumb ( false ) ; break ; } } </s>


<s> bool isThumb ( ) const { return isThumbMode ; } </s>

Tests whether the target is Thumb ( little and big endian ) .


<s> bool ARMAsmBackend :: mayNeedRelaxation ( const MCInst & Inst ) const { if ( getRelaxedOpcode ( Inst . getOpcode ( ) ) != Inst . getOpcode ( ) ) return true ; return false ; } </s>


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

ARM
ARM
256
"\n"
"unexpected instruction to relax: "


<s> bool ARMAsmBackend :: writeNopData ( uint64_t Count , MCObjectWriter * OW ) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0 ; const uint16_t Thumb2_16bitNopEncoding = 0xbf00 ; const uint32_t ARMv4_NopEncoding = 0xe1a00000 ; const uint32_t ARMv6T2_NopEncoding = 0xe320f000 ; if ( isThumb ( ) ) { const uint16_t nopEncoding = hasNOP ( ) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding ; uint64_t NumNops = Count / 2 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> Write16 ( nopEncoding ) ; if ( Count & 1 ) OW -> Write8 ( 0 ) ; return true ; } const uint32_t nopEncoding = hasNOP ( ) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding ; uint64_t NumNops = Count / 4 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> Write32 ( nopEncoding ) ; switch ( Count % 4 ) { default : break ; case 1 : OW -> Write8 ( 0 ) ; break ; case 2 : OW -> Write16 ( 0 ) ; break ; case 3 : OW -> Write16 ( 0 ) ; OW -> Write8 ( 0xa0 ) ; break ; } return true ; } </s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
,
const
MCSubtargetInfo
*
STI
)
const
{
unsigned
Kind
=
Fixup
.
getKind
(
)
;
if
(
Kind
>=
FirstLiteralRelocationKind
)
return
;
unsigned
NumBytes
=
getFixupKindNumBytes
(
Kind
)
;
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
Value
=
adjustFixupValue
(
Asm
,
Fixup
,
Target
,
Value
,
IsResolved
,
Ctx
,
STI
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
Endian
==
support
::
big
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Kind
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
Data
.
size
(
)
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
Endian
==
support
::
little
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


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

getFixupKind - Get the fixup kind of this expression .


<s>
bool
ARMAsmBackend
::
shouldForceRelocation
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
)
{
const
MCSymbolRefExpr
*
A
=
Target
.
getSymA
(
)
;
const
MCSymbol
*
Sym
=
A
&
A
->
getSymbol
(
)
:
nullptr
;
const
unsigned
FixupKind
=
Fixup
.
getKind
(
)
;
if
(
FixupKind
>=
FirstLiteralRelocationKind
)
return
true
;
if
(
FixupKind
==
ARM
::
fixup_arm_thumb_bl
)
{
assert
(
Sym
&&
"How did we resolve this?"
)
;
if
(
Sym
->
isExternal
(
)
)
return
true
;
}
if
(
Sym
&&
Sym
->
isELF
(
)
)
{
unsigned
Type
=
cast
<
MCSymbolELF
>
(
Sym
)
->
getType
(
)
;
if
(
(
Type
==
ELF
::
STT_FUNC
||
Type
==
ELF
::
STT_GNU_IFUNC
)
)
{
if
(
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_uncondbranch
)
)
return
true
;
if
(
!
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_br
||
FixupKind
==
ARM
::
fixup_arm_thumb_bl
||
FixupKind
==
ARM
::
fixup_t2_condbranch
||
FixupKind
==
ARM
::
fixup_t2_uncondbranch
)
)
return
true
;
}
}
if
(
A
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_blx
||
FixupKind
==
ARM
::
fixup_arm_blx
||
FixupKind
==
ARM
::
fixup_arm_uncondbl
||
FixupKind
==
ARM
::
fixup_arm_condbl
)
)
return
true
;
return
false
;
}
</s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCFixup
&
Fixup
,
char
*
Data
,
unsigned
DataSize
,
uint64_t
Value
,
bool
IsPCRel
,
MCContext
&
Ctx
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
Value
=
adjustFixupValue
(
Fixup
,
Value
,
IsPCRel
,
Ctx
,
IsLittleEndian
,
true
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
DataSize
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
!
IsLittleEndian
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
DataSize
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
IsLittleEndian
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


<s>
void
ARMAsmBackend
::
relaxInstruction
(
const
MCInst
&
Inst
,
const
MCSubtargetInfo
&
STI
,
MCInst
&
Res
)
const
{
unsigned
RelaxedOp
=
getRelaxedOpcode
(
Inst
.
getOpcode
(
)
)
;
if
(
RelaxedOp
==
Inst
.
getOpcode
(
)
)
{
SmallString
<
256
>
Tmp
;
raw_svector_ostream
OS
(
Tmp
)
;
Inst
.
dump_pretty
(
OS
)
;
OS
<<
"\n"
;
report_fatal_error
(
"unexpected instruction to relax: "
+
OS
.
str
(
)
)
;
}
if
(
(
Inst
.
getOpcode
(
)
==
ARM
::
tCBZ
||
Inst
.
getOpcode
(
)
==
ARM
::
tCBNZ
)
&&
RelaxedOp
==
ARM
::
tHINT
)
{
Res
.
setOpcode
(
RelaxedOp
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
0
)
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
14
)
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
0
)
)
;
return
;
}
Res
=
Inst
;
Res
.
setOpcode
(
RelaxedOp
)
;
}
</s>


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


<s> bool ARMAsmBackend :: writeNopData ( uint64_t Count , MCObjectWriter * OW ) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0 ; const uint16_t Thumb2_16bitNopEncoding = 0xbf00 ; const uint32_t ARMv4_NopEncoding = 0xe1a0000 ; const uint32_t ARMv6T2_NopEncoding = 0xe320f000 ; if ( isThumb ( ) ) { const uint16_t nopEncoding = hasNOP ( ) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding ; uint64_t NumNops = Count / 2 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> Write16 ( nopEncoding ) ; if ( Count & 1 ) OW -> Write8 ( 0 ) ; return true ; } const uint32_t nopEncoding = hasNOP ( ) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding ; uint64_t NumNops = Count / 4 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) OW -> Write32 ( nopEncoding ) ; switch ( Count % 4 ) { default : break ; case 1 : OW -> Write8 ( 0 ) ; break ; case 2 : OW -> Write16 ( 0 ) ; break ; case 3 : OW -> Write16 ( 0 ) ; OW -> Write8 ( 0xa0 ) ; break ; } return true ; } </s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCFixup
&
Fixup
,
char
*
Data
,
unsigned
DataSize
,
uint64_t
Value
,
bool
IsPCRel
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
Value
=
adjustFixupValue
(
Fixup
,
Value
,
IsPCRel
,
nullptr
,
IsLittleEndian
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
DataSize
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
!
IsLittleEndian
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
DataSize
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
IsLittleEndian
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


"Unexpected fixup kind in fixupNeedsRelaxation()!"


<s>
void
ARMAsmBackend
::
relaxInstruction
(
const
MCInst
&
Inst
,
MCInst
&
Res
)
const
{
unsigned
RelaxedOp
=
getRelaxedOpcode
(
Inst
.
getOpcode
(
)
)
;
if
(
RelaxedOp
==
Inst
.
getOpcode
(
)
)
{
SmallString
<
256
>
Tmp
;
raw_svector_ostream
OS
(
Tmp
)
;
Inst
.
dump_pretty
(
OS
)
;
OS
<<
"\n"
;
report_fatal_error
(
"unexpected instruction to relax: "
+
OS
.
str
(
)
)
;
}
if
(
(
Inst
.
getOpcode
(
)
==
ARM
::
tCBZ
||
Inst
.
getOpcode
(
)
==
ARM
::
tCBNZ
)
&&
RelaxedOp
==
ARM
::
tHINT
)
{
Res
.
setOpcode
(
RelaxedOp
)
;
Res
.
addOperand
(
MCOperand
::
CreateImm
(
0
)
)
;
Res
.
addOperand
(
MCOperand
::
CreateImm
(
14
)
)
;
Res
.
addOperand
(
MCOperand
::
CreateReg
(
0
)
)
;
return
;
}
Res
=
Inst
;
Res
.
setOpcode
(
RelaxedOp
)
;
}
</s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
Value
=
adjustFixupValue
(
Asm
,
Fixup
,
Target
,
Value
,
IsResolved
,
Ctx
,
IsLittleEndian
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
!
IsLittleEndian
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
Data
.
size
(
)
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
IsLittleEndian
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


<s>
bool
ARMAsmBackend
::
shouldForceRelocation
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
)
{
const
MCSymbolRefExpr
*
A
=
Target
.
getSymA
(
)
;
const
MCSymbol
*
Sym
=
A
&
A
->
getSymbol
(
)
:
nullptr
;
const
unsigned
FixupKind
=
Fixup
.
getKind
(
)
;
if
(
(
unsigned
)
Fixup
.
getKind
(
)
==
ARM
::
fixup_arm_thumb_bl
)
{
assert
(
Sym
&&
"How did we resolve this?"
)
;
if
(
Sym
->
isExternal
(
)
)
return
true
;
}
if
(
Sym
&&
Sym
->
isELF
(
)
)
{
unsigned
Type
=
dyn_cast
<
MCSymbolELF
>
(
Sym
)
->
getType
(
)
;
if
(
(
Type
==
ELF
::
STT_FUNC
||
Type
==
ELF
::
STT_GNU_IFUNC
)
)
{
if
(
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_uncondbranch
)
)
return
true
;
if
(
!
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_br
||
FixupKind
==
ARM
::
fixup_arm_thumb_bl
||
FixupKind
==
ARM
::
fixup_t2_condbranch
||
FixupKind
==
ARM
::
fixup_t2_uncondbranch
)
)
return
true
;
}
}
if
(
A
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_blx
||
FixupKind
==
ARM
::
fixup_arm_blx
||
FixupKind
==
ARM
::
fixup_arm_uncondbl
||
FixupKind
==
ARM
::
fixup_arm_condbl
)
)
return
true
;
return
false
;
}
</s>


<s> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const { return createMachObjectWriter ( new ARMMachObjectWriter ( false , object :: mach :: CTM_ARM , object :: mach :: CSARM_V7 ) , OS , true ) ; } </s>


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
7
,
21
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
1
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bcc"
,
1
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
TargetAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsPCRel
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
Value
=
adjustFixupValue
(
Asm
,
Fixup
,
Target
,
Value
,
IsPCRel
,
Ctx
,
IsLittleEndian
,
true
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
!
IsLittleEndian
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
Data
.
size
(
)
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
IsLittleEndian
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
Value
=
adjustFixupValue
(
Asm
,
Fixup
,
Target
,
Value
,
IsResolved
,
Ctx
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
Endian
==
support
::
big
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
Data
.
size
(
)
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
Endian
==
support
::
little
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


<s> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const override { return createARMMachObjectWriter ( OS , false , MachO :: CPU_TYPE_ARM , Subtype ) ; } </s>


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
override
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10_unscaled"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbl"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_condbl"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_blx"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_thumb_bcc"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s> void handleAssemblerFlag ( MCAssemblerFlag Flag ) override { switch ( Flag ) { default : break ; case MCAF_Code16 : setIsThumb ( true ) ; break ; case MCAF_Code32 : setIsThumb ( false ) ; break ; } } </s>


<s>
void
ARMAsmBackend
::
relaxInstruction
(
MCInst
&
Inst
,
const
MCSubtargetInfo
&
STI
)
const
{
unsigned
RelaxedOp
=
getRelaxedOpcode
(
Inst
.
getOpcode
(
)
,
STI
)
;
if
(
RelaxedOp
==
Inst
.
getOpcode
(
)
)
{
SmallString
<
256
>
Tmp
;
raw_svector_ostream
OS
(
Tmp
)
;
Inst
.
dump_pretty
(
OS
)
;
OS
<<
"\n"
;
report_fatal_error
(
"unexpected instruction to relax: "
+
OS
.
str
(
)
)
;
}
if
(
(
Inst
.
getOpcode
(
)
==
ARM
::
tCBZ
||
Inst
.
getOpcode
(
)
==
ARM
::
tCBNZ
)
&&
RelaxedOp
==
ARM
::
tHINT
)
{
MCInst
Res
;
Res
.
setOpcode
(
RelaxedOp
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
0
)
)
;
Res
.
addOperand
(
MCOperand
::
createImm
(
14
)
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
0
)
)
;
Inst
=
std
::
move
(
Res
)
;
return
;
}
Inst
.
setOpcode
(
RelaxedOp
)
;
}
</s>


<s> Optional < MCFixupKind > ARMAsmBackend :: getFixupKind ( StringRef Name ) const { if ( STI . getTargetTriple ( ) . isOSBinFormatELF ( ) && Name == "R_ARM_NONE" ) return FK_NONE ; return MCAsmBackend :: getFixupKind ( Name ) ; } </s>


<s>
bool
ARMAsmBackend
::
shouldForceRelocation
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
)
{
const
MCSymbolRefExpr
*
A
=
Target
.
getSymA
(
)
;
const
MCSymbol
*
Sym
=
A
&
A
->
getSymbol
(
)
:
nullptr
;
const
unsigned
FixupKind
=
Fixup
.
getKind
(
)
;
if
(
FixupKind
==
FK_NONE
)
return
true
;
if
(
FixupKind
==
ARM
::
fixup_arm_thumb_bl
)
{
assert
(
Sym
&&
"How did we resolve this?"
)
;
if
(
Sym
->
isExternal
(
)
)
return
true
;
}
if
(
Sym
&&
Sym
->
isELF
(
)
)
{
unsigned
Type
=
cast
<
MCSymbolELF
>
(
Sym
)
->
getType
(
)
;
if
(
(
Type
==
ELF
::
STT_FUNC
||
Type
==
ELF
::
STT_GNU_IFUNC
)
)
{
if
(
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_uncondbranch
)
)
return
true
;
if
(
!
Asm
.
isThumbFunc
(
Sym
)
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_br
||
FixupKind
==
ARM
::
fixup_arm_thumb_bl
||
FixupKind
==
ARM
::
fixup_t2_condbranch
||
FixupKind
==
ARM
::
fixup_t2_uncondbranch
)
)
return
true
;
}
}
if
(
A
&&
(
FixupKind
==
ARM
::
fixup_arm_thumb_blx
||
FixupKind
==
ARM
::
fixup_arm_blx
||
FixupKind
==
ARM
::
fixup_arm_uncondbl
||
FixupKind
==
ARM
::
fixup_arm_condbl
)
)
return
true
;
return
false
;
}
</s>


<s> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const { return createMachObjectWriter ( OS , false , object :: mach :: CTM_ARM , object :: mach :: CSARM_V7 , true ) ; } </s>


<s> virtual const MCObjectFormat & getObjectFormat ( ) const { return Format ; } </s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
,
const
MCSubtargetInfo
*
STI
)
const
{
unsigned
Kind
=
Fixup
.
getKind
(
)
;
if
(
Kind
>=
FirstLiteralRelocationKind
)
return
;
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
Value
=
adjustFixupValue
(
Asm
,
Fixup
,
Target
,
Value
,
IsResolved
,
Ctx
,
STI
)
;
if
(
!
Value
)
return
;
const
unsigned
NumBytes
=
getFixupKindNumBytes
(
Kind
)
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
Endian
==
support
::
big
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Kind
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
Data
.
size
(
)
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
Endian
==
support
::
little
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


<s> Optional < MCFixupKind > ARMAsmBackendELF :: getFixupKind ( StringRef Name ) const { unsigned Type = llvm :: StringSwitch < unsigned > ( Name ) . Case ( "BFD_RELOC_NONE" , ELF :: R_ARM_NONE ) . Case ( "BFD_RELOC_8" , ELF :: R_ARM_ABS8 ) . Case ( "BFD_RELOC_16" , ELF :: R_ARM_ABS16 ) . Case ( "BFD_RELOC_32" , ELF :: R_ARM_ABS32 ) . Default ( - 1u ) ; if ( Type == - 1u ) return None ; return static_cast < MCFixupKind > ( FirstLiteralRelocationKind + Type ) ; } </s>


<s> bool ARMAsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count , const MCSubtargetInfo * STI ) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0 ; const uint16_t Thumb2_16bitNopEncoding = 0xbf00 ; const uint32_t ARMv4_NopEncoding = 0xe1a00000 ; const uint32_t ARMv6T2_NopEncoding = 0xe320f000 ; if ( isThumb ( ) ) { const uint16_t nopEncoding = hasNOP ( STI ) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding ; uint64_t NumNops = Count / 2 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) support :: endian :: write ( OS , nopEncoding , Endian ) ; if ( Count & 1 ) OS << '\0' ; return true ; } const uint32_t nopEncoding = hasNOP ( STI ) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding ; uint64_t NumNops = Count / 4 ; for ( uint64_t i = 0 ; i != NumNops ; ++ i ) support :: endian :: write ( OS , nopEncoding , Endian ) ; switch ( Count % 4 ) { default : break ; case 1 : OS << '\0' ; break ; case 2 : OS . write ( "\0\0" , 2 ) ; break ; case 3 : OS . write ( "\0\0\xa0" , 3 ) ; break ; } return true ; } </s>


<s> Optional < MCFixupKind > ARMAsmBackend :: getFixupKind ( StringRef Name ) const { if ( ! STI . getTargetTriple ( ) . isOSBinFormatELF ( ) ) return None ; unsigned Type = llvm :: StringSwitch < unsigned > ( Name ) . Case ( "BFD_RELOC_NONE" , ELF :: R_ARM_NONE ) . Case ( "BFD_RELOC_8" , ELF :: R_ARM_ABS8 ) . Case ( "BFD_RELOC_16" , ELF :: R_ARM_ABS16 ) . Case ( "BFD_RELOC_32" , ELF :: R_ARM_ABS32 ) . Default ( - 1u ) ; if ( Type == - 1u ) return None ; return static_cast < MCFixupKind > ( FirstLiteralRelocationKind + Type ) ; } </s>


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


<s> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const override { return createARMELFObjectWriter ( OS , OSABI , isLittle ( ) ) ; } </s>


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


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10_unscaled"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbl"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_condbl"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_blx"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bcc"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


"Unexpected fixup kind in fixupNeedsRelaxation()!"


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10_unscaled"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bcc"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s>
void
ARMAsmBackend
::
applyFixup
(
const
MCFixup
&
Fixup
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsPCRel
,
MCContext
&
Ctx
)
const
{
unsigned
NumBytes
=
getFixupKindNumBytes
(
Fixup
.
getKind
(
)
)
;
Value
=
adjustFixupValue
(
Fixup
,
Value
,
IsPCRel
,
Ctx
,
IsLittleEndian
,
true
)
;
if
(
!
Value
)
return
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
unsigned
FullSizeBytes
;
if
(
!
IsLittleEndian
)
{
FullSizeBytes
=
getFixupKindContainerSizeBytes
(
Fixup
.
getKind
(
)
)
;
assert
(
(
Offset
+
FullSizeBytes
)
<=
Data
.
size
(
)
&&
"Invalid fixup size!"
)
;
assert
(
NumBytes
<=
FullSizeBytes
&&
"Invalid fixup size!"
)
;
}
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
unsigned
Idx
=
IsLittleEndian
i
:
(
FullSizeBytes
1
i
)
;
Data
[
Offset
+
Idx
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>


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


<s> MCObjectWriter * createObjectWriter ( raw_ostream & OS ) const { return createARMMachObjectWriter ( OS , false , MachO :: CPU_TYPE_ARM , Subtype ) ; } </s>


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bcc"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bcc"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
ARM
::
NumTargetFixupKinds
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_pcrel_10_unscaled"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_thumb_adr_pcrel_10"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_adr_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAlignedDownTo32Bits
}
,
{
"fixup_arm_condbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_uncondbranch"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_condbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_uncondbranch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_br"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_bl"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_blx"
,
0
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_bcc"
,
0
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movt_hi16"
,
0
,
20
,
0
}
,
{
"fixup_t2_movw_lo16"
,
0
,
20
,
0
}
,
{
"fixup_arm_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movt_hi16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_movw_lo16_pcrel"
,
0
,
20
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCAsmBackend
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s> std :: unique_ptr < MCObjectWriter > createObjectWriter ( raw_pwrite_stream & OS ) const override { return createARMMachObjectWriter ( OS , false , MachO :: CPU_TYPE_ARM , Subtype ) ; } </s>


<s> MCObjectWriter * createObjectWriter ( raw_pwrite_stream & OS ) const override { return createARMMachObjectWriter ( OS , false , MachO :: CPU_TYPE_ARM , Subtype ) ; } </s>


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


<s> std :: unique_ptr < MCObjectWriter > createObjectWriter ( raw_pwrite_stream & OS ) const override { return createARMELFObjectWriter ( OS , OSABI , isLittle ( ) ) ; } </s>


<s> std :: unique_ptr < MCObjectWriter > createObjectWriter ( raw_pwrite_stream & OS ) const override { return createARMWinCOFFObjectWriter ( OS , false ) ; } </s>


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


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


<s>
AsmToken
LexToken
(
)
{
if
(
!
Lexer
)
{
SetError
(
SMLoc
(
)
,
"No MCAsmLexer installed"
)
;
return
AsmToken
(
AsmToken
::
Error
,
""
,
0
)
;
}
switch
(
AsmInfo
.
getAssemblerDialect
(
)
)
{
default
:
SetError
(
SMLoc
(
)
,
"Unhandled dialect"
)
;
return
AsmToken
(
AsmToken
::
Error
,
""
,
0
)
;
case
0
:
return
LexTokenUAL
(
)
;
}
}
</s>

LexToken - Read the next token and return its code .


"optionally flag setting instruction missing optional def operand"

checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not expressible via match classes .


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

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


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

Returns the register associated with this edge .


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

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


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


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


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


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


"flag setting instruction only valid outside IT block"

"instruction only valid inside IT block"

"instruction variant requires ARMv6 or later"

"immediate operand must be in the range [0,4]"

"immediate operand must be in the range [0,15]"

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


<s> bool ARMAsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getIdentifier ( ) ; if ( IDVal == ".word" ) return parseDirectiveWord ( 4 , DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb" ) return parseDirectiveThumb ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".arm" ) return parseDirectiveARM ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb_func" ) return parseDirectiveThumbFunc ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".code" ) return parseDirectiveCode ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".syntax" ) return parseDirectiveSyntax ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".unreq" ) return parseDirectiveUnreq ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".arch" ) return parseDirectiveArch ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".eabi_attribute" ) return parseDirectiveEabiAttr ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".fnstart" ) return parseDirectiveFnStart ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".fnend" ) return parseDirectiveFnEnd ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".cantunwind" ) return parseDirectiveCantUnwind ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".personality" ) return parseDirectivePersonality ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".handlerdata" ) return parseDirectiveHandlerData ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".setfp" ) return parseDirectiveSetFP ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".pad" ) return parseDirectivePad ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".save" ) return parseDirectiveRegSave ( DirectiveID . getLoc ( ) , false ) ; else if ( IDVal == ".vsave" ) return parseDirectiveRegSave ( DirectiveID . getLoc ( ) , true ) ; return true ; } </s>

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


<s> unsigned ARMAsmParser :: validateTargetOperandClass ( MCParsedAsmOperand * AsmOp , unsigned Kind ) { ARMOperand * Op = static_cast < ARMOperand * > ( AsmOp ) ; if ( Kind == MCK__35_0 && Op -> isImm ( ) ) { const MCConstantExpr * CE = dyn_cast < MCConstantExpr > ( Op -> getImm ( ) ) ; if ( ! CE ) return Match_InvalidOperand ; if ( CE -> getValue ( ) == 0 ) return Match_Success ; } 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 addExpr ( MCInst & Inst , const MCExpr * Expr ) const { if ( ! Expr ) Inst . addOperand ( MCOperand :: createImm ( 0 ) ) ; else if ( const MCConstantExpr * CE = dyn_cast < MCConstantExpr > ( Expr ) ) Inst . addOperand ( MCOperand :: createImm ( CE -> getValue ( ) ) ) ; else Inst . addOperand ( MCOperand :: createExpr ( Expr ) ) ; } </s>


<s> static std :: unique_ptr < ARMOperand > CreateMem ( unsigned BaseRegNum , const MCConstantExpr * OffsetImm , unsigned OffsetRegNum , ARM_AM :: ShiftOpc ShiftType , unsigned ShiftImm , unsigned Alignment , bool isNegative , SMLoc S , SMLoc E , SMLoc AlignmentLoc = SMLoc ( ) ) { auto Op = make_unique < ARMOperand > ( k_Memory ) ; Op -> Memory . BaseRegNum = BaseRegNum ; Op -> Memory . OffsetImm = OffsetImm ; Op -> Memory . OffsetRegNum = OffsetRegNum ; Op -> Memory . ShiftType = ShiftType ; Op -> Memory . ShiftImm = ShiftImm ; Op -> Memory . Alignment = Alignment ; Op -> Memory . isNegative = isNegative ; Op -> StartLoc = S ; Op -> EndLoc = E ; Op -> AlignmentLoc = AlignmentLoc ; return Op ; } </s>


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

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


<s> bool Error ( SMLoc L , const Twine & Msg , SMRange Range = None ) { return getParser ( ) . Error ( L , Msg , Range ) ; } </s>

Return an error at the location L , with the message Msg .


<s> void flushPendingInstructions ( MCStreamer & Out ) override { if ( ! inImplicitITBlock ( ) ) { assert ( PendingConditionalInsts . size ( ) == 0 ) ; return ; } unsigned Mask = getITMaskEncoding ( ) ; MCInst ITInst ; ITInst . setOpcode ( ARM :: t2IT ) ; ITInst . addOperand ( MCOperand :: createImm ( ITState . Cond ) ) ; ITInst . addOperand ( MCOperand :: createImm ( Mask ) ) ; Out . EmitInstruction ( ITInst , getSTI ( ) ) ; assert ( PendingConditionalInsts . size ( ) <= 4 ) ; for ( const MCInst & Inst : PendingConditionalInsts ) { Out . EmitInstruction ( Inst , getSTI ( ) ) ; } PendingConditionalInsts . clear ( ) ; ITState . Mask = 0 ; ITState . CurPosition = ~ 0U ; } </s>

Ensure that all previously parsed instructions have been emitted to the output streamer , if the target does not emit them immediately .


<s> bool isThumb ( ) const { return getSTI ( ) . getFeatureBits ( ) [ ARM :: ModeThumb ] ; } </s>


<s>
bool
ARMAsmParser
::
MatchAndEmitInstruction
(
SMLoc
IDLoc
,
unsigned
&
Opcode
,
OperandVector
&
Operands
,
MCStreamer
&
Out
,
uint64_t
&
ErrorInfo
,
bool
MatchingInlineAsm
)
{
MCInst
Inst
;
unsigned
MatchResult
;
bool
PendConditionalInstruction
=
false
;
SmallVector
<
NearMissInfo
,
4
>
NearMisses
;
MatchResult
=
MatchInstruction
(
Operands
,
Inst
,
NearMisses
,
MatchingInlineAsm
,
PendConditionalInstruction
,
Out
)
;
switch
(
MatchResult
)
{
case
Match_Success
:
if
(
validateInstruction
(
Inst
,
Operands
)
)
{
forwardITPosition
(
)
;
return
true
;
}
{
bool
wasInITBlock
=
inITBlock
(
)
;
while
(
processInstruction
(
Inst
,
Operands
,
Out
)
)
;
if
(
wasInITBlock
&&
hasV8Ops
(
)
&&
isThumb
(
)
&&
!
isV8EligibleForIT
(
&
Inst
)
)
{
Warning
(
IDLoc
,
"deprecated instruction in IT block"
)
;
}
}
forwardITPosition
(
)
;
if
(
Inst
.
getOpcode
(
)
==
ARM
::
ITasm
)
return
false
;
Inst
.
setLoc
(
IDLoc
)
;
if
(
PendConditionalInstruction
)
{
PendingConditionalInsts
.
push_back
(
Inst
)
;
if
(
isITBlockFull
(
)
||
isITBlockTerminator
(
Inst
)
)
flushPendingInstructions
(
Out
)
;
}
else
{
Out
.
EmitInstruction
(
Inst
,
getSTI
(
)
)
;
}
return
false
;
case
Match_NearMisses
:
ReportNearMisses
(
NearMisses
,
IDLoc
,
Operands
)
;
return
true
;
case
Match_MnemonicFail
:
{
uint64_t
FBS
=
ComputeAvailableFeatures
(
getSTI
(
)
.
getFeatureBits
(
)
)
;
std
::
string
Suggestion
=
ARMMnemonicSpellCheck
(
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getToken
(
)
,
FBS
)
;
return
Error
(
IDLoc
,
"invalid instruction"
+
Suggestion
,
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getLocRange
(
)
)
;
}
}
llvm_unreachable
(
"Implement any new match types added!"
)
;
}
</s>

ARM
ARM
4
"deprecated instruction in IT block"
ARM::ITasm
ARM
ARM
0
"invalid instruction"
ARM
0
"Implement any new match types added!"


<s> void Note ( SMLoc L , const Twine & Msg , SMRange Range = None ) { return getParser ( ) . Note ( L , Msg , Range ) ; } </s>

Emit a note at the location L , with the message Msg .


<s> int ARMAsmParser :: tryParseRegister ( ) { MCAsmParser & Parser = getParser ( ) ; const AsmToken & Tok = Parser . getTok ( ) ; if ( Tok . isNot ( AsmToken :: Identifier ) ) return - 1 ; std :: string lowerCase = Tok . getString ( ) . lower ( ) ; unsigned RegNum = MatchRegisterName ( lowerCase ) ; if ( ! RegNum ) { RegNum = StringSwitch < unsigned > ( lowerCase ) . Case ( "r13" , ARM :: SP ) . Case ( "r14" , ARM :: LR ) . Case ( "r15" , ARM :: PC ) . Case ( "ip" , ARM :: R12 ) . Case ( "a1" , ARM :: R0 ) . Case ( "a2" , ARM :: R1 ) . Case ( "a3" , ARM :: R2 ) . Case ( "a4" , ARM :: R3 ) . Case ( "v1" , ARM :: R4 ) . Case ( "v2" , ARM :: R5 ) . Case ( "v3" , ARM :: R6 ) . Case ( "v4" , ARM :: R7 ) . Case ( "v5" , ARM :: R8 ) . Case ( "v6" , ARM :: R9 ) . Case ( "v7" , ARM :: R10 ) . Case ( "v8" , ARM :: R11 ) . Case ( "sb" , ARM :: R9 ) . Case ( "sl" , ARM :: R10 ) . Case ( "fp" , ARM :: R11 ) . Default ( 0 ) ; } if ( ! RegNum ) { StringMap < unsigned > :: const_iterator Entry = RegisterReqs . find ( lowerCase ) ; if ( Entry == RegisterReqs . end ( ) ) return - 1 ; Parser . Lex ( ) ; return Entry -> getValue ( ) ; } if ( hasD16 ( ) && RegNum >= ARM :: D16 && RegNum <= ARM :: D31 ) return - 1 ; Parser . Lex ( ) ; return RegNum ; } </s>

tryParseRegister - parse one register if possible


"expression value must be representable in 32 bits"


<s> bool Warning ( SMLoc L , const Twine & Msg , SMRange Range = None ) { return getParser ( ) . Warning ( L , Msg , Range ) ; } </s>

Emit a warning at the location L , with the message Msg .


<s> static std :: unique_ptr < ARMOperand > CreateMem ( unsigned BaseRegNum , const MCExpr * OffsetImm , unsigned OffsetRegNum , ARM_AM :: ShiftOpc ShiftType , unsigned ShiftImm , unsigned Alignment , bool isNegative , SMLoc S , SMLoc E , SMLoc AlignmentLoc = SMLoc ( ) ) { auto Op = std :: make_unique < ARMOperand > ( k_Memory ) ; Op -> Memory . BaseRegNum = BaseRegNum ; Op -> Memory . OffsetImm = OffsetImm ; Op -> Memory . OffsetRegNum = OffsetRegNum ; Op -> Memory . ShiftType = ShiftType ; Op -> Memory . ShiftImm = ShiftImm ; Op -> Memory . Alignment = Alignment ; Op -> Memory . isNegative = isNegative ; Op -> StartLoc = S ; Op -> EndLoc = E ; Op -> AlignmentLoc = AlignmentLoc ; return Op ; } </s>


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


<s> void flushPendingInstructions ( MCStreamer & Out ) override { if ( ! inImplicitITBlock ( ) ) { assert ( PendingConditionalInsts . size ( ) == 0 ) ; return ; } MCInst ITInst ; ITInst . setOpcode ( ARM :: t2IT ) ; ITInst . addOperand ( MCOperand :: createImm ( ITState . Cond ) ) ; ITInst . addOperand ( MCOperand :: createImm ( ITState . Mask ) ) ; Out . emitInstruction ( ITInst , getSTI ( ) ) ; assert ( PendingConditionalInsts . size ( ) <= 4 ) ; for ( const MCInst & Inst : PendingConditionalInsts ) { Out . emitInstruction ( Inst , getSTI ( ) ) ; } PendingConditionalInsts . clear ( ) ; ITState . Mask = 0 ; ITState . CurPosition = ~ 0U ; } </s>


<s> bool isMem ( ) const override { return isGPRMem ( ) || isMVEMem ( ) ; } </s>


<s>
bool
ARMAsmParser
::
MatchAndEmitInstruction
(
SMLoc
IDLoc
,
unsigned
&
Opcode
,
OperandVector
&
Operands
,
MCStreamer
&
Out
,
uint64_t
&
ErrorInfo
,
bool
MatchingInlineAsm
)
{
MCInst
Inst
;
unsigned
MatchResult
;
bool
PendConditionalInstruction
=
false
;
SmallVector
<
NearMissInfo
,
4
>
NearMisses
;
MatchResult
=
MatchInstruction
(
Operands
,
Inst
,
NearMisses
,
MatchingInlineAsm
,
PendConditionalInstruction
,
Out
)
;
switch
(
MatchResult
)
{
case
Match_Success
:
LLVM_DEBUG
(
dbgs
(
)
<<
"Parsed as: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
validateInstruction
(
Inst
,
Operands
)
)
{
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
return
true
;
}
{
while
(
processInstruction
(
Inst
,
Operands
,
Out
)
)
LLVM_DEBUG
(
dbgs
(
)
<<
"Changed to: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
}
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
if
(
Inst
.
getOpcode
(
)
==
ARM
::
ITasm
)
return
false
;
Inst
.
setLoc
(
IDLoc
)
;
if
(
PendConditionalInstruction
)
{
PendingConditionalInsts
.
push_back
(
Inst
)
;
if
(
isITBlockFull
(
)
||
isITBlockTerminator
(
Inst
)
)
flushPendingInstructions
(
Out
)
;
}
else
{
Out
.
emitInstruction
(
Inst
,
getSTI
(
)
)
;
}
return
false
;
case
Match_NearMisses
:
ReportNearMisses
(
NearMisses
,
IDLoc
,
Operands
)
;
return
true
;
case
Match_MnemonicFail
:
{
FeatureBitset
FBS
=
ComputeAvailableFeatures
(
getSTI
(
)
.
getFeatureBits
(
)
)
;
std
::
string
Suggestion
=
ARMMnemonicSpellCheck
(
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getToken
(
)
,
FBS
)
;
return
Error
(
IDLoc
,
"invalid instruction"
+
Suggestion
,
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getLocRange
(
)
)
;
}
}
llvm_unreachable
(
"Implement any new match types added!"
)
;
}
</s>

ARM
ARM
4
"Parsed as: "
"\n"
"Changed to: "
"\n"
ARM::ITasm
ARM
ARM
0
"invalid instruction"
ARM
0
"Implement any new match types added!"


<s> int ARMAsmParser :: tryParseRegister ( ) { MCAsmParser & Parser = getParser ( ) ; const AsmToken & Tok = Parser . getTok ( ) ; if ( Tok . isNot ( AsmToken :: Identifier ) ) return - 1 ; std :: string lowerCase = Tok . getString ( ) . lower ( ) ; unsigned RegNum = MatchRegisterName ( lowerCase ) ; if ( ! RegNum ) { RegNum = StringSwitch < unsigned > ( lowerCase ) . Case ( "r13" , ARM :: SP ) . Case ( "r14" , ARM :: LR ) . Case ( "r15" , ARM :: PC ) . Case ( "ip" , ARM :: R12 ) . Case ( "a1" , ARM :: R0 ) . Case ( "a2" , ARM :: R1 ) . Case ( "a3" , ARM :: R2 ) . Case ( "a4" , ARM :: R3 ) . Case ( "v1" , ARM :: R4 ) . Case ( "v2" , ARM :: R5 ) . Case ( "v3" , ARM :: R6 ) . Case ( "v4" , ARM :: R7 ) . Case ( "v5" , ARM :: R8 ) . Case ( "v6" , ARM :: R9 ) . Case ( "v7" , ARM :: R10 ) . Case ( "v8" , ARM :: R11 ) . Case ( "sb" , ARM :: R9 ) . Case ( "sl" , ARM :: R10 ) . Case ( "fp" , ARM :: R11 ) . Default ( 0 ) ; } if ( ! RegNum ) { StringMap < unsigned > :: const_iterator Entry = RegisterReqs . find ( lowerCase ) ; if ( Entry == RegisterReqs . end ( ) ) return - 1 ; Parser . Lex ( ) ; return Entry -> getValue ( ) ; } if ( ! hasD32 ( ) && RegNum >= ARM :: D16 && RegNum <= ARM :: D31 ) return - 1 ; Parser . Lex ( ) ; return RegNum ; } </s>


<s> static std :: unique_ptr < ARMOperand > CreateMem ( unsigned BaseRegNum , const MCConstantExpr * OffsetImm , unsigned OffsetRegNum , ARM_AM :: ShiftOpc ShiftType , unsigned ShiftImm , unsigned Alignment , bool isNegative , SMLoc S , SMLoc E , SMLoc AlignmentLoc = SMLoc ( ) ) { auto Op = std :: make_unique < ARMOperand > ( k_Memory ) ; Op -> Memory . BaseRegNum = BaseRegNum ; Op -> Memory . OffsetImm = OffsetImm ; Op -> Memory . OffsetRegNum = OffsetRegNum ; Op -> Memory . ShiftType = ShiftType ; Op -> Memory . ShiftImm = ShiftImm ; Op -> Memory . Alignment = Alignment ; Op -> Memory . isNegative = isNegative ; Op -> StartLoc = S ; Op -> EndLoc = E ; Op -> AlignmentLoc = AlignmentLoc ; return Op ; } </s>


<s> void flushPendingInstructions ( MCStreamer & Out ) override { if ( ! inImplicitITBlock ( ) ) { assert ( PendingConditionalInsts . size ( ) == 0 ) ; return ; } MCInst ITInst ; ITInst . setOpcode ( ARM :: t2IT ) ; ITInst . addOperand ( MCOperand :: createImm ( ITState . Cond ) ) ; ITInst . addOperand ( MCOperand :: createImm ( ITState . Mask ) ) ; Out . EmitInstruction ( ITInst , getSTI ( ) ) ; assert ( PendingConditionalInsts . size ( ) <= 4 ) ; for ( const MCInst & Inst : PendingConditionalInsts ) { Out . EmitInstruction ( Inst , getSTI ( ) ) ; } PendingConditionalInsts . clear ( ) ; ITState . Mask = 0 ; ITState . CurPosition = ~ 0U ; } </s>


<s>
bool
ARMAsmParser
::
MatchAndEmitInstruction
(
SMLoc
IDLoc
,
unsigned
&
Opcode
,
OperandVector
&
Operands
,
MCStreamer
&
Out
,
uint64_t
&
ErrorInfo
,
bool
MatchingInlineAsm
)
{
MCInst
Inst
;
unsigned
MatchResult
;
bool
PendConditionalInstruction
=
false
;
SmallVector
<
NearMissInfo
,
4
>
NearMisses
;
MatchResult
=
MatchInstruction
(
Operands
,
Inst
,
NearMisses
,
MatchingInlineAsm
,
PendConditionalInstruction
,
Out
)
;
switch
(
MatchResult
)
{
case
Match_Success
:
LLVM_DEBUG
(
dbgs
(
)
<<
"Parsed as: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
validateInstruction
(
Inst
,
Operands
)
)
{
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
return
true
;
}
{
bool
wasInITBlock
=
inITBlock
(
)
;
while
(
processInstruction
(
Inst
,
Operands
,
Out
)
)
LLVM_DEBUG
(
dbgs
(
)
<<
"Changed to: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
wasInITBlock
&&
hasV8Ops
(
)
&&
isThumb
(
)
&&
!
isV8EligibleForIT
(
&
Inst
)
)
{
Warning
(
IDLoc
,
"deprecated instruction in IT block"
)
;
}
}
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
if
(
Inst
.
getOpcode
(
)
==
ARM
::
ITasm
)
return
false
;
Inst
.
setLoc
(
IDLoc
)
;
if
(
PendConditionalInstruction
)
{
PendingConditionalInsts
.
push_back
(
Inst
)
;
if
(
isITBlockFull
(
)
||
isITBlockTerminator
(
Inst
)
)
flushPendingInstructions
(
Out
)
;
}
else
{
Out
.
EmitInstruction
(
Inst
,
getSTI
(
)
)
;
}
return
false
;
case
Match_NearMisses
:
ReportNearMisses
(
NearMisses
,
IDLoc
,
Operands
)
;
return
true
;
case
Match_MnemonicFail
:
{
FeatureBitset
FBS
=
ComputeAvailableFeatures
(
getSTI
(
)
.
getFeatureBits
(
)
)
;
std
::
string
Suggestion
=
ARMMnemonicSpellCheck
(
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getToken
(
)
,
FBS
)
;
return
Error
(
IDLoc
,
"invalid instruction"
+
Suggestion
,
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getLocRange
(
)
)
;
}
}
llvm_unreachable
(
"Implement any new match types added!"
)
;
}
</s>

ARM
ARM
4
"Parsed as: "
"\n"
"Changed to: "
"\n"
"deprecated instruction in IT block"
ARM::ITasm
ARM
ARM
0
"invalid instruction"
ARM
0
"Implement any new match types added!"


"optionally flag setting instruction missing optional def operand"


<s> bool Error ( SMLoc L , const Twine & Msg , ArrayRef < SMRange > Ranges = None ) { return getParser ( ) . Error ( L , Msg , Ranges ) ; } </s>


<s> void Note ( SMLoc L , const Twine & Msg , ArrayRef < SMRange > Ranges = None ) { return getParser ( ) . Note ( L , Msg , Ranges ) ; } </s>


<s> bool Warning ( SMLoc L , const Twine & Msg , ArrayRef < SMRange > Ranges = None ) { return getParser ( ) . Warning ( L , Msg , Ranges ) ; } </s>


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


<s> static ARMOperand * CreateMem ( unsigned BaseRegNum , const MCConstantExpr * OffsetImm , unsigned OffsetRegNum , ARM_AM :: ShiftOpc ShiftType , unsigned ShiftImm , unsigned Alignment , bool isNegative , SMLoc S , SMLoc E ) { ARMOperand * Op = new ARMOperand ( k_Memory ) ; Op -> Memory . BaseRegNum = BaseRegNum ; Op -> Memory . OffsetImm = OffsetImm ; Op -> Memory . OffsetRegNum = OffsetRegNum ; Op -> Memory . ShiftType = ShiftType ; Op -> Memory . ShiftImm = ShiftImm ; Op -> Memory . Alignment = Alignment ; Op -> Memory . isNegative = isNegative ; Op -> StartLoc = S ; Op -> EndLoc = E ; return Op ; } </s>


<s> static ARMOperand * CreateReg ( unsigned RegNum , SMLoc S , SMLoc E ) { ARMOperand * Op = new ARMOperand ( k_Register ) ; Op -> Reg . RegNum = RegNum ; Op -> StartLoc = S ; Op -> EndLoc = E ; return Op ; } </s>


<s> bool Error ( SMLoc L , const Twine & Msg , ArrayRef < SMRange > Ranges = None ) { return Parser . Error ( L , Msg , Ranges ) ; } </s>


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


<s> SMRange getLocRange ( ) const { return SMRange ( StartLoc , EndLoc ) ; } </s>

getLocRange - Get the range between the first and last token of this operand .


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


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


<s> bool isFPImm ( ) const { if ( ! isImm ( ) ) return false ; const MCConstantExpr * CE = dyn_cast < MCConstantExpr > ( getImm ( ) ) ; if ( ! CE ) return false ; int Val = ARM_AM :: getFP32Imm ( APInt ( 32 , CE -> getValue ( ) ) ) ; return Val != - 1 ; } </s>

isFPImm - Tests if this is a MO_FPImmediate operand .


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


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


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


<s> bool isThumb ( ) const { return ( STI . getFeatureBits ( ) & ARM :: ModeThumb ) != 0 ; } </s>

Tests whether the target is Thumb ( little and big endian ) .


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


"flag setting instruction only valid outside IT block"

"instruction only valid inside IT block"

"instruction variant requires ARMv6 or later"

"immediate operand must be in the range [0,15]"

"immediate operand must be in the range [0,239]"


<s> void Note ( SMLoc L , const Twine & Msg , ArrayRef < SMRange > Ranges = None ) { return Parser . Note ( L , Msg , Ranges ) ; } </s>


<s> void reset ( ) { FnStartLocs = Locs ( ) ; CantUnwindLocs = Locs ( ) ; PersonalityLocs = Locs ( ) ; HandlerDataLocs = Locs ( ) ; PersonalityIndexLocs = Locs ( ) ; FPReg = ARM :: SP ; } </s>

Reset an existing scalar value for Def and a given Instance .


<s> int ARMAsmParser :: tryParseRegister ( ) { const AsmToken & Tok = Parser . getTok ( ) ; if ( Tok . isNot ( AsmToken :: Identifier ) ) return - 1 ; std :: string lowerCase = Tok . getString ( ) . lower ( ) ; unsigned RegNum = MatchRegisterName ( lowerCase ) ; if ( ! RegNum ) { RegNum = StringSwitch < unsigned > ( lowerCase ) . Case ( "r13" , ARM :: SP ) . Case ( "r14" , ARM :: LR ) . Case ( "r15" , ARM :: PC ) . Case ( "ip" , ARM :: R12 ) . Case ( "a1" , ARM :: R0 ) . Case ( "a2" , ARM :: R1 ) . Case ( "a3" , ARM :: R2 ) . Case ( "a4" , ARM :: R3 ) . Case ( "v1" , ARM :: R4 ) . Case ( "v2" , ARM :: R5 ) . Case ( "v3" , ARM :: R6 ) . Case ( "v4" , ARM :: R7 ) . Case ( "v5" , ARM :: R8 ) . Case ( "v6" , ARM :: R9 ) . Case ( "v7" , ARM :: R10 ) . Case ( "v8" , ARM :: R11 ) . Case ( "sb" , ARM :: R9 ) . Case ( "sl" , ARM :: R10 ) . Case ( "fp" , ARM :: R11 ) . Default ( 0 ) ; } if ( ! RegNum ) { StringMap < unsigned > :: const_iterator Entry = RegisterReqs . find ( lowerCase ) ; if ( Entry == RegisterReqs . end ( ) ) return - 1 ; Parser . Lex ( ) ; return Entry -> getValue ( ) ; } Parser . Lex ( ) ; return RegNum ; } </s>


"expression value must be representiable in 32 bits"


<s> bool Warning ( SMLoc L , const Twine & Msg , ArrayRef < SMRange > Ranges = None ) { return Parser . Warning ( L , Msg , Ranges ) ; } </s>


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


"optionally flag setting instruction missing optional def operand"

checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not expressible via match classes .


"expression value must be representable in 32 bits"


<s> bool ARMAsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getIdentifier ( ) ; if ( IDVal == ".word" ) return parseDirectiveWord ( 4 , DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb" ) return parseDirectiveThumb ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".arm" ) return parseDirectiveARM ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb_func" ) return parseDirectiveThumbFunc ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".code" ) return parseDirectiveCode ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".syntax" ) return parseDirectiveSyntax ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".unreq" ) return parseDirectiveUnreq ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".arch" ) return parseDirectiveArch ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".eabi_attribute" ) return parseDirectiveEabiAttr ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".cpu" ) return parseDirectiveCPU ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".fpu" ) return parseDirectiveFPU ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".fnstart" ) return parseDirectiveFnStart ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".fnend" ) return parseDirectiveFnEnd ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".cantunwind" ) return parseDirectiveCantUnwind ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".personality" ) return parseDirectivePersonality ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".handlerdata" ) return parseDirectiveHandlerData ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".setfp" ) return parseDirectiveSetFP ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".pad" ) return parseDirectivePad ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".save" ) return parseDirectiveRegSave ( DirectiveID . getLoc ( ) , false ) ; else if ( IDVal == ".vsave" ) return parseDirectiveRegSave ( DirectiveID . getLoc ( ) , true ) ; return true ; } </s>


<s> bool isMem ( ) const override { if ( Kind != k_Memory ) return false ; if ( Memory . BaseRegNum && ! ARMMCRegisterClasses [ ARM :: GPRRegClassID ] . contains ( Memory . BaseRegNum ) ) return false ; if ( Memory . OffsetRegNum && ! ARMMCRegisterClasses [ ARM :: GPRRegClassID ] . contains ( Memory . OffsetRegNum ) ) return false ; return true ; } </s>

ARM ARM ARM::GPRRegClassID ARM ARM::GPRRegClassID


<s> bool isThumb ( ) const { return STI . getFeatureBits ( ) [ ARM :: ModeThumb ] ; } </s>


<s> bool Error ( SMLoc L , const Twine & Msg ) { return Parser . Error ( L , Msg ) ; } </s>


<s> bool isFPImm ( ) const { return Kind == k_FPImmediate ; } </s>


"instruction requires a CPU feature not currently enabled"

"flag setting instruction only valid outside IT block"

"instruction only valid inside IT block"

"instruction variant requires ARMv6 or later"


<s> bool ARMAsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getIdentifier ( ) ; if ( IDVal == ".word" ) return parseDirectiveWord ( 4 , DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb" ) return parseDirectiveThumb ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb_func" ) return parseDirectiveThumbFunc ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".code" ) return parseDirectiveCode ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".syntax" ) return parseDirectiveSyntax ( DirectiveID . getLoc ( ) ) ; return true ; } </s>


"immediate value expected for vector index"


<s> void Warning ( SMLoc L , const Twine & Msg ) { Parser . Warning ( L , Msg ) ; } </s>


<s>
bool
ARMAsmParser
::
MatchAndEmitInstruction
(
SMLoc
IDLoc
,
unsigned
&
Opcode
,
OperandVector
&
Operands
,
MCStreamer
&
Out
,
uint64_t
&
ErrorInfo
,
bool
MatchingInlineAsm
)
{
MCInst
Inst
;
unsigned
MatchResult
;
bool
PendConditionalInstruction
=
false
;
SmallVector
<
NearMissInfo
,
4
>
NearMisses
;
MatchResult
=
MatchInstruction
(
Operands
,
Inst
,
NearMisses
,
MatchingInlineAsm
,
PendConditionalInstruction
,
Out
)
;
switch
(
MatchResult
)
{
case
Match_Success
:
LLVM_DEBUG
(
dbgs
(
)
<<
"Parsed as: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
validateInstruction
(
Inst
,
Operands
)
)
{
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
return
true
;
}
{
bool
wasInITBlock
=
inITBlock
(
)
;
while
(
processInstruction
(
Inst
,
Operands
,
Out
)
)
LLVM_DEBUG
(
dbgs
(
)
<<
"Changed to: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
wasInITBlock
&&
hasV8Ops
(
)
&&
isThumb
(
)
&&
!
isV8EligibleForIT
(
&
Inst
)
)
{
Warning
(
IDLoc
,
"deprecated instruction in IT block"
)
;
}
}
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
if
(
Inst
.
getOpcode
(
)
==
ARM
::
ITasm
)
return
false
;
Inst
.
setLoc
(
IDLoc
)
;
if
(
PendConditionalInstruction
)
{
PendingConditionalInsts
.
push_back
(
Inst
)
;
if
(
isITBlockFull
(
)
||
isITBlockTerminator
(
Inst
)
)
flushPendingInstructions
(
Out
)
;
}
else
{
Out
.
emitInstruction
(
Inst
,
getSTI
(
)
)
;
}
return
false
;
case
Match_NearMisses
:
ReportNearMisses
(
NearMisses
,
IDLoc
,
Operands
)
;
return
true
;
case
Match_MnemonicFail
:
{
FeatureBitset
FBS
=
ComputeAvailableFeatures
(
getSTI
(
)
.
getFeatureBits
(
)
)
;
std
::
string
Suggestion
=
ARMMnemonicSpellCheck
(
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getToken
(
)
,
FBS
)
;
return
Error
(
IDLoc
,
"invalid instruction"
+
Suggestion
,
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getLocRange
(
)
)
;
}
}
llvm_unreachable
(
"Implement any new match types added!"
)
;
}
</s>


<s> int ARMAsmParser :: tryParseRegister ( ) { const AsmToken & Tok = Parser . getTok ( ) ; if ( Tok . isNot ( AsmToken :: Identifier ) ) return - 1 ; std :: string lowerCase = Tok . getString ( ) . lower ( ) ; unsigned RegNum = MatchRegisterName ( lowerCase ) ; if ( ! RegNum ) { RegNum = StringSwitch < unsigned > ( lowerCase ) . Case ( "r13" , ARM :: SP ) . Case ( "r14" , ARM :: LR ) . Case ( "r15" , ARM :: PC ) . Case ( "ip" , ARM :: R12 ) . Default ( 0 ) ; } if ( ! RegNum ) return - 1 ; Parser . Lex ( ) ; return RegNum ; } </s>


<s>
bool
ARMAsmParser
::
MatchAndEmitInstruction
(
SMLoc
IDLoc
,
unsigned
&
Opcode
,
OperandVector
&
Operands
,
MCStreamer
&
Out
,
uint64_t
&
ErrorInfo
,
bool
MatchingInlineAsm
)
{
MCInst
Inst
;
unsigned
MatchResult
;
bool
PendConditionalInstruction
=
false
;
SmallVector
<
NearMissInfo
,
4
>
NearMisses
;
MatchResult
=
MatchInstruction
(
Operands
,
Inst
,
NearMisses
,
MatchingInlineAsm
,
PendConditionalInstruction
,
Out
)
;
switch
(
MatchResult
)
{
case
Match_Success
:
LLVM_DEBUG
(
dbgs
(
)
<<
"Parsed as: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
validateInstruction
(
Inst
,
Operands
)
)
{
forwardITPosition
(
)
;
return
true
;
}
{
bool
wasInITBlock
=
inITBlock
(
)
;
while
(
processInstruction
(
Inst
,
Operands
,
Out
)
)
LLVM_DEBUG
(
dbgs
(
)
<<
"Changed to: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
wasInITBlock
&&
hasV8Ops
(
)
&&
isThumb
(
)
&&
!
isV8EligibleForIT
(
&
Inst
)
)
{
Warning
(
IDLoc
,
"deprecated instruction in IT block"
)
;
}
}
forwardITPosition
(
)
;
if
(
Inst
.
getOpcode
(
)
==
ARM
::
ITasm
)
return
false
;
Inst
.
setLoc
(
IDLoc
)
;
if
(
PendConditionalInstruction
)
{
PendingConditionalInsts
.
push_back
(
Inst
)
;
if
(
isITBlockFull
(
)
||
isITBlockTerminator
(
Inst
)
)
flushPendingInstructions
(
Out
)
;
}
else
{
Out
.
EmitInstruction
(
Inst
,
getSTI
(
)
)
;
}
return
false
;
case
Match_NearMisses
:
ReportNearMisses
(
NearMisses
,
IDLoc
,
Operands
)
;
return
true
;
case
Match_MnemonicFail
:
{
FeatureBitset
FBS
=
ComputeAvailableFeatures
(
getSTI
(
)
.
getFeatureBits
(
)
)
;
std
::
string
Suggestion
=
ARMMnemonicSpellCheck
(
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getToken
(
)
,
FBS
)
;
return
Error
(
IDLoc
,
"invalid instruction"
+
Suggestion
,
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getLocRange
(
)
)
;
}
}
llvm_unreachable
(
"Implement any new match types added!"
)
;
}
</s>


<s>
bool
ARMAsmParser
::
MatchAndEmitInstruction
(
SMLoc
IDLoc
,
unsigned
&
Opcode
,
OperandVector
&
Operands
,
MCStreamer
&
Out
,
uint64_t
&
ErrorInfo
,
bool
MatchingInlineAsm
)
{
MCInst
Inst
;
unsigned
MatchResult
;
bool
PendConditionalInstruction
=
false
;
SmallVector
<
NearMissInfo
,
4
>
NearMisses
;
MatchResult
=
MatchInstruction
(
Operands
,
Inst
,
NearMisses
,
MatchingInlineAsm
,
PendConditionalInstruction
,
Out
)
;
switch
(
MatchResult
)
{
case
Match_Success
:
LLVM_DEBUG
(
dbgs
(
)
<<
"Parsed as: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
validateInstruction
(
Inst
,
Operands
)
)
{
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
return
true
;
}
{
bool
wasInITBlock
=
inITBlock
(
)
;
while
(
processInstruction
(
Inst
,
Operands
,
Out
)
)
LLVM_DEBUG
(
dbgs
(
)
<<
"Changed to: "
;
Inst
.
dump_pretty
(
dbgs
(
)
,
MII
.
getName
(
Inst
.
getOpcode
(
)
)
)
;
dbgs
(
)
<<
"\n"
)
;
if
(
wasInITBlock
&&
hasV8Ops
(
)
&&
isThumb
(
)
&&
!
isV8EligibleForIT
(
&
Inst
)
&&
!
getTargetOptions
(
)
.
MCNoDeprecatedWarn
)
{
Warning
(
IDLoc
,
"deprecated instruction in IT block"
)
;
}
}
forwardITPosition
(
)
;
forwardVPTPosition
(
)
;
if
(
Inst
.
getOpcode
(
)
==
ARM
::
ITasm
)
return
false
;
Inst
.
setLoc
(
IDLoc
)
;
if
(
PendConditionalInstruction
)
{
PendingConditionalInsts
.
push_back
(
Inst
)
;
if
(
isITBlockFull
(
)
||
isITBlockTerminator
(
Inst
)
)
flushPendingInstructions
(
Out
)
;
}
else
{
Out
.
emitInstruction
(
Inst
,
getSTI
(
)
)
;
}
return
false
;
case
Match_NearMisses
:
ReportNearMisses
(
NearMisses
,
IDLoc
,
Operands
)
;
return
true
;
case
Match_MnemonicFail
:
{
FeatureBitset
FBS
=
ComputeAvailableFeatures
(
getSTI
(
)
.
getFeatureBits
(
)
)
;
std
::
string
Suggestion
=
ARMMnemonicSpellCheck
(
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getToken
(
)
,
FBS
)
;
return
Error
(
IDLoc
,
"invalid instruction"
+
Suggestion
,
(
(
ARMOperand
&
)
*
Operands
[
0
]
)
.
getLocRange
(
)
)
;
}
}
llvm_unreachable
(
"Implement any new match types added!"
)
;
}
</s>


<s> static void CreateMem ( OwningPtr < ARMOperand > & Op , unsigned BaseRegNum , bool OffsetIsReg , const MCExpr * Offset , unsigned OffsetRegNum , bool OffsetRegShifted , enum ShiftType ShiftType , const MCExpr * ShiftAmount , bool Preindexed , bool Postindexed , bool Negative , bool Writeback , SMLoc S , SMLoc E ) { Op . reset ( new ARMOperand ) ; Op -> Kind = Memory ; Op -> Mem . BaseRegNum = BaseRegNum ; Op -> Mem . OffsetIsReg = OffsetIsReg ; Op -> Mem . Offset = Offset ; Op -> Mem . OffsetRegNum = OffsetRegNum ; Op -> Mem . OffsetRegShifted = OffsetRegShifted ; Op -> Mem . ShiftType = ShiftType ; Op -> Mem . ShiftAmount = ShiftAmount ; Op -> Mem . Preindexed = Preindexed ; Op -> Mem . Postindexed = Postindexed ; Op -> Mem . Negative = Negative ; Op -> Mem . Writeback = Writeback ; Op -> StartLoc = S ; Op -> EndLoc = E ; } </s>


<s> static void CreateReg ( OwningPtr < ARMOperand > & Op , unsigned RegNum , bool Writeback , SMLoc S , SMLoc E ) { Op . reset ( new ARMOperand ) ; Op -> Kind = Register ; Op -> Reg . RegNum = RegNum ; Op -> Reg . Writeback = Writeback ; Op -> StartLoc = S ; Op -> EndLoc = E ; } </s>


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


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


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


<s> bool ARMAsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getIdentifier ( ) ; if ( IDVal == ".word" ) return ParseDirectiveWord ( 4 , DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb" ) return ParseDirectiveThumb ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".thumb_func" ) return ParseDirectiveThumbFunc ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".code" ) return ParseDirectiveCode ( DirectiveID . getLoc ( ) ) ; else if ( IDVal == ".syntax" ) return ParseDirectiveSyntax ( DirectiveID . getLoc ( ) ) ; return true ; } </s>


<s> bool ARMAsmParser :: ParseInstruction ( const StringRef & Name , SMLoc NameLoc , SmallVectorImpl < MCParsedAsmOperand * > & Operands ) { OwningPtr < ARMOperand > Op ; ARMOperand :: CreateToken ( Op , Name , NameLoc ) ; Operands . push_back ( Op . take ( ) ) ; SMLoc Loc = Parser . getTok ( ) . getLoc ( ) ; if ( getLexer ( ) . isNot ( AsmToken :: EndOfStatement ) ) { OwningPtr < ARMOperand > Op ; if ( ParseOperand ( Op ) ) return true ; Operands . push_back ( Op . take ( ) ) ; while ( getLexer ( ) . is ( AsmToken :: Comma ) ) { Parser . Lex ( ) ; if ( ParseOperand ( Op ) ) return true ; Operands . push_back ( Op . take ( ) ) ; } } return false ; } </s>

ParseInstruction - Parse one assembly instruction .


"expression value must be representable in 32 bits"


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


<s>
void
ARMOperand
::
dump
(
raw_ostream
&
OS
)
const
{
switch
(
Kind
)
{
case
CondCode
:
OS
<<
ARMCondCodeToString
(
getCondCode
(
)
)
;
break
;
case
Immediate
:
getImm
(
)
->
print
(
OS
)
;
break
;
case
Memory
:
OS
<<
"<memory>"
;
break
;
case
Register
:
OS
<<
"<register "
<<
getReg
(
)
<<
">"
;
break
;
case
Token
:
OS
<<
"'"
<<
getToken
(
)
<<
"'"
;
break
;
}
}
</s>

Dump the plan to stderr ( for debugging ) .

ARM
ARM
ARM
"<memory>"
"<register "
">"
"'"
"'"


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


<s> bool ARMAsmParser :: ParseInstruction ( StringRef Name , SMLoc NameLoc , SmallVectorImpl < MCParsedAsmOperand * > & Operands ) { OwningPtr < ARMOperand > Op ; size_t Start = 0 , Next = Name . find ( '.' ) ; StringRef Head = Name . slice ( Start , Next ) ; unsigned CC = StringSwitch < unsigned > ( Head . substr ( Head . size ( ) - 2 ) ) . Case ( "eq" , ARMCC :: EQ ) . Case ( "ne" , ARMCC :: NE ) . Case ( "hs" , ARMCC :: HS ) . Case ( "lo" , ARMCC :: LO ) . Case ( "mi" , ARMCC :: MI ) . Case ( "pl" , ARMCC :: PL ) . Case ( "vs" , ARMCC :: VS ) . Case ( "vc" , ARMCC :: VC ) . Case ( "hi" , ARMCC :: HI ) . Case ( "ls" , ARMCC :: LS ) . Case ( "ge" , ARMCC :: GE ) . Case ( "lt" , ARMCC :: LT ) . Case ( "gt" , ARMCC :: GT ) . Case ( "le" , ARMCC :: LE ) . Case ( "al" , ARMCC :: AL ) . Default ( ~ 0U ) ; if ( CC != ~ 0U ) { Head = Head . slice ( 0 , Head . size ( ) - 2 ) ; } else CC = ARMCC :: AL ; ARMOperand :: CreateToken ( Op , Head , NameLoc ) ; Operands . push_back ( Op . take ( ) ) ; ARMOperand :: CreateCondCode ( Op , ARMCC :: CondCodes ( CC ) , NameLoc ) ; Operands . push_back ( Op . take ( ) ) ; while ( Next != StringRef :: npos ) { Start = Next ; Next = Name . find ( '.' , Start + 1 ) ; Head = Name . slice ( Start , Next ) ; ARMOperand :: CreateToken ( Op , Head , NameLoc ) ; Operands . push_back ( Op . take ( ) ) ; } if ( getLexer ( ) . isNot ( AsmToken :: EndOfStatement ) ) { OwningPtr < ARMOperand > Op ; if ( ParseOperand ( Op ) ) return true ; Operands . push_back ( Op . take ( ) ) ; while ( getLexer ( ) . is ( AsmToken :: Comma ) ) { Parser . Lex ( ) ; if ( ParseOperand ( Op ) ) return true ; Operands . push_back ( Op . take ( ) ) ; } } return false ; } </s>

ARM ARM ARM 0 2 "eq" ARMCC::EQ "ne" ARMCC::NE "hs" ARMCC::HS "lo" ARMCC::LO "mi" ARMCC::MI "pl" ARMCC::PL "vs" ARMCC::VS "vc" ARMCC::VC "hi" ARMCC::HI "ls" ARMCC::LS "ge" ARMCC::GE "lt" ARMCC::LT "gt" ARMCC::GT "le" ARMCC::LE "al" ARMCC::AL 0U 0U 0 2 ARMCC::AL ARM ARM ARMCC::CondCodes 1 ARM ARM