Implement the missing bits corresponding to .mips_hack_elf_flags.

These were:
* noreorder handling on the target object streamer and asm parser.
* setting the initial flag bits based on the enabled features.
* setting the elf header flag for micromips

It is *really* depressing I am the one doing this instead of someone at
mips actually taking the time to understand the infrastructure.

llvm-svn: 200138
This commit is contained in:
Rafael Espindola 2014-01-26 06:57:13 +00:00
parent 9e6d27d037
commit cb1953f6d9
13 changed files with 136 additions and 119 deletions

View File

@ -805,6 +805,8 @@ enum LLVM_ENUM_INT_TYPE(unsigned) {
EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
EF_MIPS_PIC = 0x00000002, // Position independent code
EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
EF_MIPS_ABI2 = 0x00000020,
EF_MIPS_32BITMODE = 0x00000100,
EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
//ARCH_ASE

View File

@ -194,7 +194,6 @@ class MipsAsmParser : public MCTargetAsmParser {
bool isEvaluated(const MCExpr *Expr);
bool parseDirectiveSet();
bool parseDirectiveMipsHackELFFlags();
bool parseDirectiveOption();
bool parseSetAtDirective();
@ -2311,6 +2310,7 @@ bool MipsAsmParser::parseSetNoReorderDirective() {
return false;
}
Options.setNoreorder();
getTargetStreamer().emitDirectiveSetNoReorder();
Parser.Lex(); // Consume the EndOfStatement.
return false;
}
@ -2429,17 +2429,6 @@ bool MipsAsmParser::parseDirectiveSet() {
return true;
}
bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
int64_t Flags = 0;
if (Parser.parseAbsoluteExpression(Flags)) {
TokError("unexpected token");
return false;
}
getTargetStreamer().emitMipsHackELFFlags(Flags);
return false;
}
/// parseDirectiveWord
/// ::= .word [ expression (, expression)* ]
bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
@ -2558,9 +2547,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
return false;
}
if (IDVal == ".mips_hack_elf_flags")
return parseDirectiveMipsHackELFFlags();
if (IDVal == ".option")
return parseDirectiveOption();

View File

@ -134,7 +134,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
bool RelaxAll, bool NoExecStack) {
MCStreamer *S =
createELFStreamer(Context, MAB, OS, Emitter, RelaxAll, NoExecStack);
new MipsTargetELFStreamer(*S);
new MipsTargetELFStreamer(*S, STI);
return S;
}

View File

@ -12,8 +12,10 @@
//===----------------------------------------------------------------------===//
#include "MipsTargetStreamer.h"
#include "MipsMCTargetDesc.h"
#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
@ -21,9 +23,6 @@
using namespace llvm;
static cl::opt<bool> PrintHackDirectives("print-hack-directives",
cl::init(false), cl::Hidden);
// Pin vtable to this file.
void MipsTargetStreamer::anchor() {}
@ -33,15 +32,6 @@ MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
formatted_raw_ostream &OS)
: MipsTargetStreamer(S), OS(OS) {}
void MipsTargetAsmStreamer::emitMipsHackELFFlags(unsigned Flags) {
if (!PrintHackDirectives)
return;
OS << "\t.mips_hack_elf_flags 0x";
OS.write_hex(Flags);
OS << '\n';
}
void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
OS << "\t.set\tmicromips\n";
}
@ -96,8 +86,38 @@ void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
}
// This part is for ELF object output.
MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S)
: MipsTargetStreamer(S), MicroMipsEnabled(false) {}
MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
const MCSubtargetInfo &STI)
: MipsTargetStreamer(S), MicroMipsEnabled(false) {
MCAssembler &MCA = getStreamer().getAssembler();
uint64_t Features = STI.getFeatureBits();
Triple T(STI.getTargetTriple());
// Update e_header flags
unsigned EFlags = 0;
// Architecture
if (Features & Mips::FeatureMips64r2)
EFlags |= ELF::EF_MIPS_ARCH_64R2;
else if (Features & Mips::FeatureMips64)
EFlags |= ELF::EF_MIPS_ARCH_64;
else if (Features & Mips::FeatureMips32r2)
EFlags |= ELF::EF_MIPS_ARCH_32R2;
else if (Features & Mips::FeatureMips32)
EFlags |= ELF::EF_MIPS_ARCH_32;
if (T.isArch64Bit()) {
EFlags |= ELF::EF_MIPS_ABI2;
} else {
if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64)
EFlags |= ELF::EF_MIPS_32BITMODE;
// ABI
EFlags |= ELF::EF_MIPS_ABI_O32;
}
MCA.setELFHeaderEFlags(EFlags);
}
void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
if (!isMicroMipsEnabled())
@ -117,13 +137,13 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
return static_cast<MCELFStreamer &>(Streamer);
}
void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) {
MCAssembler &MCA = getStreamer().getAssembler();
MCA.setELFHeaderEFlags(Flags);
}
void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
MicroMipsEnabled = true;
MCAssembler &MCA = getStreamer().getAssembler();
unsigned Flags = MCA.getELFHeaderEFlags();
Flags |= ELF::EF_MIPS_MICROMIPS;
MCA.setELFHeaderEFlags(Flags);
}
void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
@ -146,7 +166,10 @@ void MipsTargetELFStreamer::emitDirectiveSetReorder() {
}
void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
// FIXME: implement.
MCAssembler &MCA = getStreamer().getAssembler();
unsigned Flags = MCA.getELFHeaderEFlags();
Flags |= ELF::EF_MIPS_NOREORDER;
MCA.setELFHeaderEFlags(Flags);
}
void MipsTargetELFStreamer::emitDirectiveSetMacro() {
@ -176,7 +199,7 @@ void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
MCAssembler &MCA = getStreamer().getAssembler();
unsigned Flags = MCA.getELFHeaderEFlags();
Flags |= ELF::EF_MIPS_CPIC;
Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
MCA.setELFHeaderEFlags(Flags);
}
void MipsTargetELFStreamer::emitDirectiveOptionPic0() {

View File

@ -636,54 +636,10 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
}
static void emitELFHeaderFlagsCG(MipsTargetStreamer &TargetStreamer,
const MipsSubtarget &Subtarget) {
// Update e_header flags
unsigned EFlags = 0;
// TODO: Need to add -mabicalls and -mno-abicalls flags.
// Currently we assume that -mabicalls is the default.
EFlags |= ELF::EF_MIPS_CPIC;
if (Subtarget.inMips16Mode())
EFlags |= ELF::EF_MIPS_ARCH_ASE_M16;
else
EFlags |= ELF::EF_MIPS_NOREORDER;
// Architecture
if (Subtarget.hasMips64r2())
EFlags |= ELF::EF_MIPS_ARCH_64R2;
else if (Subtarget.hasMips64())
EFlags |= ELF::EF_MIPS_ARCH_64;
else if (Subtarget.hasMips32r2())
EFlags |= ELF::EF_MIPS_ARCH_32R2;
else
EFlags |= ELF::EF_MIPS_ARCH_32;
if (Subtarget.inMicroMipsMode())
EFlags |= ELF::EF_MIPS_MICROMIPS;
// ABI
if (Subtarget.isABI_O32())
EFlags |= ELF::EF_MIPS_ABI_O32;
// Relocation Model
Reloc::Model RM = Subtarget.getRelocationModel();
if (RM == Reloc::PIC_ || RM == Reloc::Default)
EFlags |= ELF::EF_MIPS_PIC;
else if (RM == Reloc::Static)
; // Do nothing for Reloc::Static
else
llvm_unreachable("Unsupported relocation model for e_flags");
TargetStreamer.emitMipsHackELFFlags(EFlags);
}
void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
// Emit Mips ELF register info
Subtarget->getMReginfo().emitMipsReginfoSectionCG(
OutStreamer, getObjFileLowering(), *Subtarget);
emitELFHeaderFlagsCG(getTargetStreamer(), *Subtarget);
}
void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,

View File

@ -19,7 +19,6 @@ class MipsTargetStreamer : public MCTargetStreamer {
public:
MipsTargetStreamer(MCStreamer &S);
virtual void emitMipsHackELFFlags(unsigned Flags) = 0;
virtual void emitDirectiveSetMicroMips() = 0;
virtual void emitDirectiveSetNoMicroMips() = 0;
virtual void emitDirectiveSetMips16() = 0;
@ -44,7 +43,6 @@ class MipsTargetAsmStreamer : public MipsTargetStreamer {
public:
MipsTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
virtual void emitMipsHackELFFlags(unsigned Flags);
virtual void emitDirectiveSetMicroMips();
virtual void emitDirectiveSetNoMicroMips();
virtual void emitDirectiveSetMips16();
@ -70,12 +68,10 @@ class MipsTargetELFStreamer : public MipsTargetStreamer {
public:
bool isMicroMipsEnabled() const { return MicroMipsEnabled; }
MCELFStreamer &getStreamer();
MipsTargetELFStreamer(MCStreamer &S);
MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
virtual void emitLabel(MCSymbol *Symbol) LLVM_OVERRIDE;
// FIXME: emitMipsHackELFFlags() will be removed from this class.
virtual void emitMipsHackELFFlags(unsigned Flags);
virtual void emitDirectiveSetMicroMips();
virtual void emitDirectiveSetNoMicroMips();
virtual void emitDirectiveSetMips16();

View File

@ -16,52 +16,66 @@
; Note that EF_MIPS_CPIC is set by -mabicalls which is the default on Linux
; TODO need to support -mno-abicalls
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE32 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE32R2 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -relocation-model=static -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-BE32 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 %s -o - | FileCheck -check-prefix=CHECK-BE32_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-BE32R2 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 %s -o - | FileCheck -check-prefix=CHECK-BE32R2_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE64 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE64_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -relocation-model=static -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE64R2 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE64R2_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-BE64 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 %s -o - | FileCheck -check-prefix=CHECK-BE64_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-BE64R2 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 %s -o - | FileCheck -check-prefix=CHECK-BE64R2_PIC %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+mips16 -relocation-model=pic -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-LE32R2-MIPS16 %s
; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+mips16 -relocation-model=pic %s -o - | FileCheck -check-prefix=CHECK-LE32R2-MIPS16 %s
; 32(R1) bit with NO_REORDER and static
; CHECK-BE32: .mips_hack_elf_flags 0x50001005
; CHECK-BE32: .abicalls
; CHECK-BE32: .option pic0
; CHECK-BE32: .set noreorder
;
; 32(R1) bit with NO_REORDER and PIC
; CHECK-BE32_PIC: .mips_hack_elf_flags 0x50001007
; CHECK-BE32_PIC: .abicalls
; CHECK-BE32_PIC: .set noreorder
;
; 32R2 bit with NO_REORDER and static
; CHECK-BE32R2: .mips_hack_elf_flags 0x70001005
; CHECK-BE32R2: .abicalls
; CHECK-BE32R2: .option pic0
; CHECK-BE32R2: .set noreorder
;
; 32R2 bit with NO_REORDER and PIC
; CHECK-BE32R2_PIC: .mips_hack_elf_flags 0x70001007
; CHECK-BE32R2_PIC: .abicalls
; CHECK-BE32R2_PIC: .set noreorder
;
; 32R2 bit MICROMIPS with NO_REORDER and static
; CHECK-BE32R2-MICROMIPS: .mips_hack_elf_flags 0x72001005
; CHECK-BE32R2-MICROMIPS: .abicalls
; CHECK-BE32R2-MICROMIPS: .option pic0
; CHECK-BE32R2-MICROMIPS: .set micromips
;
; 32R2 bit MICROMIPS with NO_REORDER and PIC
; CHECK-BE32R2-MICROMIPS_PIC: .mips_hack_elf_flags 0x72001007
; CHECK-BE32R2-MICROMIPS_PIC: .abicalls
; CHECK-BE32R2-MICROMIPS_PIC: .set micromips
;
; 64(R1) bit with NO_REORDER and static
; CHECK-BE64: .mips_hack_elf_flags 0x60000005
; CHECK-BE64: .abicalls
; CHECK-BE64: .set noreorder
;
; 64(R1) bit with NO_REORDER and PIC
; CHECK-BE64_PIC: .mips_hack_elf_flags 0x60000007
; CHECK-BE64_PIC: .abicalls
; CHECK-BE64_PIC: .set noreorder
;
; 64R2 bit with NO_REORDER and static
; CHECK-BE64R2: .mips_hack_elf_flags 0x80000005
; CHECK-BE64R2: .abicalls
; CHECK-BE64R2: .set noreorder
;
; 64R2 bit with NO_REORDER and PIC
; CHECK-BE64R2_PIC: .mips_hack_elf_flags 0x80000007
; CHECK-BE64R2_PIC: .abicalls
; CHECK-BE64R2_PIC: .set noreorder
;
; 32R2 bit MIPS16 with PIC
; CHECK-LE32R2-MIPS16: .mips_hack_elf_flags 0x74001006
; CHECK-LE32R2-MIPS16: .abicalls
; CHECK-LE32R2-MIPS16: .set mips16
define i32 @main() nounwind {
entry:

View File

@ -1,15 +1,20 @@
// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux %s -o -| llvm-readobj -h | FileCheck %s
// The initial value will be set at 0x50001003 and
// we will override that with the negation of 0x2 (option pic0
// the addition of 0x4 (.abicalls)
# These *MUST* match the output of gas compiled with the same triple and
# corresponding options (-mcpu=mips32 -> -mips32 for example).
.mips_hack_elf_flags 0x50001003
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r2 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2 %s
# MIPSEL-MIPS64R2: Flags [ (0x80001100)
// CHECK: Flags [ (0x54001005)
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64 %s
# MIPSEL-MIPS64: Flags [ (0x60001100)
.abicalls
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32r2 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS32R2 %s
# MIPSEL-MIPS32R2: Flags [ (0x70001000)
.option pic0
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS32 %s
# MIPSEL-MIPS32: Flags [ (0x50001000)
// Set EF_MIPS_ARCH_ASE_M16 (0x04000000)
.set mips16
# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64r2 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2 %s
# MIPS64EL-MIPS64R2: Flags [ (0x80000020)
# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64 %s
# MIPS64EL-MIPS64: Flags [ (0x60000020)

View File

@ -0,0 +1,6 @@
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o -| llvm-readobj -h | FileCheck %s
# This *MUST* match the output of gas compiled with the same triple.
# CHECK: Flags [ (0x50001006)
.abicalls

View File

@ -0,0 +1,8 @@
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o -| llvm-readobj -h | FileCheck %s
# This *MUST* match the output of gas compiled with the same triple.
# CHECK: Flags [ (0x52001000)
.set micromips
f:
nop

View File

@ -0,0 +1,8 @@
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o -| llvm-readobj -h | FileCheck %s
# This *MUST* match the output of gas compiled with the same triple.
# CHECK: Flags [ (0x54001000)
.set mips16
f:
nop

View File

@ -0,0 +1,6 @@
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o -| llvm-readobj -h | FileCheck %s
# This *MUST* match the output of gas compiled with the same triple.
# CHECK: Flags [ (0x50001001)
.set noreorder

View File

@ -0,0 +1,7 @@
# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o -| llvm-readobj -h | FileCheck %s
# This *MUST* match the output of gas compiled with the same triple.
# CHECK: Flags [ (0x50001004)
.abicalls
.option pic0