summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJack Carter <jack.carter@imgtec.com>2013-10-04 21:26:15 +0000
committerJack Carter <jack.carter@imgtec.com>2013-10-04 21:26:15 +0000
commit721726adfc043224c9e5e0925b581d0448c6723d (patch)
tree2d825ccd82a884dc98d87461c3ed6c2171d6b806 /llvm/lib
parentf7a8c4f3476f88683efdb071f57012dcf906305e (diff)
downloadbcm5719-llvm-721726adfc043224c9e5e0925b581d0448c6723d.tar.gz
bcm5719-llvm-721726adfc043224c9e5e0925b581d0448c6723d.zip
[MC][AsmParser] Hook for post assembly file processing
This patch handles LLVM standalone assembler (llvm-mc) ELF flag setting based on input file directive processing. Mips assembly requires processing inline directives that directly and indirectly affect the output ELF header flags. This patch handles one ".abicalls". To process these directives we are following the model the code generator uses by storing state in a container as we go through processing and when we detect the end of input file processing, AsmParser is notified and we update the ELF header flags through a MipsELFStreamer method with a call from MCTargetAsmParser::emitEndOfAsmFile(MCStreamer &OutStreamer). This patch will allow other targets the same functionality. Jack llvm-svn: 191982
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp7
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmFlags.h53
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp19
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp21
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h2
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp4
6 files changed, 100 insertions, 6 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 9854b07a6c4..53ce02c0899 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -673,8 +673,10 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Finalize the output stream if there are no errors and if the client wants
// us to.
- if (!HadError && !NoFinalize)
+ if (!HadError && !NoFinalize) {
+ getTargetParser().emitEndOfAsmFile(Out);
Out.Finish();
+ }
return HadError;
}
@@ -779,7 +781,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
// temporary label to the streamer and refer to it.
MCSymbol *Sym = Ctx.CreateTempSymbol();
Out.EmitLabel(Sym);
- Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
+ Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
+ getContext());
EndLoc = FirstTokenLoc;
return false;
} else
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmFlags.h b/llvm/lib/Target/Mips/AsmParser/MipsAsmFlags.h
new file mode 100644
index 00000000000..bf141db6320
--- /dev/null
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmFlags.h
@@ -0,0 +1,53 @@
+//=== MipsMCAsmFlags.h - MipsMCAsmFlags --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENCE.TXT for details.
+//
+//===-------------------------------------------------------------------===//
+#ifndef MIPSMCASMFLAGS_H_
+#define MIPSMCASMFLAGS_H_
+
+namespace llvm {
+class MipsMCAsmFlags;
+
+// We have the flags apart from the ELF defines because state will determine
+// the final values put into the ELF flag bits.
+//
+// Currently we have only Relocation Model, but will soon follow with ABI,
+// Architecture, and ASE.
+class MipsMCAsmFlags {
+public:
+ // These act as bit flags because more that one can be
+ // active at the same time, sometimes ;-)
+ enum MAFRelocationModelTy {
+ MAF_RM_DEFAULT = 0,
+ MAF_RM_STATIC = 1,
+ MAF_RM_CPIC = 2,
+ MAF_RM_PIC = 4
+ } MAFRelocationModel;
+
+public:
+ MipsMCAsmFlags() : Model(MAF_RM_DEFAULT) {}
+
+ ~MipsMCAsmFlags() {}
+
+ // Setting a bit we can later translate to the ELF header flags.
+ void setRelocationModel(unsigned RM) { (Model |= RM); }
+
+ bool isModelCpic() const { return (Model & MAF_RM_CPIC) == MAF_RM_CPIC; }
+ bool isModelPic() const { return (Model & MAF_RM_PIC) == MAF_RM_PIC; }
+ bool isModelStatic() const {
+ return (Model & MAF_RM_STATIC) == MAF_RM_STATIC;
+ }
+ bool isModelDefault() const {
+ return (Model & MAF_RM_DEFAULT) == MAF_RM_DEFAULT;
+ }
+
+private:
+ unsigned Model; // pic, cpic, etc.
+};
+}
+
+#endif /* MIPSMCASMFLAGS_H_ */
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 447e7dc6e1c..c2e4bba87b3 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "AsmParser/MipsAsmFlags.h"
+#include "MCTargetDesc/MipsELFStreamer.h"
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "MipsRegisterInfo.h"
#include "llvm/ADT/StringSwitch.h"
@@ -59,6 +61,7 @@ class MipsAsmParser : public MCTargetAsmParser {
MCSubtargetInfo &STI;
MCAsmParser &Parser;
MipsAssemblerOptions Options;
+ MipsMCAsmFlags Flags;
bool hasConsumedDollar;
#define GET_ASSEMBLER_HEADER
@@ -228,6 +231,8 @@ class MipsAsmParser : public MCTargetAsmParser {
bool processInstruction(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
+ void emitEndOfAsmFile(MCStreamer &Out);
+
public:
MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
const MCInstrInfo &MII)
@@ -2172,9 +2177,23 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
return false;
}
+ if (IDVal == ".abicalls") {
+ Flags.setRelocationModel(MipsMCAsmFlags::MAF_RM_CPIC);
+ if (Parser.getTok().isNot(AsmToken::EndOfStatement))
+ return Error(Parser.getTok().getLoc(), "unexpected token in directive");
+ return false;
+ }
+
return true;
}
+/// End of assembly processing such as updating ELF header flags.
+void MipsAsmParser::emitEndOfAsmFile(MCStreamer &OutStreamer) {
+ if (MipsELFStreamer *MES = dyn_cast<MipsELFStreamer>(&OutStreamer))
+ MES->emitELFHeaderFlagsAsm(Flags);
+ MCTargetAsmParser::emitEndOfAsmFile(OutStreamer);
+}
+
extern "C" void LLVMInitializeMipsAsmParser() {
RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
index cfcb877805a..144cb1e4397 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
@@ -7,6 +7,7 @@
//
//===-------------------------------------------------------------------===//
#include "MCTargetDesc/MipsELFStreamer.h"
+#include "AsmParser/MipsAsmFlags.h"
#include "MipsSubtarget.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCELF.h"
@@ -66,10 +67,26 @@ namespace llvm {
Reloc::Model RM = Subtarget.getRelocationModel();
if (RM == Reloc::PIC_ || RM == Reloc::Default)
EFlags |= ELF::EF_MIPS_PIC;
- else if (RM == Reloc::Static)
+
+ MCA.setELFHeaderEFlags(EFlags);
+ }
+
+ // For llvm-mc. Set a group of ELF header flags
+ void MipsELFStreamer::emitELFHeaderFlagsAsm(const MipsMCAsmFlags &Flags) {
+
+ // Update e_header flags
+ MCAssembler &MCA = getAssembler();
+ unsigned EFlags = MCA.getELFHeaderEFlags();
+
+ // Relocation Model
+ if (Flags.isModelCpic() || Flags.isModelDefault())
+ EFlags |= ELF::EF_MIPS_CPIC;
+ if (Flags.isModelStatic())
; // Do nothing for Reloc::Static
+ else if (Flags.isModelPic() || Flags.isModelDefault())
+ EFlags |= ELF::EF_MIPS_PIC;
else
- llvm_unreachable("Unsupported relocation model for e_flags");
+ assert(0 && "Unsupported relocation model for e_flags");
MCA.setELFHeaderEFlags(EFlags);
}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
index b10ccc78e66..9987f348ae6 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
@@ -13,6 +13,7 @@
namespace llvm {
class MipsAsmPrinter;
+class MipsMCAsmFlags;
class MipsSubtarget;
class MCSymbol;
@@ -26,6 +27,7 @@ public:
~MipsELFStreamer() {}
void emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget);
+ void emitELFHeaderFlagsAsm(const MipsMCAsmFlags &MAFlags);
void emitMipsSTOCG(const MipsSubtarget &Subtarget,
MCSymbol *Sym,
unsigned Val);
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 1dc33265783..b12cb625a78 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -594,8 +594,8 @@ void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
// Emit Mips ELF register info
Subtarget->getMReginfo().emitMipsReginfoSectionCG(
OutStreamer, getObjFileLowering(), *Subtarget);
- if (MipsELFStreamer *MES = dyn_cast<MipsELFStreamer>(&OutStreamer))
- MES->emitELFHeaderFlagsCG(*Subtarget);
+ MipsELFStreamer *MES = cast<MipsELFStreamer>(&OutStreamer);
+ MES->emitELFHeaderFlagsCG(*Subtarget);
}
void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
OpenPOWER on IntegriCloud