Skip to content

Commit

Permalink
[mips] Add support for '.option pic2'.
Browse files Browse the repository at this point in the history
The directive '.option pic2' enables PIC from assembly source.
At the moment none of the macros/directives check the PIC bit
but that's going to be fixed relatively soon. For example, the
expansion of macros like 'la' depend on the relocation model.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204803 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Matheus Almeida committed Mar 26, 2014
1 parent c4b058f commit 0de31d5
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 0 deletions.
11 changes: 11 additions & 0 deletions lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2596,6 +2596,17 @@ bool MipsAsmParser::parseDirectiveOption() {
return false;
}

if (Option == "pic2") {
getTargetStreamer().emitDirectiveOptionPic2();
Parser.Lex();
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
Error(Parser.getTok().getLoc(),
"unexpected token in .option pic2 directive");
Parser.eatToEndOfStatement();
}
return false;
}

// Unknown option.
Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
Parser.eatToEndOfStatement();
Expand Down
21 changes: 21 additions & 0 deletions lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
OS << "\t.option\tpic0\n";
}

void MipsTargetAsmStreamer::emitDirectiveOptionPic2() {
OS << "\t.option\tpic2\n";
}

void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
unsigned ReturnReg) {
OS << "\t.frame\t$"
Expand Down Expand Up @@ -132,6 +136,9 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
MCAssembler &MCA = getStreamer().getAssembler();
uint64_t Features = STI.getFeatureBits();
Triple T(STI.getTargetTriple());
Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
? true
: false;

// Update e_header flags
unsigned EFlags = 0;
Expand Down Expand Up @@ -311,10 +318,24 @@ void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
MCAssembler &MCA = getStreamer().getAssembler();
unsigned Flags = MCA.getELFHeaderEFlags();
// This option overrides other PIC options like -KPIC.
Pic = false;
Flags &= ~ELF::EF_MIPS_PIC;
MCA.setELFHeaderEFlags(Flags);
}

void MipsTargetELFStreamer::emitDirectiveOptionPic2() {
MCAssembler &MCA = getStreamer().getAssembler();
unsigned Flags = MCA.getELFHeaderEFlags();
Pic = true;
// NOTE: We are following the GAS behaviour here which means the directive
// 'pic2' also sets the CPIC bit in the ELF header. This is different from
// what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
// EF_MIPS_CPIC to be mutually exclusive.
Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC;
MCA.setELFHeaderEFlags(Flags);
}

void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
unsigned ReturnReg) {
// FIXME: implement.
Expand Down
4 changes: 4 additions & 0 deletions lib/Target/Mips/MipsTargetStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class MipsTargetStreamer : public MCTargetStreamer {
virtual void emitDirectiveEnt(const MCSymbol &Symbol) = 0;
virtual void emitDirectiveAbiCalls() = 0;
virtual void emitDirectiveOptionPic0() = 0;
virtual void emitDirectiveOptionPic2() = 0;
virtual void emitFrame(unsigned StackReg, unsigned StackSize,
unsigned ReturnReg) = 0;
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) = 0;
Expand Down Expand Up @@ -66,6 +67,7 @@ class MipsTargetAsmStreamer : public MipsTargetStreamer {
virtual void emitDirectiveEnt(const MCSymbol &Symbol);
virtual void emitDirectiveAbiCalls();
virtual void emitDirectiveOptionPic0();
virtual void emitDirectiveOptionPic2();
virtual void emitFrame(unsigned StackReg, unsigned StackSize,
unsigned ReturnReg);
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff);
Expand All @@ -79,6 +81,7 @@ class MipsTargetAsmStreamer : public MipsTargetStreamer {
class MipsTargetELFStreamer : public MipsTargetStreamer {
bool MicroMipsEnabled;
const MCSubtargetInfo &STI;
bool Pic;

public:
bool isMicroMipsEnabled() const { return MicroMipsEnabled; }
Expand All @@ -105,6 +108,7 @@ class MipsTargetELFStreamer : public MipsTargetStreamer {
virtual void emitDirectiveEnt(const MCSymbol &Symbol);
virtual void emitDirectiveAbiCalls();
virtual void emitDirectiveOptionPic0();
virtual void emitDirectiveOptionPic2();
virtual void emitFrame(unsigned StackReg, unsigned StackSize,
unsigned ReturnReg);
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff);
Expand Down
6 changes: 6 additions & 0 deletions test/MC/Mips/elf_eflags_pic2.s
Original file line number Diff line number Diff line change
@@ -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)

.option pic2
10 changes: 10 additions & 0 deletions test/MC/Mips/mips_directives_bad.s
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,14 @@
.option pic0 pic2
# CHECK-NEXT: :{{[0-9]+}}:{{[0-9]+}}: error: unexpected token in .option pic0 directive
# CHECK-NEXT: .option pic0 pic2
# CHECK-NEXT: ^

.option pic2,
# CHECK-NEXT: :{{[0-9]+}}:{{[0-9]+}}: error: unexpected token in .option pic2 directive
# CHECK-NEXT: .option pic2,
# CHECK-NEXT: ^

.option pic2 pic3
# CHECK-NEXT: :{{[0-9]+}}:{{[0-9]+}}: error: unexpected token in .option pic2 directive
# CHECK-NEXT: .option pic2 pic3
# CHECK-NEXT: ^

0 comments on commit 0de31d5

Please sign in to comment.