[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