summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
diff options
context:
space:
mode:
authorDavid Peixotto <dpeixott@codeaurora.org>2014-02-04 17:22:40 +0000
committerDavid Peixotto <dpeixott@codeaurora.org>2014-02-04 17:22:40 +0000
commitb92cca222898d87bbc764fa22e805adb04ef7f13 (patch)
treef094e401b602d87e38489c8cb984437ce983fb4f /lib/Target/ARM/AsmParser/ARMAsmParser.cpp
parent7d9ed1cac54f5ed4274ae2735bd06e1017a83a9b (diff)
downloadllvm-b92cca222898d87bbc764fa22e805adb04ef7f13.tar.gz
llvm-b92cca222898d87bbc764fa22e805adb04ef7f13.tar.bz2
llvm-b92cca222898d87bbc764fa22e805adb04ef7f13.tar.xz
Fix PR18345: ldr= pseudo instruction produces incorrect code when using in inline assembly
This patch fixes the ldr-pseudo implementation to work when used in inline assembly. The fix is to move arm assembler constant pools from the ARMAsmParser class to the ARMTargetStreamer class. Previously we kept the assembler generated constant pools in the ARMAsmParser object. This does not work for inline assembly because a new parser object is created for each blob of inline assembly. This patch moves the constant pools to the ARMTargetStreamer class so that the constant pool will remain alive for the entire code generation process. An ARMTargetStreamer class is now required for the arm backend. There was no existing implementation for MachO, only Asm and ELF. Instead of creating an empty MachO subclass, we decided to make the ARMTargetStreamer a non-abstract class and provide default (llvm_unreachable) implementations for the non constant-pool related methods. Differential Revision: http://llvm-reviews.chandlerc.com/D2638 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200777 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp104
1 files changed, 2 insertions, 102 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 74e4e66c6e..288d9b96da 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -56,64 +56,6 @@ class ARMOperand;
enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
-// A class to keep track of assembler-generated constant pools that are use to
-// implement the ldr-pseudo.
-class ConstantPool {
- typedef SmallVector<std::pair<MCSymbol *, const MCExpr *>, 4> EntryVecTy;
- EntryVecTy Entries;
-
-public:
- // Initialize a new empty constant pool
- ConstantPool() { }
-
- // Add a new entry to the constant pool in the next slot.
- // \param Value is the new entry to put in the constant pool.
- //
- // \returns a MCExpr that references the newly inserted value
- const MCExpr *addEntry(const MCExpr *Value, MCContext &Context) {
- MCSymbol *CPEntryLabel = Context.CreateTempSymbol();
-
- Entries.push_back(std::make_pair(CPEntryLabel, Value));
- return MCSymbolRefExpr::Create(CPEntryLabel, Context);
- }
-
- // Emit the contents of the constant pool using the provided streamer.
- void emitEntries(MCStreamer &Streamer) {
- if (Entries.empty())
- return;
- Streamer.EmitCodeAlignment(4); // align to 4-byte address
- Streamer.EmitDataRegion(MCDR_DataRegion);
- for (EntryVecTy::const_iterator I = Entries.begin(), E = Entries.end();
- I != E; ++I) {
- Streamer.EmitLabel(I->first);
- Streamer.EmitValue(I->second, 4);
- }
- Streamer.EmitDataRegion(MCDR_DataRegionEnd);
- Entries.clear();
- }
-
- // Return true if the constant pool is empty
- bool empty() {
- return Entries.empty();
- }
-};
-
-// Map type used to keep track of per-Section constant pools used by the
-// ldr-pseudo opcode. The map associates a section to its constant pool. The
-// constant pool is a vector of (label, value) pairs. When the ldr
-// pseudo is parsed we insert a new (label, value) pair into the constant pool
-// for the current section and add MCSymbolRefExpr to the new label as
-// an opcode to the ldr. After we have parsed all the user input we
-// output the (label, value) pairs in each constant pool at the end of the
-// section.
-//
-// We use the MapVector for the map type to ensure stable iteration of
-// the sections at the end of the parse. We need to iterate over the
-// sections in a stable order to ensure that we have print the
-// constant pools in a deterministic order when printing an assembly
-// file.
-typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy;
-
class UnwindContext {
MCAsmParser &Parser;
@@ -191,22 +133,8 @@ class ARMAsmParser : public MCTargetAsmParser {
MCAsmParser &Parser;
const MCInstrInfo &MII;
const MCRegisterInfo *MRI;
- ConstantPoolMapTy ConstantPools;
UnwindContext UC;
- // Assembler created constant pools for ldr pseudo
- ConstantPool *getConstantPool(const MCSection *Section) {
- ConstantPoolMapTy::iterator CP = ConstantPools.find(Section);
- if (CP == ConstantPools.end())
- return 0;
-
- return &CP->second;
- }
-
- ConstantPool &getOrCreateConstantPool(const MCSection *Section) {
- return ConstantPools[Section];
- }
-
ARMTargetStreamer &getTargetStreamer() {
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
return static_cast<ARMTargetStreamer &>(TS);
@@ -443,7 +371,6 @@ public:
MCStreamer &Out, unsigned &ErrorInfo,
bool MatchingInlineAsm);
void onLabelParsed(MCSymbol *Symbol);
- void finishParse();
};
} // end anonymous namespace
@@ -4812,17 +4739,13 @@ bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
return Error(Parser.getTok().getLoc(), "unexpected token in operand");
- const MCSection *Section =
- getParser().getStreamer().getCurrentSection().first;
- assert(Section);
Parser.Lex(); // Eat '='
const MCExpr *SubExprVal;
if (getParser().parseExpression(SubExprVal))
return true;
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- const MCExpr *CPLoc =
- getOrCreateConstantPool(Section).addEntry(SubExprVal, getContext());
+ const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal);
Operands.push_back(ARMOperand::CreateImm(CPLoc, S, E));
return false;
}
@@ -8843,13 +8766,7 @@ bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
/// parseDirectiveLtorg
/// ::= .ltorg | .pool
bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
- MCStreamer &Streamer = getParser().getStreamer();
- const MCSection *Section = Streamer.getCurrentSection().first;
-
- if (ConstantPool *CP = getConstantPool(Section)) {
- if (!CP->empty())
- CP->emitEntries(Streamer);
- }
+ getTargetStreamer().emitCurrentConstantPool();
return false;
}
@@ -9181,20 +9098,3 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
}
return Match_InvalidOperand;
}
-
-void ARMAsmParser::finishParse() {
- // Dump contents of assembler constant pools.
- MCStreamer &Streamer = getParser().getStreamer();
- for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(),
- CPE = ConstantPools.end();
- CPI != CPE; ++CPI) {
- const MCSection *Section = CPI->first;
- ConstantPool &CP = CPI->second;
-
- // Dump non-empty assembler constant pools at the end of the section.
- if (!CP.empty()) {
- Streamer.SwitchSection(Section);
- CP.emitEntries(Streamer);
- }
- }
-}