• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "MCTargetDesc/SystemZMCTargetDesc.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16 #include "llvm/MC/MCStreamer.h"
17 #include "llvm/MC/MCSubtargetInfo.h"
18 #include "llvm/MC/MCTargetAsmParser.h"
19 #include "llvm/Support/TargetRegistry.h"
20 
21 using namespace llvm;
22 
23 // Return true if Expr is in the range [MinValue, MaxValue].
inRange(const MCExpr * Expr,int64_t MinValue,int64_t MaxValue)24 static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
25   if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
26     int64_t Value = CE->getValue();
27     return Value >= MinValue && Value <= MaxValue;
28   }
29   return false;
30 }
31 
32 namespace {
33 enum RegisterKind {
34   GR32Reg,
35   GRH32Reg,
36   GR64Reg,
37   GR128Reg,
38   ADDR32Reg,
39   ADDR64Reg,
40   FP32Reg,
41   FP64Reg,
42   FP128Reg
43 };
44 
45 enum MemoryKind {
46   BDMem,
47   BDXMem,
48   BDLMem
49 };
50 
51 class SystemZOperand : public MCParsedAsmOperand {
52 public:
53 private:
54   enum OperandKind {
55     KindInvalid,
56     KindToken,
57     KindReg,
58     KindAccessReg,
59     KindImm,
60     KindImmTLS,
61     KindMem
62   };
63 
64   OperandKind Kind;
65   SMLoc StartLoc, EndLoc;
66 
67   // A string of length Length, starting at Data.
68   struct TokenOp {
69     const char *Data;
70     unsigned Length;
71   };
72 
73   // LLVM register Num, which has kind Kind.  In some ways it might be
74   // easier for this class to have a register bank (general, floating-point
75   // or access) and a raw register number (0-15).  This would postpone the
76   // interpretation of the operand to the add*() methods and avoid the need
77   // for context-dependent parsing.  However, we do things the current way
78   // because of the virtual getReg() method, which needs to distinguish
79   // between (say) %r0 used as a single register and %r0 used as a pair.
80   // Context-dependent parsing can also give us slightly better error
81   // messages when invalid pairs like %r1 are used.
82   struct RegOp {
83     RegisterKind Kind;
84     unsigned Num;
85   };
86 
87   // Base + Disp + Index, where Base and Index are LLVM registers or 0.
88   // RegKind says what type the registers have (ADDR32Reg or ADDR64Reg).
89   // Length is the operand length for D(L,B)-style operands, otherwise
90   // it is null.
91   struct MemOp {
92     unsigned Base : 8;
93     unsigned Index : 8;
94     unsigned RegKind : 8;
95     unsigned Unused : 8;
96     const MCExpr *Disp;
97     const MCExpr *Length;
98   };
99 
100   // Imm is an immediate operand, and Sym is an optional TLS symbol
101   // for use with a __tls_get_offset marker relocation.
102   struct ImmTLSOp {
103     const MCExpr *Imm;
104     const MCExpr *Sym;
105   };
106 
107   union {
108     TokenOp Token;
109     RegOp Reg;
110     unsigned AccessReg;
111     const MCExpr *Imm;
112     ImmTLSOp ImmTLS;
113     MemOp Mem;
114   };
115 
addExpr(MCInst & Inst,const MCExpr * Expr) const116   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
117     // Add as immediates when possible.  Null MCExpr = 0.
118     if (!Expr)
119       Inst.addOperand(MCOperand::CreateImm(0));
120     else if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
121       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
122     else
123       Inst.addOperand(MCOperand::CreateExpr(Expr));
124   }
125 
126 public:
SystemZOperand(OperandKind kind,SMLoc startLoc,SMLoc endLoc)127   SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
128       : Kind(kind), StartLoc(startLoc), EndLoc(endLoc) {}
129 
130   // Create particular kinds of operand.
createInvalid(SMLoc StartLoc,SMLoc EndLoc)131   static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
132                                                        SMLoc EndLoc) {
133     return make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
134   }
createToken(StringRef Str,SMLoc Loc)135   static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
136     auto Op = make_unique<SystemZOperand>(KindToken, Loc, Loc);
137     Op->Token.Data = Str.data();
138     Op->Token.Length = Str.size();
139     return Op;
140   }
141   static std::unique_ptr<SystemZOperand>
createReg(RegisterKind Kind,unsigned Num,SMLoc StartLoc,SMLoc EndLoc)142   createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
143     auto Op = make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
144     Op->Reg.Kind = Kind;
145     Op->Reg.Num = Num;
146     return Op;
147   }
148   static std::unique_ptr<SystemZOperand>
createAccessReg(unsigned Num,SMLoc StartLoc,SMLoc EndLoc)149   createAccessReg(unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
150     auto Op = make_unique<SystemZOperand>(KindAccessReg, StartLoc, EndLoc);
151     Op->AccessReg = Num;
152     return Op;
153   }
154   static std::unique_ptr<SystemZOperand>
createImm(const MCExpr * Expr,SMLoc StartLoc,SMLoc EndLoc)155   createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
156     auto Op = make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
157     Op->Imm = Expr;
158     return Op;
159   }
160   static std::unique_ptr<SystemZOperand>
createMem(RegisterKind RegKind,unsigned Base,const MCExpr * Disp,unsigned Index,const MCExpr * Length,SMLoc StartLoc,SMLoc EndLoc)161   createMem(RegisterKind RegKind, unsigned Base, const MCExpr *Disp,
162             unsigned Index, const MCExpr *Length, SMLoc StartLoc,
163             SMLoc EndLoc) {
164     auto Op = make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
165     Op->Mem.RegKind = RegKind;
166     Op->Mem.Base = Base;
167     Op->Mem.Index = Index;
168     Op->Mem.Disp = Disp;
169     Op->Mem.Length = Length;
170     return Op;
171   }
172   static std::unique_ptr<SystemZOperand>
createImmTLS(const MCExpr * Imm,const MCExpr * Sym,SMLoc StartLoc,SMLoc EndLoc)173   createImmTLS(const MCExpr *Imm, const MCExpr *Sym,
174                SMLoc StartLoc, SMLoc EndLoc) {
175     auto Op = make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
176     Op->ImmTLS.Imm = Imm;
177     Op->ImmTLS.Sym = Sym;
178     return Op;
179   }
180 
181   // Token operands
isToken() const182   bool isToken() const override {
183     return Kind == KindToken;
184   }
getToken() const185   StringRef getToken() const {
186     assert(Kind == KindToken && "Not a token");
187     return StringRef(Token.Data, Token.Length);
188   }
189 
190   // Register operands.
isReg() const191   bool isReg() const override {
192     return Kind == KindReg;
193   }
isReg(RegisterKind RegKind) const194   bool isReg(RegisterKind RegKind) const {
195     return Kind == KindReg && Reg.Kind == RegKind;
196   }
getReg() const197   unsigned getReg() const override {
198     assert(Kind == KindReg && "Not a register");
199     return Reg.Num;
200   }
201 
202   // Access register operands.  Access registers aren't exposed to LLVM
203   // as registers.
isAccessReg() const204   bool isAccessReg() const {
205     return Kind == KindAccessReg;
206   }
207 
208   // Immediate operands.
isImm() const209   bool isImm() const override {
210     return Kind == KindImm;
211   }
isImm(int64_t MinValue,int64_t MaxValue) const212   bool isImm(int64_t MinValue, int64_t MaxValue) const {
213     return Kind == KindImm && inRange(Imm, MinValue, MaxValue);
214   }
getImm() const215   const MCExpr *getImm() const {
216     assert(Kind == KindImm && "Not an immediate");
217     return Imm;
218   }
219 
220   // Immediate operands with optional TLS symbol.
isImmTLS() const221   bool isImmTLS() const {
222     return Kind == KindImmTLS;
223   }
224 
225   // Memory operands.
isMem() const226   bool isMem() const override {
227     return Kind == KindMem;
228   }
isMem(RegisterKind RegKind,MemoryKind MemKind) const229   bool isMem(RegisterKind RegKind, MemoryKind MemKind) const {
230     return (Kind == KindMem &&
231             Mem.RegKind == RegKind &&
232             (MemKind == BDXMem || !Mem.Index) &&
233             (MemKind == BDLMem) == (Mem.Length != nullptr));
234   }
isMemDisp12(RegisterKind RegKind,MemoryKind MemKind) const235   bool isMemDisp12(RegisterKind RegKind, MemoryKind MemKind) const {
236     return isMem(RegKind, MemKind) && inRange(Mem.Disp, 0, 0xfff);
237   }
isMemDisp20(RegisterKind RegKind,MemoryKind MemKind) const238   bool isMemDisp20(RegisterKind RegKind, MemoryKind MemKind) const {
239     return isMem(RegKind, MemKind) && inRange(Mem.Disp, -524288, 524287);
240   }
isMemDisp12Len8(RegisterKind RegKind) const241   bool isMemDisp12Len8(RegisterKind RegKind) const {
242     return isMemDisp12(RegKind, BDLMem) && inRange(Mem.Length, 1, 0x100);
243   }
244 
245   // Override MCParsedAsmOperand.
getStartLoc() const246   SMLoc getStartLoc() const override { return StartLoc; }
getEndLoc() const247   SMLoc getEndLoc() const override { return EndLoc; }
248   void print(raw_ostream &OS) const override;
249 
250   // Used by the TableGen code to add particular types of operand
251   // to an instruction.
addRegOperands(MCInst & Inst,unsigned N) const252   void addRegOperands(MCInst &Inst, unsigned N) const {
253     assert(N == 1 && "Invalid number of operands");
254     Inst.addOperand(MCOperand::CreateReg(getReg()));
255   }
addAccessRegOperands(MCInst & Inst,unsigned N) const256   void addAccessRegOperands(MCInst &Inst, unsigned N) const {
257     assert(N == 1 && "Invalid number of operands");
258     assert(Kind == KindAccessReg && "Invalid operand type");
259     Inst.addOperand(MCOperand::CreateImm(AccessReg));
260   }
addImmOperands(MCInst & Inst,unsigned N) const261   void addImmOperands(MCInst &Inst, unsigned N) const {
262     assert(N == 1 && "Invalid number of operands");
263     addExpr(Inst, getImm());
264   }
addBDAddrOperands(MCInst & Inst,unsigned N) const265   void addBDAddrOperands(MCInst &Inst, unsigned N) const {
266     assert(N == 2 && "Invalid number of operands");
267     assert(Kind == KindMem && Mem.Index == 0 && "Invalid operand type");
268     Inst.addOperand(MCOperand::CreateReg(Mem.Base));
269     addExpr(Inst, Mem.Disp);
270   }
addBDXAddrOperands(MCInst & Inst,unsigned N) const271   void addBDXAddrOperands(MCInst &Inst, unsigned N) const {
272     assert(N == 3 && "Invalid number of operands");
273     assert(Kind == KindMem && "Invalid operand type");
274     Inst.addOperand(MCOperand::CreateReg(Mem.Base));
275     addExpr(Inst, Mem.Disp);
276     Inst.addOperand(MCOperand::CreateReg(Mem.Index));
277   }
addBDLAddrOperands(MCInst & Inst,unsigned N) const278   void addBDLAddrOperands(MCInst &Inst, unsigned N) const {
279     assert(N == 3 && "Invalid number of operands");
280     assert(Kind == KindMem && "Invalid operand type");
281     Inst.addOperand(MCOperand::CreateReg(Mem.Base));
282     addExpr(Inst, Mem.Disp);
283     addExpr(Inst, Mem.Length);
284   }
addImmTLSOperands(MCInst & Inst,unsigned N) const285   void addImmTLSOperands(MCInst &Inst, unsigned N) const {
286     assert(N == 2 && "Invalid number of operands");
287     assert(Kind == KindImmTLS && "Invalid operand type");
288     addExpr(Inst, ImmTLS.Imm);
289     if (ImmTLS.Sym)
290       addExpr(Inst, ImmTLS.Sym);
291   }
292 
293   // Used by the TableGen code to check for particular operand types.
isGR32() const294   bool isGR32() const { return isReg(GR32Reg); }
isGRH32() const295   bool isGRH32() const { return isReg(GRH32Reg); }
isGRX32() const296   bool isGRX32() const { return false; }
isGR64() const297   bool isGR64() const { return isReg(GR64Reg); }
isGR128() const298   bool isGR128() const { return isReg(GR128Reg); }
isADDR32() const299   bool isADDR32() const { return isReg(ADDR32Reg); }
isADDR64() const300   bool isADDR64() const { return isReg(ADDR64Reg); }
isADDR128() const301   bool isADDR128() const { return false; }
isFP32() const302   bool isFP32() const { return isReg(FP32Reg); }
isFP64() const303   bool isFP64() const { return isReg(FP64Reg); }
isFP128() const304   bool isFP128() const { return isReg(FP128Reg); }
isBDAddr32Disp12() const305   bool isBDAddr32Disp12() const { return isMemDisp12(ADDR32Reg, BDMem); }
isBDAddr32Disp20() const306   bool isBDAddr32Disp20() const { return isMemDisp20(ADDR32Reg, BDMem); }
isBDAddr64Disp12() const307   bool isBDAddr64Disp12() const { return isMemDisp12(ADDR64Reg, BDMem); }
isBDAddr64Disp20() const308   bool isBDAddr64Disp20() const { return isMemDisp20(ADDR64Reg, BDMem); }
isBDXAddr64Disp12() const309   bool isBDXAddr64Disp12() const { return isMemDisp12(ADDR64Reg, BDXMem); }
isBDXAddr64Disp20() const310   bool isBDXAddr64Disp20() const { return isMemDisp20(ADDR64Reg, BDXMem); }
isBDLAddr64Disp12Len8() const311   bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(ADDR64Reg); }
isU4Imm() const312   bool isU4Imm() const { return isImm(0, 15); }
isU6Imm() const313   bool isU6Imm() const { return isImm(0, 63); }
isU8Imm() const314   bool isU8Imm() const { return isImm(0, 255); }
isS8Imm() const315   bool isS8Imm() const { return isImm(-128, 127); }
isU16Imm() const316   bool isU16Imm() const { return isImm(0, 65535); }
isS16Imm() const317   bool isS16Imm() const { return isImm(-32768, 32767); }
isU32Imm() const318   bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
isS32Imm() const319   bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
320 };
321 
322 class SystemZAsmParser : public MCTargetAsmParser {
323 #define GET_ASSEMBLER_HEADER
324 #include "SystemZGenAsmMatcher.inc"
325 
326 private:
327   MCSubtargetInfo &STI;
328   MCAsmParser &Parser;
329   enum RegisterGroup {
330     RegGR,
331     RegFP,
332     RegAccess
333   };
334   struct Register {
335     RegisterGroup Group;
336     unsigned Num;
337     SMLoc StartLoc, EndLoc;
338   };
339 
340   bool parseRegister(Register &Reg);
341 
342   bool parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
343                      bool IsAddress = false);
344 
345   OperandMatchResultTy parseRegister(OperandVector &Operands,
346                                      RegisterGroup Group, const unsigned *Regs,
347                                      RegisterKind Kind);
348 
349   bool parseAddress(unsigned &Base, const MCExpr *&Disp,
350                     unsigned &Index, const MCExpr *&Length,
351                     const unsigned *Regs, RegisterKind RegKind);
352 
353   OperandMatchResultTy parseAddress(OperandVector &Operands,
354                                     const unsigned *Regs, RegisterKind RegKind,
355                                     MemoryKind MemKind);
356 
357   OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
358                                   int64_t MaxVal, bool AllowTLS);
359 
360   bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
361 
362 public:
SystemZAsmParser(MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)363   SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
364                    const MCInstrInfo &MII,
365                    const MCTargetOptions &Options)
366       : MCTargetAsmParser(), STI(sti), Parser(parser) {
367     MCAsmParserExtension::Initialize(Parser);
368 
369     // Initialize the set of available features.
370     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
371   }
372 
373   // Override MCTargetAsmParser.
374   bool ParseDirective(AsmToken DirectiveID) override;
375   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
376   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
377                         SMLoc NameLoc, OperandVector &Operands) override;
378   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
379                                OperandVector &Operands, MCStreamer &Out,
380                                uint64_t &ErrorInfo,
381                                bool MatchingInlineAsm) override;
382 
383   // Used by the TableGen code to parse particular operand types.
parseGR32(OperandVector & Operands)384   OperandMatchResultTy parseGR32(OperandVector &Operands) {
385     return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, GR32Reg);
386   }
parseGRH32(OperandVector & Operands)387   OperandMatchResultTy parseGRH32(OperandVector &Operands) {
388     return parseRegister(Operands, RegGR, SystemZMC::GRH32Regs, GRH32Reg);
389   }
parseGRX32(OperandVector & Operands)390   OperandMatchResultTy parseGRX32(OperandVector &Operands) {
391     llvm_unreachable("GRX32 should only be used for pseudo instructions");
392   }
parseGR64(OperandVector & Operands)393   OperandMatchResultTy parseGR64(OperandVector &Operands) {
394     return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, GR64Reg);
395   }
parseGR128(OperandVector & Operands)396   OperandMatchResultTy parseGR128(OperandVector &Operands) {
397     return parseRegister(Operands, RegGR, SystemZMC::GR128Regs, GR128Reg);
398   }
parseADDR32(OperandVector & Operands)399   OperandMatchResultTy parseADDR32(OperandVector &Operands) {
400     return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, ADDR32Reg);
401   }
parseADDR64(OperandVector & Operands)402   OperandMatchResultTy parseADDR64(OperandVector &Operands) {
403     return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, ADDR64Reg);
404   }
parseADDR128(OperandVector & Operands)405   OperandMatchResultTy parseADDR128(OperandVector &Operands) {
406     llvm_unreachable("Shouldn't be used as an operand");
407   }
parseFP32(OperandVector & Operands)408   OperandMatchResultTy parseFP32(OperandVector &Operands) {
409     return parseRegister(Operands, RegFP, SystemZMC::FP32Regs, FP32Reg);
410   }
parseFP64(OperandVector & Operands)411   OperandMatchResultTy parseFP64(OperandVector &Operands) {
412     return parseRegister(Operands, RegFP, SystemZMC::FP64Regs, FP64Reg);
413   }
parseFP128(OperandVector & Operands)414   OperandMatchResultTy parseFP128(OperandVector &Operands) {
415     return parseRegister(Operands, RegFP, SystemZMC::FP128Regs, FP128Reg);
416   }
parseBDAddr32(OperandVector & Operands)417   OperandMatchResultTy parseBDAddr32(OperandVector &Operands) {
418     return parseAddress(Operands, SystemZMC::GR32Regs, ADDR32Reg, BDMem);
419   }
parseBDAddr64(OperandVector & Operands)420   OperandMatchResultTy parseBDAddr64(OperandVector &Operands) {
421     return parseAddress(Operands, SystemZMC::GR64Regs, ADDR64Reg, BDMem);
422   }
parseBDXAddr64(OperandVector & Operands)423   OperandMatchResultTy parseBDXAddr64(OperandVector &Operands) {
424     return parseAddress(Operands, SystemZMC::GR64Regs, ADDR64Reg, BDXMem);
425   }
parseBDLAddr64(OperandVector & Operands)426   OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
427     return parseAddress(Operands, SystemZMC::GR64Regs, ADDR64Reg, BDLMem);
428   }
429   OperandMatchResultTy parseAccessReg(OperandVector &Operands);
parsePCRel16(OperandVector & Operands)430   OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
431     return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
432   }
parsePCRel32(OperandVector & Operands)433   OperandMatchResultTy parsePCRel32(OperandVector &Operands) {
434     return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);
435   }
parsePCRelTLS16(OperandVector & Operands)436   OperandMatchResultTy parsePCRelTLS16(OperandVector &Operands) {
437     return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);
438   }
parsePCRelTLS32(OperandVector & Operands)439   OperandMatchResultTy parsePCRelTLS32(OperandVector &Operands) {
440     return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);
441   }
442 };
443 } // end anonymous namespace
444 
445 #define GET_REGISTER_MATCHER
446 #define GET_SUBTARGET_FEATURE_NAME
447 #define GET_MATCHER_IMPLEMENTATION
448 #include "SystemZGenAsmMatcher.inc"
449 
print(raw_ostream & OS) const450 void SystemZOperand::print(raw_ostream &OS) const {
451   llvm_unreachable("Not implemented");
452 }
453 
454 // Parse one register of the form %<prefix><number>.
parseRegister(Register & Reg)455 bool SystemZAsmParser::parseRegister(Register &Reg) {
456   Reg.StartLoc = Parser.getTok().getLoc();
457 
458   // Eat the % prefix.
459   if (Parser.getTok().isNot(AsmToken::Percent))
460     return Error(Parser.getTok().getLoc(), "register expected");
461   Parser.Lex();
462 
463   // Expect a register name.
464   if (Parser.getTok().isNot(AsmToken::Identifier))
465     return Error(Reg.StartLoc, "invalid register");
466 
467   // Check that there's a prefix.
468   StringRef Name = Parser.getTok().getString();
469   if (Name.size() < 2)
470     return Error(Reg.StartLoc, "invalid register");
471   char Prefix = Name[0];
472 
473   // Treat the rest of the register name as a register number.
474   if (Name.substr(1).getAsInteger(10, Reg.Num))
475     return Error(Reg.StartLoc, "invalid register");
476 
477   // Look for valid combinations of prefix and number.
478   if (Prefix == 'r' && Reg.Num < 16)
479     Reg.Group = RegGR;
480   else if (Prefix == 'f' && Reg.Num < 16)
481     Reg.Group = RegFP;
482   else if (Prefix == 'a' && Reg.Num < 16)
483     Reg.Group = RegAccess;
484   else
485     return Error(Reg.StartLoc, "invalid register");
486 
487   Reg.EndLoc = Parser.getTok().getLoc();
488   Parser.Lex();
489   return false;
490 }
491 
492 // Parse a register of group Group.  If Regs is nonnull, use it to map
493 // the raw register number to LLVM numbering, with zero entries indicating
494 // an invalid register.  IsAddress says whether the register appears in an
495 // address context.
parseRegister(Register & Reg,RegisterGroup Group,const unsigned * Regs,bool IsAddress)496 bool SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
497                                      const unsigned *Regs, bool IsAddress) {
498   if (parseRegister(Reg))
499     return true;
500   if (Reg.Group != Group)
501     return Error(Reg.StartLoc, "invalid operand for instruction");
502   if (Regs && Regs[Reg.Num] == 0)
503     return Error(Reg.StartLoc, "invalid register pair");
504   if (Reg.Num == 0 && IsAddress)
505     return Error(Reg.StartLoc, "%r0 used in an address");
506   if (Regs)
507     Reg.Num = Regs[Reg.Num];
508   return false;
509 }
510 
511 // Parse a register and add it to Operands.  The other arguments are as above.
512 SystemZAsmParser::OperandMatchResultTy
parseRegister(OperandVector & Operands,RegisterGroup Group,const unsigned * Regs,RegisterKind Kind)513 SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterGroup Group,
514                                 const unsigned *Regs, RegisterKind Kind) {
515   if (Parser.getTok().isNot(AsmToken::Percent))
516     return MatchOperand_NoMatch;
517 
518   Register Reg;
519   bool IsAddress = (Kind == ADDR32Reg || Kind == ADDR64Reg);
520   if (parseRegister(Reg, Group, Regs, IsAddress))
521     return MatchOperand_ParseFail;
522 
523   Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
524                                                Reg.StartLoc, Reg.EndLoc));
525   return MatchOperand_Success;
526 }
527 
528 // Parse a memory operand into Base, Disp, Index and Length.
529 // Regs maps asm register numbers to LLVM register numbers and RegKind
530 // says what kind of address register we're using (ADDR32Reg or ADDR64Reg).
parseAddress(unsigned & Base,const MCExpr * & Disp,unsigned & Index,const MCExpr * & Length,const unsigned * Regs,RegisterKind RegKind)531 bool SystemZAsmParser::parseAddress(unsigned &Base, const MCExpr *&Disp,
532                                     unsigned &Index, const MCExpr *&Length,
533                                     const unsigned *Regs,
534                                     RegisterKind RegKind) {
535   // Parse the displacement, which must always be present.
536   if (getParser().parseExpression(Disp))
537     return true;
538 
539   // Parse the optional base and index.
540   Index = 0;
541   Base = 0;
542   Length = nullptr;
543   if (getLexer().is(AsmToken::LParen)) {
544     Parser.Lex();
545 
546     if (getLexer().is(AsmToken::Percent)) {
547       // Parse the first register and decide whether it's a base or an index.
548       Register Reg;
549       if (parseRegister(Reg, RegGR, Regs, RegKind))
550         return true;
551       if (getLexer().is(AsmToken::Comma))
552         Index = Reg.Num;
553       else
554         Base = Reg.Num;
555     } else {
556       // Parse the length.
557       if (getParser().parseExpression(Length))
558         return true;
559     }
560 
561     // Check whether there's a second register.  It's the base if so.
562     if (getLexer().is(AsmToken::Comma)) {
563       Parser.Lex();
564       Register Reg;
565       if (parseRegister(Reg, RegGR, Regs, RegKind))
566         return true;
567       Base = Reg.Num;
568     }
569 
570     // Consume the closing bracket.
571     if (getLexer().isNot(AsmToken::RParen))
572       return Error(Parser.getTok().getLoc(), "unexpected token in address");
573     Parser.Lex();
574   }
575   return false;
576 }
577 
578 // Parse a memory operand and add it to Operands.  The other arguments
579 // are as above.
580 SystemZAsmParser::OperandMatchResultTy
parseAddress(OperandVector & Operands,const unsigned * Regs,RegisterKind RegKind,MemoryKind MemKind)581 SystemZAsmParser::parseAddress(OperandVector &Operands, const unsigned *Regs,
582                                RegisterKind RegKind, MemoryKind MemKind) {
583   SMLoc StartLoc = Parser.getTok().getLoc();
584   unsigned Base, Index;
585   const MCExpr *Disp;
586   const MCExpr *Length;
587   if (parseAddress(Base, Disp, Index, Length, Regs, RegKind))
588     return MatchOperand_ParseFail;
589 
590   if (Index && MemKind != BDXMem)
591     {
592       Error(StartLoc, "invalid use of indexed addressing");
593       return MatchOperand_ParseFail;
594     }
595 
596   if (Length && MemKind != BDLMem)
597     {
598       Error(StartLoc, "invalid use of length addressing");
599       return MatchOperand_ParseFail;
600     }
601 
602   if (!Length && MemKind == BDLMem)
603     {
604       Error(StartLoc, "missing length in address");
605       return MatchOperand_ParseFail;
606     }
607 
608   SMLoc EndLoc =
609     SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
610   Operands.push_back(SystemZOperand::createMem(RegKind, Base, Disp, Index,
611                                                Length, StartLoc, EndLoc));
612   return MatchOperand_Success;
613 }
614 
ParseDirective(AsmToken DirectiveID)615 bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
616   return true;
617 }
618 
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)619 bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
620                                      SMLoc &EndLoc) {
621   Register Reg;
622   if (parseRegister(Reg))
623     return true;
624   if (Reg.Group == RegGR)
625     RegNo = SystemZMC::GR64Regs[Reg.Num];
626   else if (Reg.Group == RegFP)
627     RegNo = SystemZMC::FP64Regs[Reg.Num];
628   else
629     // FIXME: Access registers aren't modelled as LLVM registers yet.
630     return Error(Reg.StartLoc, "invalid operand for instruction");
631   StartLoc = Reg.StartLoc;
632   EndLoc = Reg.EndLoc;
633   return false;
634 }
635 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)636 bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
637                                         StringRef Name, SMLoc NameLoc,
638                                         OperandVector &Operands) {
639   Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
640 
641   // Read the remaining operands.
642   if (getLexer().isNot(AsmToken::EndOfStatement)) {
643     // Read the first operand.
644     if (parseOperand(Operands, Name)) {
645       Parser.eatToEndOfStatement();
646       return true;
647     }
648 
649     // Read any subsequent operands.
650     while (getLexer().is(AsmToken::Comma)) {
651       Parser.Lex();
652       if (parseOperand(Operands, Name)) {
653         Parser.eatToEndOfStatement();
654         return true;
655       }
656     }
657     if (getLexer().isNot(AsmToken::EndOfStatement)) {
658       SMLoc Loc = getLexer().getLoc();
659       Parser.eatToEndOfStatement();
660       return Error(Loc, "unexpected token in argument list");
661     }
662   }
663 
664   // Consume the EndOfStatement.
665   Parser.Lex();
666   return false;
667 }
668 
parseOperand(OperandVector & Operands,StringRef Mnemonic)669 bool SystemZAsmParser::parseOperand(OperandVector &Operands,
670                                     StringRef Mnemonic) {
671   // Check if the current operand has a custom associated parser, if so, try to
672   // custom parse the operand, or fallback to the general approach.
673   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
674   if (ResTy == MatchOperand_Success)
675     return false;
676 
677   // If there wasn't a custom match, try the generic matcher below. Otherwise,
678   // there was a match, but an error occurred, in which case, just return that
679   // the operand parsing failed.
680   if (ResTy == MatchOperand_ParseFail)
681     return true;
682 
683   // Check for a register.  All real register operands should have used
684   // a context-dependent parse routine, which gives the required register
685   // class.  The code is here to mop up other cases, like those where
686   // the instruction isn't recognized.
687   if (Parser.getTok().is(AsmToken::Percent)) {
688     Register Reg;
689     if (parseRegister(Reg))
690       return true;
691     Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));
692     return false;
693   }
694 
695   // The only other type of operand is an immediate or address.  As above,
696   // real address operands should have used a context-dependent parse routine,
697   // so we treat any plain expression as an immediate.
698   SMLoc StartLoc = Parser.getTok().getLoc();
699   unsigned Base, Index;
700   const MCExpr *Expr, *Length;
701   if (parseAddress(Base, Expr, Index, Length, SystemZMC::GR64Regs, ADDR64Reg))
702     return true;
703 
704   SMLoc EndLoc =
705     SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
706   if (Base || Index || Length)
707     Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
708   else
709     Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
710   return false;
711 }
712 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)713 bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
714                                                OperandVector &Operands,
715                                                MCStreamer &Out,
716                                                uint64_t &ErrorInfo,
717                                                bool MatchingInlineAsm) {
718   MCInst Inst;
719   unsigned MatchResult;
720 
721   MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
722                                      MatchingInlineAsm);
723   switch (MatchResult) {
724   case Match_Success:
725     Inst.setLoc(IDLoc);
726     Out.EmitInstruction(Inst, STI);
727     return false;
728 
729   case Match_MissingFeature: {
730     assert(ErrorInfo && "Unknown missing feature!");
731     // Special case the error message for the very common case where only
732     // a single subtarget feature is missing
733     std::string Msg = "instruction requires:";
734     uint64_t Mask = 1;
735     for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
736       if (ErrorInfo & Mask) {
737         Msg += " ";
738         Msg += getSubtargetFeatureName(ErrorInfo & Mask);
739       }
740       Mask <<= 1;
741     }
742     return Error(IDLoc, Msg);
743   }
744 
745   case Match_InvalidOperand: {
746     SMLoc ErrorLoc = IDLoc;
747     if (ErrorInfo != ~0ULL) {
748       if (ErrorInfo >= Operands.size())
749         return Error(IDLoc, "too few operands for instruction");
750 
751       ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();
752       if (ErrorLoc == SMLoc())
753         ErrorLoc = IDLoc;
754     }
755     return Error(ErrorLoc, "invalid operand for instruction");
756   }
757 
758   case Match_MnemonicFail:
759     return Error(IDLoc, "invalid instruction");
760   }
761 
762   llvm_unreachable("Unexpected match type");
763 }
764 
765 SystemZAsmParser::OperandMatchResultTy
parseAccessReg(OperandVector & Operands)766 SystemZAsmParser::parseAccessReg(OperandVector &Operands) {
767   if (Parser.getTok().isNot(AsmToken::Percent))
768     return MatchOperand_NoMatch;
769 
770   Register Reg;
771   if (parseRegister(Reg, RegAccess, nullptr))
772     return MatchOperand_ParseFail;
773 
774   Operands.push_back(SystemZOperand::createAccessReg(Reg.Num,
775                                                      Reg.StartLoc,
776                                                      Reg.EndLoc));
777   return MatchOperand_Success;
778 }
779 
780 SystemZAsmParser::OperandMatchResultTy
parsePCRel(OperandVector & Operands,int64_t MinVal,int64_t MaxVal,bool AllowTLS)781 SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
782                              int64_t MaxVal, bool AllowTLS) {
783   MCContext &Ctx = getContext();
784   MCStreamer &Out = getStreamer();
785   const MCExpr *Expr;
786   SMLoc StartLoc = Parser.getTok().getLoc();
787   if (getParser().parseExpression(Expr))
788     return MatchOperand_NoMatch;
789 
790   // For consistency with the GNU assembler, treat immediates as offsets
791   // from ".".
792   if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
793     int64_t Value = CE->getValue();
794     if ((Value & 1) || Value < MinVal || Value > MaxVal) {
795       Error(StartLoc, "offset out of range");
796       return MatchOperand_ParseFail;
797     }
798     MCSymbol *Sym = Ctx.CreateTempSymbol();
799     Out.EmitLabel(Sym);
800     const MCExpr *Base = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
801                                                  Ctx);
802     Expr = Value == 0 ? Base : MCBinaryExpr::CreateAdd(Base, Expr, Ctx);
803   }
804 
805   // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
806   const MCExpr *Sym = nullptr;
807   if (AllowTLS && getLexer().is(AsmToken::Colon)) {
808     Parser.Lex();
809 
810     if (Parser.getTok().isNot(AsmToken::Identifier)) {
811       Error(Parser.getTok().getLoc(), "unexpected token");
812       return MatchOperand_ParseFail;
813     }
814 
815     MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
816     StringRef Name = Parser.getTok().getString();
817     if (Name == "tls_gdcall")
818       Kind = MCSymbolRefExpr::VK_TLSGD;
819     else if (Name == "tls_ldcall")
820       Kind = MCSymbolRefExpr::VK_TLSLDM;
821     else {
822       Error(Parser.getTok().getLoc(), "unknown TLS tag");
823       return MatchOperand_ParseFail;
824     }
825     Parser.Lex();
826 
827     if (Parser.getTok().isNot(AsmToken::Colon)) {
828       Error(Parser.getTok().getLoc(), "unexpected token");
829       return MatchOperand_ParseFail;
830     }
831     Parser.Lex();
832 
833     if (Parser.getTok().isNot(AsmToken::Identifier)) {
834       Error(Parser.getTok().getLoc(), "unexpected token");
835       return MatchOperand_ParseFail;
836     }
837 
838     StringRef Identifier = Parser.getTok().getString();
839     Sym = MCSymbolRefExpr::Create(Ctx.GetOrCreateSymbol(Identifier),
840                                   Kind, Ctx);
841     Parser.Lex();
842   }
843 
844   SMLoc EndLoc =
845     SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
846 
847   if (AllowTLS)
848     Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
849                                                     StartLoc, EndLoc));
850   else
851     Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
852 
853   return MatchOperand_Success;
854 }
855 
856 // Force static initialization.
LLVMInitializeSystemZAsmParser()857 extern "C" void LLVMInitializeSystemZAsmParser() {
858   RegisterMCAsmParser<SystemZAsmParser> X(TheSystemZTarget);
859 }
860