summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h5
-rw-r--r--lib/MC/MCParser/AsmParser.cpp7
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmFlags.h53
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp19
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp21
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h2
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp4
-rw-r--r--test/MC/Mips/mips_directives.s7
8 files changed, 111 insertions, 7 deletions
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 6e96e8becd..512fd8649a 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -176,6 +176,11 @@ public:
virtual void convertToMapAndConstraints(unsigned Kind,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
+ /// End of assembly processing.
+ /// This gets called when all assembly has been read and gives the local
+ /// Target AsmParsers an opportunity for any final data processing, etc..
+ virtual void emitEndOfAsmFile(MCStreamer &Out) {}
+
virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind,
MCContext &Ctx) {
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 9854b07a6c..53ce02c089 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/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/lib/Target/Mips/AsmParser/MipsAsmFlags.h b/lib/Target/Mips/AsmParser/MipsAsmFlags.h
new file mode 100644
index 0000000000..bf141db632
--- /dev/null
+++ b/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/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 447e7dc6e1..c2e4bba87b 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/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/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
index cfcb877805..144cb1e439 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+++ b/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/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
index b10ccc78e6..9987f348ae 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
+++ b/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/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 1dc3326578..b12cb625a7 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/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,
diff --git a/test/MC/Mips/mips_directives.s b/test/MC/Mips/mips_directives.s
index bbb2616552..b1f8182728 100644
--- a/test/MC/Mips/mips_directives.s
+++ b/test/MC/Mips/mips_directives.s
@@ -1,9 +1,12 @@
# RUN: llvm-mc -show-encoding -triple mips-unknown-unknown %s | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple mips-unknown-unknown %s | \
+# RUN: llvm-readobj -h | FileCheck -check-prefix=CHECK-ELF %s
#
# CHECK: .text
# CHECK: $BB0_2:
$BB0_2:
- .ent directives_test
+ .ent directives_test
+ .abicalls
.frame $sp,0,$ra
.mask 0x00000000,0
.fmask 0x00000000,0
@@ -43,3 +46,5 @@ $JTI0_0:
# CHECK: and $3, $15, $15 # encoding: [0x01,0xef,0x18,0x24]
abs.s f6,FPU_MASK
and r3,$t7,STORE_MASK
+
+# CHECK-ELF: Flags [ (0x6)