[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