summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp34
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp14
-rw-r--r--llvm/lib/Target/Mips/MipsTargetStreamer.h4
-rw-r--r--llvm/test/MC/Mips/set-oddspreg-nooddspreg-error.s10
-rw-r--r--llvm/test/MC/Mips/set-oddspreg-nooddspreg.s10
5 files changed, 72 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 78f3884dd20..8f7968939cb 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -258,6 +258,8 @@ class MipsAsmParser : public MCTargetAsmParser {
bool parseSetMips16Directive();
bool parseSetNoMips16Directive();
bool parseSetFpDirective();
+ bool parseSetOddSPRegDirective();
+ bool parseSetNoOddSPRegDirective();
bool parseSetPopDirective();
bool parseSetPushDirective();
bool parseSetSoftFloatDirective();
@@ -4098,6 +4100,34 @@ bool MipsAsmParser::parseSetFpDirective() {
return false;
}
+bool MipsAsmParser::parseSetOddSPRegDirective() {
+ MCAsmParser &Parser = getParser();
+
+ Parser.Lex(); // Eat "oddspreg".
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token, expected end of statement");
+ return false;
+ }
+
+ clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
+ getTargetStreamer().emitDirectiveSetOddSPReg();
+ return false;
+}
+
+bool MipsAsmParser::parseSetNoOddSPRegDirective() {
+ MCAsmParser &Parser = getParser();
+
+ Parser.Lex(); // Eat "nooddspreg".
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token, expected end of statement");
+ return false;
+ }
+
+ setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
+ getTargetStreamer().emitDirectiveSetNoOddSPReg();
+ return false;
+}
+
bool MipsAsmParser::parseSetPopDirective() {
MCAsmParser &Parser = getParser();
SMLoc Loc = getLexer().getLoc();
@@ -4460,6 +4490,10 @@ bool MipsAsmParser::parseDirectiveSet() {
return parseSetArchDirective();
} else if (Tok.getString() == "fp") {
return parseSetFpDirective();
+ } else if (Tok.getString() == "oddspreg") {
+ return parseSetOddSPRegDirective();
+ } else if (Tok.getString() == "nooddspreg") {
+ return parseSetNoOddSPRegDirective();
} else if (Tok.getString() == "pop") {
return parseSetPopDirective();
} else if (Tok.getString() == "push") {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 9ffa9690958..a560ce62030 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -103,6 +103,10 @@ void MipsTargetStreamer::emitDirectiveSetFp(
MipsABIFlagsSection::FpABIKind Value) {
forbidModuleDirective();
}
+void MipsTargetStreamer::emitDirectiveSetOddSPReg() { forbidModuleDirective(); }
+void MipsTargetStreamer::emitDirectiveSetNoOddSPReg() {
+ forbidModuleDirective();
+}
MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
formatted_raw_ostream &OS)
@@ -390,6 +394,16 @@ void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg() {
OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
}
+void MipsTargetAsmStreamer::emitDirectiveSetOddSPReg() {
+ MipsTargetStreamer::emitDirectiveSetOddSPReg();
+ OS << "\t.set\toddspreg\n";
+}
+
+void MipsTargetAsmStreamer::emitDirectiveSetNoOddSPReg() {
+ MipsTargetStreamer::emitDirectiveSetNoOddSPReg();
+ OS << "\t.set\tnooddspreg\n";
+}
+
// This part is for ELF object output.
MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
const MCSubtargetInfo &STI)
diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h
index 35bdae3aee8..54460fb0f75 100644
--- a/llvm/lib/Target/Mips/MipsTargetStreamer.h
+++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h
@@ -84,6 +84,8 @@ public:
virtual void emitDirectiveModuleFP();
virtual void emitDirectiveModuleOddSPReg();
virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value);
+ virtual void emitDirectiveSetOddSPReg();
+ virtual void emitDirectiveSetNoOddSPReg();
void forbidModuleDirective() { ModuleDirectiveAllowed = false; }
void reallowModuleDirective() { ModuleDirectiveAllowed = true; }
@@ -191,6 +193,8 @@ public:
void emitDirectiveModuleFP() override;
void emitDirectiveModuleOddSPReg() override;
void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override;
+ void emitDirectiveSetOddSPReg() override;
+ void emitDirectiveSetNoOddSPReg() override;
};
// This part is for ELF object output
diff --git a/llvm/test/MC/Mips/set-oddspreg-nooddspreg-error.s b/llvm/test/MC/Mips/set-oddspreg-nooddspreg-error.s
new file mode 100644
index 00000000000..5fb1308ceb9
--- /dev/null
+++ b/llvm/test/MC/Mips/set-oddspreg-nooddspreg-error.s
@@ -0,0 +1,10 @@
+# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32 -mattr=+nooddspreg 2>%t1
+# RUN: FileCheck %s < %t1
+
+ .set oddspreg
+ sub.s $f1, $f2, $f2
+ # CHECK-NOT: :[[@LINE-1]]:{{[0-9]+}}: error: -mno-odd-spreg prohibits the use of odd FPU registers
+
+ .set nooddspreg
+ sub.s $f1, $f2, $f2
+ # CHECK: :[[@LINE-1]]:9: error: -mno-odd-spreg prohibits the use of odd FPU registers
diff --git a/llvm/test/MC/Mips/set-oddspreg-nooddspreg.s b/llvm/test/MC/Mips/set-oddspreg-nooddspreg.s
new file mode 100644
index 00000000000..a057c487f79
--- /dev/null
+++ b/llvm/test/MC/Mips/set-oddspreg-nooddspreg.s
@@ -0,0 +1,10 @@
+# RUN: llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+nooddspreg | \
+# RUN: FileCheck %s
+
+ .set oddspreg
+ sub.s $f1, $f2, $f2
+ .set nooddspreg
+
+# CHECK: .set oddspreg
+# CHECK: sub.s $f1, $f2, $f2
+# CHECK: .set nooddspreg
OpenPOWER on IntegriCloud