Coverage Report

Created: 2025-08-30 07:19

/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
}