[llvm] 2dc4eb0 - [mips] Implement .cpadd directive

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 22 13:36:45 PDT 2020


Author: Simon Atanasyan
Date: 2020-03-22T23:34:32+03:00
New Revision: 2dc4eb08cd99929841730a2d658f1217aa5770c4

URL: https://github.com/llvm/llvm-project/commit/2dc4eb08cd99929841730a2d658f1217aa5770c4
DIFF: https://github.com/llvm/llvm-project/commit/2dc4eb08cd99929841730a2d658f1217aa5770c4.diff

LOG: [mips] Implement .cpadd directive

This directive inserts code to add $gp to the argument's register when
support for position independent code is enabled.

For example, this code:
  .cpadd $4
expands to:
  addu $4, $4, $gp

Added: 
    llvm/test/MC/Mips/cpadd-bad.s
    llvm/test/MC/Mips/cpadd.s

Modified: 
    llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
    llvm/lib/Target/Mips/MipsTargetStreamer.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 79de8d746d86..9dbbdeb34dba 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -361,6 +361,7 @@ class MipsAsmParser : public MCTargetAsmParser {
   bool parseSetArchDirective();
   bool parseSetFeature(uint64_t Feature);
   bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
+  bool parseDirectiveCpAdd(SMLoc Loc);
   bool parseDirectiveCpLoad(SMLoc Loc);
   bool parseDirectiveCpLocal(SMLoc Loc);
   bool parseDirectiveCpRestore(SMLoc Loc);
@@ -7632,6 +7633,31 @@ bool MipsAsmParser::isPicAndNotNxxAbi() {
   return inPicMode() && !(isABI_N32() || isABI_N64());
 }
 
+bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
+  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
+  OperandMatchResultTy ResTy = parseAnyRegister(Reg);
+  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
+    reportParseError("expected register");
+    return false;
+  }
+
+  MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
+  if (!RegOpnd.isGPRAsmReg()) {
+    reportParseError(RegOpnd.getStartLoc(), "invalid register");
+    return false;
+  }
+
+  // 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;
+  }
+  getParser().Lex(); // Consume the EndOfStatement.
+
+  getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
+  return false;
+}
+
 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
   if (AssemblerOptions.back()->isReorder())
     Warning(Loc, ".cpload should be inside a noreorder section");
@@ -8544,6 +8570,10 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
   MCAsmParser &Parser = getParser();
   StringRef IDVal = DirectiveID.getString();
 
+  if (IDVal == ".cpadd") {
+    parseDirectiveCpAdd(DirectiveID.getLoc());
+    return false;
+  }
   if (IDVal == ".cpload") {
     parseDirectiveCpLoad(DirectiveID.getLoc());
     return false;

diff  --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 579273004f1d..6ec8fe805968 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -111,6 +111,7 @@ void MipsTargetStreamer::emitDirectiveSetDspr2() { forbidModuleDirective(); }
 void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
 void MipsTargetStreamer::emitDirectiveSetMips3D() { forbidModuleDirective(); }
 void MipsTargetStreamer::emitDirectiveSetNoMips3D() { forbidModuleDirective(); }
+void MipsTargetStreamer::emitDirectiveCpAdd(unsigned RegNo) {}
 void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
 void MipsTargetStreamer::emitDirectiveCpLocal(unsigned RegNo) {
   // .cplocal $reg
@@ -662,6 +663,12 @@ void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
   OS << "," << FPUTopSavedRegOff << '\n';
 }
 
+void MipsTargetAsmStreamer::emitDirectiveCpAdd(unsigned RegNo) {
+  OS << "\t.cpadd\t$"
+     << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
+  forbidModuleDirective();
+}
+
 void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) {
   OS << "\t.cpload\t$"
      << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
@@ -1120,6 +1127,17 @@ void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
   FPROffset = FPUTopSavedRegOff;
 }
 
+void MipsTargetELFStreamer::emitDirectiveCpAdd(unsigned RegNo) {
+  // .cpadd $reg
+  // This directive inserts code to add $gp to the argument's register
+  // when support for position independent code is enabled.
+  if (!Pic)
+    return;
+
+  emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
+  forbidModuleDirective();
+}
+
 void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
   // .cpload $reg
   // This directive expands to:

diff  --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h
index e383d749d1d1..8c2b3bb38b9c 100644
--- a/llvm/lib/Target/Mips/MipsTargetStreamer.h
+++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h
@@ -92,6 +92,7 @@ class MipsTargetStreamer : public MCTargetStreamer {
   virtual void emitDirectiveSetHardFloat();
 
   // PIC support
+  virtual void emitDirectiveCpAdd(unsigned RegNo);
   virtual void emitDirectiveCpLoad(unsigned RegNo);
   virtual void emitDirectiveCpLocal(unsigned RegNo);
   virtual bool emitDirectiveCpRestore(int Offset,
@@ -273,6 +274,7 @@ class MipsTargetAsmStreamer : public MipsTargetStreamer {
   void emitDirectiveSetHardFloat() override;
 
   // PIC support
+  void emitDirectiveCpAdd(unsigned RegNo) override;
   void emitDirectiveCpLoad(unsigned RegNo) override;
   void emitDirectiveCpLocal(unsigned RegNo) override;
 
@@ -345,6 +347,7 @@ class MipsTargetELFStreamer : public MipsTargetStreamer {
   void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override;
 
   // PIC support
+  void emitDirectiveCpAdd(unsigned RegNo) override;
   void emitDirectiveCpLoad(unsigned RegNo) override;
   void emitDirectiveCpLocal(unsigned RegNo) override;
   bool emitDirectiveCpRestore(int Offset, function_ref<unsigned()> GetATReg,

diff  --git a/llvm/test/MC/Mips/cpadd-bad.s b/llvm/test/MC/Mips/cpadd-bad.s
new file mode 100644
index 000000000000..ce0b48060563
--- /dev/null
+++ b/llvm/test/MC/Mips/cpadd-bad.s
@@ -0,0 +1,13 @@
+# RUN: not llvm-mc -triple=mips-unknown-linux-gnu %s 2>&1 | FileCheck %s
+# RUN: not llvm-mc -triple=mips64-unknown-linux-gnuabin32 %s 2>&1 | FileCheck %s
+# RUN: not llvm-mc -triple=mips64-unknown-linux-gnu %s 2>&1 | FileCheck %s
+
+  .text
+  .cpadd $32
+# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: invalid register
+  .cpadd $foo
+# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected register
+  .cpadd bar
+# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected register
+  .cpadd $25 foobar
+# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected token, expected end of statement

diff  --git a/llvm/test/MC/Mips/cpadd.s b/llvm/test/MC/Mips/cpadd.s
new file mode 100644
index 000000000000..9b87897e91f2
--- /dev/null
+++ b/llvm/test/MC/Mips/cpadd.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc -triple=mips-unknown-linux-gnu -position-independent %s \
+# RUN:   | FileCheck -check-prefix=ASM %s
+# RUN: llvm-mc -triple=mips64-unknown-linux-gnu -position-independent %s \
+# RUN:   | FileCheck -check-prefix=ASM %s
+# RUN: llvm-mc -triple=mips-unknown-linux-gnu %s \
+# RUN:   | FileCheck -check-prefix=ASM %s
+
+# RUN: llvm-mc -triple=mips-unknown-linux-gnu \
+# RUN:         -position-independent -filetype=obj -o - %s \
+# RUN:   | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ32-PIC %s
+# RUN: llvm-mc -triple=mips64-unknown-linux-gnu \
+# RUN:         -position-independent -filetype=obj -o - %s \
+# RUN:   | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ64-PIC %s
+
+# RUN: llvm-mc -triple=mips-unknown-linux-gnu \
+# RUN:         -filetype=obj -o - %s \
+# RUN:   | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ32-NPIC %s
+# RUN: llvm-mc -triple=mips64-unknown-linux-gnu \
+# RUN:         -filetype=obj -o - %s \
+# RUN:   | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ64-NPIC %s
+
+# ASM:       .cpadd $4
+# OBJ32-PIC: addu  $4, $4, $gp
+# OBJ64-PIC: daddu $4, $4, $gp
+# OBJ32-NPIC-NOT: addu
+# OBJ64-NPIC-NOT: daddu
+
+  .text
+  .cpadd $4


        


More information about the llvm-commits mailing list