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