Coverage Report

Created: 2026-10-28 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/keystone/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
Line
Count
Source
1
//===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst 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
#define DEBUG_TYPE "mcasmparser"
11
12
#include "Hexagon.h"
13
#include "HexagonTargetStreamer.h"
14
#include "MCTargetDesc/HexagonBaseInfo.h"
15
#include "MCTargetDesc/HexagonMCAsmInfo.h"
16
#include "MCTargetDesc/HexagonMCChecker.h"
17
#include "MCTargetDesc/HexagonMCExpr.h"
18
#include "MCTargetDesc/HexagonMCShuffler.h"
19
#include "MCTargetDesc/HexagonMCTargetDesc.h"
20
#include "MCTargetDesc/HexagonShuffler.h"
21
#include "llvm/ADT/SmallString.h"
22
#include "llvm/ADT/SmallVector.h"
23
#include "llvm/ADT/StringExtras.h"
24
#include "llvm/ADT/Twine.h"
25
#include "llvm/MC/MCContext.h"
26
#include "llvm/MC/MCELFStreamer.h"
27
#include "llvm/MC/MCExpr.h"
28
#include "llvm/MC/MCInst.h"
29
#include "llvm/MC/MCParser/MCAsmLexer.h"
30
#include "llvm/MC/MCParser/MCAsmParser.h"
31
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
32
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
33
#include "llvm/MC/MCSectionELF.h"
34
#include "llvm/MC/MCStreamer.h"
35
#include "llvm/MC/MCSubtargetInfo.h"
36
#include "llvm/Support/Debug.h"
37
#include "llvm/Support/ELF.h"
38
#include "llvm/Support/Format.h"
39
#include "llvm/Support/MemoryBuffer.h"
40
#include "llvm/Support/SourceMgr.h"
41
#include "llvm/Support/TargetRegistry.h"
42
#include "llvm/Support/raw_ostream.h"
43
#include <sstream>
44
45
#include "keystone/hexagon.h"
46
47
using namespace llvm_ks;
48
49
static bool WarnMissingParenthesis = true;
50
static bool ErrorMissingParenthesis = false;
51
static bool WarnSignedMismatch = true;
52
static bool WarnNoncontigiousRegister = true;
53
static bool ErrorNoncontigiousRegister = false;
54
55
namespace {
56
struct HexagonOperand;
57
58
class HexagonAsmParser : public MCTargetAsmParser {
59
60
0
  HexagonTargetStreamer &getTargetStreamer() {
61
0
    MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
62
0
    return static_cast<HexagonTargetStreamer &>(TS);
63
0
  }
64
65
  MCAsmParser &Parser;
66
  MCAssembler *Assembler;
67
  MCInstrInfo const &MCII;
68
  MCInst MCB;
69
  bool InBrackets;
70
71
2.86M
  MCAsmParser &getParser() const { return Parser; }
72
0
  MCAssembler *getAssembler() const { return Assembler; }
73
10.6M
  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
74
75
7.08k
  bool equalIsAsmAssignment() override { return false; }
76
  bool isLabel(AsmToken &Token, bool &valid) override;
77
78
4.17k
  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
79
987
  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
80
  bool ParseDirectiveFalign(unsigned Size, SMLoc L);
81
82
  virtual bool ParseRegister(unsigned &RegNo,
83
                             SMLoc &StartLoc,
84
                             SMLoc &EndLoc, unsigned int &ErrorCode) override;
85
  bool ParseDirectiveSubsection(SMLoc L);
86
  bool ParseDirectiveValue(unsigned Size, SMLoc L);
87
  bool ParseDirectiveComm(bool IsLocal, SMLoc L);
88
  bool RegisterMatchesArch(unsigned MatchNum) const;
89
90
  bool matchBundleOptions();
91
  bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
92
  bool finishBundle(SMLoc IDLoc, MCStreamer &Out, unsigned &KsError);
93
  void canonicalizeImmediates(MCInst &MCI);
94
  bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
95
                           OperandVector &InstOperands, uint64_t &ErrorInfo,
96
                           bool MatchingInlineAsm, bool &MustExtend, unsigned int &ErrorCode);
97
98
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
99
                               OperandVector &Operands, MCStreamer &Out,
100
                               uint64_t &ErrorInfo, bool MatchingInlineAsm, unsigned int &ErrorCode, uint64_t &Address) override;
101
102
  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind) override;
103
  void OutOfRange(SMLoc IDLoc, long long Val, long long Max);
104
  int processInstruction(MCInst &Inst, OperandVector const &Operands,
105
                         SMLoc IDLoc, bool &MustExtend);
106
107
  // Check if we have an assembler and, if so, set the ELF e_header flags.
108
0
  void chksetELFHeaderEFlags(unsigned flags) {
109
0
    if (getAssembler())
110
0
      getAssembler()->setELFHeaderEFlags(flags);
111
0
  }
112
113
/// @name Auto-generated Match Functions
114
/// {
115
116
#define GET_ASSEMBLER_HEADER
117
#include "HexagonGenAsmMatcher.inc"
118
119
  /// }
120
121
public:
122
  HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
123
                   const MCInstrInfo &MII, const MCTargetOptions &Options)
124
4.80k
    : MCTargetAsmParser(Options, _STI), Parser(_Parser),
125
4.80k
      MCII (MII), MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) {
126
4.80k
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
127
128
4.80k
  MCAsmParserExtension::Initialize(_Parser);
129
130
4.80k
  Assembler = nullptr;
131
  // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
132
4.80k
  if (!Parser.getStreamer().hasRawTextSupport()) {
133
4.80k
    MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
134
4.80k
    Assembler = &MES->getAssembler();
135
4.80k
  }
136
4.80k
  }
137
138
  bool mustExtend(OperandVector &Operands);
139
  bool splitIdentifier(OperandVector &Operands);
140
  bool parseOperand(OperandVector &Operands);
141
  bool parseInstruction(OperandVector &Operands);
142
  bool implicitExpressionLocation(OperandVector &Operands);
143
  bool parseExpressionOrOperand(OperandVector &Operands);
144
  bool parseExpression(MCExpr const *& Expr);
145
  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
146
                                SMLoc NameLoc, OperandVector &Operands, unsigned int &ErrorCode) override
147
0
  {
148
0
    llvm_unreachable("Unimplemented");
149
0
  }
150
  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
151
                                AsmToken ID, OperandVector &Operands, unsigned int &ErrorCode) override;
152
153
  virtual bool ParseDirective(AsmToken DirectiveID) override;
154
};
155
156
/// HexagonOperand - Instances of this class represent a parsed Hexagon machine
157
/// instruction.
158
struct HexagonOperand : public MCParsedAsmOperand {
159
  enum KindTy { Token, Immediate, Register } Kind;
160
161
  SMLoc StartLoc, EndLoc;
162
163
  struct TokTy {
164
    const char *Data;
165
    unsigned Length;
166
  };
167
168
  struct RegTy {
169
    unsigned RegNum;
170
  };
171
172
  struct ImmTy {
173
    const MCExpr *Val;
174
    bool MustExtend;
175
  };
176
177
  struct InstTy {
178
    OperandVector *SubInsts;
179
  };
180
181
  union {
182
    struct TokTy Tok;
183
    struct RegTy Reg;
184
    struct ImmTy Imm;
185
  };
186
187
1.92M
  HexagonOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
188
189
public:
190
0
  HexagonOperand(const HexagonOperand &o) : MCParsedAsmOperand() {
191
0
    Kind = o.Kind;
192
0
    StartLoc = o.StartLoc;
193
0
    EndLoc = o.EndLoc;
194
0
    switch (Kind) {
195
0
    case Register:
196
0
      Reg = o.Reg;
197
0
      break;
198
0
    case Immediate:
199
0
      Imm = o.Imm;
200
0
      break;
201
0
    case Token:
202
0
      Tok = o.Tok;
203
0
      break;
204
0
    }
205
0
  }
206
207
  /// getStartLoc - Get the location of the first token of this operand.
208
0
  SMLoc getStartLoc() const { return StartLoc; }
209
210
  /// getEndLoc - Get the location of the last token of this operand.
211
0
  SMLoc getEndLoc() const { return EndLoc; }
212
213
543k
  unsigned getReg() const {
214
543k
    assert(Kind == Register && "Invalid access!");
215
543k
    return Reg.RegNum;
216
543k
  }
217
218
12.7k
  const MCExpr *getImm() const {
219
12.7k
    assert(Kind == Immediate && "Invalid access!");
220
12.7k
    return Imm.Val;
221
12.7k
  }
222
223
11.2M
  bool isToken() const { return Kind == Token; }
224
32.8k
  bool isImm() const { return Kind == Immediate; }
225
0
  bool isMem() const { llvm_unreachable("No isMem"); }
226
536k
  bool isReg() const { return Kind == Register; }
227
228
  bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
229
4.79k
                     bool isRelocatable, bool Extendable) const {
230
4.79k
    if (Kind == Immediate) {
231
4.79k
      const MCExpr *myMCExpr = getImm();
232
4.79k
      if (Imm.MustExtend && !Extendable)
233
22
        return false;
234
4.77k
      int64_t Res;
235
4.77k
      if (myMCExpr->evaluateAsAbsolute(Res)) {
236
4.46k
        int bits = immBits + zeroBits;
237
        // Field bit range is zerobits + bits
238
        // zeroBits must be 0
239
4.46k
        if (Res & ((1 << zeroBits) - 1))
240
0
          return false;
241
4.46k
        if (isSigned) {
242
4.40k
          if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
243
4.37k
            return true;
244
4.40k
        } else {
245
52
          if (bits == 64)
246
29
            return true;
247
23
          if (Res >= 0)
248
9
            return ((uint64_t)Res < (uint64_t)(1ULL << bits)) ? true : false;
249
14
          else {
250
14
            const int64_t high_bit_set = 1ULL << 63;
251
14
            const uint64_t mask = (high_bit_set >> (63 - bits));
252
14
            return (((uint64_t)Res & mask) == mask) ? true : false;
253
14
          }
254
23
        }
255
4.46k
      } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
256
58
        return true;
257
255
      else if (myMCExpr->getKind() == MCExpr::Binary ||
258
139
               myMCExpr->getKind() == MCExpr::Unary)
259
254
        return true;
260
4.77k
    }
261
33
    return false;
262
4.79k
  }
263
264
0
  bool isf32Ext() const { return false; }
265
0
  bool iss32Imm() const { return CheckImmRange(32, 0, true, true, false); }
266
0
  bool iss8Imm() const { return CheckImmRange(8, 0, true, false, false); }
267
58
  bool iss8Imm64() const { return CheckImmRange(8, 0, true, true, false); }
268
0
  bool iss7Imm() const { return CheckImmRange(7, 0, true, false, false); }
269
0
  bool iss6Imm() const { return CheckImmRange(6, 0, true, false, false); }
270
0
  bool iss4Imm() const { return CheckImmRange(4, 0, true, false, false); }
271
0
  bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
272
0
  bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
273
0
  bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
274
0
  bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
275
0
  bool iss4_6Imm() const { return CheckImmRange(4, 0, true, false, false); }
276
0
  bool iss3_6Imm() const { return CheckImmRange(3, 0, true, false, false); }
277
0
  bool iss3Imm() const { return CheckImmRange(3, 0, true, false, false); }
278
279
45
  bool isu64Imm() const { return CheckImmRange(64, 0, false, true, true); }
280
0
  bool isu32Imm() const { return CheckImmRange(32, 0, false, true, false); }
281
0
  bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
282
18
  bool isu16Imm() const { return CheckImmRange(16, 0, false, true, false); }
283
0
  bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
284
0
  bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
285
0
  bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
286
0
  bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
287
0
  bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
288
0
  bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
289
0
  bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
290
0
  bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
291
0
  bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
292
13
  bool isu10Imm() const { return CheckImmRange(10, 0, false, false, false); }
293
0
  bool isu9Imm() const { return CheckImmRange(9, 0, false, false, false); }
294
0
  bool isu8Imm() const { return CheckImmRange(8, 0, false, false, false); }
295
0
  bool isu7Imm() const { return CheckImmRange(7, 0, false, false, false); }
296
23
  bool isu6Imm() const { return CheckImmRange(6, 0, false, false, false); }
297
0
  bool isu5Imm() const { return CheckImmRange(5, 0, false, false, false); }
298
0
  bool isu4Imm() const { return CheckImmRange(4, 0, false, false, false); }
299
0
  bool isu3Imm() const { return CheckImmRange(3, 0, false, false, false); }
300
0
  bool isu2Imm() const { return CheckImmRange(2, 0, false, false, false); }
301
0
  bool isu1Imm() const { return CheckImmRange(1, 0, false, false, false); }
302
303
0
  bool ism6Imm() const { return CheckImmRange(6, 0, false, false, false); }
304
0
  bool isn8Imm() const { return CheckImmRange(8, 0, false, false, false); }
305
306
4.63k
  bool iss16Ext() const { return CheckImmRange(16 + 26, 0, true, true, true); }
307
3
  bool iss12Ext() const { return CheckImmRange(12 + 26, 0, true, true, true); }
308
0
  bool iss10Ext() const { return CheckImmRange(10 + 26, 0, true, true, true); }
309
0
  bool iss9Ext() const { return CheckImmRange(9 + 26, 0, true, true, true); }
310
0
  bool iss8Ext() const { return CheckImmRange(8 + 26, 0, true, true, true); }
311
0
  bool iss7Ext() const { return CheckImmRange(7 + 26, 0, true, true, true); }
312
0
  bool iss6Ext() const { return CheckImmRange(6 + 26, 0, true, true, true); }
313
0
  bool iss11_0Ext() const {
314
0
    return CheckImmRange(11 + 26, 0, true, true, true);
315
0
  }
316
0
  bool iss11_1Ext() const {
317
0
    return CheckImmRange(11 + 26, 1, true, true, true);
318
0
  }
319
0
  bool iss11_2Ext() const {
320
0
    return CheckImmRange(11 + 26, 2, true, true, true);
321
0
  }
322
0
  bool iss11_3Ext() const {
323
0
    return CheckImmRange(11 + 26, 3, true, true, true);
324
0
  }
325
326
0
  bool isu6Ext() const { return CheckImmRange(6 + 26, 0, false, true, true); }
327
0
  bool isu7Ext() const { return CheckImmRange(7 + 26, 0, false, true, true); }
328
0
  bool isu8Ext() const { return CheckImmRange(8 + 26, 0, false, true, true); }
329
0
  bool isu9Ext() const { return CheckImmRange(9 + 26, 0, false, true, true); }
330
0
  bool isu10Ext() const { return CheckImmRange(10 + 26, 0, false, true, true); }
331
0
  bool isu6_0Ext() const { return CheckImmRange(6 + 26, 0, false, true, true); }
332
0
  bool isu6_1Ext() const { return CheckImmRange(6 + 26, 1, false, true, true); }
333
0
  bool isu6_2Ext() const { return CheckImmRange(6 + 26, 2, false, true, true); }
334
0
  bool isu6_3Ext() const { return CheckImmRange(6 + 26, 3, false, true, true); }
335
0
  bool isu32MustExt() const { return isImm() && Imm.MustExtend; }
336
337
7.12k
  void addRegOperands(MCInst &Inst, unsigned N) const {
338
7.12k
    assert(N == 1 && "Invalid number of operands!");
339
7.12k
    Inst.addOperand(MCOperand::createReg(getReg()));
340
7.12k
  }
341
342
3.28k
  void addImmOperands(MCInst &Inst, unsigned N) const {
343
3.28k
    assert(N == 1 && "Invalid number of operands!");
344
3.28k
    Inst.addOperand(MCOperand::createExpr(getImm()));
345
3.28k
  }
346
347
4.62k
  void addSignedImmOperands(MCInst &Inst, unsigned N) const {
348
4.62k
    assert(N == 1 && "Invalid number of operands!");
349
4.62k
    MCExpr const *Expr = getImm();
350
4.62k
    int64_t Value;
351
4.62k
    if (!Expr->evaluateAsAbsolute(Value)) {
352
262
      Inst.addOperand(MCOperand::createExpr(Expr));
353
262
      return;
354
262
    }
355
4.36k
    int64_t Extended = SignExtend64 (Value, 32);
356
4.36k
    if ((Extended < 0) == (Value < 0)) {
357
4.36k
      Inst.addOperand(MCOperand::createExpr(Expr));
358
4.36k
      return;
359
4.36k
    }
360
    // Flip bit 33 to signal signed unsigned mismatch
361
2
    Extended ^= 0x100000000;
362
2
    Inst.addOperand(MCOperand::createImm(Extended));
363
2
  }
364
365
0
  void addf32ExtOperands(MCInst &Inst, unsigned N) const {
366
0
    addImmOperands(Inst, N);
367
0
  }
368
369
0
  void adds32ImmOperands(MCInst &Inst, unsigned N) const {
370
0
    addSignedImmOperands(Inst, N);
371
0
  }
372
0
  void adds8ImmOperands(MCInst &Inst, unsigned N) const {
373
0
    addSignedImmOperands(Inst, N);
374
0
  }
375
13
  void adds8Imm64Operands(MCInst &Inst, unsigned N) const {
376
13
    addSignedImmOperands(Inst, N);
377
13
  }
378
0
  void adds6ImmOperands(MCInst &Inst, unsigned N) const {
379
0
    addSignedImmOperands(Inst, N);
380
0
  }
381
0
  void adds4ImmOperands(MCInst &Inst, unsigned N) const {
382
0
    addSignedImmOperands(Inst, N);
383
0
  }
384
0
  void adds4_0ImmOperands(MCInst &Inst, unsigned N) const {
385
0
    addSignedImmOperands(Inst, N);
386
0
  }
387
0
  void adds4_1ImmOperands(MCInst &Inst, unsigned N) const {
388
0
    addSignedImmOperands(Inst, N);
389
0
  }
390
0
  void adds4_2ImmOperands(MCInst &Inst, unsigned N) const {
391
0
    addSignedImmOperands(Inst, N);
392
0
  }
393
0
  void adds4_3ImmOperands(MCInst &Inst, unsigned N) const {
394
0
    addSignedImmOperands(Inst, N);
395
0
  }
396
0
  void adds3ImmOperands(MCInst &Inst, unsigned N) const {
397
0
    addSignedImmOperands(Inst, N);
398
0
  }
399
400
43
  void addu64ImmOperands(MCInst &Inst, unsigned N) const {
401
43
    addImmOperands(Inst, N);
402
43
  }
403
0
  void addu32ImmOperands(MCInst &Inst, unsigned N) const {
404
0
    addImmOperands(Inst, N);
405
0
  }
406
0
  void addu26_6ImmOperands(MCInst &Inst, unsigned N) const {
407
0
    addImmOperands(Inst, N);
408
0
  }
409
16
  void addu16ImmOperands(MCInst &Inst, unsigned N) const {
410
16
    addImmOperands(Inst, N);
411
16
  }
412
0
  void addu16_0ImmOperands(MCInst &Inst, unsigned N) const {
413
0
    addImmOperands(Inst, N);
414
0
  }
415
0
  void addu16_1ImmOperands(MCInst &Inst, unsigned N) const {
416
0
    addImmOperands(Inst, N);
417
0
  }
418
0
  void addu16_2ImmOperands(MCInst &Inst, unsigned N) const {
419
0
    addImmOperands(Inst, N);
420
0
  }
421
0
  void addu16_3ImmOperands(MCInst &Inst, unsigned N) const {
422
0
    addImmOperands(Inst, N);
423
0
  }
424
0
  void addu11_3ImmOperands(MCInst &Inst, unsigned N) const {
425
0
    addImmOperands(Inst, N);
426
0
  }
427
4
  void addu10ImmOperands(MCInst &Inst, unsigned N) const {
428
4
    addImmOperands(Inst, N);
429
4
  }
430
0
  void addu9ImmOperands(MCInst &Inst, unsigned N) const {
431
0
    addImmOperands(Inst, N);
432
0
  }
433
0
  void addu8ImmOperands(MCInst &Inst, unsigned N) const {
434
0
    addImmOperands(Inst, N);
435
0
  }
436
0
  void addu7ImmOperands(MCInst &Inst, unsigned N) const {
437
0
    addImmOperands(Inst, N);
438
0
  }
439
0
  void addu6ImmOperands(MCInst &Inst, unsigned N) const {
440
0
    addImmOperands(Inst, N);
441
0
  }
442
0
  void addu6_0ImmOperands(MCInst &Inst, unsigned N) const {
443
0
    addImmOperands(Inst, N);
444
0
  }
445
0
  void addu6_1ImmOperands(MCInst &Inst, unsigned N) const {
446
0
    addImmOperands(Inst, N);
447
0
  }
448
0
  void addu6_2ImmOperands(MCInst &Inst, unsigned N) const {
449
0
    addImmOperands(Inst, N);
450
0
  }
451
0
  void addu6_3ImmOperands(MCInst &Inst, unsigned N) const {
452
0
    addImmOperands(Inst, N);
453
0
  }
454
0
  void addu5ImmOperands(MCInst &Inst, unsigned N) const {
455
0
    addImmOperands(Inst, N);
456
0
  }
457
0
  void addu4ImmOperands(MCInst &Inst, unsigned N) const {
458
0
    addImmOperands(Inst, N);
459
0
  }
460
0
  void addu3ImmOperands(MCInst &Inst, unsigned N) const {
461
0
    addImmOperands(Inst, N);
462
0
  }
463
0
  void addu2ImmOperands(MCInst &Inst, unsigned N) const {
464
0
    addImmOperands(Inst, N);
465
0
  }
466
0
  void addu1ImmOperands(MCInst &Inst, unsigned N) const {
467
0
    addImmOperands(Inst, N);
468
0
  }
469
470
0
  void addm6ImmOperands(MCInst &Inst, unsigned N) const {
471
0
    addImmOperands(Inst, N);
472
0
  }
473
0
  void addn8ImmOperands(MCInst &Inst, unsigned N) const {
474
0
    addImmOperands(Inst, N);
475
0
  }
476
477
4.61k
  void adds16ExtOperands(MCInst &Inst, unsigned N) const {
478
4.61k
    addSignedImmOperands(Inst, N);
479
4.61k
  }
480
2
  void adds12ExtOperands(MCInst &Inst, unsigned N) const {
481
2
    addSignedImmOperands(Inst, N);
482
2
  }
483
0
  void adds10ExtOperands(MCInst &Inst, unsigned N) const {
484
0
    addSignedImmOperands(Inst, N);
485
0
  }
486
0
  void adds9ExtOperands(MCInst &Inst, unsigned N) const {
487
0
    addSignedImmOperands(Inst, N);
488
0
  }
489
0
  void adds8ExtOperands(MCInst &Inst, unsigned N) const {
490
0
    addSignedImmOperands(Inst, N);
491
0
  }
492
0
  void adds6ExtOperands(MCInst &Inst, unsigned N) const {
493
0
    addSignedImmOperands(Inst, N);
494
0
  }
495
0
  void adds11_0ExtOperands(MCInst &Inst, unsigned N) const {
496
0
    addSignedImmOperands(Inst, N);
497
0
  }
498
0
  void adds11_1ExtOperands(MCInst &Inst, unsigned N) const {
499
0
    addSignedImmOperands(Inst, N);
500
0
  }
501
0
  void adds11_2ExtOperands(MCInst &Inst, unsigned N) const {
502
0
    addSignedImmOperands(Inst, N);
503
0
  }
504
0
  void adds11_3ExtOperands(MCInst &Inst, unsigned N) const {
505
0
    addSignedImmOperands(Inst, N);
506
0
  }
507
508
0
  void addu6ExtOperands(MCInst &Inst, unsigned N) const {
509
0
    addImmOperands(Inst, N);
510
0
  }
511
0
  void addu7ExtOperands(MCInst &Inst, unsigned N) const {
512
0
    addImmOperands(Inst, N);
513
0
  }
514
0
  void addu8ExtOperands(MCInst &Inst, unsigned N) const {
515
0
    addImmOperands(Inst, N);
516
0
  }
517
0
  void addu9ExtOperands(MCInst &Inst, unsigned N) const {
518
0
    addImmOperands(Inst, N);
519
0
  }
520
0
  void addu10ExtOperands(MCInst &Inst, unsigned N) const {
521
0
    addImmOperands(Inst, N);
522
0
  }
523
0
  void addu6_0ExtOperands(MCInst &Inst, unsigned N) const {
524
0
    addImmOperands(Inst, N);
525
0
  }
526
0
  void addu6_1ExtOperands(MCInst &Inst, unsigned N) const {
527
0
    addImmOperands(Inst, N);
528
0
  }
529
0
  void addu6_2ExtOperands(MCInst &Inst, unsigned N) const {
530
0
    addImmOperands(Inst, N);
531
0
  }
532
0
  void addu6_3ExtOperands(MCInst &Inst, unsigned N) const {
533
0
    addImmOperands(Inst, N);
534
0
  }
535
0
  void addu32MustExtOperands(MCInst &Inst, unsigned N) const {
536
0
    addImmOperands(Inst, N);
537
0
  }
538
539
0
  void adds4_6ImmOperands(MCInst &Inst, unsigned N) const {
540
0
    assert(N == 1 && "Invalid number of operands!");
541
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
542
0
    Inst.addOperand(MCOperand::createImm(CE->getValue() * 64));
543
0
  }
544
545
0
  void adds3_6ImmOperands(MCInst &Inst, unsigned N) const {
546
0
    assert(N == 1 && "Invalid number of operands!");
547
0
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
548
0
    Inst.addOperand(MCOperand::createImm(CE->getValue() * 64));
549
0
  }
550
551
9.86M
  StringRef getToken() const {
552
9.86M
    assert(Kind == Token && "Invalid access!");
553
9.86M
    return StringRef(Tok.Data, Tok.Length);
554
9.86M
  }
555
556
  virtual void print(raw_ostream &OS) const;
557
558
1.69M
  static std::unique_ptr<HexagonOperand> CreateToken(StringRef Str, SMLoc S) {
559
1.69M
    HexagonOperand *Op = new HexagonOperand(Token);
560
1.69M
    Op->Tok.Data = Str.data();
561
1.69M
    Op->Tok.Length = Str.size();
562
1.69M
    Op->StartLoc = S;
563
1.69M
    Op->EndLoc = S;
564
1.69M
    return std::unique_ptr<HexagonOperand>(Op);
565
1.69M
  }
566
567
  static std::unique_ptr<HexagonOperand> CreateReg(unsigned RegNum, SMLoc S,
568
50.3k
                                                   SMLoc E) {
569
50.3k
    HexagonOperand *Op = new HexagonOperand(Register);
570
50.3k
    Op->Reg.RegNum = RegNum;
571
50.3k
    Op->StartLoc = S;
572
50.3k
    Op->EndLoc = E;
573
50.3k
    return std::unique_ptr<HexagonOperand>(Op);
574
50.3k
  }
575
576
  static std::unique_ptr<HexagonOperand> CreateImm(const MCExpr *Val, SMLoc S,
577
176k
                                                   SMLoc E) {
578
176k
    HexagonOperand *Op = new HexagonOperand(Immediate);
579
176k
    Op->Imm.Val = Val;
580
176k
    Op->Imm.MustExtend = false;
581
176k
    Op->StartLoc = S;
582
176k
    Op->EndLoc = E;
583
176k
    return std::unique_ptr<HexagonOperand>(Op);
584
176k
  }
585
};
586
587
} // end anonymous namespace.
588
589
0
void HexagonOperand::print(raw_ostream &OS) const {
590
0
  switch (Kind) {
591
0
  case Immediate:
592
0
    getImm()->print(OS, nullptr);
593
0
    break;
594
0
  case Register:
595
0
    OS << "<register R";
596
0
    OS << getReg() << ">";
597
0
    break;
598
0
  case Token:
599
0
    OS << "'" << getToken() << "'";
600
0
    break;
601
0
  }
602
0
}
603
604
/// @name Auto-generated Match Functions
605
static unsigned MatchRegisterName(StringRef Name);
606
607
bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out, unsigned &KsError)
608
6.61k
{
609
6.61k
  DEBUG(dbgs() << "Bundle:");
610
6.61k
  DEBUG(MCB.dump_pretty(dbgs()));
611
6.61k
  DEBUG(dbgs() << "--\n");
612
613
  // Check the bundle for errors.
614
6.61k
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
615
6.61k
  HexagonMCChecker Check(MCII, getSTI(), MCB, MCB, *RI);
616
617
6.61k
  bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MCII, getSTI(),
618
6.61k
                                                        getContext(), MCB,
619
6.61k
                                                        &Check);
620
621
7.32k
  while (Check.getNextErrInfo() == true) {
622
710
    unsigned Reg = Check.getErrRegister();
623
710
    Twine R(RI->getName(Reg));
624
625
710
    uint64_t Err = Check.getError();
626
710
    if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
627
710
      if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
628
45
        Error(IDLoc,
629
45
              "unconditional branch cannot precede another branch in packet");
630
631
710
      if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
632
710
          HexagonMCErrInfo::CHECK_ERROR_NEWV & Err)
633
0
        Error(IDLoc, "register `" + R +
634
0
                         "' used with `.new' "
635
0
                         "but not validly modified in the same packet");
636
637
710
      if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
638
96
        Error(IDLoc, "register `" + R + "' modified more than once");
639
640
710
      if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
641
375
        Error(IDLoc, "cannot write to read-only register `" + R + "'");
642
643
710
      if (HexagonMCErrInfo::CHECK_ERROR_LOOP & Err)
644
0
        Error(IDLoc, "loop-setup and some branch instructions "
645
0
                     "cannot be in the same packet");
646
647
710
      if (HexagonMCErrInfo::CHECK_ERROR_ENDLOOP & Err) {
648
0
        Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
649
0
        Error(IDLoc, "packet marked with `:endloop" + N + "' " +
650
0
                         "cannot contain instructions that modify register " +
651
0
                         "`" + R + "'");
652
0
      }
653
654
710
      if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
655
0
        Error(IDLoc,
656
0
              "instruction cannot appear in packet with other instructions");
657
658
710
      if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
659
92
        Error(IDLoc, "too many slots used in packet");
660
661
710
      if (Err & HexagonMCErrInfo::CHECK_ERROR_SHUFFLE) {
662
102
        uint64_t Erm = Check.getShuffleError();
663
664
102
        if (HexagonShuffler::SHUFFLE_ERROR_INVALID == Erm)
665
0
          Error(IDLoc, "invalid instruction packet");
666
102
        else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
667
0
          Error(IDLoc, "invalid instruction packet: too many stores");
668
102
        else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
669
0
          Error(IDLoc, "invalid instruction packet: too many loads");
670
102
        else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
671
32
          Error(IDLoc, "too many branches in packet");
672
70
        else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
673
0
          Error(IDLoc, "invalid instruction packet: out of slots");
674
70
        else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
675
70
          Error(IDLoc, "invalid instruction packet: slot error");
676
0
        else if (HexagonShuffler::SHUFFLE_ERROR_ERRATA2 == Erm)
677
0
          Error(IDLoc, "v60 packet violation");
678
0
        else if (HexagonShuffler::SHUFFLE_ERROR_STORE_LOAD_CONFLICT == Erm)
679
0
          Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
680
0
        else
681
0
          Error(IDLoc, "unknown error in instruction packet");
682
102
      }
683
710
    }
684
685
710
    unsigned Warn = Check.getWarning();
686
710
    if (Warn != HexagonMCErrInfo::CHECK_SUCCESS) {
687
0
      if (HexagonMCErrInfo::CHECK_WARN_CURRENT & Warn)
688
0
        Warning(IDLoc, "register `" + R + "' used with `.cur' "
689
0
                                          "but not used in the same packet");
690
0
      else if (HexagonMCErrInfo::CHECK_WARN_TEMPORARY & Warn)
691
0
        Warning(IDLoc, "register `" + R + "' used with `.tmp' "
692
0
                                          "but not used in the same packet");
693
0
    }
694
710
  }
695
696
6.61k
  if (CheckOk) {
697
6.13k
    MCB.setLoc(IDLoc);
698
6.13k
    if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
699
1.38k
      assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
700
1.38k
      assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
701
      // Empty packets are valid yet aren't emitted
702
1.38k
      return false;
703
1.38k
    }
704
4.75k
    Out.EmitInstruction(MCB, getSTI(), KsError);
705
4.75k
    if (KsError) {
706
3
        return true;
707
3
    }
708
4.75k
  } else {
709
    // If compounding and duplexing didn't reduce the size below
710
    // 4 or less we have a packet that is too big.
711
479
    if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
712
93
      Error(IDLoc, "invalid instruction packet: out of slots");
713
93
      return true; // Error
714
93
    }
715
479
  }
716
717
5.13k
  return false; // No error
718
6.61k
}
719
720
2.33k
bool HexagonAsmParser::matchBundleOptions() {
721
2.33k
  MCAsmParser &Parser = getParser();
722
2.33k
  MCAsmLexer &Lexer = getLexer();
723
2.33k
  while (true) {
724
2.33k
    if (!Parser.getTok().is(AsmToken::Colon))
725
2.33k
      return false;
726
1
    Lexer.Lex();
727
1
    StringRef Option = Parser.getTok().getString();
728
1
    if (Option.compare_lower("endloop0") == 0)
729
0
      HexagonMCInstrInfo::setInnerLoop(MCB);
730
1
    else if (Option.compare_lower("endloop1") == 0)
731
0
      HexagonMCInstrInfo::setOuterLoop(MCB);
732
1
    else if (Option.compare_lower("mem_noshuf") == 0)
733
0
      HexagonMCInstrInfo::setMemReorderDisabled(MCB);
734
1
    else if (Option.compare_lower("mem_shuf") == 0)
735
0
      HexagonMCInstrInfo::setMemStoreReorderEnabled(MCB);
736
1
    else
737
1
      return true;
738
0
    Lexer.Lex();
739
0
  }
740
2.33k
}
741
742
// For instruction aliases, immediates are generated rather than
743
// MCConstantExpr.  Convert them for uniform MCExpr.
744
// Also check for signed/unsigned mismatches and warn
745
9.68k
void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
746
9.68k
  MCInst NewInst;
747
9.68k
  NewInst.setOpcode(MCI.getOpcode());
748
9.68k
  for (MCOperand &I : MCI)
749
15.0k
    if (I.isImm()) {
750
2
      int64_t Value (I.getImm());
751
2
      if ((Value & 0x100000000) != (Value & 0x80000000)) {
752
        // Detect flipped bit 33 wrt bit 32 and signal warning
753
2
        Value ^= 0x100000000;
754
2
        if (WarnSignedMismatch)
755
2
          Warning (MCI.getLoc(), "Signed/Unsigned mismatch");
756
2
      }
757
2
      NewInst.addOperand(MCOperand::createExpr(
758
2
          MCConstantExpr::create(Value, getContext())));
759
2
    }
760
15.0k
    else
761
15.0k
      NewInst.addOperand(I);
762
9.68k
  MCI = NewInst;
763
9.68k
}
764
765
bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
766
                                           OperandVector &InstOperands,
767
                                           uint64_t &ErrorInfo,
768
                                           bool MatchingInlineAsm,
769
                                           bool &MustExtend, unsigned int &ErrorCode)
770
11.0k
{
771
  // Perform matching with tablegen asmmatcher generated function
772
11.0k
  int result =
773
11.0k
      MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
774
11.0k
  if (result == Match_Success) {
775
9.68k
    MCI.setLoc(IDLoc);
776
9.68k
    MustExtend = mustExtend(InstOperands);
777
9.68k
    canonicalizeImmediates(MCI);
778
9.68k
    result = processInstruction(MCI, InstOperands, IDLoc, MustExtend);
779
780
9.68k
    DEBUG(dbgs() << "Insn:");
781
9.68k
    DEBUG(MCI.dump_pretty(dbgs()));
782
9.68k
    DEBUG(dbgs() << "\n\n");
783
784
9.68k
    MCI.setLoc(IDLoc);
785
9.68k
  }
786
787
  // Create instruction operand for bundle instruction
788
  //   Break this into a separate function Code here is less readable
789
  //   Think about how to get an instruction error to report correctly.
790
  //   SMLoc will return the "{"
791
11.0k
  switch (result) {
792
0
  default:
793
0
    break;
794
9.68k
  case Match_Success:
795
9.68k
    return false;
796
0
  case Match_MissingFeature:
797
    // return Error(IDLoc, "invalid instruction");
798
0
    ErrorCode = KS_ERR_ASM_HEXAGON_MISSINGFEATURE;
799
0
    return true;
800
695
  case Match_MnemonicFail:
801
    // return Error(IDLoc, "unrecognized instruction");
802
695
    ErrorCode = KS_ERR_ASM_HEXAGON_MNEMONICFAIL;
803
695
    return true;
804
688
  case Match_InvalidOperand:
805
#if 0
806
    SMLoc ErrorLoc = IDLoc;
807
    if (ErrorInfo != ~0U) {
808
      if (ErrorInfo >= InstOperands.size()) {
809
        // return Error(IDLoc, "too few operands for instruction");
810
      }
811
812
      ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
813
                     ->getStartLoc();
814
      if (ErrorLoc == SMLoc())
815
        ErrorLoc = IDLoc;
816
    }
817
#endif
818
    // return Error(ErrorLoc, "invalid operand for instruction");
819
688
    ErrorCode = KS_ERR_ASM_HEXAGON_INVALIDOPERAND;
820
688
    return true;
821
11.0k
  }
822
11.0k
  llvm_unreachable("Implement any new match types added!");
823
11.0k
}
824
825
9.68k
bool HexagonAsmParser::mustExtend(OperandVector &Operands) {
826
9.68k
  unsigned Count = 0;
827
9.68k
  for (std::unique_ptr<MCParsedAsmOperand> &i : Operands)
828
29.5k
    if (i->isImm())
829
7.91k
      if (static_cast<HexagonOperand *>(i.get())->Imm.MustExtend)
830
4.51k
        ++Count;
831
  // Multiple extenders should have been filtered by iss9Ext et. al.
832
9.68k
  assert(Count < 2 && "Multiple extenders");
833
9.68k
  return Count == 1;
834
9.68k
}
835
836
bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
837
                                               OperandVector &Operands,
838
                                               MCStreamer &Out,
839
                                               uint64_t &ErrorInfo,
840
                                               bool MatchingInlineAsm, unsigned int &ErrorCode, uint64_t &Address)
841
15.9k
{
842
15.9k
  if (!InBrackets) {
843
8.15k
    MCB.clear();
844
8.15k
    MCB.addOperand(MCOperand::createImm(0));
845
8.15k
  }
846
15.9k
  if (Operands.size() == 0) {
847
88
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
848
88
      return true;
849
88
  }
850
15.8k
  HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
851
15.8k
  if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
852
2.43k
    assert(Operands.size() == 1 && "Brackets should be by themselves");
853
2.43k
    if (InBrackets) {
854
      //getParser().Error(IDLoc, "Already in a packet");
855
0
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
856
0
      return true;
857
0
    }
858
2.43k
    InBrackets = true;
859
2.43k
    return false;
860
2.43k
  }
861
13.4k
  if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
862
2.35k
    assert(Operands.size() == 1 && "Brackets should be by themselves");
863
2.35k
    if (!InBrackets) {
864
      //getParser().Error(IDLoc, "Not in a packet");
865
17
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
866
17
      return true;
867
17
    }
868
2.33k
    InBrackets = false;
869
2.33k
    if (matchBundleOptions()) {
870
1
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
871
1
      return true;
872
1
    }
873
2.33k
    return finishBundle(IDLoc, Out, ErrorCode);
874
2.33k
  }
875
11.0k
  MCInst *SubInst = new (getParser().getContext()) MCInst;
876
11.0k
  bool MustExtend = false;
877
11.0k
  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
878
11.0k
                          MatchingInlineAsm, MustExtend, ErrorCode)) {
879
1.38k
    ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
880
1.38k
    return true;
881
1.38k
  }
882
9.68k
  HexagonMCInstrInfo::extendIfNeeded(
883
9.68k
      getParser().getContext(), MCII, MCB, *SubInst,
884
9.68k
      HexagonMCInstrInfo::isExtended(MCII, *SubInst) || MustExtend);
885
9.68k
  MCB.addOperand(MCOperand::createInst(SubInst));
886
9.68k
  if (!InBrackets)
887
4.27k
    return finishBundle(IDLoc, Out, ErrorCode);
888
5.40k
  return false;
889
9.68k
}
890
891
/// ParseDirective parses the Hexagon specific directives
892
338k
bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
893
338k
  StringRef IDVal = DirectiveID.getIdentifier();
894
338k
  if ((IDVal.lower() == ".word") || (IDVal.lower() == ".4byte"))
895
18.9k
    return ParseDirectiveValue(4, DirectiveID.getLoc());
896
320k
  if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
897
319k
      IDVal.lower() == ".half")
898
75
    return ParseDirectiveValue(2, DirectiveID.getLoc());
899
319k
  if (IDVal.lower() == ".falign")
900
0
    return ParseDirectiveFalign(256, DirectiveID.getLoc());
901
319k
  if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
902
241
    return ParseDirectiveComm(true, DirectiveID.getLoc());
903
319k
  if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
904
4.02k
    return ParseDirectiveComm(false, DirectiveID.getLoc());
905
315k
  if (IDVal.lower() == ".subsection")
906
0
    return ParseDirectiveSubsection(DirectiveID.getLoc());
907
908
315k
  return true;
909
315k
}
910
0
bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
911
0
  const MCExpr *Subsection = 0;
912
0
  int64_t Res;
913
914
0
  assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
915
0
         "Invalid subsection directive");
916
0
  getParser().parseExpression(Subsection);
917
918
0
  if (!Subsection->evaluateAsAbsolute(Res))
919
0
    return Error(L, "Cannot evaluate subsection number");
920
921
0
  if (getLexer().isNot(AsmToken::EndOfStatement))
922
0
    return TokError("unexpected token in directive");
923
924
  // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
925
  // negative subsections together and in the same order but at the opposite
926
  // end of the section.  Only legacy hexagon-gcc created assembly code
927
  // used negative subsections.
928
0
  if ((Res < 0) && (Res > -8193))
929
0
    Subsection = MCConstantExpr::create(8192 + Res, this->getContext());
930
931
0
  getStreamer().SubSection(Subsection);
932
0
  return false;
933
0
}
934
935
///  ::= .falign [expression]
936
0
bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
937
938
0
  int64_t MaxBytesToFill = 15;
939
940
  // if there is an arguement
941
0
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
942
0
    const MCExpr *Value;
943
0
    SMLoc ExprLoc = L;
944
945
    // Make sure we have a number (false is returned if expression is a number)
946
0
    if (getParser().parseExpression(Value) == false) {
947
      // Make sure this is a number that is in range
948
0
      const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
949
0
      uint64_t IntValue = MCE->getValue();
950
0
      if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
951
0
        return Error(ExprLoc, "literal value out of range (256) for falign");
952
0
      MaxBytesToFill = IntValue;
953
0
      Lex();
954
0
    } else {
955
0
      return Error(ExprLoc, "not a valid expression for falign directive");
956
0
    }
957
0
  }
958
959
0
  getTargetStreamer().emitFAlign(16, MaxBytesToFill);
960
0
  Lex();
961
962
0
  return false;
963
0
}
964
965
///  ::= .word [ expression (, expression)* ]
966
bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L)
967
19.0k
{
968
19.0k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
969
970
59.1k
    for (;;) {
971
59.1k
      const MCExpr *Value;
972
      //SMLoc ExprLoc = L;
973
59.1k
      if (getParser().parseExpression(Value))
974
277
        return true;
975
976
      // Special case constant expressions to match code generator.
977
58.8k
      if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
978
12.5k
        bool Error;
979
        //assert(Size <= 8 && "Invalid size");
980
12.5k
        if (Size > 8)
981
0
            return true;
982
12.5k
        uint64_t IntValue = MCE->getValue();
983
12.5k
        if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
984
          //return Error(ExprLoc, "literal value out of range for directive");
985
270
          return true;
986
12.2k
        getStreamer().EmitIntValue(IntValue, Size, Error);
987
12.2k
        if (Error) {
988
0
            return true;
989
0
        }
990
12.2k
      } else
991
46.3k
        getStreamer().EmitValue(Value, Size);
992
993
58.5k
      if (getLexer().is(AsmToken::EndOfStatement))
994
16.4k
        break;
995
996
      // FIXME: Improve diagnostic.
997
42.1k
      if (getLexer().isNot(AsmToken::Comma))
998
        //return TokError("unexpected token in directive");
999
2.02k
        return true;
1000
40.1k
      Lex();
1001
40.1k
    }
1002
18.9k
  }
1003
1004
16.4k
  Lex();
1005
16.4k
  return false;
1006
19.0k
}
1007
1008
// This is largely a copy of AsmParser's ParseDirectiveComm extended to
1009
// accept a 3rd argument, AccessAlignment which indicates the smallest
1010
// memory access made to the symbol, expressed in bytes.  If no
1011
// AccessAlignment is specified it defaults to the Alignment Value.
1012
// Hexagon's .lcomm:
1013
//   .lcomm Symbol, Length, Alignment, AccessAlignment
1014
4.27k
bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
1015
  // FIXME: need better way to detect if AsmStreamer (upstream removed
1016
  // getKind())
1017
4.27k
  if (getStreamer().hasRawTextSupport())
1018
0
    return true; // Only object file output requires special treatment.
1019
1020
4.27k
  StringRef Name;
1021
4.27k
  if (getParser().parseIdentifier(Name))
1022
634
    return TokError("expected identifier in directive");
1023
  // Handle the identifier as the key symbol.
1024
3.63k
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
1025
1026
3.63k
  if (getLexer().isNot(AsmToken::Comma))
1027
2.44k
    return TokError("unexpected token in directive");
1028
1.19k
  Lex();
1029
1030
1.19k
  int64_t Size;
1031
1.19k
  SMLoc SizeLoc = getLexer().getLoc();
1032
1.19k
  if (getParser().parseAbsoluteExpression(Size))
1033
173
    return true;
1034
1035
1.02k
  int64_t ByteAlignment = 1;
1036
1.02k
  SMLoc ByteAlignmentLoc;
1037
1.02k
  if (getLexer().is(AsmToken::Comma)) {
1038
167
    Lex();
1039
167
    ByteAlignmentLoc = getLexer().getLoc();
1040
167
    if (getParser().parseAbsoluteExpression(ByteAlignment))
1041
12
      return true;
1042
155
    if (!isPowerOf2_64(ByteAlignment))
1043
148
      return Error(ByteAlignmentLoc, "alignment must be a power of 2");
1044
155
  }
1045
1046
863
  int64_t AccessAlignment = 0;
1047
863
  if (getLexer().is(AsmToken::Comma)) {
1048
    // The optional access argument specifies the size of the smallest memory
1049
    //   access to be made to the symbol, expressed in bytes.
1050
2
    SMLoc AccessAlignmentLoc;
1051
2
    Lex();
1052
2
    AccessAlignmentLoc = getLexer().getLoc();
1053
2
    if (getParser().parseAbsoluteExpression(AccessAlignment))
1054
0
      return true;
1055
1056
2
    if (!isPowerOf2_64(AccessAlignment))
1057
0
      return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
1058
2
  }
1059
1060
863
  if (getLexer().isNot(AsmToken::EndOfStatement))
1061
16
    return TokError("unexpected token in '.comm' or '.lcomm' directive");
1062
1063
847
  Lex();
1064
1065
  // NOTE: a size of zero for a .comm should create a undefined symbol
1066
  // but a size of .lcomm creates a bss symbol of size zero.
1067
847
  if (Size < 0)
1068
16
    return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1069
16
                          "be less than zero");
1070
1071
  // NOTE: The alignment in the directive is a power of 2 value, the assembler
1072
  // may internally end up wanting an alignment in bytes.
1073
  // FIXME: Diagnose overflow.
1074
831
  if (ByteAlignment < 0)
1075
0
    return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1076
0
                                   "alignment, can't be less than zero");
1077
1078
831
  if (!Sym->isUndefined())
1079
6
    return Error(Loc, "invalid symbol redefinition");
1080
1081
#if 0
1082
  HexagonMCELFStreamer &HexagonELFStreamer =
1083
      static_cast<HexagonMCELFStreamer &>(getStreamer());
1084
  if (IsLocal) {
1085
    HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
1086
                                                      AccessAlignment);
1087
    return false;
1088
  }
1089
1090
  HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
1091
                                               AccessAlignment);
1092
#endif
1093
825
  return false;
1094
831
}
1095
1096
// validate register against architecture
1097
50.3k
bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
1098
50.3k
  return true;
1099
50.3k
}
1100
1101
// extern "C" void LLVMInitializeHexagonAsmLexer();
1102
1103
/// Force static initialization.
1104
26
extern "C" void LLVMInitializeHexagonAsmParser() {
1105
26
  RegisterMCAsmParser<HexagonAsmParser> X(TheHexagonTarget);
1106
26
}
1107
1108
#define GET_MATCHER_IMPLEMENTATION
1109
#define GET_REGISTER_MATCHER
1110
#include "HexagonGenAsmMatcher.inc"
1111
1112
namespace {
1113
11.0M
bool previousEqual(OperandVector &Operands, size_t Index, StringRef String) {
1114
11.0M
  if (Index >= Operands.size())
1115
556k
    return false;
1116
10.5M
  MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
1117
10.5M
  if (!Operand.isToken())
1118
828k
    return false;
1119
9.69M
  return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
1120
10.5M
}
1121
6.98k
bool previousIsLoop(OperandVector &Operands, size_t Index) {
1122
6.98k
  return previousEqual(Operands, Index, "loop0") ||
1123
5.50k
         previousEqual(Operands, Index, "loop1") ||
1124
5.49k
         previousEqual(Operands, Index, "sp1loop0") ||
1125
5.49k
         previousEqual(Operands, Index, "sp2loop0") ||
1126
5.49k
         previousEqual(Operands, Index, "sp3loop0");
1127
6.98k
}
1128
}
1129
1130
2.48M
bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
1131
2.48M
  AsmToken const &Token = getParser().getTok();
1132
2.48M
  StringRef String = Token.getString();
1133
2.48M
  SMLoc Loc = Token.getLoc();
1134
2.48M
  getLexer().Lex();
1135
2.63M
  do {
1136
2.63M
    std::pair<StringRef, StringRef> HeadTail = String.split('.');
1137
2.63M
    if (!HeadTail.first.empty())
1138
1.26M
      Operands.push_back(HexagonOperand::CreateToken(HeadTail.first, Loc));
1139
2.63M
    if (!HeadTail.second.empty())
1140
144k
      Operands.push_back(HexagonOperand::CreateToken(
1141
144k
          String.substr(HeadTail.first.size(), 1), Loc));
1142
2.63M
    String = HeadTail.second;
1143
2.63M
  } while (!String.empty());
1144
2.48M
  return false;
1145
2.48M
}
1146
1147
2.53M
bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
1148
2.53M
  unsigned Register;
1149
2.53M
  SMLoc Begin;
1150
2.53M
  SMLoc End;
1151
2.53M
  unsigned int ErrorCode;
1152
2.53M
  MCAsmLexer &Lexer = getLexer();
1153
2.53M
  if (!ParseRegister(Register, Begin, End, ErrorCode)) {
1154
50.3k
    if (!ErrorMissingParenthesis)
1155
50.3k
      switch (Register) {
1156
42.7k
      default:
1157
42.7k
        break;
1158
42.7k
      case Hexagon::P0:
1159
5.30k
      case Hexagon::P1:
1160
6.70k
      case Hexagon::P2:
1161
7.57k
      case Hexagon::P3:
1162
7.57k
        if (previousEqual(Operands, 0, "if")) {
1163
375
          if (WarnMissingParenthesis)
1164
375
            Warning (Begin, "Missing parenthesis around predicate register");
1165
375
          static char const *LParen = "(";
1166
375
          static char const *RParen = ")";
1167
375
          Operands.push_back(HexagonOperand::CreateToken(LParen, Begin));
1168
375
          Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
1169
375
          AsmToken MaybeDotNew = Lexer.getTok();
1170
375
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
1171
83
              MaybeDotNew.getString().equals_lower(".new"))
1172
0
            splitIdentifier(Operands);
1173
375
          Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
1174
375
          return false;
1175
375
        }
1176
7.19k
        if (previousEqual(Operands, 0, "!") &&
1177
3.55k
            previousEqual(Operands, 1, "if")) {
1178
2.48k
          if (WarnMissingParenthesis)
1179
2.48k
            Warning (Begin, "Missing parenthesis around predicate register");
1180
2.48k
          static char const *LParen = "(";
1181
2.48k
          static char const *RParen = ")";
1182
2.48k
          Operands.insert(Operands.end () - 1,
1183
2.48k
                          HexagonOperand::CreateToken(LParen, Begin));
1184
2.48k
          Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
1185
2.48k
          AsmToken MaybeDotNew = Lexer.getTok();
1186
2.48k
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
1187
458
              MaybeDotNew.getString().equals_lower(".new"))
1188
0
            splitIdentifier(Operands);
1189
2.48k
          Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
1190
2.48k
          return false;
1191
2.48k
        }
1192
4.71k
        break;
1193
50.3k
      }
1194
47.4k
    Operands.push_back(HexagonOperand::CreateReg(
1195
47.4k
        Register, Begin, End));
1196
47.4k
    return false;
1197
50.3k
  }
1198
2.48M
  return splitIdentifier(Operands);
1199
2.53M
}
1200
1201
434
bool HexagonAsmParser::isLabel(AsmToken &Token, bool &valid) {
1202
434
  valid = true;
1203
434
  MCAsmLexer &Lexer = getLexer();
1204
434
  AsmToken const &Second = Lexer.getTok();
1205
434
  AsmToken Third = Lexer.peekTok();  
1206
434
  if (Third.is(AsmToken::Error)) {
1207
1
      valid = false;
1208
1
      return true;
1209
1
  }
1210
433
  StringRef String = Token.getString();
1211
433
  if (Token.is(AsmToken::TokenKind::LCurly) ||
1212
433
      Token.is(AsmToken::TokenKind::RCurly))
1213
0
    return false;
1214
433
  if (!Token.is(AsmToken::TokenKind::Identifier))
1215
158
    return true;
1216
275
  if (!MatchRegisterName(String.lower()))
1217
134
    return true;
1218
141
  (void)Second;
1219
141
  assert(Second.is(AsmToken::Colon));
1220
141
  StringRef Raw (String.data(), Third.getString().data() - String.data() +
1221
141
                 Third.getString().size());
1222
141
  std::string Collapsed = Raw;
1223
141
  Collapsed.erase(std::remove_if(Collapsed.begin(), Collapsed.end(), isspace),
1224
141
                  Collapsed.end());
1225
141
  StringRef Whole = Collapsed;
1226
141
  std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
1227
141
  if (!MatchRegisterName(DotSplit.first.lower()))
1228
49
    return true;
1229
92
  return false;
1230
141
}
1231
1232
50.3k
bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious, SMLoc &Loc) {
1233
50.3k
  if (!Contigious && ErrorNoncontigiousRegister) {
1234
0
    Error(Loc, "Register name is not contiguous");
1235
0
    return true;
1236
0
  }
1237
50.3k
  if (!Contigious && WarnNoncontigiousRegister)
1238
1.31k
    Warning(Loc, "Register name is not contiguous");
1239
50.3k
  return false;
1240
50.3k
}
1241
1242
2.53M
bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, unsigned int &ErrorCode) {
1243
2.53M
  MCAsmLexer &Lexer = getLexer();
1244
2.53M
  StartLoc = getLexer().getLoc();
1245
2.53M
  SmallVector<AsmToken, 5> Lookahead;
1246
2.53M
  StringRef RawString(Lexer.getTok().getString().data(), 0);
1247
2.53M
  bool Again = Lexer.is(AsmToken::Identifier);
1248
2.53M
  bool NeededWorkaround = false;
1249
3.16M
  while (Again) {
1250
623k
    AsmToken const &Token = Lexer.getTok();
1251
623k
    RawString = StringRef(RawString.data(),
1252
623k
                          Token.getString().data() - RawString.data () +
1253
623k
                          Token.getString().size());
1254
623k
    Lookahead.push_back(Token);
1255
623k
    Lexer.Lex();
1256
623k
    bool Contigious = Lexer.getTok().getString().data() ==
1257
623k
                      Lookahead.back().getString().data() +
1258
623k
                      Lookahead.back().getString().size();
1259
623k
    bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1260
582k
                Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1261
562k
                Lexer.is(AsmToken::Colon);
1262
623k
    bool Workaround = Lexer.is(AsmToken::Colon) ||
1263
584k
                      Lookahead.back().is(AsmToken::Colon);
1264
623k
    Again = (Contigious && Type) || (Workaround && Type);
1265
623k
    NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1266
623k
  }
1267
2.53M
  std::string Collapsed = RawString;
1268
2.53M
  Collapsed.erase(std::remove_if(Collapsed.begin(), Collapsed.end(), isspace),
1269
2.53M
                  Collapsed.end());
1270
2.53M
  StringRef FullString = Collapsed;
1271
2.53M
  std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
1272
2.53M
  unsigned DotReg = MatchRegisterName(DotSplit.first.lower());
1273
2.53M
  if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1274
43.2k
    if (DotSplit.second.empty()) {
1275
39.6k
      RegNo = DotReg;
1276
39.6k
      EndLoc = Lexer.getLoc();
1277
39.6k
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1278
0
        return true;
1279
39.6k
      return false;
1280
39.6k
    } else {
1281
3.61k
      RegNo = DotReg;
1282
3.61k
      size_t First = RawString.find('.');
1283
3.61k
      StringRef DotString (RawString.data() + First, RawString.size() - First);
1284
3.61k
      Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1285
3.61k
      EndLoc = Lexer.getLoc();
1286
3.61k
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1287
0
        return true;
1288
3.61k
      return false;
1289
3.61k
    }
1290
43.2k
  }
1291
2.49M
  std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
1292
2.49M
  unsigned ColonReg = MatchRegisterName(ColonSplit.first.lower());
1293
2.49M
  if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1294
7.11k
    Lexer.UnLex(Lookahead.back());
1295
7.11k
    Lookahead.pop_back();
1296
7.11k
    Lexer.UnLex(Lookahead.back());
1297
7.11k
    Lookahead.pop_back();
1298
7.11k
    RegNo = ColonReg;
1299
7.11k
    EndLoc = Lexer.getLoc();
1300
7.11k
    if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1301
0
      return true;
1302
7.11k
    return false;
1303
7.11k
  }
1304
3.03M
  while (!Lookahead.empty()) {
1305
541k
    Lexer.UnLex(Lookahead.back());
1306
541k
    Lookahead.pop_back();
1307
541k
  }
1308
2.48M
  return true;
1309
2.49M
}
1310
1311
2.71M
bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1312
2.71M
  if (previousEqual(Operands, 0, "call"))
1313
494
    return true;
1314
2.71M
  if (previousEqual(Operands, 0, "jump"))
1315
2.94k
    if (!getLexer().getTok().is(AsmToken::Colon))
1316
2.77k
      return true;
1317
2.71M
  if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1318
1.49k
    return true;
1319
2.71M
  if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1320
315
      (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1321
128
    return true;
1322
2.71M
  return false;
1323
2.71M
}
1324
1325
176k
bool HexagonAsmParser::parseExpression(MCExpr const *& Expr) {
1326
176k
  llvm_ks::SmallVector<AsmToken, 4> Tokens;
1327
176k
  MCAsmLexer &Lexer = getLexer();
1328
176k
  bool Done = false;
1329
176k
  static char const * Comma = ",";
1330
5.18M
  do {
1331
5.18M
    Tokens.emplace_back (Lexer.getTok());
1332
5.18M
    Lexer.Lex();
1333
5.18M
    switch (Tokens.back().getKind())
1334
5.18M
    {
1335
555k
    case AsmToken::TokenKind::Hash:
1336
555k
      if (Tokens.size () > 1)
1337
555k
        if ((Tokens.end () - 2)->getKind() == AsmToken::TokenKind::Plus) {
1338
13.7k
          Tokens.insert(Tokens.end() - 2,
1339
13.7k
                        AsmToken(AsmToken::TokenKind::Comma, Comma));
1340
13.7k
          Done = true;
1341
13.7k
        }
1342
555k
      break;
1343
1.01k
    case AsmToken::TokenKind::RCurly:
1344
162k
    case AsmToken::TokenKind::EndOfStatement:
1345
162k
    case AsmToken::TokenKind::Eof:
1346
162k
      Done = true;
1347
162k
      break;
1348
4.46M
    default:
1349
4.46M
      break;
1350
5.18M
    }
1351
5.18M
  } while (!Done);
1352
5.37M
  while (!Tokens.empty()) {
1353
5.20M
    Lexer.UnLex(Tokens.back());
1354
5.20M
    Tokens.pop_back();
1355
5.20M
  }
1356
176k
  return getParser().parseExpression(Expr);
1357
176k
}
1358
1359
2.54M
bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1360
2.54M
  if (implicitExpressionLocation(Operands)) {
1361
4.44k
    MCAsmParser &Parser = getParser();
1362
4.44k
    SMLoc Loc = Parser.getLexer().getLoc();
1363
4.44k
    std::unique_ptr<HexagonOperand> Expr =
1364
4.44k
        HexagonOperand::CreateImm(nullptr, Loc, Loc);
1365
4.44k
    MCExpr const *& Val = Expr->Imm.Val;
1366
4.44k
    Operands.push_back(std::move(Expr));
1367
4.44k
    return parseExpression(Val);
1368
4.44k
  }
1369
2.53M
  return parseOperand(Operands);
1370
2.54M
}
1371
1372
/// Parse an instruction.
1373
95.4k
bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1374
95.4k
  MCAsmParser &Parser = getParser();
1375
95.4k
  MCAsmLexer &Lexer = getLexer();
1376
2.92M
  while (true) {
1377
2.92M
    AsmToken const &Token = Parser.getTok();
1378
2.92M
    switch (Token.getKind()) {
1379
10.1k
    case AsmToken::EndOfStatement: {
1380
10.1k
      Lexer.Lex();
1381
10.1k
      return false;
1382
0
    }
1383
2.46k
    case AsmToken::LCurly: {
1384
2.46k
      if (!Operands.empty())
1385
27
        return true;
1386
2.43k
      Operands.push_back(
1387
2.43k
          HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
1388
2.43k
      Lexer.Lex();
1389
2.43k
      return false;
1390
2.46k
    }
1391
3.31k
    case AsmToken::RCurly: {
1392
3.31k
      if (Operands.empty()) {
1393
2.35k
        Operands.push_back(
1394
2.35k
            HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
1395
2.35k
        Lexer.Lex();
1396
2.35k
      }
1397
3.31k
      return false;
1398
2.46k
    }
1399
146k
    case AsmToken::Comma: {
1400
146k
      Lexer.Lex();
1401
146k
      continue;
1402
2.46k
    }
1403
860
    case AsmToken::EqualEqual:
1404
1.39k
    case AsmToken::ExclaimEqual:
1405
1.61k
    case AsmToken::GreaterEqual:
1406
32.1k
    case AsmToken::GreaterGreater:
1407
33.9k
    case AsmToken::LessEqual:
1408
50.9k
    case AsmToken::LessLess: {
1409
50.9k
      Operands.push_back(HexagonOperand::CreateToken(
1410
50.9k
          Token.getString().substr(0, 1), Token.getLoc()));
1411
50.9k
      Operands.push_back(HexagonOperand::CreateToken(
1412
50.9k
          Token.getString().substr(1, 1), Token.getLoc()));
1413
50.9k
      Lexer.Lex();
1414
50.9k
      continue;
1415
33.9k
    }
1416
172k
    case AsmToken::Hash: {
1417
172k
      bool MustNotExtend = false;
1418
172k
      bool ImplicitExpression = implicitExpressionLocation(Operands);
1419
172k
      std::unique_ptr<HexagonOperand> Expr = HexagonOperand::CreateImm(
1420
172k
          nullptr, Lexer.getLoc(), Lexer.getLoc());
1421
172k
      if (!ImplicitExpression)
1422
171k
        Operands.push_back(
1423
171k
          HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
1424
172k
      Lexer.Lex();
1425
172k
      bool MustExtend = false;
1426
172k
      bool HiOnly = false;
1427
172k
      bool LoOnly = false;
1428
172k
      if (Lexer.is(AsmToken::Hash)) {
1429
8.30k
        Lexer.Lex();
1430
8.30k
        MustExtend = true;
1431
164k
      } else if (ImplicitExpression)
1432
192
        MustNotExtend = true;
1433
172k
      AsmToken const &Token = Parser.getTok();
1434
172k
      if (Token.is(AsmToken::Identifier)) {
1435
17.1k
        StringRef String = Token.getString();
1436
17.1k
        AsmToken IDToken = Token;
1437
17.1k
        if (String.lower() == "hi") {
1438
65
          HiOnly = true;
1439
17.0k
        } else if (String.lower() == "lo") {
1440
240
          LoOnly = true;
1441
240
        }
1442
17.1k
        if (HiOnly || LoOnly) {
1443
305
          AsmToken LParen = Lexer.peekTok();
1444
305
          if (!LParen.is(AsmToken::LParen)) {
1445
305
            HiOnly = false;
1446
305
            LoOnly = false;
1447
305
          } else {
1448
0
            Lexer.Lex();
1449
0
          }
1450
305
        }
1451
17.1k
      }
1452
172k
      if (parseExpression(Expr->Imm.Val))
1453
79.4k
        return true;
1454
92.8k
      int64_t Value;
1455
92.8k
      MCContext &Context = Parser.getContext();
1456
92.8k
      assert(Expr->Imm.Val != nullptr);
1457
92.8k
      if (Expr->Imm.Val->evaluateAsAbsolute(Value)) {
1458
56.1k
        if (HiOnly)
1459
0
          Expr->Imm.Val = MCBinaryExpr::createLShr(
1460
0
              Expr->Imm.Val, MCConstantExpr::create(16, Context), Context);
1461
56.1k
        if (HiOnly || LoOnly)
1462
0
          Expr->Imm.Val = MCBinaryExpr::createAnd(
1463
0
              Expr->Imm.Val, MCConstantExpr::create(0xffff, Context), Context);
1464
56.1k
      }
1465
92.8k
      if (MustNotExtend)
1466
175
        Expr->Imm.Val = HexagonNoExtendOperand::Create(Expr->Imm.Val, Context);
1467
92.8k
      Expr->Imm.MustExtend = MustExtend;
1468
92.8k
      Operands.push_back(std::move(Expr));
1469
92.8k
      continue;
1470
92.8k
    }
1471
2.54M
    default:
1472
2.54M
      break;
1473
2.92M
    }
1474
2.54M
    if (parseExpressionOrOperand(Operands))
1475
24
      return true;
1476
2.54M
  }
1477
95.4k
}
1478
1479
bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1480
                                        StringRef Name,
1481
                                        AsmToken ID,
1482
95.4k
                                        OperandVector &Operands, unsigned int &ErrorCode) {
1483
95.4k
  getLexer().UnLex(ID);
1484
95.4k
  return parseInstruction(Operands);
1485
95.4k
}
1486
1487
namespace {
1488
MCInst makeCombineInst(int opCode, MCOperand &Rdd,
1489
56
                       MCOperand &MO1, MCOperand &MO2) {
1490
56
  MCInst TmpInst;
1491
56
  TmpInst.setOpcode(opCode);
1492
56
  TmpInst.addOperand(Rdd);
1493
56
  TmpInst.addOperand(MO1);
1494
56
  TmpInst.addOperand(MO2);
1495
1496
56
  return TmpInst;
1497
56
}
1498
}
1499
1500
// Define this matcher function after the auto-generated include so we
1501
// have the match class enum definitions.
1502
unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1503
525k
                                                      unsigned Kind) {
1504
525k
  HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1505
1506
525k
  switch (Kind) {
1507
0
  case MCK_0: {
1508
0
    int64_t Value;
1509
0
    return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1510
0
               ? Match_Success
1511
0
               : Match_InvalidOperand;
1512
0
  }
1513
0
  case MCK_1: {
1514
0
    int64_t Value;
1515
0
    return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1516
0
               ? Match_Success
1517
0
               : Match_InvalidOperand;
1518
0
  }
1519
0
  case MCK__MINUS_1: {
1520
0
    int64_t Value;
1521
0
    return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == -1
1522
0
               ? Match_Success
1523
0
               : Match_InvalidOperand;
1524
0
  }
1525
525k
  }
1526
525k
  if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1527
84.7k
    StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1528
84.7k
    if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1529
29
      return Match_Success;
1530
84.7k
    if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1531
0
      return Match_Success;
1532
84.7k
  }
1533
1534
525k
  DEBUG(dbgs() << "Unmatched Operand:");
1535
525k
  DEBUG(Op->dump());
1536
525k
  DEBUG(dbgs() << "\n");
1537
1538
525k
  return Match_InvalidOperand;
1539
525k
}
1540
1541
14
void HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1542
14
  std::string errStr;
1543
14
  raw_string_ostream ES(errStr);
1544
14
  ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1545
14
  if (Max >= 0)
1546
0
    ES << "0-" << Max;
1547
14
  else
1548
14
    ES << Max << "-" << (-Max - 1);
1549
14
  Error(IDLoc, ES.str().c_str());
1550
14
}
1551
1552
int HexagonAsmParser::processInstruction(MCInst &Inst,
1553
                                         OperandVector const &Operands,
1554
                                         SMLoc IDLoc, bool &MustExtend)
1555
9.68k
{
1556
9.68k
  MCContext &Context = getParser().getContext();
1557
9.68k
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
1558
9.68k
  std::string r = "r";
1559
9.68k
  std::string v = "v";
1560
9.68k
  std::string Colon = ":";
1561
1562
9.68k
  bool is32bit = false; // used to distinguish between CONST32 and CONST64
1563
9.68k
  switch (Inst.getOpcode()) {
1564
9.62k
  default:
1565
9.62k
    break;
1566
1567
9.62k
  case Hexagon::M4_mpyrr_addr:
1568
0
  case Hexagon::S4_addi_asl_ri:
1569
0
  case Hexagon::S4_addi_lsr_ri:
1570
0
  case Hexagon::S4_andi_asl_ri:
1571
0
  case Hexagon::S4_andi_lsr_ri:
1572
0
  case Hexagon::S4_ori_asl_ri:
1573
0
  case Hexagon::S4_ori_lsr_ri:
1574
0
  case Hexagon::S4_or_andix:
1575
0
  case Hexagon::S4_subi_asl_ri:
1576
0
  case Hexagon::S4_subi_lsr_ri: {
1577
0
    MCOperand &Ry = Inst.getOperand(0);
1578
0
    MCOperand &src = Inst.getOperand(2);
1579
0
    if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1580
0
      return Match_InvalidOperand;
1581
0
    break;
1582
0
  }
1583
1584
0
  case Hexagon::C2_cmpgei: {
1585
0
    MCOperand &MO = Inst.getOperand(2);
1586
0
    MO.setExpr(MCBinaryExpr::createSub(
1587
0
        MO.getExpr(), MCConstantExpr::create(1, Context), Context));
1588
0
    Inst.setOpcode(Hexagon::C2_cmpgti);
1589
0
    break;
1590
0
  }
1591
1592
0
  case Hexagon::C2_cmpgeui: {
1593
0
    MCOperand &MO = Inst.getOperand(2);
1594
0
    int64_t Value;
1595
0
    bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
1596
0
    (void)Success;
1597
0
    assert(Success && "Assured by matcher");
1598
0
    if (Value == 0) {
1599
0
      MCInst TmpInst;
1600
0
      MCOperand &Pd = Inst.getOperand(0);
1601
0
      MCOperand &Rt = Inst.getOperand(1);
1602
0
      TmpInst.setOpcode(Hexagon::C2_cmpeq);
1603
0
      TmpInst.addOperand(Pd);
1604
0
      TmpInst.addOperand(Rt);
1605
0
      TmpInst.addOperand(Rt);
1606
0
      Inst = TmpInst;
1607
0
    } else {
1608
0
      MO.setExpr(MCBinaryExpr::createSub(
1609
0
          MO.getExpr(), MCConstantExpr::create(1, Context), Context));
1610
0
      Inst.setOpcode(Hexagon::C2_cmpgtui);
1611
0
    }
1612
0
    break;
1613
0
  }
1614
0
  case Hexagon::J2_loop1r:
1615
3
  case Hexagon::J2_loop1i:
1616
3
  case Hexagon::J2_loop0r:
1617
4
  case Hexagon::J2_loop0i: {
1618
4
    MCOperand &MO = Inst.getOperand(0);
1619
    // Loop has different opcodes for extended vs not extended, but we should
1620
    //   not use the other opcode as it is a legacy artifact of TD files.
1621
4
    int64_t Value;
1622
4
    if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1623
      // if the operand can fit within a 7:2 field
1624
1
      if (Value < (1 << 8) && Value >= -(1 << 8)) {
1625
0
        SMLoc myLoc = Operands[2]->getStartLoc();
1626
        // # is left in startLoc in the case of ##
1627
        // If '##' found then force extension.
1628
0
        if (*myLoc.getPointer() == '#') {
1629
0
          MustExtend = true;
1630
0
          break;
1631
0
        }
1632
1
      } else {
1633
        // If immediate and out of 7:2 range.
1634
1
        MustExtend = true;
1635
1
      }
1636
1
    }
1637
4
    break;
1638
4
  }
1639
1640
  // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1641
4
  case Hexagon::A2_tfrp: {
1642
0
    MCOperand &MO = Inst.getOperand(1);
1643
0
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1644
0
    std::string R1 = r + llvm_ks::utostr(RegPairNum + 1);
1645
0
    StringRef Reg1(R1);
1646
0
    MO.setReg(MatchRegisterName(Reg1));
1647
    // Add a new operand for the second register in the pair.
1648
0
    std::string R2 = r + llvm_ks::utostr(RegPairNum);
1649
0
    StringRef Reg2(R2);
1650
0
    Inst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
1651
0
    Inst.setOpcode(Hexagon::A2_combinew);
1652
0
    break;
1653
4
  }
1654
1655
0
  case Hexagon::A2_tfrpt:
1656
0
  case Hexagon::A2_tfrpf: {
1657
0
    MCOperand &MO = Inst.getOperand(2);
1658
0
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1659
0
    std::string R1 = r + llvm_ks::utostr(RegPairNum + 1);
1660
0
    StringRef Reg1(R1);
1661
0
    MO.setReg(MatchRegisterName(Reg1));
1662
    // Add a new operand for the second register in the pair.
1663
0
    std::string R2 = r + llvm_ks::utostr(RegPairNum);
1664
0
    StringRef Reg2(R2);
1665
0
    Inst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
1666
0
    Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1667
0
                       ? Hexagon::C2_ccombinewt
1668
0
                       : Hexagon::C2_ccombinewf);
1669
0
    break;
1670
0
  }
1671
0
  case Hexagon::A2_tfrptnew:
1672
0
  case Hexagon::A2_tfrpfnew: {
1673
0
    MCOperand &MO = Inst.getOperand(2);
1674
0
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1675
0
    std::string R1 = r + llvm_ks::utostr(RegPairNum + 1);
1676
0
    StringRef Reg1(R1);
1677
0
    MO.setReg(MatchRegisterName(Reg1));
1678
    // Add a new operand for the second register in the pair.
1679
0
    std::string R2 = r + llvm_ks::utostr(RegPairNum);
1680
0
    StringRef Reg2(R2);
1681
0
    Inst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
1682
0
    Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1683
0
                       ? Hexagon::C2_ccombinewnewt
1684
0
                       : Hexagon::C2_ccombinewnewf);
1685
0
    break;
1686
0
  }
1687
1688
  // Translate a "$Rx =  CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1689
0
  case Hexagon::CONST32:
1690
0
  case Hexagon::CONST32_Float_Real:
1691
0
  case Hexagon::CONST32_Int_Real:
1692
0
  case Hexagon::FCONST32_nsdata:
1693
0
    is32bit = true;
1694
  // Translate a "$Rx:y =  CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1695
0
  case Hexagon::CONST64_Float_Real:
1696
0
  case Hexagon::CONST64_Int_Real:
1697
1698
    // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1699
0
    if (!Parser.getStreamer().hasRawTextSupport()) {
1700
0
      MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1701
0
      MCOperand &MO_1 = Inst.getOperand(1);
1702
0
      MCOperand &MO_0 = Inst.getOperand(0);
1703
1704
      // push section onto section stack
1705
0
      MES->PushSection();
1706
1707
0
      std::string myCharStr;
1708
0
      MCSectionELF *mySection;
1709
1710
      // check if this as an immediate or a symbol
1711
0
      int64_t Value;
1712
0
      bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1713
0
      if (Absolute) {
1714
        // Create a new section - one for each constant
1715
        // Some or all of the zeros are replaced with the given immediate.
1716
0
        if (is32bit) {
1717
0
          std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1718
0
          myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1719
0
                          .drop_back(myImmStr.size())
1720
0
                          .str() +
1721
0
                      myImmStr;
1722
0
        } else {
1723
0
          std::string myImmStr = utohexstr(Value);
1724
0
          myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1725
0
                          .drop_back(myImmStr.size())
1726
0
                          .str() +
1727
0
                      myImmStr;
1728
0
        }
1729
1730
0
        mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1731
0
                                               ELF::SHF_ALLOC | ELF::SHF_WRITE);
1732
0
      } else if (MO_1.isExpr()) {
1733
        // .lita - for expressions
1734
0
        myCharStr = ".lita";
1735
0
        mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1736
0
                                               ELF::SHF_ALLOC | ELF::SHF_WRITE);
1737
0
      } else
1738
0
        llvm_unreachable("unexpected type of machine operand!");
1739
1740
0
      MES->SwitchSection(mySection);
1741
0
      unsigned byteSize = is32bit ? 4 : 8;
1742
0
      getStreamer().EmitCodeAlignment(byteSize, byteSize);
1743
1744
0
      MCSymbol *Sym;
1745
1746
      // for symbols, get rid of prepended ".gnu.linkonce.lx."
1747
1748
      // emit symbol if needed
1749
0
      if (Absolute) {
1750
0
        Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1751
0
        if (Sym->isUndefined()) {
1752
0
          bool Error;
1753
0
          getStreamer().EmitLabel(Sym);
1754
0
          getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1755
0
          getStreamer().EmitIntValue(Value, byteSize, Error);
1756
0
          if (Error)
1757
0
              return Match_InvalidOperand;
1758
0
        }
1759
0
      } else if (MO_1.isExpr()) {
1760
0
        const char *StringStart = 0;
1761
0
        const char *StringEnd = 0;
1762
0
        if (*Operands[4]->getStartLoc().getPointer() == '#') {
1763
0
          StringStart = Operands[5]->getStartLoc().getPointer();
1764
0
          StringEnd = Operands[6]->getStartLoc().getPointer();
1765
0
        } else { // no pound
1766
0
          StringStart = Operands[4]->getStartLoc().getPointer();
1767
0
          StringEnd = Operands[5]->getStartLoc().getPointer();
1768
0
        }
1769
1770
0
        unsigned size = StringEnd - StringStart;
1771
0
        std::string DotConst = ".CONST_";
1772
0
        Sym = getContext().getOrCreateSymbol(DotConst +
1773
0
                                             StringRef(StringStart, size));
1774
1775
0
        if (Sym->isUndefined()) {
1776
          // case where symbol is not yet defined: emit symbol
1777
0
          getStreamer().EmitLabel(Sym);
1778
0
          getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1779
0
          getStreamer().EmitValue(MO_1.getExpr(), 4);
1780
0
        }
1781
0
      } else
1782
0
        llvm_unreachable("unexpected type of machine operand!");
1783
1784
0
      MES->PopSection();
1785
1786
0
      if (Sym) {
1787
0
        MCInst TmpInst;
1788
0
        if (is32bit) // 32 bit
1789
0
          TmpInst.setOpcode(Hexagon::L2_loadrigp);
1790
0
        else // 64 bit
1791
0
          TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1792
1793
0
        TmpInst.addOperand(MO_0);
1794
0
        TmpInst.addOperand(
1795
0
            MCOperand::createExpr(MCSymbolRefExpr::create(Sym, getContext())));
1796
0
        Inst = TmpInst;
1797
0
      }
1798
0
    }
1799
0
    break;
1800
1801
  // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1802
13
  case Hexagon::A2_tfrpi: {
1803
13
    MCOperand &Rdd = Inst.getOperand(0);
1804
13
    MCOperand &MO = Inst.getOperand(1);
1805
13
    int64_t Value;
1806
13
    int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1807
13
    MCOperand imm(MCOperand::createExpr(MCConstantExpr::create(sVal, Context)));
1808
13
    Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1809
13
    break;
1810
0
  }
1811
1812
  // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1813
43
  case Hexagon::TFRI64_V4: {
1814
43
    MCOperand &Rdd = Inst.getOperand(0);
1815
43
    MCOperand &MO = Inst.getOperand(1);
1816
43
    int64_t Value;
1817
43
    if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1818
27
      unsigned long long u64 = Value;
1819
27
      signed int s8 = (u64 >> 32) & 0xFFFFFFFF;
1820
27
      if (s8 < -128 || s8 > 127)
1821
14
        OutOfRange(IDLoc, s8, -128);
1822
27
      MCOperand imm(MCOperand::createExpr(
1823
27
          MCConstantExpr::create(s8, Context))); // upper 32
1824
27
      MCOperand imm2(MCOperand::createExpr(
1825
27
          MCConstantExpr::create(u64 & 0xFFFFFFFF, Context))); // lower 32
1826
27
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1827
27
    } else {
1828
16
      MCOperand imm(MCOperand::createExpr(
1829
16
          MCConstantExpr::create(0, Context))); // upper 32
1830
16
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1831
16
    }
1832
43
    break;
1833
0
  }
1834
1835
  // Handle $Rdd = combine(##imm, #imm)"
1836
0
  case Hexagon::TFRI64_V2_ext: {
1837
0
    MCOperand &Rdd = Inst.getOperand(0);
1838
0
    MCOperand &MO1 = Inst.getOperand(1);
1839
0
    MCOperand &MO2 = Inst.getOperand(2);
1840
0
    int64_t Value;
1841
0
    if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1842
0
      int s8 = Value;
1843
0
      if (s8 < -128 || s8 > 127)
1844
0
        OutOfRange(IDLoc, s8, -128);
1845
0
    }
1846
0
    Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1847
0
    break;
1848
0
  }
1849
1850
  // Handle $Rdd = combine(#imm, ##imm)"
1851
0
  case Hexagon::A4_combineii: {
1852
0
    MCOperand &Rdd = Inst.getOperand(0);
1853
0
    MCOperand &MO1 = Inst.getOperand(1);
1854
0
    int64_t Value;
1855
0
    if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1856
0
      int s8 = Value;
1857
0
      if (s8 < -128 || s8 > 127)
1858
0
        OutOfRange(IDLoc, s8, -128);
1859
0
    }
1860
0
    MCOperand &MO2 = Inst.getOperand(2);
1861
0
    Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1862
0
    break;
1863
0
  }
1864
1865
0
  case Hexagon::S2_tableidxb_goodsyntax: {
1866
0
    Inst.setOpcode(Hexagon::S2_tableidxb);
1867
0
    break;
1868
0
  }
1869
1870
0
  case Hexagon::S2_tableidxh_goodsyntax: {
1871
0
    MCInst TmpInst;
1872
0
    MCOperand &Rx = Inst.getOperand(0);
1873
0
    MCOperand &_dst_ = Inst.getOperand(1);
1874
0
    MCOperand &Rs = Inst.getOperand(2);
1875
0
    MCOperand &Imm4 = Inst.getOperand(3);
1876
0
    MCOperand &Imm6 = Inst.getOperand(4);
1877
0
    Imm6.setExpr(MCBinaryExpr::createSub(
1878
0
        Imm6.getExpr(), MCConstantExpr::create(1, Context), Context));
1879
0
    TmpInst.setOpcode(Hexagon::S2_tableidxh);
1880
0
    TmpInst.addOperand(Rx);
1881
0
    TmpInst.addOperand(_dst_);
1882
0
    TmpInst.addOperand(Rs);
1883
0
    TmpInst.addOperand(Imm4);
1884
0
    TmpInst.addOperand(Imm6);
1885
0
    Inst = TmpInst;
1886
0
    break;
1887
0
  }
1888
1889
0
  case Hexagon::S2_tableidxw_goodsyntax: {
1890
0
    MCInst TmpInst;
1891
0
    MCOperand &Rx = Inst.getOperand(0);
1892
0
    MCOperand &_dst_ = Inst.getOperand(1);
1893
0
    MCOperand &Rs = Inst.getOperand(2);
1894
0
    MCOperand &Imm4 = Inst.getOperand(3);
1895
0
    MCOperand &Imm6 = Inst.getOperand(4);
1896
0
    Imm6.setExpr(MCBinaryExpr::createSub(
1897
0
        Imm6.getExpr(), MCConstantExpr::create(2, Context), Context));
1898
0
    TmpInst.setOpcode(Hexagon::S2_tableidxw);
1899
0
    TmpInst.addOperand(Rx);
1900
0
    TmpInst.addOperand(_dst_);
1901
0
    TmpInst.addOperand(Rs);
1902
0
    TmpInst.addOperand(Imm4);
1903
0
    TmpInst.addOperand(Imm6);
1904
0
    Inst = TmpInst;
1905
0
    break;
1906
0
  }
1907
1908
0
  case Hexagon::S2_tableidxd_goodsyntax: {
1909
0
    MCInst TmpInst;
1910
0
    MCOperand &Rx = Inst.getOperand(0);
1911
0
    MCOperand &_dst_ = Inst.getOperand(1);
1912
0
    MCOperand &Rs = Inst.getOperand(2);
1913
0
    MCOperand &Imm4 = Inst.getOperand(3);
1914
0
    MCOperand &Imm6 = Inst.getOperand(4);
1915
0
    Imm6.setExpr(MCBinaryExpr::createSub(
1916
0
        Imm6.getExpr(), MCConstantExpr::create(3, Context), Context));
1917
0
    TmpInst.setOpcode(Hexagon::S2_tableidxd);
1918
0
    TmpInst.addOperand(Rx);
1919
0
    TmpInst.addOperand(_dst_);
1920
0
    TmpInst.addOperand(Rs);
1921
0
    TmpInst.addOperand(Imm4);
1922
0
    TmpInst.addOperand(Imm6);
1923
0
    Inst = TmpInst;
1924
0
    break;
1925
0
  }
1926
1927
0
  case Hexagon::M2_mpyui: {
1928
0
    Inst.setOpcode(Hexagon::M2_mpyi);
1929
0
    break;
1930
0
  }
1931
0
  case Hexagon::M2_mpysmi: {
1932
0
    MCInst TmpInst;
1933
0
    MCOperand &Rd = Inst.getOperand(0);
1934
0
    MCOperand &Rs = Inst.getOperand(1);
1935
0
    MCOperand &Imm = Inst.getOperand(2);
1936
0
    int64_t Value;
1937
0
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1938
0
    assert(Absolute);
1939
0
    (void)Absolute;
1940
0
    if (!MustExtend) {
1941
0
      if (Value < 0 && Value > -256) {
1942
0
        Imm.setExpr(MCConstantExpr::create(Value * -1, Context));
1943
0
        TmpInst.setOpcode(Hexagon::M2_mpysin);
1944
0
      } else if (Value < 256 && Value >= 0)
1945
0
        TmpInst.setOpcode(Hexagon::M2_mpysip);
1946
0
      else
1947
0
        return Match_InvalidOperand;
1948
0
    } else {
1949
0
      if (Value >= 0)
1950
0
        TmpInst.setOpcode(Hexagon::M2_mpysip);
1951
0
      else
1952
0
        return Match_InvalidOperand;
1953
0
    }
1954
0
    TmpInst.addOperand(Rd);
1955
0
    TmpInst.addOperand(Rs);
1956
0
    TmpInst.addOperand(Imm);
1957
0
    Inst = TmpInst;
1958
0
    break;
1959
0
  }
1960
1961
0
  case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1962
0
    MCOperand &Imm = Inst.getOperand(2);
1963
0
    MCInst TmpInst;
1964
0
    int64_t Value;
1965
0
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1966
0
    assert(Absolute);
1967
0
    (void)Absolute;
1968
0
    if (Value == 0) { // convert to $Rd = $Rs
1969
0
      TmpInst.setOpcode(Hexagon::A2_tfr);
1970
0
      MCOperand &Rd = Inst.getOperand(0);
1971
0
      MCOperand &Rs = Inst.getOperand(1);
1972
0
      TmpInst.addOperand(Rd);
1973
0
      TmpInst.addOperand(Rs);
1974
0
    } else {
1975
0
      Imm.setExpr(MCBinaryExpr::createSub(
1976
0
          Imm.getExpr(), MCConstantExpr::create(1, Context), Context));
1977
0
      TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1978
0
      MCOperand &Rd = Inst.getOperand(0);
1979
0
      MCOperand &Rs = Inst.getOperand(1);
1980
0
      TmpInst.addOperand(Rd);
1981
0
      TmpInst.addOperand(Rs);
1982
0
      TmpInst.addOperand(Imm);
1983
0
    }
1984
0
    Inst = TmpInst;
1985
0
    break;
1986
0
  }
1987
1988
0
  case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1989
0
    MCOperand &Rdd = Inst.getOperand(0);
1990
0
    MCOperand &Rss = Inst.getOperand(1);
1991
0
    MCOperand &Imm = Inst.getOperand(2);
1992
0
    int64_t Value;
1993
0
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1994
0
    assert(Absolute);
1995
0
    (void)Absolute;
1996
0
    if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1997
0
      MCInst TmpInst;
1998
0
      unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1999
0
      std::string R1 = r + llvm_ks::utostr(RegPairNum + 1);
2000
0
      StringRef Reg1(R1);
2001
0
      Rss.setReg(MatchRegisterName(Reg1));
2002
      // Add a new operand for the second register in the pair.
2003
0
      std::string R2 = r + llvm_ks::utostr(RegPairNum);
2004
0
      StringRef Reg2(R2);
2005
0
      TmpInst.setOpcode(Hexagon::A2_combinew);
2006
0
      TmpInst.addOperand(Rdd);
2007
0
      TmpInst.addOperand(Rss);
2008
0
      TmpInst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
2009
0
      Inst = TmpInst;
2010
0
    } else {
2011
0
      Imm.setExpr(MCBinaryExpr::createSub(
2012
0
          Imm.getExpr(), MCConstantExpr::create(1, Context), Context));
2013
0
      Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
2014
0
    }
2015
0
    break;
2016
0
  }
2017
2018
0
  case Hexagon::A4_boundscheck: {
2019
0
    MCOperand &Rs = Inst.getOperand(1);
2020
0
    unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
2021
0
    if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
2022
0
      Inst.setOpcode(Hexagon::A4_boundscheck_hi);
2023
0
      std::string Name =
2024
0
          r + llvm_ks::utostr(RegNum) + Colon + llvm_ks::utostr(RegNum - 1);
2025
0
      StringRef RegPair = Name;
2026
0
      Rs.setReg(MatchRegisterName(RegPair));
2027
0
    } else { // raw:lo
2028
0
      Inst.setOpcode(Hexagon::A4_boundscheck_lo);
2029
0
      std::string Name =
2030
0
          r + llvm_ks::utostr(RegNum + 1) + Colon + llvm_ks::utostr(RegNum);
2031
0
      StringRef RegPair = Name;
2032
0
      Rs.setReg(MatchRegisterName(RegPair));
2033
0
    }
2034
0
    break;
2035
0
  }
2036
2037
0
  case Hexagon::A2_addsp: {
2038
0
    MCOperand &Rs = Inst.getOperand(1);
2039
0
    unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
2040
0
    if (RegNum & 1) { // Odd mapped to raw:hi
2041
0
      Inst.setOpcode(Hexagon::A2_addsph);
2042
0
      std::string Name =
2043
0
          r + llvm_ks::utostr(RegNum) + Colon + llvm_ks::utostr(RegNum - 1);
2044
0
      StringRef RegPair = Name;
2045
0
      Rs.setReg(MatchRegisterName(RegPair));
2046
0
    } else { // Even mapped raw:lo
2047
0
      Inst.setOpcode(Hexagon::A2_addspl);
2048
0
      std::string Name =
2049
0
          r + llvm_ks::utostr(RegNum + 1) + Colon + llvm_ks::utostr(RegNum);
2050
0
      StringRef RegPair = Name;
2051
0
      Rs.setReg(MatchRegisterName(RegPair));
2052
0
    }
2053
0
    break;
2054
0
  }
2055
2056
0
  case Hexagon::M2_vrcmpys_s1: {
2057
0
    MCOperand &Rt = Inst.getOperand(2);
2058
0
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
2059
0
    if (RegNum & 1) { // Odd mapped to sat:raw:hi
2060
0
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
2061
0
      std::string Name =
2062
0
          r + llvm_ks::utostr(RegNum) + Colon + llvm_ks::utostr(RegNum - 1);
2063
0
      StringRef RegPair = Name;
2064
0
      Rt.setReg(MatchRegisterName(RegPair));
2065
0
    } else { // Even mapped sat:raw:lo
2066
0
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
2067
0
      std::string Name =
2068
0
          r + llvm_ks::utostr(RegNum + 1) + Colon + llvm_ks::utostr(RegNum);
2069
0
      StringRef RegPair = Name;
2070
0
      Rt.setReg(MatchRegisterName(RegPair));
2071
0
    }
2072
0
    break;
2073
0
  }
2074
2075
0
  case Hexagon::M2_vrcmpys_acc_s1: {
2076
0
    MCInst TmpInst;
2077
0
    MCOperand &Rxx = Inst.getOperand(0);
2078
0
    MCOperand &Rss = Inst.getOperand(2);
2079
0
    MCOperand &Rt = Inst.getOperand(3);
2080
0
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
2081
0
    if (RegNum & 1) { // Odd mapped to sat:raw:hi
2082
0
      TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
2083
0
      std::string Name =
2084
0
          r + llvm_ks::utostr(RegNum) + Colon + llvm_ks::utostr(RegNum - 1);
2085
0
      StringRef RegPair = Name;
2086
0
      Rt.setReg(MatchRegisterName(RegPair));
2087
0
    } else { // Even mapped sat:raw:lo
2088
0
      TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
2089
0
      std::string Name =
2090
0
          r + llvm_ks::utostr(RegNum + 1) + Colon + llvm_ks::utostr(RegNum);
2091
0
      StringRef RegPair = Name;
2092
0
      Rt.setReg(MatchRegisterName(RegPair));
2093
0
    }
2094
    // Registers are in different positions
2095
0
    TmpInst.addOperand(Rxx);
2096
0
    TmpInst.addOperand(Rxx);
2097
0
    TmpInst.addOperand(Rss);
2098
0
    TmpInst.addOperand(Rt);
2099
0
    Inst = TmpInst;
2100
0
    break;
2101
0
  }
2102
2103
0
  case Hexagon::M2_vrcmpys_s1rp: {
2104
0
    MCOperand &Rt = Inst.getOperand(2);
2105
0
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
2106
0
    if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
2107
0
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
2108
0
      std::string Name =
2109
0
          r + llvm_ks::utostr(RegNum) + Colon + llvm_ks::utostr(RegNum - 1);
2110
0
      StringRef RegPair = Name;
2111
0
      Rt.setReg(MatchRegisterName(RegPair));
2112
0
    } else { // Even mapped rnd:sat:raw:lo
2113
0
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
2114
0
      std::string Name =
2115
0
          r + llvm_ks::utostr(RegNum + 1) + Colon + llvm_ks::utostr(RegNum);
2116
0
      StringRef RegPair = Name;
2117
0
      Rt.setReg(MatchRegisterName(RegPair));
2118
0
    }
2119
0
    break;
2120
0
  }
2121
2122
0
  case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
2123
0
    MCOperand &Imm = Inst.getOperand(2);
2124
0
    int64_t Value;
2125
0
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
2126
0
    assert(Absolute);
2127
0
    (void)Absolute;
2128
0
    if (Value == 0)
2129
0
      Inst.setOpcode(Hexagon::S2_vsathub);
2130
0
    else {
2131
0
      Imm.setExpr(MCBinaryExpr::createSub(
2132
0
          Imm.getExpr(), MCConstantExpr::create(1, Context), Context));
2133
0
      Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
2134
0
    }
2135
0
    break;
2136
0
  }
2137
2138
0
  case Hexagon::S5_vasrhrnd_goodsyntax: {
2139
0
    MCOperand &Rdd = Inst.getOperand(0);
2140
0
    MCOperand &Rss = Inst.getOperand(1);
2141
0
    MCOperand &Imm = Inst.getOperand(2);
2142
0
    int64_t Value;
2143
0
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
2144
0
    assert(Absolute);
2145
0
    (void)Absolute;
2146
0
    if (Value == 0) {
2147
0
      MCInst TmpInst;
2148
0
      unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
2149
0
      std::string R1 = r + llvm_ks::utostr(RegPairNum + 1);
2150
0
      StringRef Reg1(R1);
2151
0
      Rss.setReg(MatchRegisterName(Reg1));
2152
      // Add a new operand for the second register in the pair.
2153
0
      std::string R2 = r + llvm_ks::utostr(RegPairNum);
2154
0
      StringRef Reg2(R2);
2155
0
      TmpInst.setOpcode(Hexagon::A2_combinew);
2156
0
      TmpInst.addOperand(Rdd);
2157
0
      TmpInst.addOperand(Rss);
2158
0
      TmpInst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
2159
0
      Inst = TmpInst;
2160
0
    } else {
2161
0
      Imm.setExpr(MCBinaryExpr::createSub(
2162
0
          Imm.getExpr(), MCConstantExpr::create(1, Context), Context));
2163
0
      Inst.setOpcode(Hexagon::S5_vasrhrnd);
2164
0
    }
2165
0
    break;
2166
0
  }
2167
2168
0
  case Hexagon::A2_not: {
2169
0
    MCInst TmpInst;
2170
0
    MCOperand &Rd = Inst.getOperand(0);
2171
0
    MCOperand &Rs = Inst.getOperand(1);
2172
0
    TmpInst.setOpcode(Hexagon::A2_subri);
2173
0
    TmpInst.addOperand(Rd);
2174
0
    TmpInst.addOperand(
2175
0
        MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
2176
0
    TmpInst.addOperand(Rs);
2177
0
    Inst = TmpInst;
2178
0
    break;
2179
0
  }
2180
9.68k
  } // switch
2181
2182
9.68k
  return Match_Success;
2183
9.68k
}