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