Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- LanaiAsmParser.cpp - Parse Lanai assembly to MCInst instructions --===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "LanaiAluCode.h"
10
#include "LanaiCondCode.h"
11
#include "LanaiInstrInfo.h"
12
#include "MCTargetDesc/LanaiMCExpr.h"
13
#include "TargetInfo/LanaiTargetInfo.h"
14
#include "llvm/ADT/STLExtras.h"
15
#include "llvm/ADT/StringRef.h"
16
#include "llvm/ADT/StringSwitch.h"
17
#include "llvm/MC/MCContext.h"
18
#include "llvm/MC/MCExpr.h"
19
#include "llvm/MC/MCInst.h"
20
#include "llvm/MC/MCParser/MCAsmLexer.h"
21
#include "llvm/MC/MCParser/MCAsmParser.h"
22
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
24
#include "llvm/MC/MCStreamer.h"
25
#include "llvm/MC/MCSubtargetInfo.h"
26
#include "llvm/MC/MCSymbol.h"
27
#include "llvm/Support/Casting.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include "llvm/Support/MathExtras.h"
30
#include "llvm/Support/SMLoc.h"
31
#include "llvm/Support/TargetRegistry.h"
32
#include "llvm/Support/raw_ostream.h"
33
#include <algorithm>
34
#include <cassert>
35
#include <cstddef>
36
#include <cstdint>
37
#include <memory>
38
39
using namespace llvm;
40
41
// Auto-generated by TableGen
42
static unsigned MatchRegisterName(StringRef Name);
43
44
namespace {
45
46
struct LanaiOperand;
47
48
class LanaiAsmParser : public MCTargetAsmParser {
49
  // Parse operands
50
  std::unique_ptr<LanaiOperand> parseRegister();
51
52
  std::unique_ptr<LanaiOperand> parseImmediate();
53
54
  std::unique_ptr<LanaiOperand> parseIdentifier();
55
56
  unsigned parseAluOperator(bool PreOp, bool PostOp);
57
58
  // Split the mnemonic stripping conditional code and quantifiers
59
  StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
60
                          OperandVector *Operands);
61
62
  bool parsePrePost(StringRef Type, int *OffsetValue);
63
64
  bool ParseDirective(AsmToken DirectiveID) override;
65
66
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
67
                        SMLoc NameLoc, OperandVector &Operands) override;
68
69
  bool ParseRegister(unsigned &RegNum, SMLoc &StartLoc, SMLoc &EndLoc) override;
70
71
  bool MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
72
                               OperandVector &Operands, MCStreamer &Out,
73
                               uint64_t &ErrorInfo,
74
                               bool MatchingInlineAsm) override;
75
76
// Auto-generated instruction matching functions
77
#define GET_ASSEMBLER_HEADER
78
#include "LanaiGenAsmMatcher.inc"
79
80
  OperandMatchResultTy parseOperand(OperandVector *Operands,
81
                                    StringRef Mnemonic);
82
83
  OperandMatchResultTy parseMemoryOperand(OperandVector &Operands);
84
85
public:
86
  LanaiAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
87
                 const MCInstrInfo &MII, const MCTargetOptions &Options)
88
      : MCTargetAsmParser(Options, STI, MII), Parser(Parser),
89
7
        Lexer(Parser.getLexer()), SubtargetInfo(STI) {
90
7
    setAvailableFeatures(
91
7
        ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
92
7
  }
93
94
private:
95
  MCAsmParser &Parser;
96
  MCAsmLexer &Lexer;
97
98
  const MCSubtargetInfo &SubtargetInfo;
99
};
100
101
// LanaiOperand - Instances of this class represented a parsed machine
102
// instruction
103
struct LanaiOperand : public MCParsedAsmOperand {
104
  enum KindTy {
105
    TOKEN,
106
    REGISTER,
107
    IMMEDIATE,
108
    MEMORY_IMM,
109
    MEMORY_REG_IMM,
110
    MEMORY_REG_REG,
111
  } Kind;
112
113
  SMLoc StartLoc, EndLoc;
114
115
  struct Token {
116
    const char *Data;
117
    unsigned Length;
118
  };
119
120
  struct RegOp {
121
    unsigned RegNum;
122
  };
123
124
  struct ImmOp {
125
    const MCExpr *Value;
126
  };
127
128
  struct MemOp {
129
    unsigned BaseReg;
130
    unsigned OffsetReg;
131
    unsigned AluOp;
132
    const MCExpr *Offset;
133
  };
134
135
  union {
136
    struct Token Tok;
137
    struct RegOp Reg;
138
    struct ImmOp Imm;
139
    struct MemOp Mem;
140
  };
141
142
1.89k
  explicit LanaiOperand(KindTy Kind) : MCParsedAsmOperand(), Kind(Kind) {}
143
144
public:
145
  // The functions below are used by the autogenerated ASM matcher and hence to
146
  // be of the form expected.
147
148
  // getStartLoc - Gets location of the first token of this operand
149
0
  SMLoc getStartLoc() const override { return StartLoc; }
150
151
  // getEndLoc - Gets location of the last token of this operand
152
0
  SMLoc getEndLoc() const override { return EndLoc; }
153
154
1.70k
  unsigned getReg() const override {
155
1.70k
    assert(isReg() && "Invalid type access!");
156
1.70k
    return Reg.RegNum;
157
1.70k
  }
158
159
399
  const MCExpr *getImm() const {
160
399
    assert(isImm() && "Invalid type access!");
161
399
    return Imm.Value;
162
399
  }
163
164
819
  StringRef getToken() const {
165
819
    assert(isToken() && "Invalid type access!");
166
819
    return StringRef(Tok.Data, Tok.Length);
167
819
  }
168
169
294
  unsigned getMemBaseReg() const {
170
294
    assert(isMem() && "Invalid type access!");
171
294
    return Mem.BaseReg;
172
294
  }
173
174
127
  unsigned getMemOffsetReg() const {
175
127
    assert(isMem() && "Invalid type access!");
176
127
    return Mem.OffsetReg;
177
127
  }
178
179
172
  const MCExpr *getMemOffset() const {
180
172
    assert(isMem() && "Invalid type access!");
181
172
    return Mem.Offset;
182
172
  }
183
184
294
  unsigned getMemOp() const {
185
294
    assert(isMem() && "Invalid type access!");
186
294
    return Mem.AluOp;
187
294
  }
188
189
  // Functions for testing operand type
190
1.35k
  bool isReg() const override { return Kind == REGISTER; }
191
192
1.08k
  bool isImm() const override { return Kind == IMMEDIATE; }
193
194
0
  bool isMem() const override {
195
0
    return isMemImm() || isMemRegImm() || isMemRegReg();
196
0
  }
197
198
119
  bool isMemImm() const { return Kind == MEMORY_IMM; }
199
200
336
  bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }
201
202
331
  bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }
203
204
102
  bool isMemSpls() const { return isMemRegImm() || 
isMemRegReg()0
; }
205
206
2.13k
  bool isToken() const override { return Kind == TOKEN; }
207
208
47
  bool isBrImm() {
209
47
    if (!isImm())
210
20
      return false;
211
27
212
27
    // Constant case
213
27
    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm.Value);
214
27
    if (!MCE)
215
5
      return true;
216
22
    int64_t Value = MCE->getValue();
217
22
    // Check if value fits in 25 bits with 2 least significant bits 0.
218
22
    return isShiftedUInt<23, 2>(static_cast<int32_t>(Value));
219
22
  }
220
221
47
  bool isBrTarget() { return isBrImm() || 
isToken()20
; }
222
223
0
  bool isCallTarget() { return isImm() || isToken(); }
224
225
44
  bool isHiImm16() {
226
44
    if (!isImm())
227
0
      return false;
228
44
229
44
    // Constant case
230
44
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
231
42
      int64_t Value = ConstExpr->getValue();
232
42
      return Value != 0 && 
isShiftedUInt<16, 16>(Value)29
;
233
42
    }
234
2
235
2
    // Symbolic reference expression
236
2
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
237
1
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
238
1
239
1
    // Binary expression
240
1
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
241
1
      if (const LanaiMCExpr *SymbolRefExpr =
242
1
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
243
1
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
244
0
245
0
    return false;
246
0
  }
247
248
13
  bool isHiImm16And() {
249
13
    if (!isImm())
250
0
      return false;
251
13
252
13
    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
253
13
    if (ConstExpr) {
254
11
      int64_t Value = ConstExpr->getValue();
255
11
      // Check if in the form 0xXYZWffff
256
11
      return (Value != 0) && 
((Value & ~0xffff0000) == 0xffff)10
;
257
11
    }
258
2
    return false;
259
2
  }
260
261
27
  bool isLoImm16() {
262
27
    if (!isImm())
263
0
      return false;
264
27
265
27
    // Constant case
266
27
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
267
27
      int64_t Value = ConstExpr->getValue();
268
27
      // Check if value fits in 16 bits
269
27
      return isUInt<16>(static_cast<int32_t>(Value));
270
27
    }
271
0
272
0
    // Symbolic reference expression
273
0
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
274
0
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
275
0
276
0
    // Binary expression
277
0
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
278
0
      if (const LanaiMCExpr *SymbolRefExpr =
279
0
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
280
0
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
281
0
282
0
    return false;
283
0
  }
284
285
167
  bool isLoImm16Signed() {
286
167
    if (!isImm())
287
0
      return false;
288
167
289
167
    // Constant case
290
167
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
291
167
      int64_t Value = ConstExpr->getValue();
292
167
      // Check if value fits in 16 bits or value of the form 0xffffxyzw
293
167
      return isInt<16>(static_cast<int32_t>(Value));
294
167
    }
295
0
296
0
    // Symbolic reference expression
297
0
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
298
0
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
299
0
300
0
    // Binary expression
301
0
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
302
0
      if (const LanaiMCExpr *SymbolRefExpr =
303
0
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
304
0
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
305
0
306
0
    return false;
307
0
  }
308
309
6
  bool isLoImm16And() {
310
6
    if (!isImm())
311
0
      return false;
312
6
313
6
    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
314
6
    if (ConstExpr) {
315
6
      int64_t Value = ConstExpr->getValue();
316
6
      // Check if in the form 0xffffXYZW
317
6
      return ((Value & ~0xffff) == 0xffff0000);
318
6
    }
319
0
    return false;
320
0
  }
321
322
16
  bool isImmShift() {
323
16
    if (!isImm())
324
0
      return false;
325
16
326
16
    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
327
16
    if (!ConstExpr)
328
0
      return false;
329
16
    int64_t Value = ConstExpr->getValue();
330
16
    return (Value >= -31) && (Value <= 31);
331
16
  }
332
333
1
  bool isLoImm21() {
334
1
    if (!isImm())
335
0
      return false;
336
1
337
1
    // Constant case
338
1
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
339
1
      int64_t Value = ConstExpr->getValue();
340
1
      return isUInt<21>(Value);
341
1
    }
342
0
343
0
    // Symbolic reference expression
344
0
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
345
0
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
346
0
    if (const MCSymbolRefExpr *SymbolRefExpr =
347
0
            dyn_cast<MCSymbolRefExpr>(Imm.Value)) {
348
0
      return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
349
0
    }
350
0
351
0
    // Binary expression
352
0
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
353
0
      if (const LanaiMCExpr *SymbolRefExpr =
354
0
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
355
0
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
356
0
      if (const MCSymbolRefExpr *SymbolRefExpr =
357
0
              dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
358
0
        return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
359
0
    }
360
0
361
0
    return false;
362
0
  }
363
364
0
  bool isImm10() {
365
0
    if (!isImm())
366
0
      return false;
367
0
368
0
    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
369
0
    if (!ConstExpr)
370
0
      return false;
371
0
    int64_t Value = ConstExpr->getValue();
372
0
    return isInt<10>(Value);
373
0
  }
374
375
23
  bool isCondCode() {
376
23
    if (!isImm())
377
0
      return false;
378
23
379
23
    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
380
23
    if (!ConstExpr)
381
0
      return false;
382
23
    uint64_t Value = ConstExpr->getValue();
383
23
    // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
384
23
    // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
385
23
    // value corresponds to a valid condition code.
386
23
    return Value < LPCC::UNKNOWN;
387
23
  }
388
389
337
  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
390
337
    // Add as immediates where possible. Null MCExpr = 0
391
337
    if (Expr == nullptr)
392
0
      Inst.addOperand(MCOperand::createImm(0));
393
337
    else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
394
332
      Inst.addOperand(
395
332
          MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
396
5
    else
397
5
      Inst.addOperand(MCOperand::createExpr(Expr));
398
337
  }
399
400
573
  void addRegOperands(MCInst &Inst, unsigned N) const {
401
573
    assert(N == 1 && "Invalid number of operands!");
402
573
    Inst.addOperand(MCOperand::createReg(getReg()));
403
573
  }
404
405
99
  void addImmOperands(MCInst &Inst, unsigned N) const {
406
99
    assert(N == 1 && "Invalid number of operands!");
407
99
    addExpr(Inst, getImm());
408
99
  }
409
410
27
  void addBrTargetOperands(MCInst &Inst, unsigned N) const {
411
27
    assert(N == 1 && "Invalid number of operands!");
412
27
    addExpr(Inst, getImm());
413
27
  }
414
415
0
  void addCallTargetOperands(MCInst &Inst, unsigned N) const {
416
0
    assert(N == 1 && "Invalid number of operands!");
417
0
    addExpr(Inst, getImm());
418
0
  }
419
420
23
  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
421
23
    assert(N == 1 && "Invalid number of operands!");
422
23
    addExpr(Inst, getImm());
423
23
  }
424
425
5
  void addMemImmOperands(MCInst &Inst, unsigned N) const {
426
5
    assert(N == 1 && "Invalid number of operands!");
427
5
    const MCExpr *Expr = getMemOffset();
428
5
    addExpr(Inst, Expr);
429
5
  }
430
431
167
  void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
432
167
    assert(N == 3 && "Invalid number of operands!");
433
167
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
434
167
    const MCExpr *Expr = getMemOffset();
435
167
    addExpr(Inst, Expr);
436
167
    Inst.addOperand(MCOperand::createImm(getMemOp()));
437
167
  }
438
439
127
  void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
440
127
    assert(N == 3 && "Invalid number of operands!");
441
127
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
442
127
    assert(getMemOffsetReg() != 0 && "Invalid offset");
443
127
    Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
444
127
    Inst.addOperand(MCOperand::createImm(getMemOp()));
445
127
  }
446
447
102
  void addMemSplsOperands(MCInst &Inst, unsigned N) const {
448
102
    if (isMemRegImm())
449
102
      addMemRegImmOperands(Inst, N);
450
102
    if (isMemRegReg())
451
0
      addMemRegRegOperands(Inst, N);
452
102
  }
453
454
16
  void addImmShiftOperands(MCInst &Inst, unsigned N) const {
455
16
    assert(N == 1 && "Invalid number of operands!");
456
16
    addExpr(Inst, getImm());
457
16
  }
458
459
0
  void addImm10Operands(MCInst &Inst, unsigned N) const {
460
0
    assert(N == 1 && "Invalid number of operands!");
461
0
    addExpr(Inst, getImm());
462
0
  }
463
464
26
  void addLoImm16Operands(MCInst &Inst, unsigned N) const {
465
26
    assert(N == 1 && "Invalid number of operands!");
466
26
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
467
26
      Inst.addOperand(
468
26
          MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
469
0
    else if (isa<LanaiMCExpr>(getImm())) {
470
#ifndef NDEBUG
471
      const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
472
      assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
473
#endif
474
      Inst.addOperand(MCOperand::createExpr(getImm()));
475
0
    } else if (isa<MCBinaryExpr>(getImm())) {
476
#ifndef NDEBUG
477
      const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
478
      assert(isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
479
             cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
480
                 LanaiMCExpr::VK_Lanai_ABS_LO);
481
#endif
482
      Inst.addOperand(MCOperand::createExpr(getImm()));
483
0
    } else
484
0
      assert(false && "Operand type not supported.");
485
26
  }
486
487
3
  void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
488
3
    assert(N == 1 && "Invalid number of operands!");
489
3
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
490
3
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
491
3
    else
492
3
      assert(false && "Operand type not supported.");
493
3
  }
494
495
16
  void addHiImm16Operands(MCInst &Inst, unsigned N) const {
496
16
    assert(N == 1 && "Invalid number of operands!");
497
16
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
498
14
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
499
2
    else if (isa<LanaiMCExpr>(getImm())) {
500
#ifndef NDEBUG
501
      const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
502
      assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
503
#endif
504
      Inst.addOperand(MCOperand::createExpr(getImm()));
505
1
    } else if (isa<MCBinaryExpr>(getImm())) {
506
#ifndef NDEBUG
507
      const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
508
      assert(isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
509
             cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
510
                 LanaiMCExpr::VK_Lanai_ABS_HI);
511
#endif
512
      Inst.addOperand(MCOperand::createExpr(getImm()));
513
1
    } else
514
1
      assert(false && "Operand type not supported.");
515
16
  }
516
517
3
  void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
518
3
    assert(N == 1 && "Invalid number of operands!");
519
3
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
520
3
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
521
3
    else
522
3
      assert(false && "Operand type not supported.");
523
3
  }
524
525
1
  void addLoImm21Operands(MCInst &Inst, unsigned N) const {
526
1
    assert(N == 1 && "Invalid number of operands!");
527
1
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
528
1
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
529
0
    else if (isa<LanaiMCExpr>(getImm())) {
530
#ifndef NDEBUG
531
      const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
532
      assert(SymbolRefExpr &&
533
             SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
534
#endif
535
      Inst.addOperand(MCOperand::createExpr(getImm()));
536
0
    } else if (isa<MCSymbolRefExpr>(getImm())) {
537
#ifndef NDEBUG
538
      const MCSymbolRefExpr *SymbolRefExpr =
539
          dyn_cast<MCSymbolRefExpr>(getImm());
540
      assert(SymbolRefExpr &&
541
             SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
542
#endif
543
      Inst.addOperand(MCOperand::createExpr(getImm()));
544
0
    } else if (isa<MCBinaryExpr>(getImm())) {
545
#ifndef NDEBUG
546
      const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
547
      const LanaiMCExpr *SymbolRefExpr =
548
          dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
549
      assert(SymbolRefExpr &&
550
             SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
551
#endif
552
      Inst.addOperand(MCOperand::createExpr(getImm()));
553
0
    } else
554
0
      assert(false && "Operand type not supported.");
555
1
  }
556
557
  void print(raw_ostream &OS) const override {
558
    switch (Kind) {
559
    case IMMEDIATE:
560
      OS << "Imm: " << getImm() << "\n";
561
      break;
562
    case TOKEN:
563
      OS << "Token: " << getToken() << "\n";
564
      break;
565
    case REGISTER:
566
      OS << "Reg: %r" << getReg() << "\n";
567
      break;
568
    case MEMORY_IMM:
569
      OS << "MemImm: " << *getMemOffset() << "\n";
570
      break;
571
    case MEMORY_REG_IMM:
572
      OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
573
      break;
574
    case MEMORY_REG_REG:
575
      assert(getMemOffset() == nullptr);
576
      OS << "MemRegReg: " << getMemBaseReg() << "+"
577
         << "%r" << getMemOffsetReg() << "\n";
578
      break;
579
    }
580
  }
581
582
510
  static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
583
510
    auto Op = make_unique<LanaiOperand>(TOKEN);
584
510
    Op->Tok.Data = Str.data();
585
510
    Op->Tok.Length = Str.size();
586
510
    Op->StartLoc = Start;
587
510
    Op->EndLoc = Start;
588
510
    return Op;
589
510
  }
590
591
  static std::unique_ptr<LanaiOperand> createReg(unsigned RegNum, SMLoc Start,
592
991
                                                 SMLoc End) {
593
991
    auto Op = make_unique<LanaiOperand>(REGISTER);
594
991
    Op->Reg.RegNum = RegNum;
595
991
    Op->StartLoc = Start;
596
991
    Op->EndLoc = End;
597
991
    return Op;
598
991
  }
599
600
  static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
601
394
                                                 SMLoc Start, SMLoc End) {
602
394
    auto Op = make_unique<LanaiOperand>(IMMEDIATE);
603
394
    Op->Imm.Value = Value;
604
394
    Op->StartLoc = Start;
605
394
    Op->EndLoc = End;
606
394
    return Op;
607
394
  }
608
609
  static std::unique_ptr<LanaiOperand>
610
5
  MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
611
5
    const MCExpr *Imm = Op->getImm();
612
5
    Op->Kind = MEMORY_IMM;
613
5
    Op->Mem.BaseReg = 0;
614
5
    Op->Mem.AluOp = LPAC::ADD;
615
5
    Op->Mem.OffsetReg = 0;
616
5
    Op->Mem.Offset = Imm;
617
5
    return Op;
618
5
  }
619
620
  static std::unique_ptr<LanaiOperand>
621
  MorphToMemRegReg(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
622
127
                   unsigned AluOp) {
623
127
    unsigned OffsetReg = Op->getReg();
624
127
    Op->Kind = MEMORY_REG_REG;
625
127
    Op->Mem.BaseReg = BaseReg;
626
127
    Op->Mem.AluOp = AluOp;
627
127
    Op->Mem.OffsetReg = OffsetReg;
628
127
    Op->Mem.Offset = nullptr;
629
127
    return Op;
630
127
  }
631
632
  static std::unique_ptr<LanaiOperand>
633
  MorphToMemRegImm(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
634
167
                   unsigned AluOp) {
635
167
    const MCExpr *Imm = Op->getImm();
636
167
    Op->Kind = MEMORY_REG_IMM;
637
167
    Op->Mem.BaseReg = BaseReg;
638
167
    Op->Mem.AluOp = AluOp;
639
167
    Op->Mem.OffsetReg = 0;
640
167
    Op->Mem.Offset = Imm;
641
167
    return Op;
642
167
  }
643
};
644
645
} // end anonymous namespace
646
647
3
bool LanaiAsmParser::ParseDirective(AsmToken /*DirectiveId*/) { return true; }
648
649
bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
650
                                             OperandVector &Operands,
651
                                             MCStreamer &Out,
652
                                             uint64_t &ErrorInfo,
653
481
                                             bool MatchingInlineAsm) {
654
481
  MCInst Inst;
655
481
  SMLoc ErrorLoc;
656
481
657
481
  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
658
481
  case Match_Success:
659
481
    Out.EmitInstruction(Inst, SubtargetInfo);
660
481
    Opcode = Inst.getOpcode();
661
481
    return false;
662
481
  case Match_MissingFeature:
663
0
    return Error(IdLoc, "Instruction use requires option to be enabled");
664
481
  case Match_MnemonicFail:
665
0
    return Error(IdLoc, "Unrecognized instruction mnemonic");
666
481
  case Match_InvalidOperand: {
667
0
    ErrorLoc = IdLoc;
668
0
    if (ErrorInfo != ~0U) {
669
0
      if (ErrorInfo >= Operands.size())
670
0
        return Error(IdLoc, "Too few operands for instruction");
671
0
672
0
      ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
673
0
      if (ErrorLoc == SMLoc())
674
0
        ErrorLoc = IdLoc;
675
0
    }
676
0
    return Error(ErrorLoc, "Invalid operand for instruction");
677
0
  }
678
0
  default:
679
0
    break;
680
0
  }
681
0
682
0
  llvm_unreachable("Unknown match type detected!");
683
0
}
684
685
// Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
686
// backwards compatible with GCC and the different ways inline assembly is
687
// handled.
688
// TODO: see if there isn't a better way to do this.
689
1.39k
std::unique_ptr<LanaiOperand> LanaiAsmParser::parseRegister() {
690
1.39k
  SMLoc Start = Parser.getTok().getLoc();
691
1.39k
  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
692
1.39k
693
1.39k
  unsigned RegNum;
694
1.39k
  // Eat the '%'.
695
1.39k
  if (Lexer.getKind() == AsmToken::Percent)
696
991
    Parser.Lex();
697
1.39k
  if (Lexer.getKind() == AsmToken::Identifier) {
698
996
    RegNum = MatchRegisterName(Lexer.getTok().getIdentifier());
699
996
    if (RegNum == 0)
700
5
      return nullptr;
701
991
    Parser.Lex(); // Eat identifier token
702
991
    return LanaiOperand::createReg(RegNum, Start, End);
703
991
  }
704
395
  return nullptr;
705
395
}
706
707
bool LanaiAsmParser::ParseRegister(unsigned &RegNum, SMLoc &StartLoc,
708
0
                                   SMLoc &EndLoc) {
709
0
  const AsmToken &Tok = getParser().getTok();
710
0
  StartLoc = Tok.getLoc();
711
0
  EndLoc = Tok.getEndLoc();
712
0
  std::unique_ptr<LanaiOperand> Op = parseRegister();
713
0
  if (Op != nullptr)
714
0
    RegNum = Op->getReg();
715
0
  return (Op == nullptr);
716
0
}
717
718
5
std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
719
5
  SMLoc Start = Parser.getTok().getLoc();
720
5
  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
721
5
  const MCExpr *Res, *RHS = nullptr;
722
5
  LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None;
723
5
724
5
  if (Lexer.getKind() != AsmToken::Identifier)
725
0
    return nullptr;
726
5
727
5
  StringRef Identifier;
728
5
  if (Parser.parseIdentifier(Identifier))
729
0
    return nullptr;
730
5
731
5
  // Check if identifier has a modifier
732
5
  if (Identifier.equals_lower("hi"))
733
2
    Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
734
3
  else if (Identifier.equals_lower("lo"))
735
0
    Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
736
5
737
5
  // If the identifier corresponds to a variant then extract the real
738
5
  // identifier.
739
5
  if (Kind != LanaiMCExpr::VK_Lanai_None) {
740
2
    if (Lexer.getKind() != AsmToken::LParen) {
741
0
      Error(Lexer.getLoc(), "Expected '('");
742
0
      return nullptr;
743
0
    }
744
2
    Lexer.Lex(); // lex '('
745
2
746
2
    // Parse identifier
747
2
    if (Parser.parseIdentifier(Identifier))
748
0
      return nullptr;
749
5
  }
750
5
751
5
  // If addition parse the RHS.
752
5
  if (Lexer.getKind() == AsmToken::Plus && 
Parser.parseExpression(RHS)1
)
753
0
    return nullptr;
754
5
755
5
  // For variants parse the final ')'
756
5
  if (Kind != LanaiMCExpr::VK_Lanai_None) {
757
2
    if (Lexer.getKind() != AsmToken::RParen) {
758
0
      Error(Lexer.getLoc(), "Expected ')'");
759
0
      return nullptr;
760
0
    }
761
2
    Lexer.Lex(); // lex ')'
762
2
  }
763
5
764
5
  End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
765
5
  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
766
5
  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
767
5
  Res = LanaiMCExpr::create(Kind, Expr, getContext());
768
5
769
5
  // Nest if this was an addition
770
5
  if (RHS)
771
1
    Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
772
5
773
5
  return LanaiOperand::createImm(Res, Start, End);
774
5
}
775
776
400
std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
777
400
  SMLoc Start = Parser.getTok().getLoc();
778
400
  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
779
400
780
400
  const MCExpr *ExprVal;
781
400
  switch (Lexer.getKind()) {
782
400
  case AsmToken::Identifier:
783
5
    return parseIdentifier();
784
400
  case AsmToken::Plus:
785
238
  case AsmToken::Minus:
786
238
  case AsmToken::Integer:
787
238
  case AsmToken::Dot:
788
238
    if (!Parser.parseExpression(ExprVal))
789
238
      return LanaiOperand::createImm(ExprVal, Start, End);
790
0
    LLVM_FALLTHROUGH;
791
157
  default:
792
157
    return nullptr;
793
400
  }
794
400
}
795
796
291
static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
797
291
  if (PreOp)
798
99
    return LPAC::makePreOp(AluCode);
799
192
  if (PostOp)
800
102
    return LPAC::makePostOp(AluCode);
801
90
  return AluCode;
802
90
}
803
804
108
unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
805
108
  StringRef IdString;
806
108
  Parser.parseIdentifier(IdString);
807
108
  unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
808
108
  if (AluCode == LPAC::UNKNOWN) {
809
0
    Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
810
0
    return 0;
811
0
  }
812
108
  return AluCode;
813
108
}
814
815
37
static int SizeForSuffix(StringRef T) {
816
37
  return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
817
37
}
818
819
491
bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
820
491
  bool PreOrPost = false;
821
491
  if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
822
37
    PreOrPost = true;
823
37
    if (Lexer.is(AsmToken::Minus))
824
19
      *OffsetValue = -SizeForSuffix(Type);
825
18
    else if (Lexer.is(AsmToken::Plus))
826
18
      *OffsetValue = SizeForSuffix(Type);
827
0
    else
828
0
      return false;
829
37
830
37
    // Eat the '-' '-' or '+' '+'
831
37
    Parser.Lex();
832
37
    Parser.Lex();
833
454
  } else if (Lexer.is(AsmToken::Star)) {
834
164
    Parser.Lex(); // Eat the '*'
835
164
    PreOrPost = true;
836
164
  }
837
491
838
491
  return PreOrPost;
839
491
}
840
841
8
bool shouldBeSls(const LanaiOperand &Op) {
842
8
  // The instruction should be encoded as an SLS if the constant is word
843
8
  // aligned and will fit in 21 bits
844
8
  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
845
8
    int64_t Value = ConstExpr->getValue();
846
8
    return (Value % 4 == 0) && 
(Value >= 0)7
&&
(Value <= 0x1fffff)6
;
847
8
  }
848
0
  // The instruction should be encoded as an SLS if the operand is a symbolic
849
0
  // reference with no variant.
850
0
  if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
851
0
    return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
852
0
  // The instruction should be encoded as an SLS if the operand is a binary
853
0
  // expression with the left-hand side being a symbolic reference with no
854
0
  // variant.
855
0
  if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
856
0
    const LanaiMCExpr *LHSSymbolRefExpr =
857
0
        dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
858
0
    return (LHSSymbolRefExpr &&
859
0
            LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
860
0
  }
861
0
  return false;
862
0
}
863
864
// Matches memory operand. Returns true if error encountered.
865
OperandMatchResultTy
866
299
LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
867
299
  // Try to match a memory operand.
868
299
  // The memory operands are of the form:
869
299
  //  (1)  Register|Immediate|'' '[' '*'? Register '*'? ']' or
870
299
  //                            ^
871
299
  //  (2)  '[' '*'? Register '*'? AluOperator Register ']'
872
299
  //      ^
873
299
  //  (3)  '[' '--'|'++' Register '--'|'++' ']'
874
299
  //
875
299
  //  (4) '[' Immediate ']' (for SLS)
876
299
877
299
  // Store the type for use in parsing pre/post increment/decrement operators
878
299
  StringRef Type;
879
299
  if (Operands[0]->isToken())
880
299
    Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
881
299
882
299
  // Use 0 if no offset given
883
299
  int OffsetValue = 0;
884
299
  unsigned BaseReg = 0;
885
299
  unsigned AluOp = LPAC::ADD;
886
299
  bool PostOp = false, PreOp = false;
887
299
888
299
  // Try to parse the offset
889
299
  std::unique_ptr<LanaiOperand> Op = parseRegister();
890
299
  if (!Op)
891
280
    Op = parseImmediate();
892
299
893
299
  // Only continue if next token is '['
894
299
  if (Lexer.isNot(AsmToken::LBrac)) {
895
0
    if (!Op)
896
0
      return MatchOperand_NoMatch;
897
0
898
0
    // The start of this custom parsing overlaps with register/immediate so
899
0
    // consider this as a successful match of an operand of that type as the
900
0
    // token stream can't be rewound to allow them to match separately.
901
0
    Operands.push_back(std::move(Op));
902
0
    return MatchOperand_Success;
903
0
  }
904
299
905
299
  Parser.Lex(); // Eat the '['.
906
299
  std::unique_ptr<LanaiOperand> Offset = nullptr;
907
299
  if (Op)
908
142
    Offset.swap(Op);
909
299
910
299
  // Determine if a pre operation
911
299
  PreOp = parsePrePost(Type, &OffsetValue);
912
299
913
299
  Op = parseRegister();
914
299
  if (!Op) {
915
8
    if (!Offset) {
916
8
      if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
917
8
        Parser.Lex(); // Eat the ']'
918
8
919
8
        // Memory address operations aligned to word boundary are encoded as
920
8
        // SLS, the rest as RM.
921
8
        if (shouldBeSls(*Op)) {
922
5
          Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
923
5
        } else {
924
3
          if (!Op->isLoImm16Signed()) {
925
0
            Error(Parser.getTok().getLoc(),
926
0
                  "Memory address is not word "
927
0
                  "aligned and larger than class RM can handle");
928
0
            return MatchOperand_ParseFail;
929
0
          }
930
3
          Operands.push_back(LanaiOperand::MorphToMemRegImm(
931
3
              Lanai::R0, std::move(Op), LPAC::ADD));
932
3
        }
933
8
        return MatchOperand_Success;
934
0
      }
935
8
    }
936
0
937
0
    Error(Parser.getTok().getLoc(),
938
0
          "Unknown operand, expected register or immediate");
939
0
    return MatchOperand_ParseFail;
940
0
  }
941
291
  BaseReg = Op->getReg();
942
291
943
291
  // Determine if a post operation
944
291
  if (!PreOp)
945
192
    PostOp = parsePrePost(Type, &OffsetValue);
946
291
947
291
  // If ] match form (1) else match form (2)
948
291
  if (Lexer.is(AsmToken::RBrac)) {
949
183
    Parser.Lex(); // Eat the ']'.
950
183
    if (!Offset) {
951
41
      SMLoc Start = Parser.getTok().getLoc();
952
41
      SMLoc End =
953
41
          SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
954
41
      const MCConstantExpr *OffsetConstExpr =
955
41
          MCConstantExpr::create(OffsetValue, getContext());
956
41
      Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
957
41
    }
958
183
  } else {
959
108
    if (Offset || OffsetValue != 0) {
960
0
      Error(Parser.getTok().getLoc(), "Expected ']'");
961
0
      return MatchOperand_ParseFail;
962
0
    }
963
108
964
108
    // Parse operator
965
108
    AluOp = parseAluOperator(PreOp, PostOp);
966
108
967
108
    // Second form requires offset register
968
108
    Offset = parseRegister();
969
108
    if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
970
0
      Error(Parser.getTok().getLoc(), "Expected ']'");
971
0
      return MatchOperand_ParseFail;
972
0
    }
973
108
    Parser.Lex(); // Eat the ']'.
974
108
  }
975
291
976
291
  // First form has addition as operator. Add pre- or post-op indicator as
977
291
  // needed.
978
291
  AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
979
291
980
291
  // Ensure immediate offset is not too large
981
291
  if (Offset->isImm() && 
!Offset->isLoImm16Signed()164
) {
982
0
    Error(Parser.getTok().getLoc(),
983
0
          "Memory address is not word "
984
0
          "aligned and larger than class RM can handle");
985
0
    return MatchOperand_ParseFail;
986
0
  }
987
291
988
291
  Operands.push_back(
989
291
      Offset->isImm()
990
291
          ? 
LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)164
991
291
          : 
LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp)127
);
992
291
993
291
  return MatchOperand_Success;
994
291
}
995
996
// Looks at a token type and creates the relevant operand from this
997
// information, adding to operands.
998
// If operand was parsed, returns false, else true.
999
OperandMatchResultTy
1000
984
LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
1001
984
  // Check if the current operand has a custom associated parser, if so, try to
1002
984
  // custom parse the operand, or fallback to the general approach.
1003
984
  OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);
1004
984
1005
984
  if (Result == MatchOperand_Success)
1006
299
    return Result;
1007
685
  if (Result == MatchOperand_ParseFail) {
1008
0
    Parser.eatToEndOfStatement();
1009
0
    return Result;
1010
0
  }
1011
685
1012
685
  // Attempt to parse token as register
1013
685
  std::unique_ptr<LanaiOperand> Op = parseRegister();
1014
685
1015
685
  // Attempt to parse token as immediate
1016
685
  if (!Op)
1017
112
    Op = parseImmediate();
1018
685
1019
685
  // If the token could not be parsed then fail
1020
685
  if (!Op) {
1021
0
    Error(Parser.getTok().getLoc(), "Unknown operand");
1022
0
    Parser.eatToEndOfStatement();
1023
0
    return MatchOperand_ParseFail;
1024
0
  }
1025
685
1026
685
  // Push back parsed operand into list of operands
1027
685
  Operands->push_back(std::move(Op));
1028
685
1029
685
  return MatchOperand_Success;
1030
685
}
1031
1032
// Split the mnemonic into ASM operand, conditional code and instruction
1033
// qualifier (half-word, byte).
1034
StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1035
481
                                        OperandVector *Operands) {
1036
481
  size_t Next = Name.find('.');
1037
481
1038
481
  StringRef Mnemonic = Name;
1039
481
1040
481
  bool IsBRR = false;
1041
481
  if (Name.endswith(".r")) {
1042
20
    Mnemonic = Name.substr(0, Name.size() - 2);
1043
20
    IsBRR = true;
1044
20
  }
1045
481
1046
481
  // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1047
481
  if (Mnemonic[0] == 'b' ||
1048
481
      
(432
Mnemonic[0] == 's'432
&&
!Mnemonic.startswith("sel")222
&&
1049
432
       
!Mnemonic.startswith("st")204
)) {
1050
104
    // Parse instructions with a conditional code. For example, 'bne' is
1051
104
    // converted into two operands 'b' and 'ne'.
1052
104
    LPCC::CondCode CondCode =
1053
104
        LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1054
104
    if (CondCode != LPCC::UNKNOWN) {
1055
68
      Mnemonic = Mnemonic.slice(0, 1);
1056
68
      Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1057
68
      Operands->push_back(LanaiOperand::createImm(
1058
68
          MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1059
68
      if (IsBRR) {
1060
20
        Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1061
20
      }
1062
68
      return Mnemonic;
1063
68
    }
1064
413
  }
1065
413
1066
413
  // Parse other instructions with condition codes (RR instructions).
1067
413
  // We ignore .f here and assume they are flag-setting operations, not
1068
413
  // conditional codes (except for select instructions where flag-setting
1069
413
  // variants are not yet implemented).
1070
413
  if (Mnemonic.startswith("sel") ||
1071
413
      
(395
!Mnemonic.endswith(".f")395
&&
!Mnemonic.startswith("st")357
)) {
1072
226
    LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
1073
226
    if (CondCode != LPCC::UNKNOWN) {
1074
22
      size_t Next = Mnemonic.rfind('.', Name.size());
1075
22
      // 'sel' doesn't use a predicate operand whose printer adds the period,
1076
22
      // but instead has the period as part of the identifier (i.e., 'sel.' is
1077
22
      // expected by the generated matcher). If the mnemonic starts with 'sel'
1078
22
      // then include the period as part of the mnemonic, else don't include it
1079
22
      // as part of the mnemonic.
1080
22
      if (Mnemonic.startswith("sel")) {
1081
18
        Mnemonic = Mnemonic.substr(0, Next + 1);
1082
18
      } else {
1083
4
        Mnemonic = Mnemonic.substr(0, Next);
1084
4
      }
1085
22
      Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1086
22
      Operands->push_back(LanaiOperand::createImm(
1087
22
          MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1088
22
      return Mnemonic;
1089
22
    }
1090
391
  }
1091
391
1092
391
  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1093
391
  if (IsBRR) {
1094
0
    Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1095
0
  }
1096
391
1097
391
  return Mnemonic;
1098
391
}
1099
1100
478
static bool IsMemoryAssignmentError(const OperandVector &Operands) {
1101
478
  // Detects if a memory operation has an erroneous base register modification.
1102
478
  // Memory operations are detected by matching the types of operands.
1103
478
  //
1104
478
  // TODO: This test is focussed on one specific instance (ld/st).
1105
478
  // Extend it to handle more cases or be more robust.
1106
478
  bool Modifies = false;
1107
478
1108
478
  int Offset = 0;
1109
478
1110
478
  if (Operands.size() < 5)
1111
456
    return false;
1112
22
  else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1113
22
           
Operands[2]->isImm()0
&&
Operands[3]->isImm()0
&&
Operands[4]->isReg()0
)
1114
0
    Offset = 0;
1115
22
  else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1116
22
           
Operands[2]->isReg()0
&&
Operands[3]->isImm()0
&&
1117
22
           
Operands[4]->isImm()0
&&
Operands[5]->isReg()0
)
1118
0
    Offset = 1;
1119
22
  else
1120
22
    return false;
1121
0
1122
0
  int PossibleAluOpIdx = Offset + 3;
1123
0
  int PossibleBaseIdx = Offset + 1;
1124
0
  int PossibleDestIdx = Offset + 4;
1125
0
  if (LanaiOperand *PossibleAluOp =
1126
0
          static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1127
0
    if (PossibleAluOp->isImm())
1128
0
      if (const MCConstantExpr *ConstExpr =
1129
0
              dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1130
0
        Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1131
0
  return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1132
0
         Operands[PossibleDestIdx]->isReg() &&
1133
0
         Operands[PossibleBaseIdx]->getReg() ==
1134
0
             Operands[PossibleDestIdx]->getReg();
1135
0
}
1136
1137
192
static bool IsRegister(const MCParsedAsmOperand &op) {
1138
192
  return static_cast<const LanaiOperand &>(op).isReg();
1139
192
}
1140
1141
478
static bool MaybePredicatedInst(const OperandVector &Operands) {
1142
478
  if (Operands.size() < 4 || 
!IsRegister(*Operands[1])117
||
1143
478
      
!IsRegister(*Operands[2])75
)
1144
459
    return false;
1145
19
  return StringSwitch<bool>(
1146
19
             static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1147
19
      .StartsWith("addc", true)
1148
19
      .StartsWith("add", true)
1149
19
      .StartsWith("and", true)
1150
19
      .StartsWith("sh", true)
1151
19
      .StartsWith("subb", true)
1152
19
      .StartsWith("sub", true)
1153
19
      .StartsWith("or", true)
1154
19
      .StartsWith("xor", true)
1155
19
      .Default(false);
1156
19
}
1157
1158
bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo & /*Info*/,
1159
                                      StringRef Name, SMLoc NameLoc,
1160
481
                                      OperandVector &Operands) {
1161
481
  // First operand is token for instruction
1162
481
  StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1163
481
1164
481
  // If there are no more operands, then finish
1165
481
  if (Lexer.is(AsmToken::EndOfStatement))
1166
3
    return false;
1167
478
1168
478
  // Parse first operand
1169
478
  if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1170
0
    return true;
1171
478
1172
478
  // If it is a st instruction with one 1 operand then it is a "store true".
1173
478
  // Transform <"st"> to <"s">, <LPCC:ICC_T>
1174
478
  if (Lexer.is(AsmToken::EndOfStatement) && 
Name == "st"69
&&
1175
478
      
Operands.size() == 21
) {
1176
1
    Operands.erase(Operands.begin(), Operands.begin() + 1);
1177
1
    Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1178
1
    Operands.insert(Operands.begin() + 1,
1179
1
                    LanaiOperand::createImm(
1180
1
                        MCConstantExpr::create(LPCC::ICC_T, getContext()),
1181
1
                        NameLoc, NameLoc));
1182
1
  }
1183
478
1184
478
  // If the instruction is a bt instruction with 1 operand (in assembly) then it
1185
478
  // is an unconditional branch instruction and the first two elements of
1186
478
  // operands need to be merged.
1187
478
  if (Lexer.is(AsmToken::EndOfStatement) && 
Name.startswith("bt")69
&&
1188
478
      
Operands.size() == 39
) {
1189
8
    Operands.erase(Operands.begin(), Operands.begin() + 2);
1190
8
    Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1191
8
  }
1192
478
1193
478
  // Parse until end of statement, consuming commas between operands
1194
984
  while (Lexer.isNot(AsmToken::EndOfStatement) && 
Lexer.is(AsmToken::Comma)506
) {
1195
506
    // Consume comma token
1196
506
    Lex();
1197
506
1198
506
    // Parse next operand
1199
506
    if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1200
0
      return true;
1201
506
  }
1202
478
1203
478
  if (IsMemoryAssignmentError(Operands)) {
1204
0
    Error(Parser.getTok().getLoc(),
1205
0
          "the destination register can't equal the base register in an "
1206
0
          "instruction that modifies the base register.");
1207
0
    return true;
1208
0
  }
1209
478
1210
478
  // Insert always true operand for instruction that may be predicated but
1211
478
  // are not. Currently the autogenerated parser always expects a predicate.
1212
478
  if (MaybePredicatedInst(Operands)) {
1213
19
    Operands.insert(Operands.begin() + 1,
1214
19
                    LanaiOperand::createImm(
1215
19
                        MCConstantExpr::create(LPCC::ICC_T, getContext()),
1216
19
                        NameLoc, NameLoc));
1217
19
  }
1218
478
1219
478
  return false;
1220
478
}
1221
1222
#define GET_REGISTER_MATCHER
1223
#define GET_MATCHER_IMPLEMENTATION
1224
#include "LanaiGenAsmMatcher.inc"
1225
1226
91.7k
extern "C" void LLVMInitializeLanaiAsmParser() {
1227
91.7k
  RegisterMCAsmParser<LanaiAsmParser> x(getTheLanaiTarget());
1228
91.7k
}