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
+ bool 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,13 @@ 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 {
166
+ if (Kind == Immediate)
167
+ return true ;
168
+
169
+ return false ;
170
+ }
152
171
153
172
bool isOffset4m32 () const {
154
173
return isImm (0 , 60 ) &&
@@ -348,6 +367,67 @@ static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
348
367
return Loc;
349
368
}
350
369
370
+ bool XtensaAsmParser::processInstruction (MCInst &Inst, SMLoc IDLoc,
371
+ MCStreamer &Out,
372
+ const MCSubtargetInfo *STI) {
373
+ Inst.setLoc (IDLoc);
374
+ const unsigned Opcode = Inst.getOpcode ();
375
+ switch (Opcode) {
376
+ case Xtensa::L32R: {
377
+ const MCSymbolRefExpr *OpExpr =
378
+ (const MCSymbolRefExpr *)Inst.getOperand (1 ).getExpr ();
379
+ XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
380
+ const MCExpr *NewOpExpr = XtensaMCExpr::create (OpExpr, Kind, getContext ());
381
+ Inst.getOperand (1 ).setExpr (NewOpExpr);
382
+ } break ;
383
+ case Xtensa::MOVI: {
384
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
385
+
386
+ // Expand MOVI operand
387
+ if (!Inst.getOperand (1 ).isExpr ()) {
388
+ uint64_t ImmOp64 = Inst.getOperand (1 ).getImm ();
389
+ int32_t Imm = ImmOp64;
390
+ if ((Imm < -2048 ) || (Imm > 2047 )) {
391
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
392
+ MCInst TmpInst;
393
+ TmpInst.setLoc (IDLoc);
394
+ TmpInst.setOpcode (Xtensa::L32R);
395
+ const MCExpr *Value = MCConstantExpr::create (ImmOp64, getContext ());
396
+ MCSymbol *Sym = getContext ().createTempSymbol ();
397
+ const MCExpr *Expr = MCSymbolRefExpr::create (
398
+ Sym, MCSymbolRefExpr::VK_None, getContext ());
399
+ const MCExpr *OpExpr = XtensaMCExpr::create (
400
+ Expr, XtensaMCExpr::VK_Xtensa_None, getContext ());
401
+ TmpInst.addOperand (Inst.getOperand (0 ));
402
+ MCOperand Op1 = MCOperand::createExpr (OpExpr);
403
+ TmpInst.addOperand (Op1);
404
+ TS.emitLiteral (Sym, Value, IDLoc);
405
+ Inst = TmpInst;
406
+ }
407
+ } else {
408
+ MCInst TmpInst;
409
+ TmpInst.setLoc (IDLoc);
410
+ TmpInst.setOpcode (Xtensa::L32R);
411
+ const MCExpr *Value = Inst.getOperand (1 ).getExpr ();
412
+ MCSymbol *Sym = getContext ().createTempSymbol ();
413
+ const MCExpr *Expr =
414
+ MCSymbolRefExpr::create (Sym, MCSymbolRefExpr::VK_None, getContext ());
415
+ const MCExpr *OpExpr = XtensaMCExpr::create (
416
+ Expr, XtensaMCExpr::VK_Xtensa_None, getContext ());
417
+ TmpInst.addOperand (Inst.getOperand (0 ));
418
+ MCOperand Op1 = MCOperand::createExpr (OpExpr);
419
+ TmpInst.addOperand (Op1);
420
+ Inst = TmpInst;
421
+ TS.emitLiteral (Sym, Value, IDLoc);
422
+ }
423
+ } break ;
424
+ default :
425
+ break ;
426
+ }
427
+
428
+ return true ;
429
+ }
430
+
351
431
bool XtensaAsmParser::MatchAndEmitInstruction (SMLoc IDLoc, unsigned &Opcode,
352
432
OperandVector &Operands,
353
433
MCStreamer &Out,
@@ -361,6 +441,7 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
361
441
default :
362
442
break ;
363
443
case Match_Success:
444
+ processInstruction (Inst, IDLoc, Out, STI);
364
445
Inst.setLoc (IDLoc);
365
446
Out.emitInstruction (Inst, getSTI ());
366
447
return false ;
@@ -686,6 +767,58 @@ bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info,
686
767
return false ;
687
768
}
688
769
770
+ bool XtensaAsmParser::parseLiteralDirective (SMLoc L) {
771
+ MCAsmParser &Parser = getParser ();
772
+ MCSymbol *Sym;
773
+ const MCExpr *Value;
774
+ SMLoc LiteralLoc = getLexer ().getLoc ();
775
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
776
+
777
+ if (Parser.parseExpression (Value))
778
+ return true ;
779
+
780
+ const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value);
781
+ if (!SE)
782
+ return Error (LiteralLoc, " literal label must be a symbol" );
783
+ else {
784
+ Sym = getContext ().getOrCreateSymbol (SE->getSymbol ().getName ());
785
+ }
786
+
787
+ if (Parser.parseToken (AsmToken::Comma, " expected comma" ))
788
+ return true ;
789
+
790
+ SMLoc OpcodeLoc = getLexer ().getLoc ();
791
+ if (parseOptionalToken (AsmToken::EndOfStatement))
792
+ return Error (OpcodeLoc, " expected value" );
793
+
794
+ if (Parser.parseExpression (Value))
795
+ return true ;
796
+
797
+ TS.emitLiteral (Sym, Value, LiteralLoc);
798
+
799
+ return false ;
800
+ }
801
+
802
+ bool XtensaAsmParser::ParseDirective (AsmToken DirectiveID) {
803
+ StringRef IDVal = DirectiveID.getString ();
804
+ SMLoc Loc = getLexer ().getLoc ();
805
+
806
+ if (IDVal == " .literal_position" ) {
807
+ XtensaTargetStreamer &TS = this ->getTargetStreamer ();
808
+ TS.emitLiteralPosition ();
809
+ Lex ();
810
+ return false ;
811
+ }
812
+
813
+ if (IDVal == " .literal" ) {
814
+ parseLiteralDirective (Loc);
815
+ Lex ();
816
+ return false ;
817
+ }
818
+
819
+ return true ;
820
+ }
821
+
689
822
// Force static initialization.
690
823
extern " C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser () {
691
824
RegisterMCAsmParser<XtensaAsmParser> X (getTheXtensaTarget ());
0 commit comments