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