mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[mips][ias] Implement .cpreturn directive.
Summary: Based on a patch by David Chisnall. I've modified the original patch as follows: * Moved the expansion to the TargetStreamers so that the directive isn't expanded when emitting assembly. * Fixed an operand order bug. * Changed the move instructions from DADDu to OR to match recent changes to GAS. Reviewers: vkalintiris Subscribers: llvm-commits, emaste, seanbruno, theraven Differential Revision: http://reviews.llvm.org/D13017 llvm-svn: 248258
This commit is contained in:
parent
d5bb1c9800
commit
446d9a74d9
@ -118,6 +118,9 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
bool IsPicEnabled;
|
||||
bool IsCpRestoreSet;
|
||||
int CpRestoreOffset;
|
||||
unsigned CpSaveLocation;
|
||||
/// If true, then CpSaveLocation is a register, otherwise it's an offset.
|
||||
bool CpSaveLocationIsRegister;
|
||||
|
||||
// Print a warning along with its fix-it message at the given range.
|
||||
void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
|
||||
@ -240,6 +243,7 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
bool parseDirectiveCpLoad(SMLoc Loc);
|
||||
bool parseDirectiveCpRestore(SMLoc Loc);
|
||||
bool parseDirectiveCPSetup();
|
||||
bool parseDirectiveCPReturn();
|
||||
bool parseDirectiveNaN();
|
||||
bool parseDirectiveSet();
|
||||
bool parseDirectiveOption();
|
||||
@ -4964,11 +4968,20 @@ bool MipsAsmParser::parseDirectiveCPSetup() {
|
||||
}
|
||||
const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
|
||||
|
||||
CpSaveLocation = Save;
|
||||
CpSaveLocationIsRegister = SaveIsReg;
|
||||
|
||||
getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
|
||||
SaveIsReg);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::parseDirectiveCPReturn() {
|
||||
getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
|
||||
CpSaveLocationIsRegister);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::parseDirectiveNaN() {
|
||||
MCAsmParser &Parser = getParser();
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
@ -5686,6 +5699,9 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||
if (IDVal == ".cpsetup")
|
||||
return parseDirectiveCPSetup();
|
||||
|
||||
if (IDVal == ".cpreturn")
|
||||
return parseDirectiveCPReturn();
|
||||
|
||||
if (IDVal == ".module")
|
||||
return parseDirectiveModule();
|
||||
|
||||
|
@ -96,6 +96,8 @@ void MipsTargetStreamer::emitDirectiveCpRestore(
|
||||
void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
const MCSymbol &Sym, bool IsReg) {
|
||||
}
|
||||
void MipsTargetStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
bool SaveLocationIsRegister) {}
|
||||
|
||||
void MipsTargetStreamer::emitDirectiveModuleFP() {}
|
||||
|
||||
@ -387,6 +389,12 @@ void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
|
||||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetAsmStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
bool SaveLocationIsRegister) {
|
||||
OS << "\t.cpreturn";
|
||||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetAsmStreamer::emitDirectiveModuleFP() {
|
||||
OS << "\t.module\tfp=";
|
||||
OS << ABIFlagsSection.getFpABIString(ABIFlagsSection.getFpABI()) << "\n";
|
||||
@ -838,6 +846,30 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
|
||||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
bool SaveLocationIsRegister) {
|
||||
// Only N32 and N64 emit anything for .cpreturn iff PIC is set.
|
||||
if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
|
||||
return;
|
||||
|
||||
MCInst Inst;
|
||||
// Either restore the old $gp from a register or on the stack
|
||||
if (SaveLocationIsRegister) {
|
||||
Inst.setOpcode(Mips::OR);
|
||||
Inst.addOperand(MCOperand::createReg(Mips::GP));
|
||||
Inst.addOperand(MCOperand::createReg(SaveLocation));
|
||||
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
|
||||
} else {
|
||||
Inst.setOpcode(Mips::LD);
|
||||
Inst.addOperand(MCOperand::createReg(Mips::GP));
|
||||
Inst.addOperand(MCOperand::createReg(Mips::SP));
|
||||
Inst.addOperand(MCOperand::createImm(SaveLocation));
|
||||
}
|
||||
getStreamer().EmitInstruction(Inst, STI);
|
||||
|
||||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitMipsAbiFlags() {
|
||||
MCAssembler &MCA = getStreamer().getAssembler();
|
||||
MCContext &Context = MCA.getContext();
|
||||
|
@ -82,6 +82,8 @@ public:
|
||||
int Offset);
|
||||
virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
const MCSymbol &Sym, bool IsReg);
|
||||
virtual void emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
bool SaveLocationIsRegister);
|
||||
|
||||
// FP abiflags directives
|
||||
virtual void emitDirectiveModuleFP();
|
||||
@ -195,6 +197,8 @@ public:
|
||||
int Offset) override;
|
||||
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
const MCSymbol &Sym, bool IsReg) override;
|
||||
void emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
bool SaveLocationIsRegister) override;
|
||||
|
||||
// FP abiflags directives
|
||||
void emitDirectiveModuleFP() override;
|
||||
@ -246,6 +250,8 @@ public:
|
||||
int Offset) override;
|
||||
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
const MCSymbol &Sym, bool IsReg) override;
|
||||
void emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
bool SaveLocationIsRegister) override;
|
||||
|
||||
void emitMipsAbiFlags();
|
||||
};
|
||||
|
@ -24,6 +24,8 @@
|
||||
t1:
|
||||
.cpsetup $25, 8, __cerror
|
||||
nop
|
||||
.cpreturn
|
||||
nop
|
||||
|
||||
# ALL-LABEL: t1:
|
||||
|
||||
@ -45,9 +47,16 @@ t1:
|
||||
|
||||
# ALL-NEXT: nop
|
||||
|
||||
# ASM-NEXT: .cpreturn
|
||||
# NXX-NEXT: ld $gp, 8($sp)
|
||||
|
||||
# ALL-NEXT: nop
|
||||
|
||||
t2:
|
||||
.cpsetup $25, $2, __cerror
|
||||
nop
|
||||
.cpreturn
|
||||
nop
|
||||
|
||||
# ALL-LABEL: t2:
|
||||
|
||||
@ -69,6 +78,11 @@ t2:
|
||||
|
||||
# ALL-NEXT: nop
|
||||
|
||||
# ASM-NEXT: .cpreturn
|
||||
# NXX-NEXT: move $gp, $2
|
||||
|
||||
# ALL-NEXT: nop
|
||||
|
||||
# .cpsetup with local labels (PR22518):
|
||||
|
||||
# The '1:' label isn't emitted in all cases but we still want a label to match
|
||||
@ -115,6 +129,8 @@ t4:
|
||||
nop
|
||||
.cpsetup $25, 8, __cerror
|
||||
nop
|
||||
.cpreturn
|
||||
nop
|
||||
|
||||
# Testing that .cpsetup expands to nothing in this case
|
||||
# by checking that the next instruction after the first
|
||||
@ -122,12 +138,15 @@ t4:
|
||||
|
||||
# ALL-LABEL: t4:
|
||||
|
||||
# NXX-NEXT: nop
|
||||
# NXX-NEXT: nop
|
||||
# NXX-NEXT: nop
|
||||
|
||||
# ASM-NEXT: nop
|
||||
# ASM-NEXT: .cpsetup $25, 8, __cerror
|
||||
# ASM-NEXT: nop
|
||||
# ASM-NEXT: .cpreturn
|
||||
# ASM-NEXT: nop
|
||||
|
||||
# Test that we accept constant expressions.
|
||||
.option pic2
|
||||
|
Loading…
Reference in New Issue
Block a user