Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/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
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#define DEBUG_TYPE "mcasmparser"
10
11
#include "HexagonTargetStreamer.h"
12
#include "MCTargetDesc/HexagonMCChecker.h"
13
#include "MCTargetDesc/HexagonMCELFStreamer.h"
14
#include "MCTargetDesc/HexagonMCExpr.h"
15
#include "MCTargetDesc/HexagonMCInstrInfo.h"
16
#include "MCTargetDesc/HexagonMCTargetDesc.h"
17
#include "MCTargetDesc/HexagonShuffler.h"
18
#include "TargetInfo/HexagonTargetInfo.h"
19
#include "llvm/ADT/STLExtras.h"
20
#include "llvm/ADT/SmallVector.h"
21
#include "llvm/ADT/StringExtras.h"
22
#include "llvm/ADT/StringRef.h"
23
#include "llvm/ADT/Twine.h"
24
#include "llvm/BinaryFormat/ELF.h"
25
#include "llvm/MC/MCAssembler.h"
26
#include "llvm/MC/MCContext.h"
27
#include "llvm/MC/MCDirectives.h"
28
#include "llvm/MC/MCELFStreamer.h"
29
#include "llvm/MC/MCExpr.h"
30
#include "llvm/MC/MCInst.h"
31
#include "llvm/MC/MCParser/MCAsmLexer.h"
32
#include "llvm/MC/MCParser/MCAsmParser.h"
33
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
34
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
35
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
36
#include "llvm/MC/MCRegisterInfo.h"
37
#include "llvm/MC/MCSectionELF.h"
38
#include "llvm/MC/MCStreamer.h"
39
#include "llvm/MC/MCSubtargetInfo.h"
40
#include "llvm/MC/MCSymbol.h"
41
#include "llvm/MC/MCValue.h"
42
#include "llvm/Support/Casting.h"
43
#include "llvm/Support/CommandLine.h"
44
#include "llvm/Support/Debug.h"
45
#include "llvm/Support/ErrorHandling.h"
46
#include "llvm/Support/Format.h"
47
#include "llvm/Support/MathExtras.h"
48
#include "llvm/Support/SMLoc.h"
49
#include "llvm/Support/SourceMgr.h"
50
#include "llvm/Support/TargetRegistry.h"
51
#include "llvm/Support/raw_ostream.h"
52
#include <algorithm>
53
#include <cassert>
54
#include <cctype>
55
#include <cstddef>
56
#include <cstdint>
57
#include <memory>
58
#include <string>
59
#include <utility>
60
61
using namespace llvm;
62
63
static cl::opt<bool> WarnMissingParenthesis(
64
    "mwarn-missing-parenthesis",
65
    cl::desc("Warn for missing parenthesis around predicate registers"),
66
    cl::init(true));
67
static cl::opt<bool> ErrorMissingParenthesis(
68
    "merror-missing-parenthesis",
69
    cl::desc("Error for missing parenthesis around predicate registers"),
70
    cl::init(false));
71
static cl::opt<bool> WarnSignedMismatch(
72
    "mwarn-sign-mismatch",
73
    cl::desc("Warn for mismatching a signed and unsigned value"),
74
    cl::init(true));
75
static cl::opt<bool> WarnNoncontigiousRegister(
76
    "mwarn-noncontigious-register",
77
    cl::desc("Warn for register names that arent contigious"), cl::init(true));
78
static cl::opt<bool> ErrorNoncontigiousRegister(
79
    "merror-noncontigious-register",
80
    cl::desc("Error for register names that aren't contigious"),
81
    cl::init(false));
82
83
namespace {
84
85
struct HexagonOperand;
86
87
class HexagonAsmParser : public MCTargetAsmParser {
88
89
1
  HexagonTargetStreamer &getTargetStreamer() {
90
1
    MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
91
1
    return static_cast<HexagonTargetStreamer &>(TS);
92
1
  }
93
94
  MCAsmParser &Parser;
95
  MCInst MCB;
96
  bool InBrackets;
97
98
33.3k
  MCAsmParser &getParser() const { return Parser; }
99
0
  MCAssembler *getAssembler() const {
100
0
    MCAssembler *Assembler = nullptr;
101
0
    // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
102
0
    if (!Parser.getStreamer().hasRawTextSupport()) {
103
0
      MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
104
0
      Assembler = &MES->getAssembler();
105
0
    }
106
0
    return Assembler;
107
0
  }
108
109
85.5k
  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
110
111
1.36k
  bool equalIsAsmAssignment() override { return false; }
112
  bool isLabel(AsmToken &Token) override;
113
114
1
  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
115
20
  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
116
  bool ParseDirectiveFalign(unsigned Size, SMLoc L);
117
118
  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
119
  bool ParseDirectiveSubsection(SMLoc L);
120
  bool ParseDirectiveComm(bool IsLocal, SMLoc L);
121
  bool RegisterMatchesArch(unsigned MatchNum) const;
122
123
  bool matchBundleOptions();
124
  bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
125
  bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
126
  void canonicalizeImmediates(MCInst &MCI);
127
  bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
128
                           OperandVector &InstOperands, uint64_t &ErrorInfo,
129
                           bool MatchingInlineAsm);
130
  void eatToEndOfPacket();
131
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
132
                               OperandVector &Operands, MCStreamer &Out,
133
                               uint64_t &ErrorInfo,
134
                               bool MatchingInlineAsm) override;
135
136
  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
137
                                      unsigned Kind) override;
138
  bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
139
  int processInstruction(MCInst &Inst, OperandVector const &Operands,
140
                         SMLoc IDLoc);
141
142
  // Check if we have an assembler and, if so, set the ELF e_header flags.
143
0
  void chksetELFHeaderEFlags(unsigned flags) {
144
0
    if (getAssembler())
145
0
      getAssembler()->setELFHeaderEFlags(flags);
146
0
  }
147
148
  unsigned matchRegister(StringRef Name);
149
150
/// @name Auto-generated Match Functions
151
/// {
152
153
#define GET_ASSEMBLER_HEADER
154
#include "HexagonGenAsmMatcher.inc"
155
156
  /// }
157
158
public:
159
  HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
160
                   const MCInstrInfo &MII, const MCTargetOptions &Options)
161
    : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),
162
120
      InBrackets(false) {
163
120
    MCB.setOpcode(Hexagon::BUNDLE);
164
120
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
165
120
166
120
    Parser.addAliasForDirective(".half", ".2byte");
167
120
    Parser.addAliasForDirective(".hword", ".2byte");
168
120
    Parser.addAliasForDirective(".word", ".4byte");
169
120
170
120
    MCAsmParserExtension::Initialize(_Parser);
171
120
  }
172
173
  bool splitIdentifier(OperandVector &Operands);
174
  bool parseOperand(OperandVector &Operands);
175
  bool parseInstruction(OperandVector &Operands);
176
  bool implicitExpressionLocation(OperandVector &Operands);
177
  bool parseExpressionOrOperand(OperandVector &Operands);
178
  bool parseExpression(MCExpr const *&Expr);
179
180
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
181
0
                        SMLoc NameLoc, OperandVector &Operands) override {
182
0
    llvm_unreachable("Unimplemented");
183
0
  }
184
185
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
186
                        OperandVector &Operands) override;
187
188
  bool ParseDirective(AsmToken DirectiveID) override;
189
};
190
191
/// HexagonOperand - Instances of this class represent a parsed Hexagon machine
192
/// instruction.
193
struct HexagonOperand : public MCParsedAsmOperand {
194
  enum KindTy { Token, Immediate, Register } Kind;
195
  MCContext &Context;
196
197
  SMLoc StartLoc, EndLoc;
198
199
  struct TokTy {
200
    const char *Data;
201
    unsigned Length;
202
  };
203
204
  struct RegTy {
205
    unsigned RegNum;
206
  };
207
208
  struct ImmTy {
209
    const MCExpr *Val;
210
  };
211
212
  struct InstTy {
213
    OperandVector *SubInsts;
214
  };
215
216
  union {
217
    struct TokTy Tok;
218
    struct RegTy Reg;
219
    struct ImmTy Imm;
220
  };
221
222
  HexagonOperand(KindTy K, MCContext &Context)
223
31.4k
      : MCParsedAsmOperand(), Kind(K), Context(Context) {}
224
225
public:
226
  HexagonOperand(const HexagonOperand &o)
227
0
      : MCParsedAsmOperand(), Context(o.Context) {
228
0
    Kind = o.Kind;
229
0
    StartLoc = o.StartLoc;
230
0
    EndLoc = o.EndLoc;
231
0
    switch (Kind) {
232
0
    case Register:
233
0
      Reg = o.Reg;
234
0
      break;
235
0
    case Immediate:
236
0
      Imm = o.Imm;
237
0
      break;
238
0
    case Token:
239
0
      Tok = o.Tok;
240
0
      break;
241
0
    }
242
0
  }
243
244
  /// getStartLoc - Get the location of the first token of this operand.
245
19
  SMLoc getStartLoc() const override { return StartLoc; }
246
247
  /// getEndLoc - Get the location of the last token of this operand.
248
0
  SMLoc getEndLoc() const override { return EndLoc; }
249
250
1.56M
  unsigned getReg() const override {
251
1.56M
    assert(Kind == Register && "Invalid access!");
252
1.56M
    return Reg.RegNum;
253
1.56M
  }
254
255
2.38k
  const MCExpr *getImm() const {
256
2.38k
    assert(Kind == Immediate && "Invalid access!");
257
2.38k
    return Imm.Val;
258
2.38k
  }
259
260
2.62M
  bool isToken() const override { return Kind == Token; }
261
73
  bool isImm() const override { return Kind == Immediate; }
262
0
  bool isMem() const override { llvm_unreachable("No isMem"); }
263
1.63M
  bool isReg() const override { return Kind == Register; }
264
265
  bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
266
970
                     bool isRelocatable, bool Extendable) const {
267
970
    if (Kind == Immediate) {
268
968
      const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
269
968
      if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && 
!Extendable21
)
270
6
        return false;
271
962
      int64_t Res;
272
962
      if (myMCExpr->evaluateAsAbsolute(Res)) {
273
904
        int bits = immBits + zeroBits;
274
904
        // Field bit range is zerobits + bits
275
904
        // zeroBits must be 0
276
904
        if (Res & ((1 << zeroBits) - 1))
277
0
          return false;
278
904
        if (isSigned) {
279
501
          if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
280
501
            return true;
281
403
        } else {
282
403
          if (bits == 64)
283
1
            return true;
284
402
          if (Res >= 0)
285
399
            return ((uint64_t)Res < (uint64_t)(1ULL << bits));
286
3
          else {
287
3
            const int64_t high_bit_set = 1ULL << 63;
288
3
            const uint64_t mask = (high_bit_set >> (63 - bits));
289
3
            return (((uint64_t)Res & mask) == mask);
290
3
          }
291
58
        }
292
58
      } else if (myMCExpr->getKind() == MCExpr::SymbolRef && 
isRelocatable57
)
293
55
        return true;
294
3
      else if (myMCExpr->getKind() == MCExpr::Binary ||
295
3
               
myMCExpr->getKind() == MCExpr::Unary2
)
296
1
        return true;
297
4
    }
298
4
    return false;
299
4
  }
300
301
16
  bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
302
180
  bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
303
0
  bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
304
10
  bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }
305
306
4
  bool ism32_0Imm() const { return true; }
307
308
0
  bool isf32Imm() const { return false; }
309
0
  bool isf64Imm() const { return false; }
310
276
  bool iss32_0Imm() const { return true; }
311
30
  bool iss31_1Imm() const { return true; }
312
38
  bool iss30_2Imm() const { return true; }
313
4
  bool iss29_3Imm() const { return true; }
314
1
  bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
315
0
  bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }
316
15
  bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
317
0
  bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
318
0
  bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
319
7
  bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
320
0
  bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
321
134
  bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
322
67
  bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
323
36
  bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
324
14
  bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
325
78
  bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
326
327
1
  bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
328
287
  bool isu32_0Imm() const { return true; }
329
143
  bool isu31_1Imm() const { return true; }
330
140
  bool isu30_2Imm() const { return true; }
331
27
  bool isu29_3Imm() const { return true; }
332
0
  bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
333
16
  bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
334
0
  bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
335
0
  bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
336
0
  bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
337
6
  bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
338
13
  bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
339
0
  bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
340
13
  bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
341
3
  bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
342
48
  bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
343
19
  bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
344
21
  bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
345
0
  bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
346
128
  bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
347
0
  bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
348
0
  bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
349
26
  bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
350
0
  bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
351
6
  bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
352
0
  bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
353
110
  bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
354
2
  bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
355
356
48
  bool isn1Const() const {
357
48
    if (!isImm())
358
0
      return false;
359
48
    int64_t Value;
360
48
    if (!getImm()->evaluateAsAbsolute(Value))
361
0
      return false;
362
48
    return Value == -1;
363
48
  }
364
0
  bool iss11_0Imm() const {
365
0
    return CheckImmRange(11 + 26, 0, true, true, true);
366
0
  }
367
0
  bool iss11_1Imm() const {
368
0
    return CheckImmRange(11 + 26, 1, true, true, true);
369
0
  }
370
0
  bool iss11_2Imm() const {
371
0
    return CheckImmRange(11 + 26, 2, true, true, true);
372
0
  }
373
0
  bool iss11_3Imm() const {
374
0
    return CheckImmRange(11 + 26, 3, true, true, true);
375
0
  }
376
0
  bool isu32_0MustExt() const { return isImm(); }
377
378
7.22k
  void addRegOperands(MCInst &Inst, unsigned N) const {
379
7.22k
    assert(N == 1 && "Invalid number of operands!");
380
7.22k
    Inst.addOperand(MCOperand::createReg(getReg()));
381
7.22k
  }
382
383
683
  void addImmOperands(MCInst &Inst, unsigned N) const {
384
683
    assert(N == 1 && "Invalid number of operands!");
385
683
    Inst.addOperand(MCOperand::createExpr(getImm()));
386
683
  }
387
388
690
  void addSignedImmOperands(MCInst &Inst, unsigned N) const {
389
690
    assert(N == 1 && "Invalid number of operands!");
390
690
    HexagonMCExpr *Expr =
391
690
        const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
392
690
    int64_t Value;
393
690
    if (!Expr->evaluateAsAbsolute(Value)) {
394
94
      Inst.addOperand(MCOperand::createExpr(Expr));
395
94
      return;
396
94
    }
397
596
    int64_t Extended = SignExtend64(Value, 32);
398
596
    HexagonMCExpr *NewExpr = HexagonMCExpr::create(
399
596
        MCConstantExpr::create(Extended, Context), Context);
400
596
    if ((Extended < 0) != (Value < 0))
401
0
      NewExpr->setSignMismatch();
402
596
    NewExpr->setMustExtend(Expr->mustExtend());
403
596
    NewExpr->setMustNotExtend(Expr->mustNotExtend());
404
596
    Inst.addOperand(MCOperand::createExpr(NewExpr));
405
596
  }
406
407
8
  void addn1ConstOperands(MCInst &Inst, unsigned N) const {
408
8
    addImmOperands(Inst, N);
409
8
  }
410
411
955k
  StringRef getToken() const {
412
955k
    assert(Kind == Token && "Invalid access!");
413
955k
    return StringRef(Tok.Data, Tok.Length);
414
955k
  }
415
416
  void print(raw_ostream &OS) const override;
417
418
  static std::unique_ptr<HexagonOperand> CreateToken(MCContext &Context,
419
22.7k
                                                     StringRef Str, SMLoc S) {
420
22.7k
    HexagonOperand *Op = new HexagonOperand(Token, Context);
421
22.7k
    Op->Tok.Data = Str.data();
422
22.7k
    Op->Tok.Length = Str.size();
423
22.7k
    Op->StartLoc = S;
424
22.7k
    Op->EndLoc = S;
425
22.7k
    return std::unique_ptr<HexagonOperand>(Op);
426
22.7k
  }
427
428
  static std::unique_ptr<HexagonOperand>
429
7.33k
  CreateReg(MCContext &Context, unsigned RegNum, SMLoc S, SMLoc E) {
430
7.33k
    HexagonOperand *Op = new HexagonOperand(Register, Context);
431
7.33k
    Op->Reg.RegNum = RegNum;
432
7.33k
    Op->StartLoc = S;
433
7.33k
    Op->EndLoc = E;
434
7.33k
    return std::unique_ptr<HexagonOperand>(Op);
435
7.33k
  }
436
437
  static std::unique_ptr<HexagonOperand>
438
1.39k
  CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {
439
1.39k
    HexagonOperand *Op = new HexagonOperand(Immediate, Context);
440
1.39k
    Op->Imm.Val = Val;
441
1.39k
    Op->StartLoc = S;
442
1.39k
    Op->EndLoc = E;
443
1.39k
    return std::unique_ptr<HexagonOperand>(Op);
444
1.39k
  }
445
};
446
447
} // end anonymous namespace
448
449
void HexagonOperand::print(raw_ostream &OS) const {
450
  switch (Kind) {
451
  case Immediate:
452
    getImm()->print(OS, nullptr);
453
    break;
454
  case Register:
455
    OS << "<register R";
456
    OS << getReg() << ">";
457
    break;
458
  case Token:
459
    OS << "'" << getToken() << "'";
460
    break;
461
  }
462
}
463
464
2.48k
bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
465
2.48k
  LLVM_DEBUG(dbgs() << "Bundle:");
466
2.48k
  LLVM_DEBUG(MCB.dump_pretty(dbgs()));
467
2.48k
  LLVM_DEBUG(dbgs() << "--\n");
468
2.48k
469
2.48k
  MCB.setLoc(IDLoc);
470
2.48k
  // Check the bundle for errors.
471
2.48k
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
472
2.48k
  HexagonMCChecker Check(getContext(), MII, getSTI(), MCB, *RI);
473
2.48k
474
2.48k
  bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MII, getSTI(),
475
2.48k
                                                        getContext(), MCB,
476
2.48k
                                                        &Check);
477
2.48k
478
2.48k
  if (CheckOk) {
479
2.45k
    if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
480
1
      assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
481
1
      assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
482
1
      // Empty packets are valid yet aren't emitted
483
1
      return false;
484
1
    }
485
2.45k
    Out.EmitInstruction(MCB, getSTI());
486
2.45k
  } else {
487
24
    // If compounding and duplexing didn't reduce the size below
488
24
    // 4 or less we have a packet that is too big.
489
24
    if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
490
0
      Error(IDLoc, "invalid instruction packet: out of slots");
491
0
    }
492
24
    return true; // Error
493
24
  }
494
2.45k
495
2.45k
  return false; // No error
496
2.45k
}
497
498
665
bool HexagonAsmParser::matchBundleOptions() {
499
665
  MCAsmParser &Parser = getParser();
500
685
  while (true) {
501
685
    if (!Parser.getTok().is(AsmToken::Colon))
502
665
      return false;
503
20
    Lex();
504
20
    char const *MemNoShuffMsg =
505
20
        "invalid instruction packet: mem_noshuf specifier not "
506
20
        "supported with this architecture";
507
20
    StringRef Option = Parser.getTok().getString();
508
20
    auto IDLoc = Parser.getTok().getLoc();
509
20
    if (Option.compare_lower("endloop01") == 0) {
510
3
      HexagonMCInstrInfo::setInnerLoop(MCB);
511
3
      HexagonMCInstrInfo::setOuterLoop(MCB);
512
17
    } else if (Option.compare_lower("endloop0") == 0) {
513
10
      HexagonMCInstrInfo::setInnerLoop(MCB);
514
10
    } else 
if (7
Option.compare_lower("endloop1") == 07
) {
515
7
      HexagonMCInstrInfo::setOuterLoop(MCB);
516
7
    } else 
if (0
Option.compare_lower("mem_noshuf") == 00
) {
517
0
      if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
518
0
        HexagonMCInstrInfo::setMemReorderDisabled(MCB);
519
0
      else
520
0
        return getParser().Error(IDLoc, MemNoShuffMsg);
521
0
    } else
522
0
      return getParser().Error(IDLoc, llvm::Twine("'") + Option +
523
0
                                          "' is not a valid bundle option");
524
20
    Lex();
525
20
  }
526
665
}
527
528
// For instruction aliases, immediates are generated rather than
529
// MCConstantExpr.  Convert them for uniform MCExpr.
530
// Also check for signed/unsigned mismatches and warn
531
3.07k
void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
532
3.07k
  MCInst NewInst;
533
3.07k
  NewInst.setOpcode(MCI.getOpcode());
534
3.07k
  for (MCOperand &I : MCI)
535
9.39k
    if (I.isImm()) {
536
162
      int64_t Value(I.getImm());
537
162
      NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
538
162
          MCConstantExpr::create(Value, getContext()), getContext())));
539
9.23k
    } else {
540
9.23k
      if (I.isExpr() && 
cast<HexagonMCExpr>(I.getExpr())->signMismatch()1.37k
&&
541
9.23k
          
WarnSignedMismatch0
)
542
0
        Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
543
9.23k
      NewInst.addOperand(I);
544
9.23k
    }
545
3.07k
  MCI = NewInst;
546
3.07k
}
547
548
bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
549
                                           OperandVector &InstOperands,
550
                                           uint64_t &ErrorInfo,
551
3.09k
                                           bool MatchingInlineAsm) {
552
3.09k
  // Perform matching with tablegen asmmatcher generated function
553
3.09k
  int result =
554
3.09k
      MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
555
3.09k
  if (result == Match_Success) {
556
3.07k
    MCI.setLoc(IDLoc);
557
3.07k
    canonicalizeImmediates(MCI);
558
3.07k
    result = processInstruction(MCI, InstOperands, IDLoc);
559
3.07k
560
3.07k
    LLVM_DEBUG(dbgs() << "Insn:");
561
3.07k
    LLVM_DEBUG(MCI.dump_pretty(dbgs()));
562
3.07k
    LLVM_DEBUG(dbgs() << "\n\n");
563
3.07k
564
3.07k
    MCI.setLoc(IDLoc);
565
3.07k
  }
566
3.09k
567
3.09k
  // Create instruction operand for bundle instruction
568
3.09k
  //   Break this into a separate function Code here is less readable
569
3.09k
  //   Think about how to get an instruction error to report correctly.
570
3.09k
  //   SMLoc will return the "{"
571
3.09k
  switch (result) {
572
3.09k
  default:
573
0
    break;
574
3.09k
  case Match_Success:
575
3.07k
    return false;
576
3.09k
  case Match_MissingFeature:
577
0
    return Error(IDLoc, "invalid instruction");
578
3.09k
  case Match_MnemonicFail:
579
1
    return Error(IDLoc, "unrecognized instruction");
580
3.09k
  case Match_InvalidOperand:
581
19
  case Match_InvalidTiedOperand:
582
19
    SMLoc ErrorLoc = IDLoc;
583
19
    if (ErrorInfo != ~0U) {
584
19
      if (ErrorInfo >= InstOperands.size())
585
0
        return Error(IDLoc, "too few operands for instruction");
586
19
587
19
      ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
588
19
                     ->getStartLoc();
589
19
      if (ErrorLoc == SMLoc())
590
0
        ErrorLoc = IDLoc;
591
19
    }
592
19
    return Error(ErrorLoc, "invalid operand for instruction");
593
0
  }
594
0
  llvm_unreachable("Implement any new match types added!");
595
0
}
596
597
2
void HexagonAsmParser::eatToEndOfPacket() {
598
2
  assert(InBrackets);
599
2
  MCAsmLexer &Lexer = getLexer();
600
2
  while (!Lexer.is(AsmToken::RCurly))
601
0
    Lexer.Lex();
602
2
  Lexer.Lex();
603
2
  InBrackets = false;
604
2
}
605
606
bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
607
                                               OperandVector &Operands,
608
                                               MCStreamer &Out,
609
                                               uint64_t &ErrorInfo,
610
4.42k
                                               bool MatchingInlineAsm) {
611
4.42k
  if (!InBrackets) {
612
2.50k
    MCB.clear();
613
2.50k
    MCB.addOperand(MCOperand::createImm(0));
614
2.50k
  }
615
4.42k
  HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
616
4.42k
  if (FirstOperand.isToken() && 
FirstOperand.getToken() == "{"2.37k
) {
617
667
    assert(Operands.size() == 1 && "Brackets should be by themselves");
618
667
    if (InBrackets) {
619
0
      getParser().Error(IDLoc, "Already in a packet");
620
0
      InBrackets = false;
621
0
      return true;
622
0
    }
623
667
    InBrackets = true;
624
667
    return false;
625
667
  }
626
3.75k
  if (FirstOperand.isToken() && 
FirstOperand.getToken() == "}"1.70k
) {
627
665
    assert(Operands.size() == 1 && "Brackets should be by themselves");
628
665
    if (!InBrackets) {
629
0
      getParser().Error(IDLoc, "Not in a packet");
630
0
      return true;
631
0
    }
632
665
    InBrackets = false;
633
665
    if (matchBundleOptions())
634
0
      return true;
635
665
    return finishBundle(IDLoc, Out);
636
665
  }
637
3.09k
  MCInst *SubInst = new (getParser().getContext()) MCInst;
638
3.09k
  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
639
3.09k
                          MatchingInlineAsm)) {
640
20
    if (InBrackets)
641
2
      eatToEndOfPacket();
642
20
    return true;
643
20
  }
644
3.07k
  HexagonMCInstrInfo::extendIfNeeded(
645
3.07k
      getParser().getContext(), MII, MCB, *SubInst);
646
3.07k
  MCB.addOperand(MCOperand::createInst(SubInst));
647
3.07k
  if (!InBrackets)
648
1.81k
    return finishBundle(IDLoc, Out);
649
1.25k
  return false;
650
1.25k
}
651
652
/// ParseDirective parses the Hexagon specific directives
653
98
bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
654
98
  StringRef IDVal = DirectiveID.getIdentifier();
655
98
  if (IDVal.lower() == ".falign")
656
1
    return ParseDirectiveFalign(256, DirectiveID.getLoc());
657
97
  if ((IDVal.lower() == ".lcomm") || 
(IDVal.lower() == ".lcommon")93
)
658
4
    return ParseDirectiveComm(true, DirectiveID.getLoc());
659
93
  if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
660
2
    return ParseDirectiveComm(false, DirectiveID.getLoc());
661
91
  if (IDVal.lower() == ".subsection")
662
0
    return ParseDirectiveSubsection(DirectiveID.getLoc());
663
91
664
91
  return true;
665
91
}
666
0
bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
667
0
  const MCExpr *Subsection = nullptr;
668
0
  int64_t Res;
669
0
670
0
  assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
671
0
         "Invalid subsection directive");
672
0
  getParser().parseExpression(Subsection);
673
0
674
0
  if (!Subsection->evaluateAsAbsolute(Res))
675
0
    return Error(L, "Cannot evaluate subsection number");
676
0
677
0
  if (getLexer().isNot(AsmToken::EndOfStatement))
678
0
    return TokError("unexpected token in directive");
679
0
680
0
  // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
681
0
  // negative subsections together and in the same order but at the opposite
682
0
  // end of the section.  Only legacy hexagon-gcc created assembly code
683
0
  // used negative subsections.
684
0
  if ((Res < 0) && (Res > -8193))
685
0
    Subsection = HexagonMCExpr::create(
686
0
        MCConstantExpr::create(8192 + Res, getContext()), getContext());
687
0
688
0
  getStreamer().SubSection(Subsection);
689
0
  return false;
690
0
}
691
692
///  ::= .falign [expression]
693
1
bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
694
1
695
1
  int64_t MaxBytesToFill = 15;
696
1
697
1
  // if there is an argument
698
1
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
699
0
    const MCExpr *Value;
700
0
    SMLoc ExprLoc = L;
701
0
702
0
    // Make sure we have a number (false is returned if expression is a number)
703
0
    if (!getParser().parseExpression(Value)) {
704
0
      // Make sure this is a number that is in range
705
0
      const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
706
0
      uint64_t IntValue = MCE->getValue();
707
0
      if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
708
0
        return Error(ExprLoc, "literal value out of range (256) for falign");
709
0
      MaxBytesToFill = IntValue;
710
0
      Lex();
711
0
    } else {
712
0
      return Error(ExprLoc, "not a valid expression for falign directive");
713
0
    }
714
1
  }
715
1
716
1
  getTargetStreamer().emitFAlign(16, MaxBytesToFill);
717
1
  Lex();
718
1
719
1
  return false;
720
1
}
721
722
// This is largely a copy of AsmParser's ParseDirectiveComm extended to
723
// accept a 3rd argument, AccessAlignment which indicates the smallest
724
// memory access made to the symbol, expressed in bytes.  If no
725
// AccessAlignment is specified it defaults to the Alignment Value.
726
// Hexagon's .lcomm:
727
//   .lcomm Symbol, Length, Alignment, AccessAlignment
728
6
bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
729
6
  // FIXME: need better way to detect if AsmStreamer (upstream removed
730
6
  // getKind())
731
6
  if (getStreamer().hasRawTextSupport())
732
0
    return true; // Only object file output requires special treatment.
733
6
734
6
  StringRef Name;
735
6
  if (getParser().parseIdentifier(Name))
736
0
    return TokError("expected identifier in directive");
737
6
  // Handle the identifier as the key symbol.
738
6
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
739
6
740
6
  if (getLexer().isNot(AsmToken::Comma))
741
0
    return TokError("unexpected token in directive");
742
6
  Lex();
743
6
744
6
  int64_t Size;
745
6
  SMLoc SizeLoc = getLexer().getLoc();
746
6
  if (getParser().parseAbsoluteExpression(Size))
747
0
    return true;
748
6
749
6
  int64_t ByteAlignment = 1;
750
6
  SMLoc ByteAlignmentLoc;
751
6
  if (getLexer().is(AsmToken::Comma)) {
752
6
    Lex();
753
6
    ByteAlignmentLoc = getLexer().getLoc();
754
6
    if (getParser().parseAbsoluteExpression(ByteAlignment))
755
0
      return true;
756
6
    if (!isPowerOf2_64(ByteAlignment))
757
0
      return Error(ByteAlignmentLoc, "alignment must be a power of 2");
758
6
  }
759
6
760
6
  int64_t AccessAlignment = 0;
761
6
  if (getLexer().is(AsmToken::Comma)) {
762
4
    // The optional access argument specifies the size of the smallest memory
763
4
    //   access to be made to the symbol, expressed in bytes.
764
4
    SMLoc AccessAlignmentLoc;
765
4
    Lex();
766
4
    AccessAlignmentLoc = getLexer().getLoc();
767
4
    if (getParser().parseAbsoluteExpression(AccessAlignment))
768
0
      return true;
769
4
770
4
    if (!isPowerOf2_64(AccessAlignment))
771
0
      return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
772
6
  }
773
6
774
6
  if (getLexer().isNot(AsmToken::EndOfStatement))
775
0
    return TokError("unexpected token in '.comm' or '.lcomm' directive");
776
6
777
6
  Lex();
778
6
779
6
  // NOTE: a size of zero for a .comm should create a undefined symbol
780
6
  // but a size of .lcomm creates a bss symbol of size zero.
781
6
  if (Size < 0)
782
0
    return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
783
0
                          "be less than zero");
784
6
785
6
  // NOTE: The alignment in the directive is a power of 2 value, the assembler
786
6
  // may internally end up wanting an alignment in bytes.
787
6
  // FIXME: Diagnose overflow.
788
6
  if (ByteAlignment < 0)
789
0
    return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
790
0
                                   "alignment, can't be less than zero");
791
6
792
6
  if (!Sym->isUndefined())
793
0
    return Error(Loc, "invalid symbol redefinition");
794
6
795
6
  HexagonMCELFStreamer &HexagonELFStreamer =
796
6
      static_cast<HexagonMCELFStreamer &>(getStreamer());
797
6
  if (IsLocal) {
798
4
    HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
799
4
                                                      AccessAlignment);
800
4
    return false;
801
4
  }
802
2
803
2
  HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
804
2
                                               AccessAlignment);
805
2
  return false;
806
2
}
807
808
// validate register against architecture
809
7.35k
bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
810
7.35k
  if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
811
33
    if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
812
22
      return false;
813
7.33k
  return true;
814
7.33k
}
815
816
// extern "C" void LLVMInitializeHexagonAsmLexer();
817
818
/// Force static initialization.
819
91.7k
extern "C" void LLVMInitializeHexagonAsmParser() {
820
91.7k
  RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
821
91.7k
}
822
823
#define GET_MATCHER_IMPLEMENTATION
824
#define GET_REGISTER_MATCHER
825
#include "HexagonGenAsmMatcher.inc"
826
827
static bool previousEqual(OperandVector &Operands, size_t Index,
828
123k
                          StringRef String) {
829
123k
  if (Index >= Operands.size())
830
16.1k
    return false;
831
107k
  MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
832
107k
  if (!Operand.isToken())
833
27.4k
    return false;
834
79.9k
  return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
835
79.9k
}
836
837
3.18k
static bool previousIsLoop(OperandVector &Operands, size_t Index) {
838
3.18k
  return previousEqual(Operands, Index, "loop0") ||
839
3.18k
         
previousEqual(Operands, Index, "loop1")3.17k
||
840
3.18k
         
previousEqual(Operands, Index, "sp1loop0")3.17k
||
841
3.18k
         
previousEqual(Operands, Index, "sp2loop0")3.17k
||
842
3.18k
         
previousEqual(Operands, Index, "sp3loop0")3.16k
;
843
3.18k
}
844
845
17.4k
bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
846
17.4k
  AsmToken const &Token = getParser().getTok();
847
17.4k
  StringRef String = Token.getString();
848
17.4k
  SMLoc Loc = Token.getLoc();
849
17.4k
  Lex();
850
19.4k
  do {
851
19.4k
    std::pair<StringRef, StringRef> HeadTail = String.split('.');
852
19.4k
    if (!HeadTail.first.empty())
853
17.7k
      Operands.push_back(
854
17.7k
          HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
855
19.4k
    if (!HeadTail.second.empty())
856
1.96k
      Operands.push_back(HexagonOperand::CreateToken(
857
1.96k
          getContext(), String.substr(HeadTail.first.size(), 1), Loc));
858
19.4k
    String = HeadTail.second;
859
19.4k
  } while (!String.empty());
860
17.4k
  return false;
861
17.4k
}
862
863
24.8k
bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
864
24.8k
  unsigned Register;
865
24.8k
  SMLoc Begin;
866
24.8k
  SMLoc End;
867
24.8k
  MCAsmLexer &Lexer = getLexer();
868
24.8k
  if (!ParseRegister(Register, Begin, End)) {
869
7.33k
    if (!ErrorMissingParenthesis)
870
7.33k
      switch (Register) {
871
7.33k
      default:
872
6.26k
        break;
873
7.33k
      case Hexagon::P0:
874
1.07k
      case Hexagon::P1:
875
1.07k
      case Hexagon::P2:
876
1.07k
      case Hexagon::P3:
877
1.07k
        if (previousEqual(Operands, 0, "if")) {
878
0
          if (WarnMissingParenthesis)
879
0
            Warning(Begin, "Missing parenthesis around predicate register");
880
0
          static char const *LParen = "(";
881
0
          static char const *RParen = ")";
882
0
          Operands.push_back(
883
0
              HexagonOperand::CreateToken(getContext(), LParen, Begin));
884
0
          Operands.push_back(
885
0
              HexagonOperand::CreateReg(getContext(), Register, Begin, End));
886
0
          const AsmToken &MaybeDotNew = Lexer.getTok();
887
0
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
888
0
              MaybeDotNew.getString().equals_lower(".new"))
889
0
            splitIdentifier(Operands);
890
0
          Operands.push_back(
891
0
              HexagonOperand::CreateToken(getContext(), RParen, Begin));
892
0
          return false;
893
0
        }
894
1.07k
        if (previousEqual(Operands, 0, "!") &&
895
1.07k
            
previousEqual(Operands, 1, "if")298
) {
896
1
          if (WarnMissingParenthesis)
897
1
            Warning(Begin, "Missing parenthesis around predicate register");
898
1
          static char const *LParen = "(";
899
1
          static char const *RParen = ")";
900
1
          Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
901
1
                                                  getContext(), LParen, Begin));
902
1
          Operands.push_back(
903
1
              HexagonOperand::CreateReg(getContext(), Register, Begin, End));
904
1
          const AsmToken &MaybeDotNew = Lexer.getTok();
905
1
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
906
1
              MaybeDotNew.getString().equals_lower(".new"))
907
0
            splitIdentifier(Operands);
908
1
          Operands.push_back(
909
1
              HexagonOperand::CreateToken(getContext(), RParen, Begin));
910
1
          return false;
911
1
        }
912
1.07k
        break;
913
7.33k
      }
914
7.33k
    Operands.push_back(
915
7.33k
        HexagonOperand::CreateReg(getContext(), Register, Begin, End));
916
7.33k
    return false;
917
7.33k
  }
918
17.4k
  return splitIdentifier(Operands);
919
17.4k
}
920
921
641
bool HexagonAsmParser::isLabel(AsmToken &Token) {
922
641
  MCAsmLexer &Lexer = getLexer();
923
641
  AsmToken const &Second = Lexer.getTok();
924
641
  AsmToken Third = Lexer.peekTok();
925
641
  StringRef String = Token.getString();
926
641
  if (Token.is(AsmToken::TokenKind::LCurly) ||
927
641
      Token.is(AsmToken::TokenKind::RCurly))
928
17
    return false;
929
624
  // special case for parsing vwhist256:sat
930
624
  if (String.lower() == "vwhist256" && 
Second.is(AsmToken::Colon)1
&&
931
624
      
Third.getString().lower() == "sat"1
)
932
1
    return false;
933
623
  if (!Token.is(AsmToken::TokenKind::Identifier))
934
2
    return true;
935
621
  if (!matchRegister(String.lower()))
936
82
    return true;
937
539
  assert(Second.is(AsmToken::Colon));
938
539
  StringRef Raw(String.data(), Third.getString().data() - String.data() +
939
539
                                   Third.getString().size());
940
539
  std::string Collapsed = Raw;
941
539
  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
942
539
  StringRef Whole = Collapsed;
943
539
  std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
944
539
  if (!matchRegister(DotSplit.first.lower()))
945
2
    return true;
946
537
  return false;
947
537
}
948
949
bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
950
7.33k
                                                   SMLoc &Loc) {
951
7.33k
  if (!Contigious && 
ErrorNoncontigiousRegister0
) {
952
0
    Error(Loc, "Register name is not contigious");
953
0
    return true;
954
0
  }
955
7.33k
  if (!Contigious && 
WarnNoncontigiousRegister0
)
956
0
    Warning(Loc, "Register name is not contigious");
957
7.33k
  return false;
958
7.33k
}
959
960
bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
961
24.8k
                                     SMLoc &EndLoc) {
962
24.8k
  MCAsmLexer &Lexer = getLexer();
963
24.8k
  StartLoc = getLexer().getLoc();
964
24.8k
  SmallVector<AsmToken, 5> Lookahead;
965
24.8k
  StringRef RawString(Lexer.getTok().getString().data(), 0);
966
24.8k
  bool Again = Lexer.is(AsmToken::Identifier);
967
24.8k
  bool NeededWorkaround = false;
968
41.1k
  while (Again) {
969
16.3k
    AsmToken const &Token = Lexer.getTok();
970
16.3k
    RawString = StringRef(RawString.data(), Token.getString().data() -
971
16.3k
                                                RawString.data() +
972
16.3k
                                                Token.getString().size());
973
16.3k
    Lookahead.push_back(Token);
974
16.3k
    Lexer.Lex();
975
16.3k
    bool Contigious = Lexer.getTok().getString().data() ==
976
16.3k
                      Lookahead.back().getString().data() +
977
16.3k
                          Lookahead.back().getString().size();
978
16.3k
    bool Type = Lexer.is(AsmToken::Identifier) || 
Lexer.is(AsmToken::Dot)15.8k
||
979
16.3k
                
Lexer.is(AsmToken::Integer)15.8k
||
Lexer.is(AsmToken::Real)14.4k
||
980
16.3k
                
Lexer.is(AsmToken::Colon)14.2k
;
981
16.3k
    bool Workaround =
982
16.3k
        Lexer.is(AsmToken::Colon) || 
Lookahead.back().is(AsmToken::Colon)14.7k
;
983
16.3k
    Again = (Contigious && 
Type13.0k
) ||
(13.0k
Workaround13.0k
&&
Type11
);
984
16.3k
    NeededWorkaround = NeededWorkaround || (Again && 
!(3.22k
Contigious3.22k
&&
Type3.22k
));
985
16.3k
  }
986
24.8k
  std::string Collapsed = RawString;
987
24.8k
  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
988
24.8k
  StringRef FullString = Collapsed;
989
24.8k
  std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
990
24.8k
  unsigned DotReg = matchRegister(DotSplit.first.lower());
991
24.8k
  if (DotReg != Hexagon::NoRegister && 
RegisterMatchesArch(DotReg)7.32k
) {
992
7.31k
    if (DotSplit.second.empty()) {
993
5.63k
      RegNo = DotReg;
994
5.63k
      EndLoc = Lexer.getLoc();
995
5.63k
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
996
0
        return true;
997
5.63k
      return false;
998
5.63k
    } else {
999
1.68k
      RegNo = DotReg;
1000
1.68k
      size_t First = RawString.find('.');
1001
1.68k
      StringRef DotString (RawString.data() + First, RawString.size() - First);
1002
1.68k
      Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1003
1.68k
      EndLoc = Lexer.getLoc();
1004
1.68k
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1005
0
        return true;
1006
1.68k
      return false;
1007
1.68k
    }
1008
7.31k
  }
1009
17.4k
  std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
1010
17.4k
  unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1011
17.4k
  if (ColonReg != Hexagon::NoRegister && 
RegisterMatchesArch(DotReg)29
) {
1012
36
    do {
1013
36
      Lexer.UnLex(Lookahead.back());
1014
36
      Lookahead.pop_back();
1015
36
    } while (!Lookahead.empty () && !Lexer.is(AsmToken::Colon));
1016
18
    RegNo = ColonReg;
1017
18
    EndLoc = Lexer.getLoc();
1018
18
    if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1019
0
      return true;
1020
18
    return false;
1021
18
  }
1022
23.7k
  
while (17.4k
!Lookahead.empty()) {
1023
6.28k
    Lexer.UnLex(Lookahead.back());
1024
6.28k
    Lookahead.pop_back();
1025
6.28k
  }
1026
17.4k
  return true;
1027
17.4k
}
1028
1029
26.2k
bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1030
26.2k
  if (previousEqual(Operands, 0, "call"))
1031
16
    return true;
1032
26.1k
  if (previousEqual(Operands, 0, "jump"))
1033
167
    if (!getLexer().getTok().is(AsmToken::Colon))
1034
21
      return true;
1035
26.1k
  if (previousEqual(Operands, 0, "(") && 
previousIsLoop(Operands, 1)3.18k
)
1036
14
    return true;
1037
26.1k
  if (previousEqual(Operands, 1, ":") && 
previousEqual(Operands, 2, "jump")318
&&
1038
26.1k
      
(146
previousEqual(Operands, 0, "nt")146
||
previousEqual(Operands, 0, "t")69
))
1039
146
    return true;
1040
26.0k
  return false;
1041
26.0k
}
1042
1043
1.39k
bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
1044
1.39k
  SmallVector<AsmToken, 4> Tokens;
1045
1.39k
  MCAsmLexer &Lexer = getLexer();
1046
1.39k
  bool Done = false;
1047
1.39k
  static char const *Comma = ",";
1048
5.50k
  do {
1049
5.50k
    Tokens.emplace_back(Lexer.getTok());
1050
5.50k
    Lex();
1051
5.50k
    switch (Tokens.back().getKind()) {
1052
5.50k
    case AsmToken::TokenKind::Hash:
1053
86
      if (Tokens.size() > 1)
1054
86
        if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1055
12
          Tokens.insert(Tokens.end() - 2,
1056
12
                        AsmToken(AsmToken::TokenKind::Comma, Comma));
1057
12
          Done = true;
1058
12
        }
1059
86
      break;
1060
5.50k
    case AsmToken::TokenKind::RCurly:
1061
1.38k
    case AsmToken::TokenKind::EndOfStatement:
1062
1.38k
    case AsmToken::TokenKind::Eof:
1063
1.38k
      Done = true;
1064
1.38k
      break;
1065
4.03k
    default:
1066
4.03k
      break;
1067
5.50k
    }
1068
5.50k
  } while (!Done);
1069
6.91k
  
while (1.39k
!Tokens.empty()) {
1070
5.51k
    Lexer.UnLex(Tokens.back());
1071
5.51k
    Tokens.pop_back();
1072
5.51k
  }
1073
1.39k
  SMLoc Loc = Lexer.getLoc();
1074
1.39k
  return getParser().parseExpression(Expr, Loc);
1075
1.39k
}
1076
1077
24.9k
bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1078
24.9k
  if (implicitExpressionLocation(Operands)) {
1079
174
    MCAsmParser &Parser = getParser();
1080
174
    SMLoc Loc = Parser.getLexer().getLoc();
1081
174
    MCExpr const *Expr = nullptr;
1082
174
    bool Error = parseExpression(Expr);
1083
174
    Expr = HexagonMCExpr::create(Expr, getContext());
1084
174
    if (!Error)
1085
174
      Operands.push_back(
1086
174
          HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1087
174
    return Error;
1088
174
  }
1089
24.8k
  return parseOperand(Operands);
1090
24.8k
}
1091
1092
/// Parse an instruction.
1093
4.42k
bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1094
4.42k
  MCAsmParser &Parser = getParser();
1095
4.42k
  MCAsmLexer &Lexer = getLexer();
1096
32.3k
  while (true) {
1097
32.3k
    AsmToken const &Token = Parser.getTok();
1098
32.3k
    switch (Token.getKind()) {
1099
32.3k
    case AsmToken::Eof:
1100
2.65k
    case AsmToken::EndOfStatement: {
1101
2.65k
      Lex();
1102
2.65k
      return false;
1103
2.65k
    }
1104
2.65k
    case AsmToken::LCurly: {
1105
667
      if (!Operands.empty())
1106
0
        return true;
1107
667
      Operands.push_back(HexagonOperand::CreateToken(
1108
667
          getContext(), Token.getString(), Token.getLoc()));
1109
667
      Lex();
1110
667
      return false;
1111
667
    }
1112
1.09k
    case AsmToken::RCurly: {
1113
1.09k
      if (Operands.empty()) {
1114
665
        Operands.push_back(HexagonOperand::CreateToken(
1115
665
            getContext(), Token.getString(), Token.getLoc()));
1116
665
        Lex();
1117
665
      }
1118
1.09k
      return false;
1119
667
    }
1120
1.44k
    case AsmToken::Comma: {
1121
1.44k
      Lex();
1122
1.44k
      continue;
1123
667
    }
1124
667
    case AsmToken::EqualEqual:
1125
252
    case AsmToken::ExclaimEqual:
1126
252
    case AsmToken::GreaterEqual:
1127
252
    case AsmToken::GreaterGreater:
1128
252
    case AsmToken::LessEqual:
1129
252
    case AsmToken::LessLess: {
1130
252
      Operands.push_back(HexagonOperand::CreateToken(
1131
252
          getContext(), Token.getString().substr(0, 1), Token.getLoc()));
1132
252
      Operands.push_back(HexagonOperand::CreateToken(
1133
252
          getContext(), Token.getString().substr(1, 1), Token.getLoc()));
1134
252
      Lex();
1135
252
      continue;
1136
252
    }
1137
1.22k
    case AsmToken::Hash: {
1138
1.22k
      bool MustNotExtend = false;
1139
1.22k
      bool ImplicitExpression = implicitExpressionLocation(Operands);
1140
1.22k
      SMLoc ExprLoc = Lexer.getLoc();
1141
1.22k
      if (!ImplicitExpression)
1142
1.19k
        Operands.push_back(HexagonOperand::CreateToken(
1143
1.19k
            getContext(), Token.getString(), Token.getLoc()));
1144
1.22k
      Lex();
1145
1.22k
      bool MustExtend = false;
1146
1.22k
      bool HiOnly = false;
1147
1.22k
      bool LoOnly = false;
1148
1.22k
      if (Lexer.is(AsmToken::Hash)) {
1149
258
        Lex();
1150
258
        MustExtend = true;
1151
963
      } else if (ImplicitExpression)
1152
10
        MustNotExtend = true;
1153
1.22k
      AsmToken const &Token = Parser.getTok();
1154
1.22k
      if (Token.is(AsmToken::Identifier)) {
1155
139
        StringRef String = Token.getString();
1156
139
        if (String.lower() == "hi") {
1157
11
          HiOnly = true;
1158
128
        } else if (String.lower() == "lo") {
1159
10
          LoOnly = true;
1160
10
        }
1161
139
        if (HiOnly || 
LoOnly128
) {
1162
21
          AsmToken LParen = Lexer.peekTok();
1163
21
          if (!LParen.is(AsmToken::LParen)) {
1164
8
            HiOnly = false;
1165
8
            LoOnly = false;
1166
13
          } else {
1167
13
            Lex();
1168
13
          }
1169
21
        }
1170
139
      }
1171
1.22k
      MCExpr const *Expr = nullptr;
1172
1.22k
      if (parseExpression(Expr))
1173
0
        return true;
1174
1.22k
      int64_t Value;
1175
1.22k
      MCContext &Context = Parser.getContext();
1176
1.22k
      assert(Expr != nullptr);
1177
1.22k
      if (Expr->evaluateAsAbsolute(Value)) {
1178
1.09k
        if (HiOnly)
1179
5
          Expr = MCBinaryExpr::createLShr(
1180
5
              Expr, MCConstantExpr::create(16, Context), Context);
1181
1.09k
        if (HiOnly || 
LoOnly1.08k
)
1182
9
          Expr = MCBinaryExpr::createAnd(
1183
9
              Expr, MCConstantExpr::create(0xffff, Context), Context);
1184
1.09k
      } else {
1185
130
        MCValue Value;
1186
130
        if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1187
130
          if (!Value.isAbsolute()) {
1188
130
            switch (Value.getAccessVariant()) {
1189
130
            case MCSymbolRefExpr::VariantKind::VK_TPREL:
1190
9
            case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1191
9
              // Don't lazy extend these expression variants
1192
9
              MustNotExtend = !MustExtend;
1193
9
              break;
1194
121
            default:
1195
121
              break;
1196
1.22k
            }
1197
1.22k
          }
1198
130
        }
1199
130
      }
1200
1.22k
      Expr = HexagonMCExpr::create(Expr, Context);
1201
1.22k
      HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
1202
1.22k
      HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
1203
1.22k
      std::unique_ptr<HexagonOperand> Operand =
1204
1.22k
          HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1205
1.22k
      Operands.push_back(std::move(Operand));
1206
1.22k
      continue;
1207
1.22k
    }
1208
24.9k
    default:
1209
24.9k
      break;
1210
24.9k
    }
1211
24.9k
    if (parseExpressionOrOperand(Operands))
1212
0
      return true;
1213
24.9k
  }
1214
4.42k
}
1215
1216
bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1217
                                        StringRef Name, AsmToken ID,
1218
4.42k
                                        OperandVector &Operands) {
1219
4.42k
  getLexer().UnLex(ID);
1220
4.42k
  return parseInstruction(Operands);
1221
4.42k
}
1222
1223
static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
1224
3
                              MCOperand &MO2) {
1225
3
  MCInst TmpInst;
1226
3
  TmpInst.setOpcode(opCode);
1227
3
  TmpInst.addOperand(Rdd);
1228
3
  TmpInst.addOperand(MO1);
1229
3
  TmpInst.addOperand(MO2);
1230
3
1231
3
  return TmpInst;
1232
3
}
1233
1234
// Define this matcher function after the auto-generated include so we
1235
// have the match class enum definitions.
1236
unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1237
1.59M
                                                      unsigned Kind) {
1238
1.59M
  HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1239
1.59M
1240
1.59M
  switch (Kind) {
1241
1.59M
  case MCK_0: {
1242
23
    int64_t Value;
1243
23
    return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1244
23
               ? Match_Success
1245
23
               : 
Match_InvalidOperand0
;
1246
1.59M
  }
1247
1.59M
  case MCK_1: {
1248
2
    int64_t Value;
1249
2
    return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1250
2
               ? Match_Success
1251
2
               : 
Match_InvalidOperand0
;
1252
1.59M
  }
1253
1.59M
  }
1254
1.59M
  if (Op->Kind == HexagonOperand::Token && 
Kind != InvalidMatchClass428k
) {
1255
428k
    StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1256
428k
    if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1257
47
      return Match_Success;
1258
428k
    if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1259
0
      return Match_Success;
1260
1.59M
  }
1261
1.59M
1262
1.59M
  LLVM_DEBUG(dbgs() << "Unmatched Operand:");
1263
1.59M
  LLVM_DEBUG(Op->dump());
1264
1.59M
  LLVM_DEBUG(dbgs() << "\n");
1265
1.59M
1266
1.59M
  return Match_InvalidOperand;
1267
1.59M
}
1268
1269
// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1270
1
bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1271
1
  std::string errStr;
1272
1
  raw_string_ostream ES(errStr);
1273
1
  ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1274
1
  if (Max >= 0)
1275
0
    ES << "0-" << Max;
1276
1
  else
1277
1
    ES << Max << "-" << (-Max - 1);
1278
1
  return Parser.printError(IDLoc, ES.str());
1279
1
}
1280
1281
int HexagonAsmParser::processInstruction(MCInst &Inst,
1282
                                         OperandVector const &Operands,
1283
3.07k
                                         SMLoc IDLoc) {
1284
3.07k
  MCContext &Context = getParser().getContext();
1285
3.07k
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
1286
3.07k
  std::string r = "r";
1287
3.07k
  std::string v = "v";
1288
3.07k
  std::string Colon = ":";
1289
3.07k
1290
3.07k
  bool is32bit = false; // used to distinguish between CONST32 and CONST64
1291
3.07k
  switch (Inst.getOpcode()) {
1292
3.07k
  default:
1293
2.96k
    if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
1294
0
      SMDiagnostic Diag = getSourceManager().GetMessage(
1295
0
          IDLoc, SourceMgr::DK_Error,
1296
0
          "Found pseudo instruction with no expansion");
1297
0
      Diag.print("", errs());
1298
0
      report_fatal_error("Invalid pseudo instruction");
1299
0
    }
1300
2.96k
    break;
1301
2.96k
1302
2.96k
  case Hexagon::J2_trap1:
1303
4
    if (!getSTI().getFeatureBits()[Hexagon::ArchV65]) {
1304
1
      MCOperand &Rx = Inst.getOperand(0);
1305
1
      MCOperand &Ry = Inst.getOperand(1);
1306
1
      if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {
1307
0
        Error(IDLoc, "trap1 can only have register r0 as operand");
1308
0
        return Match_InvalidOperand;
1309
0
      }
1310
4
    }
1311
4
    break;
1312
4
1313
4
  case Hexagon::A2_iconst: {
1314
1
    Inst.setOpcode(Hexagon::A2_addi);
1315
1
    MCOperand Reg = Inst.getOperand(0);
1316
1
    MCOperand S27 = Inst.getOperand(1);
1317
1
    HexagonMCInstrInfo::setMustNotExtend(*S27.getExpr());
1318
1
    HexagonMCInstrInfo::setS27_2_reloc(*S27.getExpr());
1319
1
    Inst.clear();
1320
1
    Inst.addOperand(Reg);
1321
1
    Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1322
1
    Inst.addOperand(S27);
1323
1
    break;
1324
4
  }
1325
11
  case Hexagon::M4_mpyrr_addr:
1326
11
  case Hexagon::S4_addi_asl_ri:
1327
11
  case Hexagon::S4_addi_lsr_ri:
1328
11
  case Hexagon::S4_andi_asl_ri:
1329
11
  case Hexagon::S4_andi_lsr_ri:
1330
11
  case Hexagon::S4_ori_asl_ri:
1331
11
  case Hexagon::S4_ori_lsr_ri:
1332
11
  case Hexagon::S4_or_andix:
1333
11
  case Hexagon::S4_subi_asl_ri:
1334
11
  case Hexagon::S4_subi_lsr_ri: {
1335
11
    MCOperand &Ry = Inst.getOperand(0);
1336
11
    MCOperand &src = Inst.getOperand(2);
1337
11
    if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1338
0
      return Match_InvalidOperand;
1339
11
    break;
1340
11
  }
1341
11
1342
11
  case Hexagon::C2_cmpgei: {
1343
1
    MCOperand &MO = Inst.getOperand(2);
1344
1
    MO.setExpr(HexagonMCExpr::create(
1345
1
        MCBinaryExpr::createSub(MO.getExpr(),
1346
1
                                MCConstantExpr::create(1, Context), Context),
1347
1
        Context));
1348
1
    Inst.setOpcode(Hexagon::C2_cmpgti);
1349
1
    break;
1350
11
  }
1351
11
1352
11
  case Hexagon::C2_cmpgeui: {
1353
1
    MCOperand &MO = Inst.getOperand(2);
1354
1
    int64_t Value;
1355
1
    bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
1356
1
    (void)Success;
1357
1
    assert(Success && "Assured by matcher");
1358
1
    if (Value == 0) {
1359
0
      MCInst TmpInst;
1360
0
      MCOperand &Pd = Inst.getOperand(0);
1361
0
      MCOperand &Rt = Inst.getOperand(1);
1362
0
      TmpInst.setOpcode(Hexagon::C2_cmpeq);
1363
0
      TmpInst.addOperand(Pd);
1364
0
      TmpInst.addOperand(Rt);
1365
0
      TmpInst.addOperand(Rt);
1366
0
      Inst = TmpInst;
1367
1
    } else {
1368
1
      MO.setExpr(HexagonMCExpr::create(
1369
1
          MCBinaryExpr::createSub(MO.getExpr(),
1370
1
                                  MCConstantExpr::create(1, Context), Context),
1371
1
          Context));
1372
1
      Inst.setOpcode(Hexagon::C2_cmpgtui);
1373
1
    }
1374
1
    break;
1375
11
  }
1376
11
1377
11
  // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1378
11
  case Hexagon::A2_tfrp: {
1379
3
    MCOperand &MO = Inst.getOperand(1);
1380
3
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1381
3
    std::string R1 = r + utostr(RegPairNum + 1);
1382
3
    StringRef Reg1(R1);
1383
3
    MO.setReg(matchRegister(Reg1));
1384
3
    // Add a new operand for the second register in the pair.
1385
3
    std::string R2 = r + utostr(RegPairNum);
1386
3
    StringRef Reg2(R2);
1387
3
    Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1388
3
    Inst.setOpcode(Hexagon::A2_combinew);
1389
3
    break;
1390
11
  }
1391
11
1392
11
  case Hexagon::A2_tfrpt:
1393
2
  case Hexagon::A2_tfrpf: {
1394
2
    MCOperand &MO = Inst.getOperand(2);
1395
2
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1396
2
    std::string R1 = r + utostr(RegPairNum + 1);
1397
2
    StringRef Reg1(R1);
1398
2
    MO.setReg(matchRegister(Reg1));
1399
2
    // Add a new operand for the second register in the pair.
1400
2
    std::string R2 = r + utostr(RegPairNum);
1401
2
    StringRef Reg2(R2);
1402
2
    Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1403
2
    Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1404
2
                       ? 
Hexagon::C2_ccombinewt1
1405
2
                       : 
Hexagon::C2_ccombinewf1
);
1406
2
    break;
1407
2
  }
1408
2
  case Hexagon::A2_tfrptnew:
1409
2
  case Hexagon::A2_tfrpfnew: {
1410
2
    MCOperand &MO = Inst.getOperand(2);
1411
2
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1412
2
    std::string R1 = r + utostr(RegPairNum + 1);
1413
2
    StringRef Reg1(R1);
1414
2
    MO.setReg(matchRegister(Reg1));
1415
2
    // Add a new operand for the second register in the pair.
1416
2
    std::string R2 = r + utostr(RegPairNum);
1417
2
    StringRef Reg2(R2);
1418
2
    Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1419
2
    Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1420
2
                       ? 
Hexagon::C2_ccombinewnewt1
1421
2
                       : 
Hexagon::C2_ccombinewnewf1
);
1422
2
    break;
1423
2
  }
1424
2
1425
2
  // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
1426
2
  case Hexagon::V6_vassignp: {
1427
1
    MCOperand &MO = Inst.getOperand(1);
1428
1
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1429
1
    std::string R1 = v + utostr(RegPairNum + 1);
1430
1
    MO.setReg(MatchRegisterName(R1));
1431
1
    // Add a new operand for the second register in the pair.
1432
1
    std::string R2 = v + utostr(RegPairNum);
1433
1
    Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
1434
1
    Inst.setOpcode(Hexagon::V6_vcombine);
1435
1
    break;
1436
2
  }
1437
2
1438
2
  // Translate a "$Rx =  CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1439
2
  case Hexagon::CONST32:
1440
0
    is32bit = true;
1441
0
    LLVM_FALLTHROUGH;
1442
0
  // Translate a "$Rx:y =  CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1443
0
  case Hexagon::CONST64:
1444
0
    // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1445
0
    if (!Parser.getStreamer().hasRawTextSupport()) {
1446
0
      MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1447
0
      MCOperand &MO_1 = Inst.getOperand(1);
1448
0
      MCOperand &MO_0 = Inst.getOperand(0);
1449
0
1450
0
      // push section onto section stack
1451
0
      MES->PushSection();
1452
0
1453
0
      std::string myCharStr;
1454
0
      MCSectionELF *mySection;
1455
0
1456
0
      // check if this as an immediate or a symbol
1457
0
      int64_t Value;
1458
0
      bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1459
0
      if (Absolute) {
1460
0
        // Create a new section - one for each constant
1461
0
        // Some or all of the zeros are replaced with the given immediate.
1462
0
        if (is32bit) {
1463
0
          std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1464
0
          myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1465
0
                          .drop_back(myImmStr.size())
1466
0
                          .str() +
1467
0
                      myImmStr;
1468
0
        } else {
1469
0
          std::string myImmStr = utohexstr(Value);
1470
0
          myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1471
0
                          .drop_back(myImmStr.size())
1472
0
                          .str() +
1473
0
                      myImmStr;
1474
0
        }
1475
0
1476
0
        mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1477
0
                                               ELF::SHF_ALLOC | ELF::SHF_WRITE);
1478
0
      } else if (MO_1.isExpr()) {
1479
0
        // .lita - for expressions
1480
0
        myCharStr = ".lita";
1481
0
        mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1482
0
                                               ELF::SHF_ALLOC | ELF::SHF_WRITE);
1483
0
      } else
1484
0
        llvm_unreachable("unexpected type of machine operand!");
1485
0
1486
0
      MES->SwitchSection(mySection);
1487
0
      unsigned byteSize = is32bit ? 4 : 8;
1488
0
      getStreamer().EmitCodeAlignment(byteSize, byteSize);
1489
0
1490
0
      MCSymbol *Sym;
1491
0
1492
0
      // for symbols, get rid of prepended ".gnu.linkonce.lx."
1493
0
1494
0
      // emit symbol if needed
1495
0
      if (Absolute) {
1496
0
        Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1497
0
        if (Sym->isUndefined()) {
1498
0
          getStreamer().EmitLabel(Sym);
1499
0
          getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1500
0
          getStreamer().EmitIntValue(Value, byteSize);
1501
0
        }
1502
0
      } else if (MO_1.isExpr()) {
1503
0
        const char *StringStart = nullptr;
1504
0
        const char *StringEnd = nullptr;
1505
0
        if (*Operands[4]->getStartLoc().getPointer() == '#') {
1506
0
          StringStart = Operands[5]->getStartLoc().getPointer();
1507
0
          StringEnd = Operands[6]->getStartLoc().getPointer();
1508
0
        } else { // no pound
1509
0
          StringStart = Operands[4]->getStartLoc().getPointer();
1510
0
          StringEnd = Operands[5]->getStartLoc().getPointer();
1511
0
        }
1512
0
1513
0
        unsigned size = StringEnd - StringStart;
1514
0
        std::string DotConst = ".CONST_";
1515
0
        Sym = getContext().getOrCreateSymbol(DotConst +
1516
0
                                             StringRef(StringStart, size));
1517
0
1518
0
        if (Sym->isUndefined()) {
1519
0
          // case where symbol is not yet defined: emit symbol
1520
0
          getStreamer().EmitLabel(Sym);
1521
0
          getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1522
0
          getStreamer().EmitValue(MO_1.getExpr(), 4);
1523
0
        }
1524
0
      } else
1525
0
        llvm_unreachable("unexpected type of machine operand!");
1526
0
1527
0
      MES->PopSection();
1528
0
1529
0
      if (Sym) {
1530
0
        MCInst TmpInst;
1531
0
        if (is32bit) // 32 bit
1532
0
          TmpInst.setOpcode(Hexagon::L2_loadrigp);
1533
0
        else // 64 bit
1534
0
          TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1535
0
1536
0
        TmpInst.addOperand(MO_0);
1537
0
        TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
1538
0
            MCSymbolRefExpr::create(Sym, getContext()), getContext())));
1539
0
        Inst = TmpInst;
1540
0
      }
1541
0
    }
1542
0
    break;
1543
0
1544
0
  // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1545
1
  case Hexagon::A2_tfrpi: {
1546
1
    MCOperand &Rdd = Inst.getOperand(0);
1547
1
    MCOperand &MO = Inst.getOperand(1);
1548
1
    int64_t Value;
1549
1
    int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 
00
;
1550
1
    MCOperand imm(MCOperand::createExpr(
1551
1
        HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
1552
1
    Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1553
1
    break;
1554
0
  }
1555
0
1556
0
  // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1557
1
  case Hexagon::TFRI64_V4: {
1558
1
    MCOperand &Rdd = Inst.getOperand(0);
1559
1
    MCOperand &MO = Inst.getOperand(1);
1560
1
    int64_t Value;
1561
1
    if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1562
1
      int s8 = Hi_32(Value);
1563
1
      if (!isInt<8>(s8))
1564
1
        OutOfRange(IDLoc, s8, -128);
1565
1
      MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
1566
1
          MCConstantExpr::create(s8, Context), Context))); // upper 32
1567
1
      auto Expr = HexagonMCExpr::create(
1568
1
          MCConstantExpr::create(Lo_32(Value), Context), Context);
1569
1
      HexagonMCInstrInfo::setMustExtend(
1570
1
          *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
1571
1
      MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
1572
1
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1573
1
    } else {
1574
0
      MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
1575
0
          MCConstantExpr::create(0, Context), Context))); // upper 32
1576
0
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1577
0
    }
1578
1
    break;
1579
0
  }
1580
0
1581
0
  // Handle $Rdd = combine(##imm, #imm)"
1582
0
  case Hexagon::TFRI64_V2_ext: {
1583
0
    MCOperand &Rdd = Inst.getOperand(0);
1584
0
    MCOperand &MO1 = Inst.getOperand(1);
1585
0
    MCOperand &MO2 = Inst.getOperand(2);
1586
0
    int64_t Value;
1587
0
    if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1588
0
      int s8 = Value;
1589
0
      if (s8 < -128 || s8 > 127)
1590
0
        OutOfRange(IDLoc, s8, -128);
1591
0
    }
1592
0
    Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1593
0
    break;
1594
0
  }
1595
0
1596
0
  // Handle $Rdd = combine(#imm, ##imm)"
1597
1
  case Hexagon::A4_combineii: {
1598
1
    MCOperand &Rdd = Inst.getOperand(0);
1599
1
    MCOperand &MO1 = Inst.getOperand(1);
1600
1
    int64_t Value;
1601
1
    if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1602
1
      int s8 = Value;
1603
1
      if (s8 < -128 || s8 > 127)
1604
0
        OutOfRange(IDLoc, s8, -128);
1605
1
    }
1606
1
    MCOperand &MO2 = Inst.getOperand(2);
1607
1
    Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1608
1
    break;
1609
0
  }
1610
0
1611
0
  case Hexagon::S2_tableidxb_goodsyntax:
1612
0
    Inst.setOpcode(Hexagon::S2_tableidxb);
1613
0
    break;
1614
0
1615
1
  case Hexagon::S2_tableidxh_goodsyntax: {
1616
1
    MCInst TmpInst;
1617
1
    MCOperand &Rx = Inst.getOperand(0);
1618
1
    MCOperand &Rs = Inst.getOperand(2);
1619
1
    MCOperand &Imm4 = Inst.getOperand(3);
1620
1
    MCOperand &Imm6 = Inst.getOperand(4);
1621
1
    Imm6.setExpr(HexagonMCExpr::create(
1622
1
        MCBinaryExpr::createSub(Imm6.getExpr(),
1623
1
                                MCConstantExpr::create(1, Context), Context),
1624
1
        Context));
1625
1
    TmpInst.setOpcode(Hexagon::S2_tableidxh);
1626
1
    TmpInst.addOperand(Rx);
1627
1
    TmpInst.addOperand(Rx);
1628
1
    TmpInst.addOperand(Rs);
1629
1
    TmpInst.addOperand(Imm4);
1630
1
    TmpInst.addOperand(Imm6);
1631
1
    Inst = TmpInst;
1632
1
    break;
1633
0
  }
1634
0
1635
1
  case Hexagon::S2_tableidxw_goodsyntax: {
1636
1
    MCInst TmpInst;
1637
1
    MCOperand &Rx = Inst.getOperand(0);
1638
1
    MCOperand &Rs = Inst.getOperand(2);
1639
1
    MCOperand &Imm4 = Inst.getOperand(3);
1640
1
    MCOperand &Imm6 = Inst.getOperand(4);
1641
1
    Imm6.setExpr(HexagonMCExpr::create(
1642
1
        MCBinaryExpr::createSub(Imm6.getExpr(),
1643
1
                                MCConstantExpr::create(2, Context), Context),
1644
1
        Context));
1645
1
    TmpInst.setOpcode(Hexagon::S2_tableidxw);
1646
1
    TmpInst.addOperand(Rx);
1647
1
    TmpInst.addOperand(Rx);
1648
1
    TmpInst.addOperand(Rs);
1649
1
    TmpInst.addOperand(Imm4);
1650
1
    TmpInst.addOperand(Imm6);
1651
1
    Inst = TmpInst;
1652
1
    break;
1653
0
  }
1654
0
1655
1
  case Hexagon::S2_tableidxd_goodsyntax: {
1656
1
    MCInst TmpInst;
1657
1
    MCOperand &Rx = Inst.getOperand(0);
1658
1
    MCOperand &Rs = Inst.getOperand(2);
1659
1
    MCOperand &Imm4 = Inst.getOperand(3);
1660
1
    MCOperand &Imm6 = Inst.getOperand(4);
1661
1
    Imm6.setExpr(HexagonMCExpr::create(
1662
1
        MCBinaryExpr::createSub(Imm6.getExpr(),
1663
1
                                MCConstantExpr::create(3, Context), Context),
1664
1
        Context));
1665
1
    TmpInst.setOpcode(Hexagon::S2_tableidxd);
1666
1
    TmpInst.addOperand(Rx);
1667
1
    TmpInst.addOperand(Rx);
1668
1
    TmpInst.addOperand(Rs);
1669
1
    TmpInst.addOperand(Imm4);
1670
1
    TmpInst.addOperand(Imm6);
1671
1
    Inst = TmpInst;
1672
1
    break;
1673
0
  }
1674
0
1675
0
  case Hexagon::M2_mpyui:
1676
0
    Inst.setOpcode(Hexagon::M2_mpyi);
1677
0
    break;
1678
4
  case Hexagon::M2_mpysmi: {
1679
4
    MCInst TmpInst;
1680
4
    MCOperand &Rd = Inst.getOperand(0);
1681
4
    MCOperand &Rs = Inst.getOperand(1);
1682
4
    MCOperand &Imm = Inst.getOperand(2);
1683
4
    int64_t Value;
1684
4
    MCExpr const &Expr = *Imm.getExpr();
1685
4
    bool Absolute = Expr.evaluateAsAbsolute(Value);
1686
4
    if (!Absolute)
1687
1
      return Match_InvalidOperand;
1688
3
    if (!HexagonMCInstrInfo::mustExtend(Expr) &&
1689
3
        ((Value <= -256) || 
Value >= 2562
))
1690
2
      return Match_InvalidOperand;
1691
1
    if (Value < 0 && 
Value > -2560
) {
1692
0
      Imm.setExpr(HexagonMCExpr::create(
1693
0
          MCConstantExpr::create(Value * -1, Context), Context));
1694
0
      TmpInst.setOpcode(Hexagon::M2_mpysin);
1695
0
    } else
1696
1
      TmpInst.setOpcode(Hexagon::M2_mpysip);
1697
1
    TmpInst.addOperand(Rd);
1698
1
    TmpInst.addOperand(Rs);
1699
1
    TmpInst.addOperand(Imm);
1700
1
    Inst = TmpInst;
1701
1
    break;
1702
1
  }
1703
1
1704
1
  case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1705
1
    MCOperand &Imm = Inst.getOperand(2);
1706
1
    MCInst TmpInst;
1707
1
    int64_t Value;
1708
1
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1709
1
    if (!Absolute)
1710
0
      return Match_InvalidOperand;
1711
1
    if (Value == 0) { // convert to $Rd = $Rs
1712
0
      TmpInst.setOpcode(Hexagon::A2_tfr);
1713
0
      MCOperand &Rd = Inst.getOperand(0);
1714
0
      MCOperand &Rs = Inst.getOperand(1);
1715
0
      TmpInst.addOperand(Rd);
1716
0
      TmpInst.addOperand(Rs);
1717
1
    } else {
1718
1
      Imm.setExpr(HexagonMCExpr::create(
1719
1
          MCBinaryExpr::createSub(Imm.getExpr(),
1720
1
                                  MCConstantExpr::create(1, Context), Context),
1721
1
          Context));
1722
1
      TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1723
1
      MCOperand &Rd = Inst.getOperand(0);
1724
1
      MCOperand &Rs = Inst.getOperand(1);
1725
1
      TmpInst.addOperand(Rd);
1726
1
      TmpInst.addOperand(Rs);
1727
1
      TmpInst.addOperand(Imm);
1728
1
    }
1729
1
    Inst = TmpInst;
1730
1
    break;
1731
1
  }
1732
1
1733
1
  case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1734
0
    MCOperand &Rdd = Inst.getOperand(0);
1735
0
    MCOperand &Rss = Inst.getOperand(1);
1736
0
    MCOperand &Imm = Inst.getOperand(2);
1737
0
    int64_t Value;
1738
0
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1739
0
    if (!Absolute)
1740
0
      return Match_InvalidOperand;
1741
0
    if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1742
0
      MCInst TmpInst;
1743
0
      unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1744
0
      std::string R1 = r + utostr(RegPairNum + 1);
1745
0
      StringRef Reg1(R1);
1746
0
      Rss.setReg(matchRegister(Reg1));
1747
0
      // Add a new operand for the second register in the pair.
1748
0
      std::string R2 = r + utostr(RegPairNum);
1749
0
      StringRef Reg2(R2);
1750
0
      TmpInst.setOpcode(Hexagon::A2_combinew);
1751
0
      TmpInst.addOperand(Rdd);
1752
0
      TmpInst.addOperand(Rss);
1753
0
      TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1754
0
      Inst = TmpInst;
1755
0
    } else {
1756
0
      Imm.setExpr(HexagonMCExpr::create(
1757
0
          MCBinaryExpr::createSub(Imm.getExpr(),
1758
0
                                  MCConstantExpr::create(1, Context), Context),
1759
0
          Context));
1760
0
      Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1761
0
    }
1762
0
    break;
1763
0
  }
1764
0
1765
1
  case Hexagon::A4_boundscheck: {
1766
1
    MCOperand &Rs = Inst.getOperand(1);
1767
1
    unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1768
1
    if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1769
1
      Inst.setOpcode(Hexagon::A4_boundscheck_hi);
1770
1
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1771
1
      StringRef RegPair = Name;
1772
1
      Rs.setReg(matchRegister(RegPair));
1773
1
    } else { // raw:lo
1774
0
      Inst.setOpcode(Hexagon::A4_boundscheck_lo);
1775
0
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1776
0
      StringRef RegPair = Name;
1777
0
      Rs.setReg(matchRegister(RegPair));
1778
0
    }
1779
1
    break;
1780
0
  }
1781
0
1782
1
  case Hexagon::A2_addsp: {
1783
1
    MCOperand &Rs = Inst.getOperand(1);
1784
1
    unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1785
1
    if (RegNum & 1) { // Odd mapped to raw:hi
1786
0
      Inst.setOpcode(Hexagon::A2_addsph);
1787
0
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1788
0
      StringRef RegPair = Name;
1789
0
      Rs.setReg(matchRegister(RegPair));
1790
1
    } else { // Even mapped raw:lo
1791
1
      Inst.setOpcode(Hexagon::A2_addspl);
1792
1
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1793
1
      StringRef RegPair = Name;
1794
1
      Rs.setReg(matchRegister(RegPair));
1795
1
    }
1796
1
    break;
1797
0
  }
1798
0
1799
1
  case Hexagon::M2_vrcmpys_s1: {
1800
1
    MCOperand &Rt = Inst.getOperand(2);
1801
1
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1802
1
    if (RegNum & 1) { // Odd mapped to sat:raw:hi
1803
0
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
1804
0
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1805
0
      StringRef RegPair = Name;
1806
0
      Rt.setReg(matchRegister(RegPair));
1807
1
    } else { // Even mapped sat:raw:lo
1808
1
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
1809
1
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1810
1
      StringRef RegPair = Name;
1811
1
      Rt.setReg(matchRegister(RegPair));
1812
1
    }
1813
1
    break;
1814
0
  }
1815
0
1816
1
  case Hexagon::M2_vrcmpys_acc_s1: {
1817
1
    MCInst TmpInst;
1818
1
    MCOperand &Rxx = Inst.getOperand(0);
1819
1
    MCOperand &Rss = Inst.getOperand(2);
1820
1
    MCOperand &Rt = Inst.getOperand(3);
1821
1
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1822
1
    if (RegNum & 1) { // Odd mapped to sat:raw:hi
1823
0
      TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
1824
0
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1825
0
      StringRef RegPair = Name;
1826
0
      Rt.setReg(matchRegister(RegPair));
1827
1
    } else { // Even mapped sat:raw:lo
1828
1
      TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1829
1
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1830
1
      StringRef RegPair = Name;
1831
1
      Rt.setReg(matchRegister(RegPair));
1832
1
    }
1833
1
    // Registers are in different positions
1834
1
    TmpInst.addOperand(Rxx);
1835
1
    TmpInst.addOperand(Rxx);
1836
1
    TmpInst.addOperand(Rss);
1837
1
    TmpInst.addOperand(Rt);
1838
1
    Inst = TmpInst;
1839
1
    break;
1840
0
  }
1841
0
1842
3
  case Hexagon::M2_vrcmpys_s1rp: {
1843
3
    MCOperand &Rt = Inst.getOperand(2);
1844
3
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1845
3
    if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
1846
1
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1847
1
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1848
1
      StringRef RegPair = Name;
1849
1
      Rt.setReg(matchRegister(RegPair));
1850
2
    } else { // Even mapped rnd:sat:raw:lo
1851
2
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1852
2
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1853
2
      StringRef RegPair = Name;
1854
2
      Rt.setReg(matchRegister(RegPair));
1855
2
    }
1856
3
    break;
1857
0
  }
1858
0
1859
1
  case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1860
1
    MCOperand &Imm = Inst.getOperand(2);
1861
1
    int64_t Value;
1862
1
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1863
1
    if (!Absolute)
1864
0
      return Match_InvalidOperand;
1865
1
    if (Value == 0)
1866
0
      Inst.setOpcode(Hexagon::S2_vsathub);
1867
1
    else {
1868
1
      Imm.setExpr(HexagonMCExpr::create(
1869
1
          MCBinaryExpr::createSub(Imm.getExpr(),
1870
1
                                  MCConstantExpr::create(1, Context), Context),
1871
1
          Context));
1872
1
      Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
1873
1
    }
1874
1
    break;
1875
1
  }
1876
1
1877
1
  case Hexagon::S5_vasrhrnd_goodsyntax: {
1878
1
    MCOperand &Rdd = Inst.getOperand(0);
1879
1
    MCOperand &Rss = Inst.getOperand(1);
1880
1
    MCOperand &Imm = Inst.getOperand(2);
1881
1
    int64_t Value;
1882
1
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1883
1
    if (!Absolute)
1884
0
      return Match_InvalidOperand;
1885
1
    if (Value == 0) {
1886
0
      MCInst TmpInst;
1887
0
      unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1888
0
      std::string R1 = r + utostr(RegPairNum + 1);
1889
0
      StringRef Reg1(R1);
1890
0
      Rss.setReg(matchRegister(Reg1));
1891
0
      // Add a new operand for the second register in the pair.
1892
0
      std::string R2 = r + utostr(RegPairNum);
1893
0
      StringRef Reg2(R2);
1894
0
      TmpInst.setOpcode(Hexagon::A2_combinew);
1895
0
      TmpInst.addOperand(Rdd);
1896
0
      TmpInst.addOperand(Rss);
1897
0
      TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1898
0
      Inst = TmpInst;
1899
1
    } else {
1900
1
      Imm.setExpr(HexagonMCExpr::create(
1901
1
          MCBinaryExpr::createSub(Imm.getExpr(),
1902
1
                                  MCConstantExpr::create(1, Context), Context),
1903
1
          Context));
1904
1
      Inst.setOpcode(Hexagon::S5_vasrhrnd);
1905
1
    }
1906
1
    break;
1907
1
  }
1908
1
1909
1
  case Hexagon::A2_not: {
1910
0
    MCInst TmpInst;
1911
0
    MCOperand &Rd = Inst.getOperand(0);
1912
0
    MCOperand &Rs = Inst.getOperand(1);
1913
0
    TmpInst.setOpcode(Hexagon::A2_subri);
1914
0
    TmpInst.addOperand(Rd);
1915
0
    TmpInst.addOperand(MCOperand::createExpr(
1916
0
        HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
1917
0
    TmpInst.addOperand(Rs);
1918
0
    Inst = TmpInst;
1919
0
    break;
1920
1
  }
1921
4
  case Hexagon::PS_loadrubabs:
1922
4
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1923
1
      Inst.setOpcode(Hexagon::L2_loadrubgp);
1924
4
    break;
1925
4
  case Hexagon::PS_loadrbabs:
1926
4
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1927
1
      Inst.setOpcode(Hexagon::L2_loadrbgp);
1928
4
    break;
1929
5
  case Hexagon::PS_loadruhabs:
1930
5
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1931
1
      Inst.setOpcode(Hexagon::L2_loadruhgp);
1932
5
    break;
1933
5
  case Hexagon::PS_loadrhabs:
1934
5
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1935
1
      Inst.setOpcode(Hexagon::L2_loadrhgp);
1936
5
    break;
1937
5
  case Hexagon::PS_loadriabs:
1938
5
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1939
1
      Inst.setOpcode(Hexagon::L2_loadrigp);
1940
5
    break;
1941
4
  case Hexagon::PS_loadrdabs:
1942
4
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1943
1
      Inst.setOpcode(Hexagon::L2_loadrdgp);
1944
4
    break;
1945
5
  case Hexagon::PS_storerbabs:
1946
5
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1947
1
      Inst.setOpcode(Hexagon::S2_storerbgp);
1948
5
    break;
1949
5
  case Hexagon::PS_storerhabs:
1950
5
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1951
1
      Inst.setOpcode(Hexagon::S2_storerhgp);
1952
5
    break;
1953
3
  case Hexagon::PS_storerfabs:
1954
3
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1955
0
      Inst.setOpcode(Hexagon::S2_storerfgp);
1956
3
    break;
1957
7
  case Hexagon::PS_storeriabs:
1958
7
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1959
1
      Inst.setOpcode(Hexagon::S2_storerigp);
1960
7
    break;
1961
5
  case Hexagon::PS_storerdabs:
1962
5
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1963
1
      Inst.setOpcode(Hexagon::S2_storerdgp);
1964
5
    break;
1965
4
  case Hexagon::PS_storerbnewabs:
1966
4
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1967
1
      Inst.setOpcode(Hexagon::S2_storerbnewgp);
1968
4
    break;
1969
3
  case Hexagon::PS_storerhnewabs:
1970
3
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1971
1
      Inst.setOpcode(Hexagon::S2_storerhnewgp);
1972
3
    break;
1973
4
  case Hexagon::PS_storerinewabs:
1974
4
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
1975
1
      Inst.setOpcode(Hexagon::S2_storerinewgp);
1976
4
    break;
1977
1
  case Hexagon::A2_zxtb: {
1978
0
    Inst.setOpcode(Hexagon::A2_andir);
1979
0
    Inst.addOperand(
1980
0
        MCOperand::createExpr(MCConstantExpr::create(255, Context)));
1981
0
    break;
1982
3.07k
  }
1983
3.07k
  } // switch
1984
3.07k
1985
3.07k
  return Match_Success;
1986
3.07k
}
1987
1988
43.4k
unsigned HexagonAsmParser::matchRegister(StringRef Name) {
1989
43.4k
  if (unsigned Reg = MatchRegisterName(Name))
1990
8.42k
    return Reg;
1991
35.0k
  return MatchRegisterAltName(Name);
1992
35.0k
}