7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " MCTargetDesc/SBFMCTargetDesc.h"
10
+ #include " MCTargetDesc/SBFInstPrinter.h"
10
11
#include " TargetInfo/SBFTargetInfo.h"
11
12
#include " llvm/ADT/STLExtras.h"
12
13
#include " llvm/ADT/StringSwitch.h"
@@ -31,6 +32,10 @@ class SBFAsmParser : public MCTargetAsmParser {
31
32
32
33
SMLoc getLoc () const { return getParser ().getTok ().getLoc (); }
33
34
35
+ bool isNewSyntax () {
36
+ return getParser ().getAssemblerDialect () == 0 ;
37
+ }
38
+
34
39
bool PreMatchCheck (OperandVector &Operands);
35
40
36
41
bool MatchAndEmitInstruction (SMLoc IDLoc, unsigned &Opcode,
@@ -45,21 +50,26 @@ class SBFAsmParser : public MCTargetAsmParser {
45
50
bool ParseInstruction (ParseInstructionInfo &Info, StringRef Name,
46
51
SMLoc NameLoc, OperandVector &Operands) override ;
47
52
53
+ bool parseOldInstruction (ParseInstructionInfo &Info, StringRef Name,
54
+ SMLoc NameLoc, OperandVector &Operands);
55
+
48
56
bool ParseDirective (AsmToken DirectiveID) override ;
49
57
50
- // "=" is used as assignment operator for assembly statment , so can't be used
51
- // for symbol assignment.
52
- bool equalIsAsmAssignment () override { return false ; }
58
+ // "=" is used as assignment operator for assembly statement , so can't be used
59
+ // for symbol assignment (old syntax only) .
60
+ bool equalIsAsmAssignment () override { return isNewSyntax () ; }
53
61
// "*" is used for dereferencing memory that it will be the start of
54
- // statement.
55
- bool starIsStartOfStatement () override { return true ; }
62
+ // statement (old syntax only) .
63
+ bool starIsStartOfStatement () override { return ! isNewSyntax () ; }
56
64
57
65
#define GET_ASSEMBLER_HEADER
58
66
#include " SBFGenAsmMatcher.inc"
59
67
68
+ bool parseOperand (OperandVector &Operands, StringRef Mnemonic);
60
69
OperandMatchResultTy parseImmediate (OperandVector &Operands);
61
70
OperandMatchResultTy parseRegister (OperandVector &Operands);
62
71
OperandMatchResultTy parseOperandAsOperator (OperandVector &Operands);
72
+ OperandMatchResultTy parseMemOperand (OperandVector &Operands);
63
73
64
74
public:
65
75
enum SBFMatchResultTy {
@@ -161,13 +171,20 @@ struct SBFOperand : public MCParsedAsmOperand {
161
171
}
162
172
163
173
void print (raw_ostream &OS) const override {
174
+ auto RegName = [](unsigned Reg) {
175
+ if (Reg)
176
+ return SBFInstPrinter::getRegisterName (Reg);
177
+ else
178
+ return " noreg" ;
179
+ };
180
+
164
181
switch (Kind) {
165
182
case Immediate:
166
183
OS << *getImm ();
167
184
break ;
168
185
case Register:
169
- OS << " <register x " ;
170
- OS << getReg () << " >" ;
186
+ OS << " <register " ;
187
+ OS << RegName ( getReg () ) << " >" ;
171
188
break ;
172
189
case Token:
173
190
OS << " '" << getToken () << " '" ;
@@ -263,6 +280,10 @@ struct SBFOperand : public MCParsedAsmOperand {
263
280
264
281
bool SBFAsmParser::PreMatchCheck (OperandVector &Operands) {
265
282
283
+ // These checks not needed for the new syntax.
284
+ if (isNewSyntax ())
285
+ return false ;
286
+
266
287
if (Operands.size () == 4 ) {
267
288
// check "reg1 = -reg2" and "reg1 = be16/be32/be64/le16/le32/le64 reg2",
268
289
// reg1 must be the same as reg2
@@ -293,7 +314,9 @@ bool SBFAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
293
314
if (PreMatchCheck (Operands))
294
315
return Error (IDLoc, " additional inst constraint not met" );
295
316
296
- switch (MatchInstructionImpl (Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
317
+ unsigned Dialect = getParser ().getAssemblerDialect ();
318
+ switch (MatchInstructionImpl (Operands, Inst, ErrorInfo, MatchingInlineAsm,
319
+ Dialect)) {
297
320
default :
298
321
break ;
299
322
case Match_Success:
@@ -349,6 +372,9 @@ OperandMatchResultTy SBFAsmParser::tryParseRegister(unsigned &RegNo,
349
372
350
373
OperandMatchResultTy
351
374
SBFAsmParser::parseOperandAsOperator (OperandVector &Operands) {
375
+ if (isNewSyntax ())
376
+ llvm_unreachable (" parseOperandAsOperator called for new syntax" );
377
+
352
378
SMLoc S = getLoc ();
353
379
354
380
if (getLexer ().getKind () == AsmToken::Identifier) {
@@ -458,10 +484,108 @@ OperandMatchResultTy SBFAsmParser::parseImmediate(OperandVector &Operands) {
458
484
return MatchOperand_Success;
459
485
}
460
486
461
- // / ParseInstruction - Parse an SBF instruction which is in SBF verifier
462
- // / format.
487
+ OperandMatchResultTy SBFAsmParser::parseMemOperand (OperandVector &Operands) {
488
+ if (getLexer ().isNot (AsmToken::LBrac)) {
489
+ return MatchOperand_ParseFail;
490
+ }
491
+
492
+ getParser ().Lex (); // Eat '['.
493
+ Operands.push_back (SBFOperand::createToken (" [" , getLoc ()));
494
+
495
+ if (parseRegister (Operands) != MatchOperand_Success) {
496
+ Error (getLoc (), " expected register" );
497
+ return MatchOperand_ParseFail;
498
+ }
499
+
500
+ if (parseImmediate (Operands) != MatchOperand_Success) {
501
+ Error (getLoc (), " expected immediate offset" );
502
+ return MatchOperand_ParseFail;
503
+ }
504
+
505
+ if (getLexer ().isNot (AsmToken::RBrac)) {
506
+ Error (getLoc (), " expected ']'" );
507
+ return MatchOperand_ParseFail;
508
+ }
509
+
510
+ getParser ().Lex (); // Eat ']'.
511
+ Operands.push_back (SBFOperand::createToken (" ]" , getLoc ()));
512
+
513
+ return MatchOperand_Success;
514
+ }
515
+
516
+ // / Looks at a token type and creates the relevant operand from this
517
+ // / information, adding to Operands. If operand was parsed, returns false, else
518
+ // / true.
519
+ bool SBFAsmParser::parseOperand (OperandVector &Operands, StringRef Mnemonic) {
520
+ if (!isNewSyntax ())
521
+ llvm_unreachable (" parseOperand called for old syntax" );
522
+
523
+ // Attempt to parse token as a register.
524
+ if (parseRegister (Operands) == MatchOperand_Success)
525
+ return false ;
526
+
527
+ // Attempt to parse token as an immediate.
528
+ if (parseImmediate (Operands) == MatchOperand_Success) {
529
+ return false ;
530
+ }
531
+
532
+ // Attempt to parse token sequence as a memory operand ("[reg+/-offset]").
533
+ if (parseMemOperand (Operands) == MatchOperand_Success) {
534
+ return false ;
535
+ }
536
+
537
+ // Finally we have exhausted all options and must declare defeat.
538
+ Error (getLoc (), " unknown operand" );
539
+ return true ;
540
+ }
541
+
542
+ // / Parse an SBF instruction.
463
543
bool SBFAsmParser::ParseInstruction (ParseInstructionInfo &Info, StringRef Name,
464
544
SMLoc NameLoc, OperandVector &Operands) {
545
+ if (!isNewSyntax ()) {
546
+ return parseOldInstruction (Info, Name, NameLoc, Operands);
547
+ }
548
+
549
+ // First operand is token for instruction mnemonic.
550
+ Operands.push_back (SBFOperand::createToken (Name, NameLoc));
551
+
552
+ // If there are no more operands, then finish.
553
+ if (getLexer ().is (AsmToken::EndOfStatement)) {
554
+ getParser ().Lex (); // Consume the EndOfStatement.
555
+ return false ;
556
+ }
557
+
558
+ // Parse first operand.
559
+ if (parseOperand (Operands, Name))
560
+ return true ;
561
+
562
+ // Parse until end of statement, consuming commas between operands.
563
+ while (getLexer ().is (AsmToken::Comma)) {
564
+ // Consume comma token.
565
+ getLexer ().Lex ();
566
+
567
+ // Parse next operand.
568
+ if (parseOperand (Operands, Name))
569
+ return true ;
570
+ }
571
+
572
+ if (getLexer ().isNot (AsmToken::EndOfStatement)) {
573
+ SMLoc Loc = getLexer ().getLoc ();
574
+ getParser ().eatToEndOfStatement ();
575
+ return Error (Loc, " unexpected token" );
576
+ }
577
+
578
+ getParser ().Lex (); // Consume the EndOfStatement.
579
+ return false ;
580
+ }
581
+
582
+ // / Parse an SBF instruction which is in SBF verifier format (old syntax).
583
+ bool SBFAsmParser::parseOldInstruction (ParseInstructionInfo &Info,
584
+ StringRef Name, SMLoc NameLoc,
585
+ OperandVector &Operands) {
586
+ if (isNewSyntax ())
587
+ llvm_unreachable (" parseOldInstruction called for new syntax" );
588
+
465
589
// The first operand could be either register or actually an operator.
466
590
unsigned RegNo = MatchRegisterName (Name);
467
591
@@ -502,7 +626,24 @@ bool SBFAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
502
626
return false ;
503
627
}
504
628
505
- bool SBFAsmParser::ParseDirective (AsmToken DirectiveID) { return true ; }
629
+ bool SBFAsmParser::ParseDirective (AsmToken DirectiveID) {
630
+ // This returns false if this function recognizes the directive
631
+ // regardless of whether it is successfully handles or reports an
632
+ // error. Otherwise it returns true to give the generic parser a
633
+ // chance at recognizing it.
634
+ StringRef IDVal = DirectiveID.getString ();
635
+
636
+ if (IDVal == " .syntax_old" ) {
637
+ getParser ().setAssemblerDialect (1 );
638
+ return false ;
639
+ }
640
+ if (IDVal == " .syntax_new" ) {
641
+ getParser ().setAssemblerDialect (0 );
642
+ return false ;
643
+ }
644
+
645
+ return true ;
646
+ }
506
647
507
648
extern " C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSBFAsmParser () {
508
649
RegisterMCAsmParser<SBFAsmParser> XX (getTheSBFXTarget ());
0 commit comments