[llvm] r204924 - [mips] Add support for .cpsetup
Daniel Sanders
daniel.sanders at imgtec.com
Thu Mar 27 06:52:54 PDT 2014
Author: dsanders
Date: Thu Mar 27 08:52:53 2014
New Revision: 204924
URL: http://llvm.org/viewvc/llvm-project?rev=204924&view=rev
Log:
[mips] Add support for .cpsetup
Summary:
Patch by Robert N. M. Watson
His work was sponsored by: DARPA, AFRL
Small corrections by myself.
CC: theraven, matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3199
Added:
llvm/trunk/test/MC/Mips/cpsetup.s
Modified:
llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
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=204924&r1=204923&r2=204924&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Thu Mar 27 08:52:53 2014
@@ -196,6 +196,7 @@ class MipsAsmParser : public MCTargetAsm
bool isEvaluated(const MCExpr *Expr);
bool parseSetFeature(uint64_t Feature);
+ bool parseDirectiveCPSetup();
bool parseDirectiveSet();
bool parseDirectiveOption();
@@ -229,6 +230,10 @@ class MipsAsmParser : public MCTargetAsm
return STI.getFeatureBits() & Mips::FeatureMicroMips;
}
+ bool parseRegister(unsigned &RegNum);
+
+ bool eatComma(StringRef ErrorStr);
+
int matchRegisterName(StringRef Symbol, bool is64BitReg);
int matchCPURegisterName(StringRef Symbol);
@@ -249,6 +254,8 @@ class MipsAsmParser : public MCTargetAsm
unsigned getReg(int RC, int RegNo);
+ unsigned getGPR(int RegNo);
+
int getATReg();
// Warn if RegNo is the current assembler temporary.
@@ -1202,6 +1209,12 @@ unsigned MipsAsmParser::getReg(int RC, i
return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
}
+unsigned MipsAsmParser::getGPR(int RegNo) {
+ return getReg((isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
+ RegNo);
+}
+
+
int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
if (RegNum >
getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
@@ -2501,6 +2514,123 @@ bool MipsAsmParser::parseSetFeature(uint
return false;
}
+bool MipsAsmParser::parseRegister(unsigned &RegNum) {
+ if (!getLexer().is(AsmToken::Dollar))
+ return false;
+
+ Parser.Lex();
+
+ const AsmToken &Reg = Parser.getTok();
+ if (Reg.is(AsmToken::Identifier)) {
+ RegNum = matchCPURegisterName(Reg.getIdentifier());
+ } else if (Reg.is(AsmToken::Integer)) {
+ RegNum = Reg.getIntVal();
+ } else {
+ return false;
+ }
+
+ Parser.Lex();
+ return true;
+}
+
+bool MipsAsmParser::eatComma(StringRef ErrorStr) {
+ if (getLexer().isNot(AsmToken::Comma)) {
+ SMLoc Loc = getLexer().getLoc();
+ Parser.eatToEndOfStatement();
+ return Error(Loc, ErrorStr);
+ }
+
+ Parser.Lex(); // Eat the comma.
+ return true;
+}
+
+bool MipsAsmParser::parseDirectiveCPSetup() {
+ unsigned FuncReg;
+ unsigned Save;
+ bool SaveIsReg = true;
+
+ if (!parseRegister(FuncReg))
+ return reportParseError("expected register containing function address");
+ FuncReg = getGPR(FuncReg);
+
+ if (!eatComma("expected comma parsing directive"))
+ return true;
+
+ if (!parseRegister(Save)) {
+ const AsmToken &Tok = Parser.getTok();
+ if (Tok.is(AsmToken::Integer)) {
+ Save = Tok.getIntVal();
+ SaveIsReg = false;
+ Parser.Lex();
+ } else
+ return reportParseError("expected save register or stack offset");
+ } else
+ Save = getGPR(Save);
+
+ if (!eatComma("expected comma parsing directive"))
+ return true;
+
+ StringRef Name;
+ if (Parser.parseIdentifier(Name))
+ reportParseError("expected identifier");
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+ unsigned GPReg = getGPR(matchCPURegisterName("gp"));
+
+ // FIXME: The code below this point should be in the TargetStreamers.
+ // Only N32 and N64 emit anything for .cpsetup
+ // FIXME: We should only emit something for PIC mode too.
+ if (!isN32() && !isN64())
+ return false;
+
+ MCStreamer &TS = getStreamer();
+ MCInst Inst;
+ // Either store the old $gp in a register or on the stack
+ if (SaveIsReg) {
+ // move $save, $gpreg
+ Inst.setOpcode(Mips::DADDu);
+ Inst.addOperand(MCOperand::CreateReg(Save));
+ Inst.addOperand(MCOperand::CreateReg(GPReg));
+ Inst.addOperand(MCOperand::CreateReg(getGPR(0)));
+ } else {
+ // sd $gpreg, offset($sp)
+ Inst.setOpcode(Mips::SD);
+ Inst.addOperand(MCOperand::CreateReg(GPReg));
+ Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp"))));
+ Inst.addOperand(MCOperand::CreateImm(Save));
+ }
+ TS.EmitInstruction(Inst, STI);
+ Inst.clear();
+
+ const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
+ Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI,
+ getContext());
+ const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
+ Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO,
+ getContext());
+ // lui $gp, %hi(%neg(%gp_rel(funcSym)))
+ Inst.setOpcode(Mips::LUi);
+ Inst.addOperand(MCOperand::CreateReg(GPReg));
+ Inst.addOperand(MCOperand::CreateExpr(HiExpr));
+ TS.EmitInstruction(Inst, STI);
+ Inst.clear();
+
+ // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
+ Inst.setOpcode(Mips::ADDiu);
+ Inst.addOperand(MCOperand::CreateReg(GPReg));
+ Inst.addOperand(MCOperand::CreateReg(GPReg));
+ Inst.addOperand(MCOperand::CreateExpr(LoExpr));
+ TS.EmitInstruction(Inst, STI);
+ Inst.clear();
+
+ // daddu $gp, $gp, $funcreg
+ Inst.setOpcode(Mips::DADDu);
+ Inst.addOperand(MCOperand::CreateReg(GPReg));
+ Inst.addOperand(MCOperand::CreateReg(GPReg));
+ Inst.addOperand(MCOperand::CreateReg(FuncReg));
+ TS.EmitInstruction(Inst, STI);
+ return false;
+}
+
bool MipsAsmParser::parseDirectiveSet() {
// Get the next token.
@@ -2692,6 +2822,9 @@ bool MipsAsmParser::ParseDirective(AsmTo
return false;
}
+ if (IDVal == ".cpsetup")
+ return parseDirectiveCPSetup();
+
return true;
}
Added: llvm/trunk/test/MC/Mips/cpsetup.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/cpsetup.s?rev=204924&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/cpsetup.s (added)
+++ llvm/trunk/test/MC/Mips/cpsetup.s Thu Mar 27 08:52:53 2014
@@ -0,0 +1,36 @@
+# RUN: llvm-mc -triple mips64-unknown-unknown -mattr=-n64,+o32 %s | \
+# RUN: FileCheck -check-prefix=ANY -check-prefix=O32 %s
+# RUN: llvm-mc -triple mips64-unknown-unknown -mattr=-n64,+n32 %s | \
+# RUN: FileCheck -check-prefix=ANY -check-prefix=NXX -check-prefix=N32 %s
+# RUN: llvm-mc -triple mips64-unknown-unknown %s | \
+# RUN: FileCheck -check-prefix=ANY -check-prefix=NXX -check-prefix=N64 %s
+
+# TODO: !PIC -> no output
+
+ .text
+ .option pic2
+t1:
+ .cpsetup $25, 8, __cerror
+
+# ANY-LABEL: t1:
+
+# O32-NOT: __cerror
+
+# NXX: sd $gp, 8($sp)
+# NXX: lui $gp, %hi(%neg(%gp_rel(__cerror)))
+# NXX: addiu $gp, $gp, %lo(%neg(%gp_rel(__cerror)))
+# N32: addu $gp, $gp, $25
+# N64: daddu $gp, $gp, $25
+
+t2:
+# ANY-LABEL: t2:
+
+ .cpsetup $25, $2, __cerror
+
+# O32-NOT: __cerror
+
+# NXX: move $2, $gp
+# NXX: lui $gp, %hi(%neg(%gp_rel(__cerror)))
+# NXX: addiu $gp, $gp, %lo(%neg(%gp_rel(__cerror)))
+# N32: addu $gp, $gp, $25
+# N64: daddu $gp, $gp, $25
More information about the llvm-commits
mailing list