mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-18 22:15:46 +01:00
Pull in r222587 from upstream llvm trunk (by Jörg Sonnenberger):
Fix transformation of add with pc argument to adr for non-immediate arguments. This fixes an "Unimplemented" error when assembling certain ARM add instructions with pc-relative arguments. Reported by: sbruno PR: 196412, 196423
This commit is contained in:
parent
0df7827e83
commit
e5eac9539c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=276537
@ -314,7 +314,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
void cvtThumbBranches(MCInst &Inst, const OperandVector &);
|
||||
|
||||
bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
|
||||
bool processInstruction(MCInst &Inst, const OperandVector &Ops);
|
||||
bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
|
||||
bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
|
||||
bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
|
||||
|
||||
@ -6175,7 +6175,8 @@ static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
|
||||
}
|
||||
|
||||
bool ARMAsmParser::processInstruction(MCInst &Inst,
|
||||
const OperandVector &Operands) {
|
||||
const OperandVector &Operands,
|
||||
MCStreamer &Out) {
|
||||
switch (Inst.getOpcode()) {
|
||||
// Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
|
||||
case ARM::LDRT_POST:
|
||||
@ -6216,12 +6217,31 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,
|
||||
// Alias for alternate form of 'ADR Rd, #imm' instruction.
|
||||
case ARM::ADDri: {
|
||||
if (Inst.getOperand(1).getReg() != ARM::PC ||
|
||||
Inst.getOperand(5).getReg() != 0)
|
||||
Inst.getOperand(5).getReg() != 0 ||
|
||||
!(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
|
||||
return false;
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(ARM::ADR);
|
||||
TmpInst.addOperand(Inst.getOperand(0));
|
||||
TmpInst.addOperand(Inst.getOperand(2));
|
||||
if (Inst.getOperand(2).isImm()) {
|
||||
TmpInst.addOperand(Inst.getOperand(2));
|
||||
} else {
|
||||
// Turn PC-relative expression into absolute expression.
|
||||
// Reading PC provides the start of the current instruction + 8 and
|
||||
// the transform to adr is biased by that.
|
||||
MCSymbol *Dot = getContext().CreateTempSymbol();
|
||||
Out.EmitLabel(Dot);
|
||||
const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
|
||||
const MCExpr *InstPC = MCSymbolRefExpr::Create(Dot,
|
||||
MCSymbolRefExpr::VK_None,
|
||||
getContext());
|
||||
const MCExpr *Const8 = MCConstantExpr::Create(8, getContext());
|
||||
const MCExpr *ReadPC = MCBinaryExpr::CreateAdd(InstPC, Const8,
|
||||
getContext());
|
||||
const MCExpr *FixupAddr = MCBinaryExpr::CreateAdd(ReadPC, OpExpr,
|
||||
getContext());
|
||||
TmpInst.addOperand(MCOperand::CreateExpr(FixupAddr));
|
||||
}
|
||||
TmpInst.addOperand(Inst.getOperand(3));
|
||||
TmpInst.addOperand(Inst.getOperand(4));
|
||||
Inst = TmpInst;
|
||||
@ -8061,7 +8081,7 @@ bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
// encoding is selected. Loop on it while changes happen so the
|
||||
// individual transformations can chain off each other. E.g.,
|
||||
// tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
|
||||
while (processInstruction(Inst, Operands))
|
||||
while (processInstruction(Inst, Operands, Out))
|
||||
;
|
||||
|
||||
// Only after the instruction is fully processed, we can validate it
|
||||
|
Loading…
Reference in New Issue
Block a user