llvm.org GIT mirror llvm / 33550d7
Merging r217432: ------------------------------------------------------------------------ r217432 | tomatabacu | 2014-09-09 11:15:38 +0100 (Tue, 09 Sep 2014) | 12 lines [mips] Add assembler support for .set push/pop directive. Summary: These directives are used to save the current assembler options (in the case of ".set push") and restore the previously saved options (in the case of ".set pop"). Contains work done by Matheus Almeida. Reviewers: dsanders Reviewed By: dsanders Differential Revision: http://reviews.llvm.org/D4821 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@232082 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 5 years ago
5 changed file(s) with 156 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
1212 #include "MipsTargetStreamer.h"
1313 #include "llvm/ADT/APInt.h"
1414 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/ADT/SmallVector.h"
1516 #include "llvm/MC/MCContext.h"
1617 #include "llvm/MC/MCExpr.h"
1718 #include "llvm/MC/MCInst.h"
2526 #include "llvm/Support/Debug.h"
2627 #include "llvm/Support/MathExtras.h"
2728 #include "llvm/Support/TargetRegistry.h"
29 #include
2830
2931 using namespace llvm;
3032
3739 namespace {
3840 class MipsAssemblerOptions {
3941 public:
40 MipsAssemblerOptions() : ATReg(1), Reorder(true), Macro(true) {}
41
42 unsigned getATRegNum() { return ATReg; }
42 MipsAssemblerOptions(uint64_t Features_) :
43 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
44
45 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
46 ATReg = Opts->getATRegNum();
47 Reorder = Opts->isReorder();
48 Macro = Opts->isMacro();
49 Features = Opts->getFeatures();
50 }
51
52 unsigned getATRegNum() const { return ATReg; }
4353 bool setATReg(unsigned Reg);
4454
45 bool isReorder() { return Reorder; }
55 bool isReorder() const { return Reorder; }
4656 void setReorder() { Reorder = true; }
4757 void setNoReorder() { Reorder = false; }
4858
49 bool isMacro() { return Macro; }
59 bool isMacro() const { return Macro; }
5060 void setMacro() { Macro = true; }
5161 void setNoMacro() { Macro = false; }
62
63 uint64_t getFeatures() const { return Features; }
64 void setFeatures(uint64_t Features_) { Features = Features_; }
5265
5366 private:
5467 unsigned ATReg;
5568 bool Reorder;
5669 bool Macro;
70 uint64_t Features;
5771 };
5872 }
5973
6680
6781 MCSubtargetInfo &STI;
6882 MCAsmParser &Parser;
69 MipsAssemblerOptions Options;
83 SmallVector, 2> AssemblerOptions;
7084
7185 #define GET_ASSEMBLER_HEADER
7286 #include "MipsGenAsmMatcher.inc"
156170 bool parseSetNoReorderDirective();
157171 bool parseSetNoMips16Directive();
158172 bool parseSetFpDirective();
173 bool parseSetPopDirective();
174 bool parseSetPushDirective();
159175
160176 bool parseSetAssignment();
161177
204220 setAvailableFeatures(
205221 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
206222 }
223 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
207224 }
208225
209226 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
211228 setAvailableFeatures(
212229 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
213230 }
231 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
214232 }
215233
216234 public:
227245 : MCTargetAsmParser(), STI(sti), Parser(parser) {
228246 // Initialize the set of available features.
229247 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
248
249 // Remember the initial assembler options. The user can not modify these.
250 MipsAssemblerOptions *TmpAOPtr =
251 new MipsAssemblerOptions(getAvailableFeatures());
252 AssemblerOptions.push_back(std::unique_ptr(TmpAOPtr));
253
254 // Create an assembler options environment for the user to modify.
255 TmpAOPtr = new MipsAssemblerOptions(getAvailableFeatures());
256 AssemblerOptions.push_back(std::unique_ptr(TmpAOPtr));
257 TmpAOPtr = nullptr;
230258
231259 getTargetStreamer().updateABIInfo(*this);
232260
960988 "nop instruction");
961989 }
962990
963 if (MCID.hasDelaySlot() && Options.isReorder()) {
991 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
964992 // If this instruction has a delay slot and .set reorder is active,
965993 // emit a NOP after it.
966994 Instructions.push_back(Inst);
14231451 }
14241452
14251453 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1426 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1454 if ((RegIndex != 0) &&
1455 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
14271456 if (RegIndex == 1)
14281457 Warning(Loc, "Used $at without \".set noat\"");
14291458 else
15721601 }
15731602
15741603 int MipsAsmParser::getATReg(SMLoc Loc) {
1575 int AT = Options.getATRegNum();
1604 int AT = AssemblerOptions.back()->getATRegNum();
15761605 if (AT == 0)
15771606 reportParseError(Loc,
15781607 "Pseudo instruction requires $at, which is not available");
23272356 bool MipsAsmParser::parseSetNoAtDirective() {
23282357 // Line should look like: ".set noat".
23292358 // set at reg to 0.
2330 Options.setATReg(0);
2359 AssemblerOptions.back()->setATReg(0);
23312360 // eat noat
23322361 Parser.Lex();
23332362 // If this is not the end of the statement, report an error.
23452374 int AtRegNo;
23462375 getParser().Lex();
23472376 if (getLexer().is(AsmToken::EndOfStatement)) {
2348 Options.setATReg(1);
2377 AssemblerOptions.back()->setATReg(1);
23492378 Parser.Lex(); // Consume the EndOfStatement.
23502379 return false;
23512380 } else if (getLexer().is(AsmToken::Equal)) {
23702399 return false;
23712400 }
23722401
2373 if (!Options.setATReg(AtRegNo)) {
2402 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
23742403 reportParseError("unexpected token in statement");
23752404 return false;
23762405 }
23952424 reportParseError("unexpected token in statement");
23962425 return false;
23972426 }
2398 Options.setReorder();
2427 AssemblerOptions.back()->setReorder();
23992428 getTargetStreamer().emitDirectiveSetReorder();
24002429 Parser.Lex(); // Consume the EndOfStatement.
24012430 return false;
24082437 reportParseError("unexpected token in statement");
24092438 return false;
24102439 }
2411 Options.setNoReorder();
2440 AssemblerOptions.back()->setNoReorder();
24122441 getTargetStreamer().emitDirectiveSetNoReorder();
24132442 Parser.Lex(); // Consume the EndOfStatement.
24142443 return false;
24212450 reportParseError("unexpected token in statement");
24222451 return false;
24232452 }
2424 Options.setMacro();
2453 AssemblerOptions.back()->setMacro();
24252454 Parser.Lex(); // Consume the EndOfStatement.
24262455 return false;
24272456 }
24332462 reportParseError("`noreorder' must be set before `nomacro'");
24342463 return false;
24352464 }
2436 if (Options.isReorder()) {
2465 if (AssemblerOptions.back()->isReorder()) {
24372466 reportParseError("`noreorder' must be set before `nomacro'");
24382467 return false;
24392468 }
2440 Options.setNoMacro();
2469 AssemblerOptions.back()->setNoMacro();
24412470 Parser.Lex(); // Consume the EndOfStatement.
24422471 return false;
24432472 }
24772506 }
24782507 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
24792508 Parser.Lex(); // Consume the EndOfStatement.
2509 return false;
2510 }
2511
2512 bool MipsAsmParser::parseSetPopDirective() {
2513 SMLoc Loc = getLexer().getLoc();
2514
2515 Parser.Lex();
2516 if (getLexer().isNot(AsmToken::EndOfStatement))
2517 return reportParseError("unexpected token, expected end of statement");
2518
2519 // Always keep an element on the options "stack" to prevent the user
2520 // from changing the initial options. This is how we remember them.
2521 if (AssemblerOptions.size() == 2)
2522 return reportParseError(Loc, ".set pop with no .set push");
2523
2524 AssemblerOptions.pop_back();
2525 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2526
2527 getTargetStreamer().emitDirectiveSetPop();
2528 return false;
2529 }
2530
2531 bool MipsAsmParser::parseSetPushDirective() {
2532 Parser.Lex();
2533 if (getLexer().isNot(AsmToken::EndOfStatement))
2534 return reportParseError("unexpected token, expected end of statement");
2535
2536 // Create a copy of the current assembler options environment and push it.
2537 MipsAssemblerOptions *TmpAOPtr =
2538 new MipsAssemblerOptions(AssemblerOptions.back().get());
2539 AssemblerOptions.push_back(std::unique_ptr(TmpAOPtr));
2540
2541 getTargetStreamer().emitDirectiveSetPush();
24802542 return false;
24812543 }
24822544
25502612 }
25512613
25522614 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2553 if (Options.isReorder())
2615 if (AssemblerOptions.back()->isReorder())
25542616 Warning(Loc, ".cpload in reorder section");
25552617
25562618 // FIXME: Warn if cpload is used in Mips16 mode.
26632725 return parseSetAtDirective();
26642726 } else if (Tok.getString() == "fp") {
26652727 return parseSetFpDirective();
2728 } else if (Tok.getString() == "pop") {
2729 return parseSetPopDirective();
2730 } else if (Tok.getString() == "push") {
2731 return parseSetPushDirective();
26662732 } else if (Tok.getString() == "reorder") {
26672733 return parseSetReorderDirective();
26682734 } else if (Tok.getString() == "noreorder") {
5454 void MipsTargetStreamer::emitDirectiveSetMips32R2() {}
5555 void MipsTargetStreamer::emitDirectiveSetMips64() {}
5656 void MipsTargetStreamer::emitDirectiveSetMips64R2() {}
57 void MipsTargetStreamer::emitDirectiveSetPop() {}
58 void MipsTargetStreamer::emitDirectiveSetPush() {}
5759 void MipsTargetStreamer::emitDirectiveSetDsp() {}
5860 void MipsTargetStreamer::emitDirectiveCpload(unsigned RegNo) {}
5961 void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
170172 OS << "\t.set\tdsp\n";
171173 setCanHaveModuleDir(false);
172174 }
175
176 void MipsTargetAsmStreamer::emitDirectiveSetPop() { OS << "\t.set\tpop\n"; }
177
178 void MipsTargetAsmStreamer::emitDirectiveSetPush() { OS << "\t.set\tpush\n"; }
179
173180 // Print a 32 bit hex number with all numbers.
174181 static void printHex32(unsigned Value, raw_ostream &OS) {
175182 OS << "0x";
4848 virtual void emitDirectiveSetMips64();
4949 virtual void emitDirectiveSetMips64R2();
5050 virtual void emitDirectiveSetDsp();
51 virtual void emitDirectiveSetPop();
52 virtual void emitDirectiveSetPush();
5153
5254 // PIC support
5355 virtual void emitDirectiveCpload(unsigned RegNo);
124126 void emitDirectiveSetMips64() override;
125127 void emitDirectiveSetMips64R2() override;
126128 void emitDirectiveSetDsp() override;
129 void emitDirectiveSetPop() override;
130 void emitDirectiveSetPush() override;
127131
128132 // PIC support
129133 virtual void emitDirectiveCpload(unsigned RegNo);
0 # RUN: not llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 2>%t1
1 # RUN: FileCheck %s < %t1
2
3 .text
4 .set pop
5 # CHECK: :[[@LINE-1]]:14: error: .set pop with no .set push
6 .set push
7 .set pop
8 .set pop
9 # CHECK: :[[@LINE-1]]:14: error: .set pop with no .set push
10 .set push foo
11 # CHECK: :[[@LINE-1]]:19: error: unexpected token, expected end of statement
12 .set pop bar
13 # CHECK: :[[@LINE-1]]:18: error: unexpected token, expected end of statement
0 # RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -mattr=+msa | \
1 # RUN: FileCheck %s
2 # .set push creates a copy of the current environment.
3 # .set pop restores the previous environment.
4 # FIXME: Also test resetting of .set macro/nomacro option.
5
6 .text
7 # The first environment on the stack (with initial values).
8 lw $1, 65536($1)
9 b 1336
10 addvi.b $w15, $w13, 18
11
12 # Create a new environment.
13 .set push
14 .set at=$ra # Test the ATReg option.
15 lw $1, 65536($1)
16 .set noreorder # Test the Reorder option.
17 b 1336
18
19 # Switch back to the first environment.
20 .set pop
21 lw $1, 65536($1)
22 b 1336
23 addvi.b $w15, $w13, 18
24
25 # CHECK: lui $1, 1
26 # CHECK: addu $1, $1, $1
27 # CHECK: lw $1, 0($1)
28 # CHECK: b 1336
29 # CHECK: nop
30 # CHECK: addvi.b $w15, $w13, 18
31
32 # CHECK: .set push
33 # CHECK: lui $ra, 1
34 # CHECK: addu $ra, $ra, $1
35 # CHECK: lw $1, 0($ra)
36 # CHECK: .set noreorder
37 # CHECK: b 1336
38 # CHECK-NOT: nop
39
40 # CHECK: .set pop
41 # CHECK: lui $1, 1
42 # CHECK: addu $1, $1, $1
43 # CHECK: lw $1, 0($1)
44 # CHECK: b 1336
45 # CHECK: nop
46 # CHECK: addvi.b $w15, $w13, 18