[llvm] r247897 - [mips] Add assembler support for the .cprestore directive.
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 17 09:08:40 PDT 2015
Author: dsanders
Date: Thu Sep 17 11:08:39 2015
New Revision: 247897
URL: http://llvm.org/viewvc/llvm-project?rev=247897&view=rev
Log:
[mips] Add assembler support for the .cprestore directive.
Summary:
This assembler directive is used in O32 PIC to restore the current function's $gp after executing JAL's. The $gp is first stored on the stack at a user-specified offset.
It has the following format: ".cprestore 8" (where 8 is the offset).
This fixes llvm.org/PR20967.
Patch by Toma Tabacu.
Reviewers: seanbruno, tomatabacu
Subscribers: brooks, seanbruno, emaste, llvm-commits
Differential Revision: http://reviews.llvm.org/D6267
Added:
llvm/trunk/test/MC/Mips/cprestore-bad.s
llvm/trunk/test/MC/Mips/cprestore-noreorder.s
llvm/trunk/test/MC/Mips/cprestore-reorder.s
llvm/trunk/test/MC/Mips/cprestore-warning-unused.s
Modified:
llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=247897&r1=247896&r2=247897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Thu Sep 17 11:08:39 2015
@@ -116,6 +116,8 @@ class MipsAsmParser : public MCTargetAsm
// directive.
bool IsLittleEndian;
bool IsPicEnabled;
+ bool IsCpRestoreSet;
+ int CpRestoreOffset;
// Print a warning along with its fix-it message at the given range.
void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
@@ -219,6 +221,9 @@ class MipsAsmParser : public MCTargetAsm
void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
+ void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+
bool reportParseError(Twine ErrorMsg);
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
@@ -231,7 +236,9 @@ class MipsAsmParser : public MCTargetAsm
bool parseSetMips0Directive();
bool parseSetArchDirective();
bool parseSetFeature(uint64_t Feature);
+ bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
bool parseDirectiveCpLoad(SMLoc Loc);
+ bool parseDirectiveCpRestore(SMLoc Loc);
bool parseDirectiveCPSetup();
bool parseDirectiveNaN();
bool parseDirectiveSet();
@@ -402,6 +409,9 @@ public:
IsPicEnabled =
(getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
+ IsCpRestoreSet = false;
+ CpRestoreOffset = -1;
+
Triple TheTriple(sti.getTargetTriple());
if ((TheTriple.getArch() == Triple::mips) ||
(TheTriple.getArch() == Triple::mips64))
@@ -1355,6 +1365,7 @@ static unsigned countMCSymbolRefExpr(con
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+ bool ExpandedJalSym = false;
Inst.setLoc(IDLoc);
@@ -1581,7 +1592,10 @@ bool MipsAsmParser::processInstruction(M
}
MCInst JalrInst;
- JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
+ if (IsCpRestoreSet && inMicroMipsMode())
+ JalrInst.setOpcode(Mips::JALRS_MM);
+ else
+ JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
JalrInst.addOperand(MCOperand::createReg(Mips::RA));
JalrInst.addOperand(MCOperand::createReg(Mips::T9));
@@ -1590,6 +1604,7 @@ bool MipsAsmParser::processInstruction(M
// and is not necessary for correctness.
Inst = JalrInst;
+ ExpandedJalSym = true;
}
if (MCID.mayLoad() || MCID.mayStore()) {
@@ -1800,6 +1815,28 @@ bool MipsAsmParser::processInstruction(M
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
+ if ((Inst.getOpcode() == Mips::JalOneReg ||
+ Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
+ isPicAndNotNxxAbi()) {
+ if (IsCpRestoreSet) {
+ // We need a NOP between the JALR and the LW:
+ // If .set reorder has been used, we've already emitted a NOP.
+ // If .set noreorder has been used, we need to emit a NOP at this point.
+ if (!AssemblerOptions.back()->isReorder())
+ createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
+
+ // Load the $gp from the stack.
+ SmallVector<MCInst, 3> LoadInsts;
+ createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
+ IDLoc, LoadInsts);
+
+ for (const MCInst &Inst : LoadInsts)
+ Instructions.push_back(Inst);
+
+ } else
+ Warning(IDLoc, "no .cprestore used in PIC mode");
+ }
+
return false;
}
@@ -2004,7 +2041,10 @@ bool MipsAsmParser::expandJalWithRegs(MC
if (Opcode == Mips::JalOneReg) {
// jal $rs => jalr $rs
- if (inMicroMipsMode()) {
+ if (IsCpRestoreSet && inMicroMipsMode()) {
+ JalrInst.setOpcode(Mips::JALRS16_MM);
+ JalrInst.addOperand(FirstRegOp);
+ } else if (inMicroMipsMode()) {
JalrInst.setOpcode(Mips::JALR16_MM);
JalrInst.addOperand(FirstRegOp);
} else {
@@ -2014,7 +2054,10 @@ bool MipsAsmParser::expandJalWithRegs(MC
}
} else if (Opcode == Mips::JalTwoReg) {
// jal $rd, $rs => jalr $rd, $rs
- JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
+ if (IsCpRestoreSet && inMicroMipsMode())
+ JalrInst.setOpcode(Mips::JALRS_MM);
+ else
+ JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
JalrInst.addOperand(FirstRegOp);
const MCOperand SecondRegOp = Inst.getOperand(1);
JalrInst.addOperand(SecondRegOp);
@@ -2022,16 +2065,8 @@ bool MipsAsmParser::expandJalWithRegs(MC
Instructions.push_back(JalrInst);
// If .set reorder is active, emit a NOP after it.
- if (AssemblerOptions.back()->isReorder()) {
- // This is a 32-bit NOP because these 2 pseudo-instructions
- // do not have a short delay slot.
- MCInst NopInst;
- NopInst.setOpcode(Mips::SLL);
- NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
- NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
- NopInst.addOperand(MCOperand::createImm(0));
- Instructions.push_back(NopInst);
- }
+ if (AssemblerOptions.back()->isReorder())
+ createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
return false;
}
@@ -3109,6 +3144,22 @@ void MipsAsmParser::createAddu(unsigned
Instructions);
}
+void MipsAsmParser::createCpRestoreMemOp(
+ bool IsLoad, int StackOffset, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions) {
+ MCInst MemInst;
+ MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
+ MemInst.addOperand(MCOperand::createReg(Mips::GP));
+ MemInst.addOperand(MCOperand::createReg(Mips::SP));
+ MemInst.addOperand(MCOperand::createImm(StackOffset));
+
+ // If the offset can not fit into 16 bits, we need to expand.
+ if (!isInt<16>(StackOffset))
+ expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
+ else
+ Instructions.push_back(MemInst);
+}
+
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
// As described by the Mips32r2 spec, the registers Rd and Rs for
// jalr.hb must be different.
@@ -4758,6 +4809,14 @@ bool MipsAsmParser::eatComma(StringRef E
return true;
}
+// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
+// In this class, it is only used for .cprestore.
+// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
+// MipsTargetELFStreamer and MipsAsmParser.
+bool MipsAsmParser::isPicAndNotNxxAbi() {
+ return inPicMode() && !(isABI_N32() || isABI_N64());
+}
+
bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
if (AssemblerOptions.back()->isReorder())
Warning(Loc, ".cpload should be inside a noreorder section");
@@ -4790,6 +4849,54 @@ bool MipsAsmParser::parseDirectiveCpLoad
return false;
}
+bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
+ MCAsmParser &Parser = getParser();
+
+ // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
+ // is used in non-PIC mode.
+
+ if (inMips16Mode()) {
+ reportParseError(".cprestore is not supported in Mips16 mode");
+ return false;
+ }
+
+ // Get the stack offset value.
+ const MCExpr *StackOffset;
+ int64_t StackOffsetVal;
+ if (Parser.parseExpression(StackOffset)) {
+ reportParseError("expected stack offset value");
+ return false;
+ }
+
+ if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
+ reportParseError("stack offset is not an absolute expression");
+ return false;
+ }
+
+ if (StackOffsetVal < 0) {
+ Warning(Loc, ".cprestore with negative stack offset has no effect");
+ IsCpRestoreSet = false;
+ } else {
+ IsCpRestoreSet = true;
+ CpRestoreOffset = StackOffsetVal;
+ }
+
+ // If this is not the end of the statement, report an error.
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token, expected end of statement");
+ return false;
+ }
+
+ // Store the $gp on the stack.
+ SmallVector<MCInst, 3> StoreInsts;
+ createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
+ StoreInsts);
+
+ getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
+ Parser.Lex(); // Consume the EndOfStatement.
+ return false;
+}
+
bool MipsAsmParser::parseDirectiveCPSetup() {
MCAsmParser &Parser = getParser();
unsigned FuncReg;
@@ -5322,6 +5429,8 @@ bool MipsAsmParser::ParseDirective(AsmTo
if (IDVal == ".cpload")
return parseDirectiveCpLoad(DirectiveID.getLoc());
+ if (IDVal == ".cprestore")
+ return parseDirectiveCpRestore(DirectiveID.getLoc());
if (IDVal == ".dword") {
parseDataDirective(8, DirectiveID.getLoc());
return false;
@@ -5372,6 +5481,7 @@ bool MipsAsmParser::ParseDirective(AsmTo
getTargetStreamer().emitDirectiveEnt(*Sym);
CurrentFn = Sym;
+ IsCpRestoreSet = false;
return false;
}
@@ -5400,6 +5510,7 @@ bool MipsAsmParser::ParseDirective(AsmTo
getTargetStreamer().emitDirectiveEnd(SymbolName);
CurrentFn = nullptr;
+ IsCpRestoreSet = false;
return false;
}
@@ -5471,6 +5582,7 @@ bool MipsAsmParser::ParseDirective(AsmTo
getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
ReturnRegOpnd.getGPR32Reg());
+ IsCpRestoreSet = false;
return false;
}
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp?rev=247897&r1=247896&r2=247897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp Thu Sep 17 11:08:39 2015
@@ -89,6 +89,10 @@ void MipsTargetStreamer::emitDirectiveSe
void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
+void MipsTargetStreamer::emitDirectiveCpRestore(
+ SmallVector<MCInst, 3> &StoreInsts, int Offset) {
+ forbidModuleDirective();
+}
void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg) {
}
@@ -358,6 +362,12 @@ void MipsTargetAsmStreamer::emitDirectiv
forbidModuleDirective();
}
+void MipsTargetAsmStreamer::emitDirectiveCpRestore(
+ SmallVector<MCInst, 3> &StoreInsts, int Offset) {
+ MipsTargetStreamer::emitDirectiveCpRestore(StoreInsts, Offset);
+ OS << "\t.cprestore\t" << Offset << "\n";
+}
+
void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
int RegOrOffset,
const MCSymbol &Sym,
@@ -752,6 +762,24 @@ void MipsTargetELFStreamer::emitDirectiv
forbidModuleDirective();
}
+void MipsTargetELFStreamer::emitDirectiveCpRestore(
+ SmallVector<MCInst, 3> &StoreInsts, int Offset) {
+ MipsTargetStreamer::emitDirectiveCpRestore(StoreInsts, Offset);
+ // .cprestore offset
+ // When PIC mode is enabled and the O32 ABI is used, this directive expands
+ // to:
+ // sw $gp, offset($sp)
+ // and adds a corresponding LW after every JAL.
+
+ // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
+ // is used in non-PIC mode.
+ if (!Pic || (getABI().IsN32() || getABI().IsN64()))
+ return;
+
+ for (const MCInst &Inst : StoreInsts)
+ getStreamer().EmitInstruction(Inst, STI);
+}
+
void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
int RegOrOffset,
const MCSymbol &Sym,
Modified: llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h?rev=247897&r1=247896&r2=247897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h Thu Sep 17 11:08:39 2015
@@ -78,6 +78,8 @@ public:
// PIC support
virtual void emitDirectiveCpLoad(unsigned RegNo);
+ virtual void emitDirectiveCpRestore(SmallVector<MCInst, 3> &StoreInsts,
+ int Offset);
virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg);
@@ -189,6 +191,8 @@ public:
// PIC support
void emitDirectiveCpLoad(unsigned RegNo) override;
+ void emitDirectiveCpRestore(SmallVector<MCInst, 3> &StoreInsts,
+ int Offset) override;
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg) override;
@@ -238,6 +242,8 @@ public:
// PIC support
void emitDirectiveCpLoad(unsigned RegNo) override;
+ void emitDirectiveCpRestore(SmallVector<MCInst, 3> &StoreInsts,
+ int Offset) override;
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg) override;
Added: llvm/trunk/test/MC/Mips/cprestore-bad.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/cprestore-bad.s?rev=247897&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/cprestore-bad.s (added)
+++ llvm/trunk/test/MC/Mips/cprestore-bad.s Thu Sep 17 11:08:39 2015
@@ -0,0 +1,23 @@
+# RUN: not llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=pic 2>%t1
+# RUN: FileCheck %s < %t1
+
+ .text
+ .set noreorder
+ .cpload $25
+
+ .set mips16
+ .cprestore 8
+# CHECK: :[[@LINE-1]]:14: error: .cprestore is not supported in Mips16 mode
+ .set nomips16
+
+ .cprestore
+# CHECK: :[[@LINE-1]]:13: error: expected stack offset value
+
+ .cprestore foo
+# CHECK: :[[@LINE-1]]:17: error: stack offset is not an absolute expression
+
+ .cprestore -8
+# CHECK: :[[@LINE-1]]:3: warning: .cprestore with negative stack offset has no effect
+
+ .cprestore 8, 35, bar
+# CHECK: :[[@LINE-1]]:15: error: unexpected token, expected end of statement
Added: llvm/trunk/test/MC/Mips/cprestore-noreorder.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/cprestore-noreorder.s?rev=247897&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/cprestore-noreorder.s (added)
+++ llvm/trunk/test/MC/Mips/cprestore-noreorder.s Thu Sep 17 11:08:39 2015
@@ -0,0 +1,97 @@
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=pic -filetype=obj -o -| \
+# RUN: llvm-objdump -d -r -arch=mips - | \
+# RUN: FileCheck %s -check-prefix=CHECK-FOR-STORE
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -mattr=+micromips -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s -check-prefix=MICROMIPS
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=static -show-encoding | \
+# RUN: FileCheck %s -check-prefix=NO-PIC
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips64 -target-abi n32 -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s -check-prefix=BAD-ABI -check-prefix=BAD-ABI-N32
+
+# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64 -target-abi n64 -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s -check-prefix=BAD-ABI -check-prefix=BAD-ABI-N64
+
+ .text
+ .ent foo
+foo:
+ .frame $sp, 0, $ra
+ .set noreorder
+
+ .cpload $25
+ .cprestore 8
+
+ jal $25
+ jal $4, $25
+ jal foo
+
+ .end foo
+
+# CHECK-FOR-STORE: sw $gp, 8($sp)
+
+# CHECK: .cprestore 8
+# CHECK: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# CHECK: nop # encoding: [0x00,0x00,0x00,0x00]
+# CHECK: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# CHECK: jalr $4, $25 # encoding: [0x03,0x20,0x20,0x09]
+# CHECK: nop # encoding: [0x00,0x00,0x00,0x00]
+# CHECK: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# CHECK: lw $25, %got(foo)($gp) # encoding: [0x8f,0x99,A,A]
+# CHECK: # fixup A - offset: 0, value: foo at GOT, kind: fixup_Mips_GOT_Local
+# CHECK: addiu $25, $25, %lo(foo) # encoding: [0x27,0x39,A,A]
+# CHECK: # fixup A - offset: 0, value: foo at ABS_LO, kind: fixup_Mips_LO16
+# CHECK: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# CHECK: nop # encoding: [0x00,0x00,0x00,0x00]
+# CHECK: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+# CHECK: .end foo
+
+# MICROMIPS: .cprestore 8
+# MICROMIPS: jalrs16 $25 # encoding: [0x45,0xf9]
+# MICROMIPS: nop # encoding: [0x00,0x00,0x00,0x00]
+# MICROMIPS: lw $gp, 8($sp) # encoding: [0xff,0x9d,0x00,0x08]
+
+# MICROMIPS: jalrs $4, $25 # encoding: [0x00,0x99,0x4f,0x3c]
+# MICROMIPS: nop # encoding: [0x00,0x00,0x00,0x00]
+# MICROMIPS: lw $gp, 8($sp) # encoding: [0xff,0x9d,0x00,0x08]
+
+# MICROMIPS: lw $25, %got(foo)($gp) # encoding: [0xff,0x3c,A,A]
+# MICROMIPS: # fixup A - offset: 0, value: foo at GOT, kind: fixup_MICROMIPS_GOT16
+# MICROMIPS: addiu $25, $25, %lo(foo) # encoding: [0x33,0x39,A,A]
+# MICROMIPS: # fixup A - offset: 0, value: foo at ABS_LO, kind: fixup_MICROMIPS_LO16
+# MICROMIPS: jalrs $ra, $25 # encoding: [0x03,0xf9,0x4f,0x3c]
+# MICROMIPS: nop # encoding: [0x0c,0x00]
+# MICROMIPS: lw $gp, 8($sp) # encoding: [0xff,0x9d,0x00,0x08]
+# MICROMIPS: .end foo
+
+# NO-PIC: .cprestore 8
+# NO-PIC: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# NO-PIC-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# NO-PIC: jalr $4, $25 # encoding: [0x03,0x20,0x20,0x09]
+# NO-PIC-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# NO-PIC: jal foo # encoding: [0b000011AA,A,A,A]
+# NO-PIC: # fixup A - offset: 0, value: foo, kind: fixup_Mips_26
+# NO-PIC-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+# NO-PIC: .end foo
+
+# BAD-ABI: .cprestore 8
+# BAD-ABI: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# BAD-ABI-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# BAD-ABI: jalr $4, $25 # encoding: [0x03,0x20,0x20,0x09]
+# BAD-ABI-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# BAD-ABI-N32: lw $25, %got_disp(foo)($gp) # encoding: [0x8f,0x99,A,A]
+# BAD-ABI-N64: ld $25, %got_disp(foo)($gp) # encoding: [0xdf,0x99,A,A]
+# BAD-ABI: # fixup A - offset: 0, value: foo at GOT_DISP, kind: fixup_Mips_GOT_DISP
+# BAD-ABI: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# BAD-ABI-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+# BAD-ABI: .end foo
Added: llvm/trunk/test/MC/Mips/cprestore-reorder.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/cprestore-reorder.s?rev=247897&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/cprestore-reorder.s (added)
+++ llvm/trunk/test/MC/Mips/cprestore-reorder.s Thu Sep 17 11:08:39 2015
@@ -0,0 +1,98 @@
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=pic -filetype=obj -o -| \
+# RUN: llvm-objdump -d -r -arch=mips - | \
+# RUN: FileCheck %s -check-prefix=CHECK-FOR-STORE
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -mattr=+micromips -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s -check-prefix=MICROMIPS
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=static -show-encoding | \
+# RUN: FileCheck %s -check-prefix=NO-PIC
+
+# RUN: llvm-mc %s -arch=mips -mcpu=mips64 -target-abi n32 -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s -check-prefix=BAD-ABI -check-prefix=BAD-ABI-N32
+
+# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64 -target-abi n64 -relocation-model=pic -show-encoding | \
+# RUN: FileCheck %s -check-prefix=BAD-ABI -check-prefix=BAD-ABI-N64
+
+ .text
+ .ent foo
+foo:
+ .frame $sp, 0, $ra
+ .set noreorder
+ .cpload $25
+ .set reorder
+
+ .cprestore 8
+
+ jal $25
+ jal $4, $25
+ jal foo
+
+ .end foo
+
+# CHECK-FOR-STORE: sw $gp, 8($sp)
+
+# CHECK: .cprestore 8
+# CHECK: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# CHECK: nop # encoding: [0x00,0x00,0x00,0x00]
+# CHECK: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# CHECK: jalr $4, $25 # encoding: [0x03,0x20,0x20,0x09]
+# CHECK: nop # encoding: [0x00,0x00,0x00,0x00]
+# CHECK: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# CHECK: lw $25, %got(foo)($gp) # encoding: [0x8f,0x99,A,A]
+# CHECK: # fixup A - offset: 0, value: foo at GOT, kind: fixup_Mips_GOT_Local
+# CHECK: addiu $25, $25, %lo(foo) # encoding: [0x27,0x39,A,A]
+# CHECK: # fixup A - offset: 0, value: foo at ABS_LO, kind: fixup_Mips_LO16
+# CHECK: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# CHECK: nop # encoding: [0x00,0x00,0x00,0x00]
+# CHECK: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+# CHECK: .end foo
+
+# MICROMIPS: .cprestore 8
+# MICROMIPS: jalrs16 $25 # encoding: [0x45,0xf9]
+# MICROMIPS: nop # encoding: [0x0c,0x00]
+# MICROMIPS: lw $gp, 8($sp) # encoding: [0xff,0x9d,0x00,0x08]
+
+# MICROMIPS: jalrs $4, $25 # encoding: [0x00,0x99,0x4f,0x3c]
+# MICROMIPS: nop # encoding: [0x0c,0x00]
+# MICROMIPS: lw $gp, 8($sp) # encoding: [0xff,0x9d,0x00,0x08]
+
+# MICROMIPS: lw $25, %got(foo)($gp) # encoding: [0xff,0x3c,A,A]
+# MICROMIPS: # fixup A - offset: 0, value: foo at GOT, kind: fixup_MICROMIPS_GOT16
+# MICROMIPS: addiu $25, $25, %lo(foo) # encoding: [0x33,0x39,A,A]
+# MICROMIPS: # fixup A - offset: 0, value: foo at ABS_LO, kind: fixup_MICROMIPS_LO16
+# MICROMIPS: jalrs $ra, $25 # encoding: [0x03,0xf9,0x4f,0x3c]
+# MICROMIPS: nop # encoding: [0x0c,0x00]
+# MICROMIPS: lw $gp, 8($sp) # encoding: [0xff,0x9d,0x00,0x08]
+# MICROMIPS: .end foo
+
+# NO-PIC: .cprestore 8
+# NO-PIC: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# NO-PIC-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# NO-PIC: jalr $4, $25 # encoding: [0x03,0x20,0x20,0x09]
+# NO-PIC-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# NO-PIC: jal foo # encoding: [0b000011AA,A,A,A]
+# NO-PIC: # fixup A - offset: 0, value: foo, kind: fixup_Mips_26
+# NO-PIC-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+# NO-PIC: .end foo
+
+# BAD-ABI: .cprestore 8
+# BAD-ABI: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# BAD-ABI-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# BAD-ABI: jalr $4, $25 # encoding: [0x03,0x20,0x20,0x09]
+# BAD-ABI-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+
+# BAD-ABI-N32: lw $25, %got_disp(foo)($gp) # encoding: [0x8f,0x99,A,A]
+# BAD-ABI-N64: ld $25, %got_disp(foo)($gp) # encoding: [0xdf,0x99,A,A]
+# BAD-ABI: # fixup A - offset: 0, value: foo at GOT_DISP, kind: fixup_Mips_GOT_DISP
+# BAD-ABI: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
+# BAD-ABI-NOT: lw $gp, 8($sp) # encoding: [0x8f,0xbc,0x00,0x08]
+# BAD-ABI: .end foo
Added: llvm/trunk/test/MC/Mips/cprestore-warning-unused.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/cprestore-warning-unused.s?rev=247897&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/cprestore-warning-unused.s (added)
+++ llvm/trunk/test/MC/Mips/cprestore-warning-unused.s Thu Sep 17 11:08:39 2015
@@ -0,0 +1,10 @@
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=pic 2>%t1
+# RUN: FileCheck %s < %t1
+
+ .text
+ .set noreorder
+ .cpload $25
+ .set reorder
+
+ jal $25
+# CHECK: :[[@LINE-1]]:3: warning: no .cprestore used in PIC mode
More information about the llvm-commits
mailing list