8
8
//
9
9
// ===----------------------------------------------------------------------===//
10
10
11
+ #include " MCTargetDesc/XtensaMCExpr.h"
11
12
#include " MCTargetDesc/XtensaMCTargetDesc.h"
13
+ #include " MCTargetDesc/XtensaTargetStreamer.h"
12
14
#include " TargetInfo/XtensaTargetInfo.h"
13
15
#include " llvm/ADT/STLExtras.h"
14
16
#include " llvm/ADT/StringSwitch.h"
22
24
#include " llvm/MC/MCRegisterInfo.h"
23
25
#include " llvm/MC/MCStreamer.h"
24
26
#include " llvm/MC/MCSubtargetInfo.h"
27
+ #include " llvm/MC/MCSymbol.h"
25
28
#include " llvm/MC/TargetRegistry.h"
26
29
#include " llvm/Support/Casting.h"
27
30
@@ -35,6 +38,12 @@ class XtensaAsmParser : public MCTargetAsmParser {
35
38
36
39
SMLoc getLoc () const { return getParser ().getTok ().getLoc (); }
37
40
41
+ XtensaTargetStreamer &getTargetStreamer () {
42
+ MCTargetStreamer &TS = *getParser ().getStreamer ().getTargetStreamer ();
43
+ return static_cast <XtensaTargetStreamer &>(TS);
44
+ }
45
+
46
+ ParseStatus parseDirective (AsmToken DirectiveID) override ;
38
47
bool parseRegister (MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override ;
39
48
bool ParseInstruction (ParseInstructionInfo &Info, StringRef Name,
40
49
SMLoc NameLoc, OperandVector &Operands) override ;
@@ -45,6 +54,9 @@ class XtensaAsmParser : public MCTargetAsmParser {
45
54
unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
46
55
unsigned Kind) override ;
47
56
57
+ bool processInstruction (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
58
+ const MCSubtargetInfo *STI);
59
+
48
60
// Auto-generated instruction matching functions
49
61
#define GET_ASSEMBLER_HEADER
50
62
#include " XtensaGenAsmMatcher.inc"
@@ -62,6 +74,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
62
74
return ParseStatus::NoMatch;
63
75
}
64
76
ParseStatus parsePCRelTarget (OperandVector &Operands);
77
+ bool parseLiteralDirective (SMLoc L);
65
78
66
79
public:
67
80
enum XtensaMatchResultTy {
@@ -148,7 +161,8 @@ struct XtensaOperand : public MCParsedAsmOperand {
148
161
149
162
bool isImm12 () const { return isImm (-2048 , 2047 ); }
150
163
151
- bool isImm12m () const { return isImm (-2048 , 2047 ); }
164
+ // Convert MOVI to literal load, when immediate is not in range (-2048, 2047)
165
+ bool isImm12m () const { return Kind == Immediate; }
152
166
153
167
bool isOffset4m32 () const {
154
168
return isImm (0 , 60 ) &&
@@ -348,6 +362,69 @@ static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
348
362
return Loc;
349
363
}
350
364
365
+ bool XtensaAsmParser::processInstruction (MCInst &Inst, SMLoc IDLoc,
366
+ MCStreamer &Out,
367
+ const MCSubtargetInfo *STI) {
368
+ Inst.setLoc (IDLoc);
369
+ const unsigned Opcode = Inst.getOpcode ();
370
+ switch (Opcode) {
371
+ case Xtensa::L32R: {
372
+ const MCSymbolRefExpr *OpExpr =
373
+ static_cast <const MCSymbolRefExpr *>(Inst.getOperand (1 ).getExpr ());
374
+ XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
375
+ const MCExpr *NewOpExpr = XtensaMCExpr::create (OpExpr, Kind, getContext ());
376
+ Inst.getOperand (1 ).setExpr (NewOpExpr);
377
+ break ;
378
+ }
379
+ case Xtensa::MOVI: {
380
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
381
+
382
+ // Expand MOVI operand
383
+ if (!Inst.getOperand (1 ).isExpr ()) {
384
+ uint64_t ImmOp64 = Inst.getOperand (1 ).getImm ();
385
+ int32_t Imm = ImmOp64;
386
+ if (!isInt<12 >(Imm)) {
387
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
388
+ MCInst TmpInst;
389
+ TmpInst.setLoc (IDLoc);
390
+ TmpInst.setOpcode (Xtensa::L32R);
391
+ const MCExpr *Value = MCConstantExpr::create (ImmOp64, getContext ());
392
+ MCSymbol *Sym = getContext ().createTempSymbol ();
393
+ const MCExpr *Expr = MCSymbolRefExpr::create (
394
+ Sym, MCSymbolRefExpr::VK_None, getContext ());
395
+ const MCExpr *OpExpr = XtensaMCExpr::create (
396
+ Expr, XtensaMCExpr::VK_Xtensa_None, getContext ());
397
+ TmpInst.addOperand (Inst.getOperand (0 ));
398
+ MCOperand Op1 = MCOperand::createExpr (OpExpr);
399
+ TmpInst.addOperand (Op1);
400
+ TS.emitLiteral (Sym, Value, true , IDLoc);
401
+ Inst = TmpInst;
402
+ }
403
+ } else {
404
+ MCInst TmpInst;
405
+ TmpInst.setLoc (IDLoc);
406
+ TmpInst.setOpcode (Xtensa::L32R);
407
+ const MCExpr *Value = Inst.getOperand (1 ).getExpr ();
408
+ MCSymbol *Sym = getContext ().createTempSymbol ();
409
+ const MCExpr *Expr =
410
+ MCSymbolRefExpr::create (Sym, MCSymbolRefExpr::VK_None, getContext ());
411
+ const MCExpr *OpExpr = XtensaMCExpr::create (
412
+ Expr, XtensaMCExpr::VK_Xtensa_None, getContext ());
413
+ TmpInst.addOperand (Inst.getOperand (0 ));
414
+ MCOperand Op1 = MCOperand::createExpr (OpExpr);
415
+ TmpInst.addOperand (Op1);
416
+ Inst = TmpInst;
417
+ TS.emitLiteral (Sym, Value, true , IDLoc);
418
+ }
419
+ break ;
420
+ }
421
+ default :
422
+ break ;
423
+ }
424
+
425
+ return true ;
426
+ }
427
+
351
428
bool XtensaAsmParser::MatchAndEmitInstruction (SMLoc IDLoc, unsigned &Opcode,
352
429
OperandVector &Operands,
353
430
MCStreamer &Out,
@@ -361,6 +438,7 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
361
438
default :
362
439
break ;
363
440
case Match_Success:
441
+ processInstruction (Inst, IDLoc, Out, STI);
364
442
Inst.setLoc (IDLoc);
365
443
Out.emitInstruction (Inst, getSTI ());
366
444
return false ;
@@ -686,6 +764,57 @@ bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info,
686
764
return false ;
687
765
}
688
766
767
+ bool XtensaAsmParser::parseLiteralDirective (SMLoc L) {
768
+ MCAsmParser &Parser = getParser ();
769
+ const MCExpr *Value;
770
+ SMLoc LiteralLoc = getLexer ().getLoc ();
771
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
772
+
773
+ if (Parser.parseExpression (Value))
774
+ return true ;
775
+
776
+ const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value);
777
+
778
+ if (!SE)
779
+ return Error (LiteralLoc, " literal label must be a symbol" );
780
+
781
+ if (Parser.parseComma ())
782
+ return true ;
783
+
784
+ SMLoc OpcodeLoc = getLexer ().getLoc ();
785
+ if (parseOptionalToken (AsmToken::EndOfStatement))
786
+ return Error (OpcodeLoc, " expected value" );
787
+
788
+ if (Parser.parseExpression (Value))
789
+ return true ;
790
+
791
+ if (parseEOL ())
792
+ return true ;
793
+
794
+ MCSymbol *Sym = getContext ().getOrCreateSymbol (SE->getSymbol ().getName ());
795
+
796
+ TS.emitLiteral (Sym, Value, true , LiteralLoc);
797
+
798
+ return false ;
799
+ }
800
+
801
+ ParseStatus XtensaAsmParser::parseDirective (AsmToken DirectiveID) {
802
+ StringRef IDVal = DirectiveID.getString ();
803
+ SMLoc Loc = getLexer ().getLoc ();
804
+
805
+ if (IDVal == " .literal_position" ) {
806
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
807
+ TS.emitLiteralPosition ();
808
+ return parseEOL ();
809
+ }
810
+
811
+ if (IDVal == " .literal" ) {
812
+ return parseLiteralDirective (Loc);
813
+ }
814
+
815
+ return ParseStatus::NoMatch;
816
+ }
817
+
689
818
// Force static initialization.
690
819
extern " C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser () {
691
820
RegisterMCAsmParser<XtensaAsmParser> X (getTheXtensaTarget ());
0 commit comments