55//
66// ===----------------------------------------------------------------------===//
77
8+ #include " MCTargetDesc/ParasolInstPrinter.h"
89#include " ParasolInstrInfo.h"
910#include " ParasolTargetMachine.h"
1011#include " TargetInfo/ParasolTargetInfo.h"
@@ -56,6 +57,136 @@ using namespace llvm;
5657
5758namespace {
5859
60+ // / ARMOperand - Instances of this class represent a parsed ARM machine
61+ // / operand.
62+ class ParasolOperand : public MCParsedAsmOperand {
63+ enum KindTy {
64+ k_Token,
65+ k_Register,
66+ k_Immediate
67+
68+ } Kind;
69+
70+ SMLoc StartLoc, EndLoc, AlignmentLoc;
71+ SmallVector<unsigned , 8 > Registers;
72+
73+ struct TokOp {
74+ const char *Data;
75+ unsigned Length;
76+ };
77+
78+ struct RegOp {
79+ unsigned RegNum;
80+ };
81+
82+ struct ImmOp {
83+ const MCExpr *Val;
84+ };
85+
86+ union {
87+ struct TokOp Tok;
88+ struct RegOp Reg;
89+ struct ImmOp Imm;
90+ };
91+
92+ public:
93+ ParasolOperand (KindTy K) : Kind(K) {}
94+
95+ bool isImm () const override { return Kind == k_Immediate; }
96+
97+ bool isToken () const override { return Kind == k_Token; }
98+
99+ bool isMem () const override { return false ; }
100+
101+ bool isReg () const override { return Kind == k_Register; }
102+
103+ // / getStartLoc - Get the location of the first token of this operand.
104+ SMLoc getStartLoc () const override { return StartLoc; }
105+
106+ // / getEndLoc - Get the location of the last token of this operand.
107+ SMLoc getEndLoc () const override { return EndLoc; }
108+
109+ // / getLocRange - Get the range between the first and last token of this
110+ // / operand.
111+ SMRange getLocRange () const { return SMRange (StartLoc, EndLoc); }
112+
113+ StringRef getToken () const {
114+ assert (Kind == k_Token && " Invalid access!" );
115+ return StringRef (Tok.Data , Tok.Length );
116+ }
117+
118+ unsigned getReg () const override {
119+ assert (Kind == k_Register && " Invalid access!" );
120+ return Reg.RegNum ;
121+ }
122+
123+ const MCExpr *getImm () const {
124+ assert (isImm () && " Invalid access!" );
125+ return Imm.Val ;
126+ }
127+
128+ void addRegOperands (MCInst &Inst, unsigned N) const {
129+ assert (N == 1 && " Invalid number of operands!" );
130+ Inst.addOperand (MCOperand::createReg (getReg ()));
131+ }
132+
133+ void addExpr (MCInst &Inst, const MCExpr *Expr) const {
134+ // Add as immediates when possible. Null MCExpr = 0.
135+ if (!Expr)
136+ Inst.addOperand (MCOperand::createImm (0 ));
137+ else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
138+ Inst.addOperand (MCOperand::createImm (CE->getValue ()));
139+ else
140+ Inst.addOperand (MCOperand::createExpr (Expr));
141+ }
142+
143+ void addImmOperands (MCInst &Inst, unsigned N) const {
144+ assert (N == 1 && " Invalid number of operands!" );
145+ addExpr (Inst, getImm ());
146+ }
147+
148+ void print (raw_ostream &OS) const override ;
149+
150+ static std::unique_ptr<ParasolOperand> CreateToken (StringRef Str, SMLoc S) {
151+ auto Op = std::make_unique<ParasolOperand>(k_Token);
152+ Op->Tok .Data = Str.data ();
153+ Op->Tok .Length = Str.size ();
154+ Op->StartLoc = S;
155+ Op->EndLoc = S;
156+ return Op;
157+ }
158+
159+ static std::unique_ptr<ParasolOperand>
160+ createReg (unsigned RegNo, SMLoc S, SMLoc E, bool IsGPRAsFPR = false ) {
161+ auto Op = std::make_unique<ParasolOperand>(k_Register);
162+ Op->Reg .RegNum = RegNo;
163+ Op->StartLoc = S;
164+ Op->EndLoc = E;
165+ return Op;
166+ }
167+ };
168+
169+ void ParasolOperand::print (raw_ostream &OS) const {
170+ auto RegName = [](MCRegister Reg) {
171+ if (Reg)
172+ return ParasolInstPrinter::getRegisterName (Reg);
173+ else
174+ return " noreg" ;
175+ };
176+
177+ switch (Kind) {
178+ case k_Token:
179+ OS << " '" << getToken () << " '" ;
180+ break ;
181+ case k_Register:
182+ OS << " <register " << RegName (getReg ()) << " >" ;
183+ break ;
184+ case k_Immediate:
185+ OS << *getImm ();
186+ break ;
187+ }
188+ }
189+
59190class ParasolAsmParser : public MCTargetAsmParser {
60191 MCAsmParser &Parser;
61192 MCInst MCB;
@@ -73,19 +204,18 @@ class ParasolAsmParser : public MCTargetAsmParser {
73204 }
74205
75206 MCAsmLexer &getLexer () const { return Parser.getLexer (); }
76-
207+ SMLoc getLoc () const { return getParser (). getTok (). getLoc (); }
77208 bool equalIsAsmAssignment () override { return false ; }
78209 bool isLabel (AsmToken &Token) override { llvm_unreachable (" Unimplemented" ); };
79210
80211 void Warning (SMLoc L, const Twine &Msg) { Parser.Warning (L, Msg); }
81212 bool Error (SMLoc L, const Twine &Msg) { return Parser.Error (L, Msg); }
82213 bool ParseDirectiveFalign (unsigned Size, SMLoc L);
83214
215+ bool parseOperand (OperandVector &, StringRef Mnemonic);
84216 bool parseRegister (MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override ;
85217 ParseStatus tryParseRegister (MCRegister &Reg, SMLoc &StartLoc,
86- SMLoc &EndLoc) override {
87- llvm_unreachable (" Unimplemented" );
88- }
218+ SMLoc &EndLoc) override ;
89219 bool ParseDirectiveSubsection (SMLoc L);
90220 bool ParseDirectiveComm (bool IsLocal, SMLoc L);
91221 bool RegisterMatchesArch (unsigned MatchNum) const ;
@@ -101,9 +231,7 @@ class ParasolAsmParser : public MCTargetAsmParser {
101231 bool MatchAndEmitInstruction (SMLoc IDLoc, unsigned &Opcode,
102232 OperandVector &Operands, MCStreamer &Out,
103233 uint64_t &ErrorInfo,
104- bool MatchingInlineAsm) override {
105- llvm_unreachable (" Unimplemented" );
106- }
234+ bool MatchingInlineAsm) override ;
107235
108236 unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
109237 unsigned Kind) override {
@@ -132,38 +260,141 @@ class ParasolAsmParser : public MCTargetAsmParser {
132260 }
133261
134262 bool splitIdentifier (OperandVector &Operands);
135- bool parseOperand (OperandVector &Operands);
136- bool parseInstruction (OperandVector &Operands);
137263 bool implicitExpressionLocation (OperandVector &Operands);
138264 bool parseExpressionOrOperand (OperandVector &Operands);
139265 bool parseExpression (MCExpr const *&Expr);
140266
141- bool ParseInstruction (ParseInstructionInfo &Info, StringRef Name,
142- SMLoc NameLoc, OperandVector &Operands) override {
143- llvm_unreachable (" Unimplemented" );
144- }
267+ ParseStatus parseRegister (OperandVector &Operands);
145268
146- bool ParseInstruction (ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
147- OperandVector &Operands) override {
148- llvm_unreachable (" Unimplemented" );
149- }
269+ bool ParseInstruction (ParseInstructionInfo &Info, StringRef Name,
270+ SMLoc NameLoc, OperandVector &Operands) override ;
150271
151272 bool ParseDirective (AsmToken DirectiveID) override {
152273 llvm_unreachable (" Unimplemented" );
153274 }
154275};
155276} // namespace
156277
278+ #define GET_REGISTER_MATCHER
279+ #define GET_SUBTARGET_FEATURE_NAME
280+ #define GET_MATCHER_IMPLEMENTATION
281+ #define GET_MNEMONIC_SPELL_CHECKER
282+ #include " ParasolGenAsmMatcher.inc"
283+
284+ bool ParasolAsmParser::MatchAndEmitInstruction (SMLoc IDLoc, unsigned &Opcode,
285+ OperandVector &Operands,
286+ MCStreamer &Out,
287+ uint64_t &ErrorInfo,
288+ bool MatchingInlineAsm) {
289+ FeatureBitset MissingFeatures;
290+ MCInst Inst;
291+
292+ auto Result = MatchInstructionImpl (Operands, Inst, ErrorInfo, MissingFeatures,
293+ MatchingInlineAsm);
294+
295+ switch (Result) {
296+ default :
297+ break ;
298+ case Match_Success:
299+ Inst.setLoc (IDLoc);
300+ Out.emitInstruction (Inst, getSTI ());
301+ return false ;
302+ }
303+
304+ llvm_unreachable (" Unknown match type detected!" );
305+ }
306+
307+ bool ParasolAsmParser::parseOperand (OperandVector &Operands,
308+ StringRef Mnemonic) {
309+ MCAsmParser &Parser = getParser ();
310+ SMLoc S, E;
311+
312+ if (parseRegister (Operands).isSuccess ()) {
313+ return false ;
314+ }
315+
316+ return false ;
317+ }
318+
319+ bool ParasolAsmParser::ParseInstruction (ParseInstructionInfo &Info,
320+ StringRef Name, SMLoc NameLoc,
321+ OperandVector &Operands) {
322+ MCAsmParser &Parser = getParser ();
323+
324+ Operands.push_back (ParasolOperand::CreateToken (Name, NameLoc));
325+
326+ // Read the remaining operands.
327+ if (getLexer ().isNot (AsmToken::EndOfStatement)) {
328+ // Read the first operand.
329+ if (parseOperand (Operands, Name)) {
330+ return true ;
331+ }
332+
333+ while (parseOptionalToken (AsmToken::Comma)) {
334+ // Parse and remember the operand.
335+ if (parseOperand (Operands, Name)) {
336+ return true ;
337+ }
338+ }
339+ }
340+
341+ return false ;
342+ }
343+
344+ static MCRegister matchRegisterNameHelper (StringRef Name) {
345+ MCRegister Reg = MatchRegisterName (Name);
346+ assert (Reg >= Parasol::X0 && Reg <= Parasol::X63);
347+
348+ if (!Reg)
349+ return Parasol::NoRegister;
350+
351+ return Reg;
352+ }
353+
157354bool ParasolAsmParser::parseRegister (MCRegister &Reg, SMLoc &StartLoc,
158355 SMLoc &EndLoc) {
159- llvm_unreachable (" unimplemented" );
356+ if (!tryParseRegister (Reg, StartLoc, EndLoc).isSuccess ())
357+ return Error (StartLoc, " invalid register name" );
358+ return false ;
160359}
161360
162- void ParasolAsmParser::convertToMapAndConstraints (
163- unsigned Kind, const OperandVector &Operands) {
164- llvm_unreachable (" unimplemented" );
361+ ParseStatus ParasolAsmParser::tryParseRegister (MCRegister &Reg, SMLoc &StartLoc,
362+ SMLoc &EndLoc) {
363+ const AsmToken &Tok = getParser ().getTok ();
364+ StartLoc = Tok.getLoc ();
365+ EndLoc = Tok.getEndLoc ();
366+ StringRef Name = getLexer ().getTok ().getIdentifier ();
367+
368+ Reg = matchRegisterNameHelper (Name);
369+ if (!Reg)
370+ return ParseStatus::NoMatch;
371+
372+ getParser ().Lex (); // Eat identifier token.
373+ return ParseStatus::Success;
165374}
375+
166376// / Force static initialization.
167377extern " C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeParasolAsmParser () {
168378 RegisterMCAsmParser<ParasolAsmParser> X (getTheParasolTarget ());
169379}
380+
381+ ParseStatus ParasolAsmParser::parseRegister (OperandVector &Operands) {
382+ SMLoc FirstS = getLoc ();
383+ bool HadParens = false ;
384+ AsmToken LParen;
385+
386+ switch (getLexer ().getKind ()) {
387+ default :
388+ return ParseStatus::NoMatch;
389+ case AsmToken::Identifier:
390+ StringRef Name = getLexer ().getTok ().getIdentifier ();
391+ MCRegister RegNo = matchRegisterNameHelper (Name);
392+
393+ SMLoc S = getLoc ();
394+ SMLoc E = SMLoc::getFromPointer (S.getPointer () + Name.size ());
395+ getLexer ().Lex ();
396+ Operands.push_back (ParasolOperand::createReg (RegNo, S, E));
397+ }
398+
399+ return ParseStatus::Success;
400+ }
0 commit comments