mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 12:19:53 +00:00
[ARM,AArch64] Store source location of asm constant pool entries
Storing the source location of the expression that created a constant pool entry allows us to emit better error messages if we later discover that the expression cannot be represented by a relocation. Differential Revision: http://reviews.llvm.org/D14646 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253220 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1b10e7aa06
commit
20bb042d74
@ -17,6 +17,7 @@
|
||||
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/SMLoc.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCContext;
|
||||
@ -26,11 +27,12 @@ class MCStreamer;
|
||||
class MCSymbol;
|
||||
|
||||
struct ConstantPoolEntry {
|
||||
ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz)
|
||||
: Label(L), Value(Val), Size(Sz) {}
|
||||
ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz, SMLoc Loc_)
|
||||
: Label(L), Value(Val), Size(Sz), Loc(Loc_) {}
|
||||
MCSymbol *Label;
|
||||
const MCExpr *Value;
|
||||
unsigned Size;
|
||||
SMLoc Loc;
|
||||
};
|
||||
|
||||
// A class to keep track of assembler-generated constant pools that are use to
|
||||
@ -49,7 +51,7 @@ public:
|
||||
//
|
||||
// \returns a MCExpr that references the newly inserted value
|
||||
const MCExpr *addEntry(const MCExpr *Value, MCContext &Context,
|
||||
unsigned Size);
|
||||
unsigned Size, SMLoc Loc);
|
||||
|
||||
// Emit the contents of the constant pool using the provided streamer.
|
||||
void emitEntries(MCStreamer &Streamer);
|
||||
@ -80,7 +82,7 @@ public:
|
||||
void emitAll(MCStreamer &Streamer);
|
||||
void emitForCurrentSection(MCStreamer &Streamer);
|
||||
const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr,
|
||||
unsigned Size);
|
||||
unsigned Size, SMLoc Loc);
|
||||
|
||||
private:
|
||||
ConstantPool *getConstantPool(MCSection *Section);
|
||||
|
@ -134,7 +134,7 @@ public:
|
||||
/// Callback used to implement the ldr= pseudo.
|
||||
/// Add a new entry to the constant pool for the current section and return an
|
||||
/// MCExpr that can be used to refer to the constant pool location.
|
||||
const MCExpr *addConstantPoolEntry(const MCExpr *);
|
||||
const MCExpr *addConstantPoolEntry(const MCExpr *, SMLoc Loc);
|
||||
|
||||
/// Callback used to implemnt the .ltorg directive.
|
||||
/// Emit contents of constant pool for the current section.
|
||||
|
@ -29,17 +29,17 @@ void ConstantPool::emitEntries(MCStreamer &Streamer) {
|
||||
I != E; ++I) {
|
||||
Streamer.EmitCodeAlignment(I->Size); // align naturally
|
||||
Streamer.EmitLabel(I->Label);
|
||||
Streamer.EmitValue(I->Value, I->Size);
|
||||
Streamer.EmitValue(I->Value, I->Size, I->Loc);
|
||||
}
|
||||
Streamer.EmitDataRegion(MCDR_DataRegionEnd);
|
||||
Entries.clear();
|
||||
}
|
||||
|
||||
const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context,
|
||||
unsigned Size) {
|
||||
unsigned Size, SMLoc Loc) {
|
||||
MCSymbol *CPEntryLabel = Context.createTempSymbol();
|
||||
|
||||
Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size));
|
||||
Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
|
||||
return MCSymbolRefExpr::create(CPEntryLabel, Context);
|
||||
}
|
||||
|
||||
@ -90,8 +90,8 @@ void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
|
||||
|
||||
const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer,
|
||||
const MCExpr *Expr,
|
||||
unsigned Size) {
|
||||
unsigned Size, SMLoc Loc) {
|
||||
MCSection *Section = Streamer.getCurrentSection().first;
|
||||
return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(),
|
||||
Size);
|
||||
Size, Loc);
|
||||
}
|
||||
|
@ -3210,7 +3210,7 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
|
||||
}
|
||||
// If it is a label or an imm that cannot fit in a movz, put it into CP.
|
||||
const MCExpr *CPLoc =
|
||||
getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4);
|
||||
getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
|
||||
Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
|
||||
return false;
|
||||
}
|
||||
|
@ -26,8 +26,9 @@ AArch64TargetStreamer::~AArch64TargetStreamer() {}
|
||||
// The constant pool handling is shared by all AArch64TargetStreamer
|
||||
// implementations.
|
||||
const MCExpr *AArch64TargetStreamer::addConstantPoolEntry(const MCExpr *Expr,
|
||||
unsigned Size) {
|
||||
return ConstantPools->addEntry(Streamer, Expr, Size);
|
||||
unsigned Size,
|
||||
SMLoc Loc) {
|
||||
return ConstantPools->addEntry(Streamer, Expr, Size, Loc);
|
||||
}
|
||||
|
||||
void AArch64TargetStreamer::emitCurrentConstantPool() {
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
/// Callback used to implement the ldr= pseudo.
|
||||
/// Add a new entry to the constant pool for the current section and return an
|
||||
/// MCExpr that can be used to refer to the constant pool location.
|
||||
const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size);
|
||||
const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size, SMLoc Loc);
|
||||
|
||||
/// Callback used to implemnt the .ltorg directive.
|
||||
/// Emit contents of constant pool for the current section.
|
||||
|
@ -5122,6 +5122,7 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
|
||||
// FALLTHROUGH
|
||||
}
|
||||
case AsmToken::Colon: {
|
||||
S = Parser.getTok().getLoc();
|
||||
// ":lower16:" and ":upper16:" expression prefixes
|
||||
// FIXME: Check it's an expression prefix,
|
||||
// e.g. (FOO - :lower16:BAR) isn't legal.
|
||||
@ -5140,8 +5141,9 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
|
||||
return false;
|
||||
}
|
||||
case AsmToken::Equal: {
|
||||
S = Parser.getTok().getLoc();
|
||||
if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
|
||||
return Error(Parser.getTok().getLoc(), "unexpected token in operand");
|
||||
return Error(S, "unexpected token in operand");
|
||||
|
||||
Parser.Lex(); // Eat '='
|
||||
const MCExpr *SubExprVal;
|
||||
@ -5149,7 +5151,8 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
|
||||
return true;
|
||||
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
||||
|
||||
const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal);
|
||||
const MCExpr *CPLoc =
|
||||
getTargetStreamer().addConstantPoolEntry(SubExprVal, S);
|
||||
Operands.push_back(ARMOperand::CreateImm(CPLoc, S, E));
|
||||
return false;
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ ARMTargetStreamer::~ARMTargetStreamer() {}
|
||||
|
||||
// The constant pool handling is shared by all ARMTargetStreamer
|
||||
// implementations.
|
||||
const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr) {
|
||||
return ConstantPools->addEntry(Streamer, Expr, 4);
|
||||
const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc) {
|
||||
return ConstantPools->addEntry(Streamer, Expr, 4, Loc);
|
||||
}
|
||||
|
||||
void ARMTargetStreamer::emitCurrentConstantPool() {
|
||||
|
5
test/MC/AArch64/error-location-ldr-pseudo.s
Normal file
5
test/MC/AArch64/error-location-ldr-pseudo.s
Normal file
@ -0,0 +1,5 @@
|
||||
// RUN: not llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
.text
|
||||
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected relocatable expression
|
||||
ldr x0, =(-undef)
|
5
test/MC/ARM/error-location-ldr-pseudo.s
Normal file
5
test/MC/ARM/error-location-ldr-pseudo.s
Normal file
@ -0,0 +1,5 @@
|
||||
@ RUN: not llvm-mc -triple armv7a--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
.text
|
||||
@ CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected relocatable expression
|
||||
ldr r0, =(-undef)
|
Loading…
Reference in New Issue
Block a user