[mips] Add assembler support for .set arch=x directive.

Summary:
This directive is similar to ".set mipsX".
It is used to change the CPU target of the assembler, enabling it to accept instructions for a specific CPU.

This patch only implements the r4000 CPU (which is treated internally as generic mips3) and the generic ISAs.

Contains work done by Matheus Almeida.

Reviewers: dsanders

Reviewed By: dsanders

Differential Revision: http://reviews.llvm.org/D4884

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215978 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Toma Tabacu 2014-08-19 14:22:52 +00:00
parent ecdb0ab90f
commit 109447ff1b
4 changed files with 103 additions and 0 deletions

View File

@ -163,6 +163,7 @@ class MipsAsmParser : public MCTargetAsmParser {
const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
bool isEvaluated(const MCExpr *Expr);
bool parseSetArchDirective();
bool parseSetFeature(uint64_t Feature);
bool parseDirectiveCPLoad(SMLoc Loc);
bool parseDirectiveCPSetup();
@ -2667,6 +2668,41 @@ bool MipsAsmParser::parseSetAssignment() {
return false;
}
bool MipsAsmParser::parseSetArchDirective() {
Parser.Lex();
if (getLexer().isNot(AsmToken::Equal))
return reportParseError("unexpected token, expected equals sign");
Parser.Lex();
StringRef Arch;
if (Parser.parseIdentifier(Arch))
return reportParseError("expected arch identifier");
StringRef ArchFeatureName =
StringSwitch<StringRef>(Arch)
.Case("mips1", "mips1")
.Case("mips2", "mips2")
.Case("mips3", "mips3")
.Case("mips4", "mips4")
.Case("mips5", "mips5")
.Case("mips32", "mips32")
.Case("mips32r2", "mips32r2")
.Case("mips32r6", "mips32r6")
.Case("mips64", "mips64")
.Case("mips64r2", "mips64r2")
.Case("mips64r6", "mips64r6")
.Case("cnmips", "cnmips")
.Case("r4000", "mips3") // This is an implementation of Mips3.
.Default("");
if (ArchFeatureName.empty())
return reportParseError("unsupported architecture");
selectArch(ArchFeatureName);
getTargetStreamer().emitDirectiveSetArch(Arch);
return false;
}
bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
Parser.Lex();
if (getLexer().isNot(AsmToken::EndOfStatement))
@ -2856,6 +2892,8 @@ bool MipsAsmParser::parseDirectiveSet() {
return parseSetNoAtDirective();
} else if (Tok.getString() == "at") {
return parseSetAtDirective();
} else if (Tok.getString() == "arch") {
return parseSetArchDirective();
} else if (Tok.getString() == "fp") {
return parseSetFpDirective();
} else if (Tok.getString() == "reorder") {

View File

@ -56,6 +56,9 @@ void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
}
void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) {
forbidModuleDirective();
}
void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); }
@ -174,6 +177,11 @@ void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
<< StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n';
}
void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) {
OS << "\t.set arch=" << Arch << "\n";
MipsTargetStreamer::emitDirectiveSetArch(Arch);
}
void MipsTargetAsmStreamer::emitDirectiveSetMips1() {
OS << "\t.set\tmips1\n";
MipsTargetStreamer::emitDirectiveSetMips1();

View File

@ -48,6 +48,7 @@ public:
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff);
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff);
virtual void emitDirectiveSetArch(StringRef Arch);
virtual void emitDirectiveSetMips1();
virtual void emitDirectiveSetMips2();
virtual void emitDirectiveSetMips3();
@ -147,6 +148,7 @@ public:
void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override;
void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override;
void emitDirectiveSetArch(StringRef Arch) override;
void emitDirectiveSetMips1() override;
void emitDirectiveSetMips2() override;
void emitDirectiveSetMips3() override;

55
test/MC/Mips/set-arch.s Normal file
View File

@ -0,0 +1,55 @@
# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32 | \
# RUN: FileCheck %s
.text
.set arch=mips1
add $2, $2, $2
.set arch=mips2
ll $2, -2($2)
.set arch=mips3
dadd $2, $2, $2
.set arch=mips4
ldxc1 $f8, $2($4)
.set arch=mips5
luxc1 $f19, $2($4)
.set arch=mips32
clo $2, $2
.set arch=mips32r2
rotr $2, $2, 15
.set arch=mips32r6
mod $2, $4, $6
.set arch=mips64
daddi $2, $2, 10
.set arch=mips64r2
drotr32 $1, $14, 15
.set arch=mips64r6
mod $2, $4, $6
.set arch=cnmips
.set arch=r4000
dadd $2, $2, $2
# CHECK: .set arch=mips1
# CHECK: add $2, $2, $2
# CHECK: .set arch=mips2
# CHECK: ll $2, -2($2)
# CHECK: .set arch=mips3
# CHECK: dadd $2, $2, $2
# CHECK: .set arch=mips4
# CHECK: ldxc1 $f8, $2($4)
# CHECK: .set arch=mips5
# CHECK: luxc1 $f19, $2($4)
# CHECK: .set arch=mips32
# CHECK: clo $2, $2
# CHECK: .set arch=mips32r2
# CHECK: rotr $2, $2, 15
# CHECK: .set arch=mips32r6
# CHECK: mod $2, $4, $6
# CHECK: .set arch=mips64
# CHECK: daddi $2, $2, 10
# CHECK: .set arch=mips64r2
# CHECK: drotr32 $1, $14, 15
# CHECK: .set arch=mips64r6
# CHECK: mod $2, $4, $6
# CHECK: .set arch=cnmips
# CHECK: .set arch=r4000
# CHECK: dadd $2, $2, $2