Coverage Report

Created: 2025-08-25 07:49

/src/keystone/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
Line
Count
Source (jump to first uncovered line)
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
785k
  MCAsmParser &getParser() const { return Parser; }
72
0
  MCAssembler *getAssembler() const { return Assembler; }
73
2.88M
  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
74
75
2.79k
  bool equalIsAsmAssignment() override { return false; }
76
  bool isLabel(AsmToken &Token, bool &valid) override;
77
78
2.00k
  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
79
570
  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
3.00k
    : MCTargetAsmParser(Options, _STI), Parser(_Parser),
125
3.00k
      MCII (MII), MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) {
126
3.00k
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
127
128
3.00k
  MCAsmParserExtension::Initialize(_Parser);
129
130
3.00k
  Assembler = nullptr;
131
  // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
132
3.00k
  if (!Parser.getStreamer().hasRawTextSupport()) {
133
3.00k
    MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
134
3.00k
    Assembler = &MES->getAssembler();
135
3.00k
  }
136
3.00k
  }
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
517k
  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
434k
  unsigned getReg() const {
214
434k
    assert(Kind == Register && "Invalid access!");
215
434k
    return Reg.RegNum;
216
434k
  }
217
218
6.01k
  const MCExpr *getImm() const {
219
6.01k
    assert(Kind == Immediate && "Invalid access!");
220
6.01k
    return Imm.Val;
221
6.01k
  }
222
223
3.37M
  bool isToken() const { return Kind == Token; }
224
16.8k
  bool isImm() const { return Kind == Immediate; }
225
0
  bool isMem() const { llvm_unreachable("No isMem"); }
226
431k
  bool isReg() const { return Kind == Register; }
227
228
  bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
229
2.04k
                     bool isRelocatable, bool Extendable) const {
230
2.04k
    if (Kind == Immediate) {
231
2.04k
      const MCExpr *myMCExpr = getImm();
232
2.04k
      if (Imm.MustExtend && !Extendable)
233
3
        return false;
234
2.04k
      int64_t Res;
235
2.04k
      if (myMCExpr->evaluateAsAbsolute(Res)) {
236
1.92k
        int bits = immBits + zeroBits;
237
        // Field bit range is zerobits + bits
238
        // zeroBits must be 0
239
1.92k
        if (Res & ((1 << zeroBits) - 1))
240
0
          return false;
241
1.92k
        if (isSigned) {
242
1.89k
          if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
243
1.87k
            return true;
244
1.89k
        } else {
245
28
          if (bits == 64)
246
16
            return true;
247
12
          if (Res >= 0)
248
6
            return ((uint64_t)Res < (uint64_t)(1ULL << bits)) ? true : false;
249
6
          else {
250
6
            const int64_t high_bit_set = 1ULL << 63;
251
6
            const uint64_t mask = (high_bit_set >> (63 - bits));
252
6
            return (((uint64_t)Res & mask) == mask) ? true : false;
253
6
          }
254
12
        }
255
1.92k
      } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
256
25
        return true;
257
95
      else if (myMCExpr->getKind() == MCExpr::Binary ||
258
95
               myMCExpr->getKind() == MCExpr::Unary)
259
95
        return true;
260
2.04k
    }
261
16
    return false;
262
2.04k
  }
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
17
  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
16
  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
17
  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
3
  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
11
  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
1.97k
  bool iss16Ext() const { return CheckImmRange(16 + 26, 0, true, true, true); }
307
1
  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
3.55k
  void addRegOperands(MCInst &Inst, unsigned N) const {
338
3.55k
    assert(N == 1 && "Invalid number of operands!");
339
3.55k
    Inst.addOperand(MCOperand::createReg(getReg()));
340
3.55k
  }
341
342
2.00k
  void addImmOperands(MCInst &Inst, unsigned N) const {
343
2.00k
    assert(N == 1 && "Invalid number of operands!");
344
2.00k
    Inst.addOperand(MCOperand::createExpr(getImm()));
345
2.00k
  }
346
347
1.96k
  void addSignedImmOperands(MCInst &Inst, unsigned N) const {
348
1.96k
    assert(N == 1 && "Invalid number of operands!");
349
1.96k
    MCExpr const *Expr = getImm();
350
1.96k
    int64_t Value;
351
1.96k
    if (!Expr->evaluateAsAbsolute(Value)) {
352
98
      Inst.addOperand(MCOperand::createExpr(Expr));
353
98
      return;
354
98
    }
355
1.87k
    int64_t Extended = SignExtend64 (Value, 32);
356
1.87k
    if ((Extended < 0) == (Value < 0)) {
357
1.86k
      Inst.addOperand(MCOperand::createExpr(Expr));
358
1.86k
      return;
359
1.86k
    }
360
    // Flip bit 33 to signal signed unsigned mismatch
361
3
    Extended ^= 0x100000000;
362
3
    Inst.addOperand(MCOperand::createImm(Extended));
363
3
  }
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
1
  void adds8Imm64Operands(MCInst &Inst, unsigned N) const {
376
1
    addSignedImmOperands(Inst, N);
377
1
  }
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
16
  void addu64ImmOperands(MCInst &Inst, unsigned N) const {
401
16
    addImmOperands(Inst, N);
402
16
  }
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
17
  void addu16ImmOperands(MCInst &Inst, unsigned N) const {
410
17
    addImmOperands(Inst, N);
411
17
  }
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
0
  void addu10ImmOperands(MCInst &Inst, unsigned N) const {
428
0
    addImmOperands(Inst, N);
429
0
  }
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
1.96k
  void adds16ExtOperands(MCInst &Inst, unsigned N) const {
478
1.96k
    addSignedImmOperands(Inst, N);
479
1.96k
  }
480
1
  void adds12ExtOperands(MCInst &Inst, unsigned N) const {
481
1
    addSignedImmOperands(Inst, N);
482
1
  }
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
2.59M
  StringRef getToken() const {
552
2.59M
    assert(Kind == Token && "Invalid access!");
553
2.59M
    return StringRef(Tok.Data, Tok.Length);
554
2.59M
  }
555
556
  virtual void print(raw_ostream &OS) const;
557
558
455k
  static std::unique_ptr<HexagonOperand> CreateToken(StringRef Str, SMLoc S) {
559
455k
    HexagonOperand *Op = new HexagonOperand(Token);
560
455k
    Op->Tok.Data = Str.data();
561
455k
    Op->Tok.Length = Str.size();
562
455k
    Op->StartLoc = S;
563
455k
    Op->EndLoc = S;
564
455k
    return std::unique_ptr<HexagonOperand>(Op);
565
455k
  }
566
567
  static std::unique_ptr<HexagonOperand> CreateReg(unsigned RegNum, SMLoc S,
568
17.0k
                                                   SMLoc E) {
569
17.0k
    HexagonOperand *Op = new HexagonOperand(Register);
570
17.0k
    Op->Reg.RegNum = RegNum;
571
17.0k
    Op->StartLoc = S;
572
17.0k
    Op->EndLoc = E;
573
17.0k
    return std::unique_ptr<HexagonOperand>(Op);
574
17.0k
  }
575
576
  static std::unique_ptr<HexagonOperand> CreateImm(const MCExpr *Val, SMLoc S,
577
44.5k
                                                   SMLoc E) {
578
44.5k
    HexagonOperand *Op = new HexagonOperand(Immediate);
579
44.5k
    Op->Imm.Val = Val;
580
44.5k
    Op->Imm.MustExtend = false;
581
44.5k
    Op->StartLoc = S;
582
44.5k
    Op->EndLoc = E;
583
44.5k
    return std::unique_ptr<HexagonOperand>(Op);
584
44.5k
  }
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
3.25k
{
609
3.25k
  DEBUG(dbgs() << "Bundle:");
610
3.25k
  DEBUG(MCB.dump_pretty(dbgs()));
611
3.25k
  DEBUG(dbgs() << "--\n");
612
613
  // Check the bundle for errors.
614
3.25k
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
615
3.25k
  HexagonMCChecker Check(MCII, getSTI(), MCB, MCB, *RI);
616
617
3.25k
  bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MCII, getSTI(),
618
3.25k
                                                        getContext(), MCB,
619
3.25k
                                                        &Check);
620
621
3.67k
  while (Check.getNextErrInfo() == true) {
622
411
    unsigned Reg = Check.getErrRegister();
623
411
    Twine R(RI->getName(Reg));
624
625
411
    uint64_t Err = Check.getError();
626
411
    if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
627
411
      if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
628
17
        Error(IDLoc,
629
17
              "unconditional branch cannot precede another branch in packet");
630
631
411
      if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
632
411
          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
411
      if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
638
40
        Error(IDLoc, "register `" + R + "' modified more than once");
639
640
411
      if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
641
271
        Error(IDLoc, "cannot write to read-only register `" + R + "'");
642
643
411
      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
411
      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
411
      if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
655
0
        Error(IDLoc,
656
0
              "instruction cannot appear in packet with other instructions");
657
658
411
      if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
659
41
        Error(IDLoc, "too many slots used in packet");
660
661
411
      if (Err & HexagonMCErrInfo::CHECK_ERROR_SHUFFLE) {
662
42
        uint64_t Erm = Check.getShuffleError();
663
664
42
        if (HexagonShuffler::SHUFFLE_ERROR_INVALID == Erm)
665
0
          Error(IDLoc, "invalid instruction packet");
666
42
        else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
667
0
          Error(IDLoc, "invalid instruction packet: too many stores");
668
42
        else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
669
0
          Error(IDLoc, "invalid instruction packet: too many loads");
670
42
        else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
671
13
          Error(IDLoc, "too many branches in packet");
672
29
        else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
673
0
          Error(IDLoc, "invalid instruction packet: out of slots");
674
29
        else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
675
29
          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
42
      }
683
411
    }
684
685
411
    unsigned Warn = Check.getWarning();
686
411
    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
411
  }
695
696
3.25k
  if (CheckOk) {
697
2.94k
    MCB.setLoc(IDLoc);
698
2.94k
    if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
699
40
      assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
700
40
      assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
701
      // Empty packets are valid yet aren't emitted
702
40
      return false;
703
40
    }
704
2.90k
    Out.EmitInstruction(MCB, getSTI(), KsError);
705
2.90k
    if (KsError) {
706
4
        return true;
707
4
    }
708
2.90k
  } 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
313
    if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
712
41
      Error(IDLoc, "invalid instruction packet: out of slots");
713
41
      return true; // Error
714
41
    }
715
313
  }
716
717
3.17k
  return false; // No error
718
3.25k
}
719
720
768
bool HexagonAsmParser::matchBundleOptions() {
721
768
  MCAsmParser &Parser = getParser();
722
768
  MCAsmLexer &Lexer = getLexer();
723
768
  while (true) {
724
768
    if (!Parser.getTok().is(AsmToken::Colon))
725
768
      return false;
726
0
    Lexer.Lex();
727
0
    StringRef Option = Parser.getTok().getString();
728
0
    if (Option.compare_lower("endloop0") == 0)
729
0
      HexagonMCInstrInfo::setInnerLoop(MCB);
730
0
    else if (Option.compare_lower("endloop1") == 0)
731
0
      HexagonMCInstrInfo::setOuterLoop(MCB);
732
0
    else if (Option.compare_lower("mem_noshuf") == 0)
733
0
      HexagonMCInstrInfo::setMemReorderDisabled(MCB);
734
0
    else if (Option.compare_lower("mem_shuf") == 0)
735
0
      HexagonMCInstrInfo::setMemStoreReorderEnabled(MCB);
736
0
    else
737
0
      return true;
738
0
    Lexer.Lex();
739
0
  }
740
768
}
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
5.26k
void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
746
5.26k
  MCInst NewInst;
747
5.26k
  NewInst.setOpcode(MCI.getOpcode());
748
5.26k
  for (MCOperand &I : MCI)
749
7.54k
    if (I.isImm()) {
750
3
      int64_t Value (I.getImm());
751
3
      if ((Value & 0x100000000) != (Value & 0x80000000)) {
752
        // Detect flipped bit 33 wrt bit 32 and signal warning
753
3
        Value ^= 0x100000000;
754
3
        if (WarnSignedMismatch)
755
3
          Warning (MCI.getLoc(), "Signed/Unsigned mismatch");
756
3
      }
757
3
      NewInst.addOperand(MCOperand::createExpr(
758
3
          MCConstantExpr::create(Value, getContext())));
759
3
    }
760
7.54k
    else
761
7.54k
      NewInst.addOperand(I);
762
5.26k
  MCI = NewInst;
763
5.26k
}
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
6.42k
{
771
  // Perform matching with tablegen asmmatcher generated function
772
6.42k
  int result =
773
6.42k
      MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
774
6.42k
  if (result == Match_Success) {
775
5.26k
    MCI.setLoc(IDLoc);
776
5.26k
    MustExtend = mustExtend(InstOperands);
777
5.26k
    canonicalizeImmediates(MCI);
778
5.26k
    result = processInstruction(MCI, InstOperands, IDLoc, MustExtend);
779
780
5.26k
    DEBUG(dbgs() << "Insn:");
781
5.26k
    DEBUG(MCI.dump_pretty(dbgs()));
782
5.26k
    DEBUG(dbgs() << "\n\n");
783
784
5.26k
    MCI.setLoc(IDLoc);
785
5.26k
  }
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
6.42k
  switch (result) {
792
0
  default:
793
0
    break;
794
5.26k
  case Match_Success:
795
5.26k
    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
532
  case Match_MnemonicFail:
801
    // return Error(IDLoc, "unrecognized instruction");
802
532
    ErrorCode = KS_ERR_ASM_HEXAGON_MNEMONICFAIL;
803
532
    return true;
804
634
  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
634
    ErrorCode = KS_ERR_ASM_HEXAGON_INVALIDOPERAND;
820
634
    return true;
821
6.42k
  }
822
6.42k
  llvm_unreachable("Implement any new match types added!");
823
6.42k
}
824
825
5.26k
bool HexagonAsmParser::mustExtend(OperandVector &Operands) {
826
5.26k
  unsigned Count = 0;
827
5.26k
  for (std::unique_ptr<MCParsedAsmOperand> &i : Operands)
828
14.8k
    if (i->isImm())
829
3.97k
      if (static_cast<HexagonOperand *>(i.get())->Imm.MustExtend)
830
2.03k
        ++Count;
831
  // Multiple extenders should have been filtered by iss9Ext et. al.
832
5.26k
  assert(Count < 2 && "Multiple extenders");
833
5.26k
  return Count == 1;
834
5.26k
}
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
8.07k
{
842
8.07k
  if (!InBrackets) {
843
4.51k
    MCB.clear();
844
4.51k
    MCB.addOperand(MCOperand::createImm(0));
845
4.51k
  }
846
8.07k
  if (Operands.size() == 0) {
847
46
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
848
46
      return true;
849
46
  }
850
8.03k
  HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
851
8.03k
  if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
852
833
    assert(Operands.size() == 1 && "Brackets should be by themselves");
853
833
    if (InBrackets) {
854
      //getParser().Error(IDLoc, "Already in a packet");
855
0
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
856
0
      return true;
857
0
    }
858
833
    InBrackets = true;
859
833
    return false;
860
833
  }
861
7.20k
  if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
862
773
    assert(Operands.size() == 1 && "Brackets should be by themselves");
863
773
    if (!InBrackets) {
864
      //getParser().Error(IDLoc, "Not in a packet");
865
5
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
866
5
      return true;
867
5
    }
868
768
    InBrackets = false;
869
768
    if (matchBundleOptions()) {
870
0
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
871
0
      return true;
872
0
    }
873
768
    return finishBundle(IDLoc, Out, ErrorCode);
874
768
  }
875
6.42k
  MCInst *SubInst = new (getParser().getContext()) MCInst;
876
6.42k
  bool MustExtend = false;
877
6.42k
  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
878
6.42k
                          MatchingInlineAsm, MustExtend, ErrorCode)) {
879
1.16k
    ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
880
1.16k
    return true;
881
1.16k
  }
882
5.26k
  HexagonMCInstrInfo::extendIfNeeded(
883
5.26k
      getParser().getContext(), MCII, MCB, *SubInst,
884
5.26k
      HexagonMCInstrInfo::isExtended(MCII, *SubInst) || MustExtend);
885
5.26k
  MCB.addOperand(MCOperand::createInst(SubInst));
886
5.26k
  if (!InBrackets)
887
2.49k
    return finishBundle(IDLoc, Out, ErrorCode);
888
2.77k
  return false;
889
5.26k
}
890
891
/// ParseDirective parses the Hexagon specific directives
892
64.1k
bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
893
64.1k
  StringRef IDVal = DirectiveID.getIdentifier();
894
64.1k
  if ((IDVal.lower() == ".word") || (IDVal.lower() == ".4byte"))
895
4.73k
    return ParseDirectiveValue(4, DirectiveID.getLoc());
896
59.4k
  if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
897
59.4k
      IDVal.lower() == ".half")
898
24
    return ParseDirectiveValue(2, DirectiveID.getLoc());
899
59.4k
  if (IDVal.lower() == ".falign")
900
0
    return ParseDirectiveFalign(256, DirectiveID.getLoc());
901
59.4k
  if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
902
89
    return ParseDirectiveComm(true, DirectiveID.getLoc());
903
59.3k
  if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
904
1.64k
    return ParseDirectiveComm(false, DirectiveID.getLoc());
905
57.6k
  if (IDVal.lower() == ".subsection")
906
0
    return ParseDirectiveSubsection(DirectiveID.getLoc());
907
908
57.6k
  return true;
909
57.6k
}
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
4.75k
{
968
4.75k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
969
970
14.2k
    for (;;) {
971
14.2k
      const MCExpr *Value;
972
      //SMLoc ExprLoc = L;
973
14.2k
      if (getParser().parseExpression(Value))
974
724
        return true;
975
976
      // Special case constant expressions to match code generator.
977
13.5k
      if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
978
2.43k
        bool Error;
979
        //assert(Size <= 8 && "Invalid size");
980
2.43k
        if (Size > 8)
981
0
            return true;
982
2.43k
        uint64_t IntValue = MCE->getValue();
983
2.43k
        if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
984
          //return Error(ExprLoc, "literal value out of range for directive");
985
2
          return true;
986
2.42k
        getStreamer().EmitIntValue(IntValue, Size, Error);
987
2.42k
        if (Error) {
988
0
            return true;
989
0
        }
990
2.42k
      } else
991
11.1k
        getStreamer().EmitValue(Value, Size);
992
993
13.5k
      if (getLexer().is(AsmToken::EndOfStatement))
994
3.39k
        break;
995
996
      // FIXME: Improve diagnostic.
997
10.1k
      if (getLexer().isNot(AsmToken::Comma))
998
        //return TokError("unexpected token in directive");
999
604
        return true;
1000
9.55k
      Lex();
1001
9.55k
    }
1002
4.72k
  }
1003
1004
3.42k
  Lex();
1005
3.42k
  return false;
1006
4.75k
}
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
1.73k
bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
1015
  // FIXME: need better way to detect if AsmStreamer (upstream removed
1016
  // getKind())
1017
1.73k
  if (getStreamer().hasRawTextSupport())
1018
0
    return true; // Only object file output requires special treatment.
1019
1020
1.73k
  StringRef Name;
1021
1.73k
  if (getParser().parseIdentifier(Name))
1022
731
    return TokError("expected identifier in directive");
1023
  // Handle the identifier as the key symbol.
1024
1.00k
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
1025
1026
1.00k
  if (getLexer().isNot(AsmToken::Comma))
1027
30
    return TokError("unexpected token in directive");
1028
972
  Lex();
1029
1030
972
  int64_t Size;
1031
972
  SMLoc SizeLoc = getLexer().getLoc();
1032
972
  if (getParser().parseAbsoluteExpression(Size))
1033
181
    return true;
1034
1035
791
  int64_t ByteAlignment = 1;
1036
791
  SMLoc ByteAlignmentLoc;
1037
791
  if (getLexer().is(AsmToken::Comma)) {
1038
108
    Lex();
1039
108
    ByteAlignmentLoc = getLexer().getLoc();
1040
108
    if (getParser().parseAbsoluteExpression(ByteAlignment))
1041
0
      return true;
1042
108
    if (!isPowerOf2_64(ByteAlignment))
1043
108
      return Error(ByteAlignmentLoc, "alignment must be a power of 2");
1044
108
  }
1045
1046
683
  int64_t AccessAlignment = 0;
1047
683
  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
0
    SMLoc AccessAlignmentLoc;
1051
0
    Lex();
1052
0
    AccessAlignmentLoc = getLexer().getLoc();
1053
0
    if (getParser().parseAbsoluteExpression(AccessAlignment))
1054
0
      return true;
1055
1056
0
    if (!isPowerOf2_64(AccessAlignment))
1057
0
      return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
1058
0
  }
1059
1060
683
  if (getLexer().isNot(AsmToken::EndOfStatement))
1061
6
    return TokError("unexpected token in '.comm' or '.lcomm' directive");
1062
1063
677
  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
677
  if (Size < 0)
1068
9
    return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1069
9
                          "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
668
  if (ByteAlignment < 0)
1075
0
    return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1076
0
                                   "alignment, can't be less than zero");
1077
1078
668
  if (!Sym->isUndefined())
1079
0
    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
668
  return false;
1094
668
}
1095
1096
// validate register against architecture
1097
17.0k
bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
1098
17.0k
  return true;
1099
17.0k
}
1100
1101
// extern "C" void LLVMInitializeHexagonAsmLexer();
1102
1103
/// Force static initialization.
1104
25
extern "C" void LLVMInitializeHexagonAsmParser() {
1105
25
  RegisterMCAsmParser<HexagonAsmParser> X(TheHexagonTarget);
1106
25
}
1107
1108
#define GET_MATCHER_IMPLEMENTATION
1109
#define GET_REGISTER_MATCHER
1110
#include "HexagonGenAsmMatcher.inc"
1111
1112
namespace {
1113
2.99M
bool previousEqual(OperandVector &Operands, size_t Index, StringRef String) {
1114
2.99M
  if (Index >= Operands.size())
1115
169k
    return false;
1116
2.82M
  MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
1117
2.82M
  if (!Operand.isToken())
1118
330k
    return false;
1119
2.49M
  return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
1120
2.82M
}
1121
4.77k
bool previousIsLoop(OperandVector &Operands, size_t Index) {
1122
4.77k
  return previousEqual(Operands, Index, "loop0") ||
1123
4.77k
         previousEqual(Operands, Index, "loop1") ||
1124
4.77k
         previousEqual(Operands, Index, "sp1loop0") ||
1125
4.77k
         previousEqual(Operands, Index, "sp2loop0") ||
1126
4.77k
         previousEqual(Operands, Index, "sp3loop0");
1127
4.77k
}
1128
}
1129
1130
673k
bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
1131
673k
  AsmToken const &Token = getParser().getTok();
1132
673k
  StringRef String = Token.getString();
1133
673k
  SMLoc Loc = Token.getLoc();
1134
673k
  getLexer().Lex();
1135
715k
  do {
1136
715k
    std::pair<StringRef, StringRef> HeadTail = String.split('.');
1137
715k
    if (!HeadTail.first.empty())
1138
364k
      Operands.push_back(HexagonOperand::CreateToken(HeadTail.first, Loc));
1139
715k
    if (!HeadTail.second.empty())
1140
42.0k
      Operands.push_back(HexagonOperand::CreateToken(
1141
42.0k
          String.substr(HeadTail.first.size(), 1), Loc));
1142
715k
    String = HeadTail.second;
1143
715k
  } while (!String.empty());
1144
673k
  return false;
1145
673k
}
1146
1147
690k
bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
1148
690k
  unsigned Register;
1149
690k
  SMLoc Begin;
1150
690k
  SMLoc End;
1151
690k
  unsigned int ErrorCode;
1152
690k
  MCAsmLexer &Lexer = getLexer();
1153
690k
  if (!ParseRegister(Register, Begin, End, ErrorCode)) {
1154
17.0k
    if (!ErrorMissingParenthesis)
1155
17.0k
      switch (Register) {
1156
11.2k
      default:
1157
11.2k
        break;
1158
11.2k
      case Hexagon::P0:
1159
3.67k
      case Hexagon::P1:
1160
5.76k
      case Hexagon::P2:
1161
5.81k
      case Hexagon::P3:
1162
5.81k
        if (previousEqual(Operands, 0, "if")) {
1163
645
          if (WarnMissingParenthesis)
1164
645
            Warning (Begin, "Missing parenthesis around predicate register");
1165
645
          static char const *LParen = "(";
1166
645
          static char const *RParen = ")";
1167
645
          Operands.push_back(HexagonOperand::CreateToken(LParen, Begin));
1168
645
          Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
1169
645
          AsmToken MaybeDotNew = Lexer.getTok();
1170
645
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
1171
645
              MaybeDotNew.getString().equals_lower(".new"))
1172
0
            splitIdentifier(Operands);
1173
645
          Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
1174
645
          return false;
1175
645
        }
1176
5.17k
        if (previousEqual(Operands, 0, "!") &&
1177
5.17k
            previousEqual(Operands, 1, "if")) {
1178
1.11k
          if (WarnMissingParenthesis)
1179
1.11k
            Warning (Begin, "Missing parenthesis around predicate register");
1180
1.11k
          static char const *LParen = "(";
1181
1.11k
          static char const *RParen = ")";
1182
1.11k
          Operands.insert(Operands.end () - 1,
1183
1.11k
                          HexagonOperand::CreateToken(LParen, Begin));
1184
1.11k
          Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
1185
1.11k
          AsmToken MaybeDotNew = Lexer.getTok();
1186
1.11k
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
1187
1.11k
              MaybeDotNew.getString().equals_lower(".new"))
1188
0
            splitIdentifier(Operands);
1189
1.11k
          Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
1190
1.11k
          return false;
1191
1.11k
        }
1192
4.05k
        break;
1193
17.0k
      }
1194
15.2k
    Operands.push_back(HexagonOperand::CreateReg(
1195
15.2k
        Register, Begin, End));
1196
15.2k
    return false;
1197
17.0k
  }
1198
673k
  return splitIdentifier(Operands);
1199
690k
}
1200
1201
296
bool HexagonAsmParser::isLabel(AsmToken &Token, bool &valid) {
1202
296
  valid = true;
1203
296
  MCAsmLexer &Lexer = getLexer();
1204
296
  AsmToken const &Second = Lexer.getTok();
1205
296
  AsmToken Third = Lexer.peekTok();  
1206
296
  if (Third.is(AsmToken::Error)) {
1207
0
      valid = false;
1208
0
      return true;
1209
0
  }
1210
296
  StringRef String = Token.getString();
1211
296
  if (Token.is(AsmToken::TokenKind::LCurly) ||
1212
296
      Token.is(AsmToken::TokenKind::RCurly))
1213
0
    return false;
1214
296
  if (!Token.is(AsmToken::TokenKind::Identifier))
1215
147
    return true;
1216
149
  if (!MatchRegisterName(String.lower()))
1217
87
    return true;
1218
62
  (void)Second;
1219
62
  assert(Second.is(AsmToken::Colon));
1220
62
  StringRef Raw (String.data(), Third.getString().data() - String.data() +
1221
62
                 Third.getString().size());
1222
62
  std::string Collapsed = Raw;
1223
62
  Collapsed.erase(std::remove_if(Collapsed.begin(), Collapsed.end(), isspace),
1224
62
                  Collapsed.end());
1225
62
  StringRef Whole = Collapsed;
1226
62
  std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
1227
62
  if (!MatchRegisterName(DotSplit.first.lower()))
1228
23
    return true;
1229
39
  return false;
1230
62
}
1231
1232
17.0k
bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious, SMLoc &Loc) {
1233
17.0k
  if (!Contigious && ErrorNoncontigiousRegister) {
1234
0
    Error(Loc, "Register name is not contiguous");
1235
0
    return true;
1236
0
  }
1237
17.0k
  if (!Contigious && WarnNoncontigiousRegister)
1238
245
    Warning(Loc, "Register name is not contiguous");
1239
17.0k
  return false;
1240
17.0k
}
1241
1242
690k
bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, unsigned int &ErrorCode) {
1243
690k
  MCAsmLexer &Lexer = getLexer();
1244
690k
  StartLoc = getLexer().getLoc();
1245
690k
  SmallVector<AsmToken, 5> Lookahead;
1246
690k
  StringRef RawString(Lexer.getTok().getString().data(), 0);
1247
690k
  bool Again = Lexer.is(AsmToken::Identifier);
1248
690k
  bool NeededWorkaround = false;
1249
858k
  while (Again) {
1250
167k
    AsmToken const &Token = Lexer.getTok();
1251
167k
    RawString = StringRef(RawString.data(),
1252
167k
                          Token.getString().data() - RawString.data () +
1253
167k
                          Token.getString().size());
1254
167k
    Lookahead.push_back(Token);
1255
167k
    Lexer.Lex();
1256
167k
    bool Contigious = Lexer.getTok().getString().data() ==
1257
167k
                      Lookahead.back().getString().data() +
1258
167k
                      Lookahead.back().getString().size();
1259
167k
    bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1260
167k
                Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1261
167k
                Lexer.is(AsmToken::Colon);
1262
167k
    bool Workaround = Lexer.is(AsmToken::Colon) ||
1263
167k
                      Lookahead.back().is(AsmToken::Colon);
1264
167k
    Again = (Contigious && Type) || (Workaround && Type);
1265
167k
    NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1266
167k
  }
1267
690k
  std::string Collapsed = RawString;
1268
690k
  Collapsed.erase(std::remove_if(Collapsed.begin(), Collapsed.end(), isspace),
1269
690k
                  Collapsed.end());
1270
690k
  StringRef FullString = Collapsed;
1271
690k
  std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
1272
690k
  unsigned DotReg = MatchRegisterName(DotSplit.first.lower());
1273
690k
  if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1274
15.9k
    if (DotSplit.second.empty()) {
1275
14.4k
      RegNo = DotReg;
1276
14.4k
      EndLoc = Lexer.getLoc();
1277
14.4k
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1278
0
        return true;
1279
14.4k
      return false;
1280
14.4k
    } else {
1281
1.55k
      RegNo = DotReg;
1282
1.55k
      size_t First = RawString.find('.');
1283
1.55k
      StringRef DotString (RawString.data() + First, RawString.size() - First);
1284
1.55k
      Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1285
1.55k
      EndLoc = Lexer.getLoc();
1286
1.55k
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1287
0
        return true;
1288
1.55k
      return false;
1289
1.55k
    }
1290
15.9k
  }
1291
674k
  std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
1292
674k
  unsigned ColonReg = MatchRegisterName(ColonSplit.first.lower());
1293
674k
  if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1294
1.04k
    Lexer.UnLex(Lookahead.back());
1295
1.04k
    Lookahead.pop_back();
1296
1.04k
    Lexer.UnLex(Lookahead.back());
1297
1.04k
    Lookahead.pop_back();
1298
1.04k
    RegNo = ColonReg;
1299
1.04k
    EndLoc = Lexer.getLoc();
1300
1.04k
    if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1301
0
      return true;
1302
1.04k
    return false;
1303
1.04k
  }
1304
820k
  while (!Lookahead.empty()) {
1305
146k
    Lexer.UnLex(Lookahead.back());
1306
146k
    Lookahead.pop_back();
1307
146k
  }
1308
673k
  return true;
1309
674k
}
1310
1311
735k
bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1312
735k
  if (previousEqual(Operands, 0, "call"))
1313
357
    return true;
1314
735k
  if (previousEqual(Operands, 0, "jump"))
1315
1.76k
    if (!getLexer().getTok().is(AsmToken::Colon))
1316
1.66k
      return true;
1317
733k
  if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1318
24
    return true;
1319
733k
  if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1320
733k
      (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1321
72
    return true;
1322
733k
  return false;
1323
733k
}
1324
1325
44.5k
bool HexagonAsmParser::parseExpression(MCExpr const *& Expr) {
1326
44.5k
  llvm_ks::SmallVector<AsmToken, 4> Tokens;
1327
44.5k
  MCAsmLexer &Lexer = getLexer();
1328
44.5k
  bool Done = false;
1329
44.5k
  static char const * Comma = ",";
1330
2.73M
  do {
1331
2.73M
    Tokens.emplace_back (Lexer.getTok());
1332
2.73M
    Lexer.Lex();
1333
2.73M
    switch (Tokens.back().getKind())
1334
2.73M
    {
1335
315k
    case AsmToken::TokenKind::Hash:
1336
315k
      if (Tokens.size () > 1)
1337
315k
        if ((Tokens.end () - 2)->getKind() == AsmToken::TokenKind::Plus) {
1338
407
          Tokens.insert(Tokens.end() - 2,
1339
407
                        AsmToken(AsmToken::TokenKind::Comma, Comma));
1340
407
          Done = true;
1341
407
        }
1342
315k
      break;
1343
870
    case AsmToken::TokenKind::RCurly:
1344
43.9k
    case AsmToken::TokenKind::EndOfStatement:
1345
44.1k
    case AsmToken::TokenKind::Eof:
1346
44.1k
      Done = true;
1347
44.1k
      break;
1348
2.37M
    default:
1349
2.37M
      break;
1350
2.73M
    }
1351
2.73M
  } while (!Done);
1352
2.77M
  while (!Tokens.empty()) {
1353
2.73M
    Lexer.UnLex(Tokens.back());
1354
2.73M
    Tokens.pop_back();
1355
2.73M
  }
1356
44.5k
  return getParser().parseExpression(Expr);
1357
44.5k
}
1358
1359
692k
bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1360
692k
  if (implicitExpressionLocation(Operands)) {
1361
1.79k
    MCAsmParser &Parser = getParser();
1362
1.79k
    SMLoc Loc = Parser.getLexer().getLoc();
1363
1.79k
    std::unique_ptr<HexagonOperand> Expr =
1364
1.79k
        HexagonOperand::CreateImm(nullptr, Loc, Loc);
1365
1.79k
    MCExpr const *& Val = Expr->Imm.Val;
1366
1.79k
    Operands.push_back(std::move(Expr));
1367
1.79k
    return parseExpression(Val);
1368
1.79k
  }
1369
690k
  return parseOperand(Operands);
1370
692k
}
1371
1372
/// Parse an instruction.
1373
30.7k
bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1374
30.7k
  MCAsmParser &Parser = getParser();
1375
30.7k
  MCAsmLexer &Lexer = getLexer();
1376
771k
  while (true) {
1377
771k
    AsmToken const &Token = Parser.getTok();
1378
771k
    switch (Token.getKind()) {
1379
5.74k
    case AsmToken::EndOfStatement: {
1380
5.74k
      Lexer.Lex();
1381
5.74k
      return false;
1382
0
    }
1383
845
    case AsmToken::LCurly: {
1384
845
      if (!Operands.empty())
1385
12
        return true;
1386
833
      Operands.push_back(
1387
833
          HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
1388
833
      Lexer.Lex();
1389
833
      return false;
1390
845
    }
1391
1.50k
    case AsmToken::RCurly: {
1392
1.50k
      if (Operands.empty()) {
1393
773
        Operands.push_back(
1394
773
            HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
1395
773
        Lexer.Lex();
1396
773
      }
1397
1.50k
      return false;
1398
845
    }
1399
27.2k
    case AsmToken::Comma: {
1400
27.2k
      Lexer.Lex();
1401
27.2k
      continue;
1402
845
    }
1403
419
    case AsmToken::EqualEqual:
1404
502
    case AsmToken::ExclaimEqual:
1405
600
    case AsmToken::GreaterEqual:
1406
788
    case AsmToken::GreaterGreater:
1407
809
    case AsmToken::LessEqual:
1408
928
    case AsmToken::LessLess: {
1409
928
      Operands.push_back(HexagonOperand::CreateToken(
1410
928
          Token.getString().substr(0, 1), Token.getLoc()));
1411
928
      Operands.push_back(HexagonOperand::CreateToken(
1412
928
          Token.getString().substr(1, 1), Token.getLoc()));
1413
928
      Lexer.Lex();
1414
928
      continue;
1415
809
    }
1416
42.7k
    case AsmToken::Hash: {
1417
42.7k
      bool MustNotExtend = false;
1418
42.7k
      bool ImplicitExpression = implicitExpressionLocation(Operands);
1419
42.7k
      std::unique_ptr<HexagonOperand> Expr = HexagonOperand::CreateImm(
1420
42.7k
          nullptr, Lexer.getLoc(), Lexer.getLoc());
1421
42.7k
      if (!ImplicitExpression)
1422
42.4k
        Operands.push_back(
1423
42.4k
          HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
1424
42.7k
      Lexer.Lex();
1425
42.7k
      bool MustExtend = false;
1426
42.7k
      bool HiOnly = false;
1427
42.7k
      bool LoOnly = false;
1428
42.7k
      if (Lexer.is(AsmToken::Hash)) {
1429
4.15k
        Lexer.Lex();
1430
4.15k
        MustExtend = true;
1431
38.6k
      } else if (ImplicitExpression)
1432
110
        MustNotExtend = true;
1433
42.7k
      AsmToken const &Token = Parser.getTok();
1434
42.7k
      if (Token.is(AsmToken::Identifier)) {
1435
5.20k
        StringRef String = Token.getString();
1436
5.20k
        AsmToken IDToken = Token;
1437
5.20k
        if (String.lower() == "hi") {
1438
14
          HiOnly = true;
1439
5.19k
        } else if (String.lower() == "lo") {
1440
71
          LoOnly = true;
1441
71
        }
1442
5.20k
        if (HiOnly || LoOnly) {
1443
85
          AsmToken LParen = Lexer.peekTok();
1444
85
          if (!LParen.is(AsmToken::LParen)) {
1445
85
            HiOnly = false;
1446
85
            LoOnly = false;
1447
85
          } else {
1448
0
            Lexer.Lex();
1449
0
          }
1450
85
        }
1451
5.20k
      }
1452
42.7k
      if (parseExpression(Expr->Imm.Val))
1453
22.6k
        return true;
1454
20.1k
      int64_t Value;
1455
20.1k
      MCContext &Context = Parser.getContext();
1456
20.1k
      assert(Expr->Imm.Val != nullptr);
1457
20.1k
      if (Expr->Imm.Val->evaluateAsAbsolute(Value)) {
1458
10.4k
        if (HiOnly)
1459
0
          Expr->Imm.Val = MCBinaryExpr::createLShr(
1460
0
              Expr->Imm.Val, MCConstantExpr::create(16, Context), Context);
1461
10.4k
        if (HiOnly || LoOnly)
1462
0
          Expr->Imm.Val = MCBinaryExpr::createAnd(
1463
0
              Expr->Imm.Val, MCConstantExpr::create(0xffff, Context), Context);
1464
10.4k
      }
1465
20.1k
      if (MustNotExtend)
1466
96
        Expr->Imm.Val = HexagonNoExtendOperand::Create(Expr->Imm.Val, Context);
1467
20.1k
      Expr->Imm.MustExtend = MustExtend;
1468
20.1k
      Operands.push_back(std::move(Expr));
1469
20.1k
      continue;
1470
20.1k
    }
1471
692k
    default:
1472
692k
      break;
1473
771k
    }
1474
692k
    if (parseExpressionOrOperand(Operands))
1475
20
      return true;
1476
692k
  }
1477
30.7k
}
1478
1479
bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1480
                                        StringRef Name,
1481
                                        AsmToken ID,
1482
30.7k
                                        OperandVector &Operands, unsigned int &ErrorCode) {
1483
30.7k
  getLexer().UnLex(ID);
1484
30.7k
  return parseInstruction(Operands);
1485
30.7k
}
1486
1487
namespace {
1488
MCInst makeCombineInst(int opCode, MCOperand &Rdd,
1489
17
                       MCOperand &MO1, MCOperand &MO2) {
1490
17
  MCInst TmpInst;
1491
17
  TmpInst.setOpcode(opCode);
1492
17
  TmpInst.addOperand(Rdd);
1493
17
  TmpInst.addOperand(MO1);
1494
17
  TmpInst.addOperand(MO2);
1495
1496
17
  return TmpInst;
1497
17
}
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
424k
                                                      unsigned Kind) {
1504
424k
  HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1505
1506
424k
  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
424k
  }
1526
424k
  if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1527
56.8k
    StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1528
56.8k
    if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1529
22
      return Match_Success;
1530
56.8k
    if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1531
0
      return Match_Success;
1532
56.8k
  }
1533
1534
424k
  DEBUG(dbgs() << "Unmatched Operand:");
1535
424k
  DEBUG(Op->dump());
1536
424k
  DEBUG(dbgs() << "\n");
1537
1538
424k
  return Match_InvalidOperand;
1539
424k
}
1540
1541
1
void HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1542
1
  std::string errStr;
1543
1
  raw_string_ostream ES(errStr);
1544
1
  ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1545
1
  if (Max >= 0)
1546
0
    ES << "0-" << Max;
1547
1
  else
1548
1
    ES << Max << "-" << (-Max - 1);
1549
1
  Error(IDLoc, ES.str().c_str());
1550
1
}
1551
1552
int HexagonAsmParser::processInstruction(MCInst &Inst,
1553
                                         OperandVector const &Operands,
1554
                                         SMLoc IDLoc, bool &MustExtend)
1555
5.26k
{
1556
5.26k
  MCContext &Context = getParser().getContext();
1557
5.26k
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
1558
5.26k
  std::string r = "r";
1559
5.26k
  std::string v = "v";
1560
5.26k
  std::string Colon = ":";
1561
1562
5.26k
  bool is32bit = false; // used to distinguish between CONST32 and CONST64
1563
5.26k
  switch (Inst.getOpcode()) {
1564
5.24k
  default:
1565
5.24k
    break;
1566
1567
5.24k
  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
0
  case Hexagon::J2_loop1i:
1616
0
  case Hexagon::J2_loop0r:
1617
0
  case Hexagon::J2_loop0i: {
1618
0
    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
0
    int64_t Value;
1622
0
    if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1623
      // if the operand can fit within a 7:2 field
1624
0
      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
0
      } else {
1633
        // If immediate and out of 7:2 range.
1634
0
        MustExtend = true;
1635
0
      }
1636
0
    }
1637
0
    break;
1638
0
  }
1639
1640
  // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1641
1
  case Hexagon::A2_tfrp: {
1642
1
    MCOperand &MO = Inst.getOperand(1);
1643
1
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1644
1
    std::string R1 = r + llvm_ks::utostr(RegPairNum + 1);
1645
1
    StringRef Reg1(R1);
1646
1
    MO.setReg(MatchRegisterName(Reg1));
1647
    // Add a new operand for the second register in the pair.
1648
1
    std::string R2 = r + llvm_ks::utostr(RegPairNum);
1649
1
    StringRef Reg2(R2);
1650
1
    Inst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
1651
1
    Inst.setOpcode(Hexagon::A2_combinew);
1652
1
    break;
1653
0
  }
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
1
  case Hexagon::A2_tfrpi: {
1803
1
    MCOperand &Rdd = Inst.getOperand(0);
1804
1
    MCOperand &MO = Inst.getOperand(1);
1805
1
    int64_t Value;
1806
1
    int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1807
1
    MCOperand imm(MCOperand::createExpr(MCConstantExpr::create(sVal, Context)));
1808
1
    Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1809
1
    break;
1810
0
  }
1811
1812
  // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1813
16
  case Hexagon::TFRI64_V4: {
1814
16
    MCOperand &Rdd = Inst.getOperand(0);
1815
16
    MCOperand &MO = Inst.getOperand(1);
1816
16
    int64_t Value;
1817
16
    if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1818
16
      unsigned long long u64 = Value;
1819
16
      signed int s8 = (u64 >> 32) & 0xFFFFFFFF;
1820
16
      if (s8 < -128 || s8 > 127)
1821
1
        OutOfRange(IDLoc, s8, -128);
1822
16
      MCOperand imm(MCOperand::createExpr(
1823
16
          MCConstantExpr::create(s8, Context))); // upper 32
1824
16
      MCOperand imm2(MCOperand::createExpr(
1825
16
          MCConstantExpr::create(u64 & 0xFFFFFFFF, Context))); // lower 32
1826
16
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1827
16
    } else {
1828
0
      MCOperand imm(MCOperand::createExpr(
1829
0
          MCConstantExpr::create(0, Context))); // upper 32
1830
0
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1831
0
    }
1832
16
    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
5.26k
  } // switch
2181
2182
5.26k
  return Match_Success;
2183
5.26k
}