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 HexagonMCChecker Check(getContext(), MII, STI, MCB, *RI, true);
483
485 MII, STI, getContext(), MCB, &Check, true);
486
487 if (CheckOk) {
488 if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
491 // Empty packets are valid yet aren't emitted
492 return false;
493 }
494
496
497 Out.emitInstruction(MCB, STI);
498 } else
499 return true; // Error
500
501 return false; // No error
502}
503
504bool HexagonAsmParser::matchBundleOptions() {
505 MCAsmParser &Parser = getParser();
506 while (true) {
507 if (!Parser.getTok().is(AsmToken::Colon))
508 return false;
509 Lex();
510 char const *MemNoShuffMsg =
511 "invalid instruction packet: mem_noshuf specifier not "
512 "supported with this architecture";
513 StringRef Option = Parser.getTok().getString();
514 auto IDLoc = Parser.getTok().getLoc();
515 if (Option.compare_insensitive("endloop01") == 0) {
518 } else if (Option.compare_insensitive("endloop0") == 0) {
520 } else if (Option.compare_insensitive("endloop1") == 0) {
522 } else if (Option.compare_insensitive("mem_noshuf") == 0) {
523 if (getSTI().hasFeature(Hexagon::FeatureMemNoShuf))
525 else
526 return getParser().Error(IDLoc, MemNoShuffMsg);
527 } else if (Option.compare_insensitive("mem_no_order") == 0) {
528 // Nothing.
529 } else
530 return getParser().Error(IDLoc, llvm::Twine("'") + Option +
531 "' is not a valid bundle option");
532 Lex();
533 }
534}
535
536// For instruction aliases, immediates are generated rather than
537// MCConstantExpr. Convert them for uniform MCExpr.
538// Also check for signed/unsigned mismatches and warn
539void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
540 MCInst NewInst;
541 NewInst.setOpcode(MCI.getOpcode());
542 for (MCOperand &I : MCI)
543 if (I.isImm()) {
544 int64_t Value(I.getImm());
547 } else {
548 if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
550 Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
551 NewInst.addOperand(I);
552 }
553 MCI = NewInst;
554}
555
556bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
557 OperandVector &InstOperands,
558 uint64_t &ErrorInfo,
559 bool MatchingInlineAsm) {
560 // Perform matching with tablegen asmmatcher generated function
561 int result =
562 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
563 if (result == Match_Success) {
564 MCI.setLoc(IDLoc);
565 canonicalizeImmediates(MCI);
566 result = processInstruction(MCI, InstOperands, IDLoc);
567
568 LLVM_DEBUG(dbgs() << "Insn:");
570 LLVM_DEBUG(dbgs() << "\n\n");
571
572 MCI.setLoc(IDLoc);
573 }
574
575 // Create instruction operand for bundle instruction
576 // Break this into a separate function Code here is less readable
577 // Think about how to get an instruction error to report correctly.
578 // SMLoc will return the "{"
579 switch (result) {
580 default:
581 break;
582 case Match_Success:
583 return false;
584 case Match_MissingFeature:
585 return Error(IDLoc, "invalid instruction");
586 case Match_MnemonicFail:
587 return Error(IDLoc, "unrecognized instruction");
588 case Match_InvalidOperand:
589 [[fallthrough]];
590 case Match_InvalidTiedOperand:
591 SMLoc ErrorLoc = IDLoc;
592 if (ErrorInfo != ~0U) {
593 if (ErrorInfo >= InstOperands.size())
594 return Error(IDLoc, "too few operands for instruction");
595
596 ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
597 ->getStartLoc();
598 if (ErrorLoc == SMLoc())
599 ErrorLoc = IDLoc;
600 }
601 return Error(ErrorLoc, "invalid operand for instruction");
602 }
603 llvm_unreachable("Implement any new match types added!");
604}
605
606void HexagonAsmParser::eatToEndOfPacket() {
607 assert(InBrackets);
608 AsmLexer &Lexer = getLexer();
609 while (!Lexer.is(AsmToken::RCurly))
610 Lexer.Lex();
611 Lexer.Lex();
612 InBrackets = false;
613}
614
615bool HexagonAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
617 MCStreamer &Out,
618 uint64_t &ErrorInfo,
619 bool MatchingInlineAsm) {
620 if (!InBrackets) {
621 MCB.clear();
623 }
624 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
625 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
626 assert(Operands.size() == 1 && "Brackets should be by themselves");
627 if (InBrackets) {
628 getParser().Error(IDLoc, "Already in a packet");
629 InBrackets = false;
630 return true;
631 }
632 InBrackets = true;
633 return false;
634 }
635 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
636 assert(Operands.size() == 1 && "Brackets should be by themselves");
637 if (!InBrackets) {
638 getParser().Error(IDLoc, "Not in a packet");
639 return true;
640 }
641 InBrackets = false;
642 if (matchBundleOptions())
643 return true;
644 return finishBundle(IDLoc, Out);
645 }
646 MCInst *SubInst = getParser().getContext().createMCInst();
647 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
648 MatchingInlineAsm)) {
649 if (InBrackets)
650 eatToEndOfPacket();
651 return true;
652 }
654 getParser().getContext(), MII, MCB, *SubInst);
655 MCB.addOperand(MCOperand::createInst(SubInst));
656 if (!InBrackets)
657 return finishBundle(IDLoc, Out);
658 return false;
659}
660/// parseDirectiveAttribute
661/// ::= .attribute int, int
662/// ::= .attribute Tag_name, int
663bool HexagonAsmParser::parseDirectiveAttribute(SMLoc L) {
664 MCAsmParser &Parser = getParser();
665 int64_t Tag;
666 SMLoc TagLoc = Parser.getTok().getLoc();
667 if (Parser.getTok().is(AsmToken::Identifier)) {
668 StringRef Name = Parser.getTok().getIdentifier();
669 std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
671 if (!Ret)
672 return Error(TagLoc, "attribute name not recognized: " + Name);
673 Tag = *Ret;
674 Parser.Lex();
675 } else {
676 const MCExpr *AttrExpr;
677
678 TagLoc = Parser.getTok().getLoc();
679 if (Parser.parseExpression(AttrExpr))
680 return true;
681
682 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
683 if (check(!CE, TagLoc, "expected numeric constant"))
684 return true;
685
686 Tag = CE->getValue();
687 }
688
689 if (Parser.parseComma())
690 return true;
691
692 // We currently only have integer values.
693 int64_t IntegerValue = 0;
694 SMLoc ValueExprLoc = Parser.getTok().getLoc();
695 const MCExpr *ValueExpr;
696 if (Parser.parseExpression(ValueExpr))
697 return true;
698
699 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
700 if (!CE)
701 return Error(ValueExprLoc, "expected numeric constant");
702 IntegerValue = CE->getValue();
703
704 if (Parser.parseEOL())
705 return true;
706
707 getTargetStreamer().emitAttribute(Tag, IntegerValue);
708 return false;
709}
710
711/// ParseDirective parses the Hexagon specific directives
712bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
713 StringRef IDVal = DirectiveID.getIdentifier();
714 if (IDVal.lower() == ".falign")
715 return ParseDirectiveFalign(256, DirectiveID.getLoc());
716 if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
717 return ParseDirectiveComm(true, DirectiveID.getLoc());
718 if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
719 return ParseDirectiveComm(false, DirectiveID.getLoc());
720 if (IDVal.lower() == ".subsection")
721 return ParseDirectiveSubsection(DirectiveID.getLoc());
722 if (IDVal == ".attribute")
723 return parseDirectiveAttribute(DirectiveID.getLoc());
724
725 return true;
726}
727bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
728 const MCExpr *Subsection = nullptr;
729 int64_t Res;
730
731 assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
732 "Invalid subsection directive");
733 getParser().parseExpression(Subsection);
734
735 if (!Subsection->evaluateAsAbsolute(Res))
736 return Error(L, "Cannot evaluate subsection number");
737
738 if (getLexer().isNot(AsmToken::EndOfStatement))
739 return TokError("unexpected token in directive");
740
741 // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
742 // negative subsections together and in the same order but at the opposite
743 // end of the section. Only legacy hexagon-gcc created assembly code
744 // used negative subsections.
745 if ((Res < 0) && (Res > -8193))
746 Res += 8192;
747 getStreamer().switchSection(getStreamer().getCurrentSectionOnly(), Res);
748 return false;
749}
750
751/// ::= .falign [expression]
752bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
753
754 int64_t MaxBytesToFill = 15;
755
756 // if there is an argument
757 if (getLexer().isNot(AsmToken::EndOfStatement)) {
758 const MCExpr *Value;
759 SMLoc ExprLoc = L;
760
761 // Make sure we have a number (false is returned if expression is a number)
762 if (!getParser().parseExpression(Value)) {
763 // Make sure this is a number that is in range
764 auto *MCE = cast<MCConstantExpr>(Value);
765 uint64_t IntValue = MCE->getValue();
766 if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
767 return Error(ExprLoc, "literal value out of range (256) for falign");
768 MaxBytesToFill = IntValue;
769 Lex();
770 } else {
771 return Error(ExprLoc, "not a valid expression for falign directive");
772 }
773 }
774
775 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
776 Lex();
777
778 return false;
779}
780
781// This is largely a copy of AsmParser's ParseDirectiveComm extended to
782// accept a 3rd argument, AccessAlignment which indicates the smallest
783// memory access made to the symbol, expressed in bytes. If no
784// AccessAlignment is specified it defaults to the Alignment Value.
785// Hexagon's .lcomm:
786// .lcomm Symbol, Length, Alignment, AccessAlignment
787bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
788 // FIXME: need better way to detect if AsmStreamer (upstream removed
789 // getKind())
790 if (getStreamer().hasRawTextSupport())
791 return true; // Only object file output requires special treatment.
792
793 StringRef Name;
794 if (getParser().parseIdentifier(Name))
795 return TokError("expected identifier in directive");
796 // Handle the identifier as the key symbol.
797 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
798
799 if (getLexer().isNot(AsmToken::Comma))
800 return TokError("unexpected token in directive");
801 Lex();
802
803 int64_t Size;
804 SMLoc SizeLoc = getLexer().getLoc();
805 if (getParser().parseAbsoluteExpression(Size))
806 return true;
807
808 int64_t ByteAlignment = 1;
809 SMLoc ByteAlignmentLoc;
810 if (getLexer().is(AsmToken::Comma)) {
811 Lex();
812 ByteAlignmentLoc = getLexer().getLoc();
813 if (getParser().parseAbsoluteExpression(ByteAlignment))
814 return true;
815 if (!isPowerOf2_64(ByteAlignment))
816 return Error(ByteAlignmentLoc, "alignment must be a power of 2");
817 }
818
819 int64_t AccessAlignment = 0;
820 if (getLexer().is(AsmToken::Comma)) {
821 // The optional access argument specifies the size of the smallest memory
822 // access to be made to the symbol, expressed in bytes.
823 SMLoc AccessAlignmentLoc;
824 Lex();
825 AccessAlignmentLoc = getLexer().getLoc();
826 if (getParser().parseAbsoluteExpression(AccessAlignment))
827 return true;
828
829 if (!isPowerOf2_64(AccessAlignment))
830 return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
831 }
832
833 if (getLexer().isNot(AsmToken::EndOfStatement))
834 return TokError("unexpected token in '.comm' or '.lcomm' directive");
835
836 Lex();
837
838 // NOTE: a size of zero for a .comm should create a undefined symbol
839 // but a size of .lcomm creates a bss symbol of size zero.
840 if (Size < 0)
841 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
842 "be less than zero");
843
844 // NOTE: The alignment in the directive is a power of 2 value, the assembler
845 // may internally end up wanting an alignment in bytes.
846 // FIXME: Diagnose overflow.
847 if (ByteAlignment < 0)
848 return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
849 "alignment, can't be less than zero");
850
851 if (!Sym->isUndefined())
852 return Error(Loc, "invalid symbol redefinition");
853
854 HexagonMCELFStreamer &HexagonELFStreamer =
855 static_cast<HexagonMCELFStreamer &>(getStreamer());
856 if (IsLocal) {
857 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
858 Sym, Size, Align(ByteAlignment), AccessAlignment);
859 return false;
860 }
861
862 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, Align(ByteAlignment),
863 AccessAlignment);
864 return false;
865}
866
867// validate register against architecture
868bool HexagonAsmParser::RegisterMatchesArch(MCRegister MatchNum) const {
869 if (getHexagonMCRegisterClass(Hexagon::V62RegsRegClassID).contains(MatchNum))
870 if (!getSTI().hasFeature(Hexagon::ArchV62))
871 return false;
872 return true;
873}
874
875// extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmLexer();
876
877/// Force static initialization.
882
883#define GET_MATCHER_IMPLEMENTATION
884#define GET_REGISTER_MATCHER
885#include "HexagonGenAsmMatcher.inc"
886
887static bool previousEqual(OperandVector &Operands, size_t Index,
889 if (Index >= Operands.size())
890 return false;
891 MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
892 if (!Operand.isToken())
893 return false;
894 return static_cast<HexagonOperand &>(Operand).getToken().equals_insensitive(
895 String);
896}
897
898static bool previousIsLoop(OperandVector &Operands, size_t Index) {
899 return previousEqual(Operands, Index, "loop0") ||
900 previousEqual(Operands, Index, "loop1") ||
901 previousEqual(Operands, Index, "sp1loop0") ||
902 previousEqual(Operands, Index, "sp2loop0") ||
903 previousEqual(Operands, Index, "sp3loop0");
904}
905
906bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
907 AsmToken const &Token = getParser().getTok();
908 StringRef String = Token.getString();
909 SMLoc Loc = Token.getLoc();
910 Lex();
911 do {
912 std::pair<StringRef, StringRef> HeadTail = String.split('.');
913 if (!HeadTail.first.empty())
914 Operands.push_back(
915 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
916 if (!HeadTail.second.empty())
917 Operands.push_back(HexagonOperand::CreateToken(
918 getContext(), String.substr(HeadTail.first.size(), 1), Loc));
919 String = HeadTail.second;
920 } while (!String.empty());
921 return false;
922}
923
924bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
925 MCRegister Register;
926 SMLoc Begin;
927 SMLoc End;
928 AsmLexer &Lexer = getLexer();
929 if (!parseRegister(Register, Begin, End)) {
931 switch (Register.id()) {
932 default:
933 break;
934 case Hexagon::P0:
935 case Hexagon::P1:
936 case Hexagon::P2:
937 case Hexagon::P3:
938 if (previousEqual(Operands, 0, "if")) {
940 Warning(Begin, "Missing parenthesis around predicate register");
941 static char const *LParen = "(";
942 static char const *RParen = ")";
943 Operands.push_back(
944 HexagonOperand::CreateToken(getContext(), LParen, Begin));
945 Operands.push_back(
946 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
947 const AsmToken &MaybeDotNew = Lexer.getTok();
948 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
949 MaybeDotNew.getString().equals_insensitive(".new"))
950 splitIdentifier(Operands);
951 Operands.push_back(
952 HexagonOperand::CreateToken(getContext(), RParen, Begin));
953 return false;
954 }
955 if (previousEqual(Operands, 0, "!") &&
956 previousEqual(Operands, 1, "if")) {
958 Warning(Begin, "Missing parenthesis around predicate register");
959 static char const *LParen = "(";
960 static char const *RParen = ")";
961 Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
962 getContext(), LParen, Begin));
963 Operands.push_back(
964 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
965 const AsmToken &MaybeDotNew = Lexer.getTok();
966 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
967 MaybeDotNew.getString().equals_insensitive(".new"))
968 splitIdentifier(Operands);
969 Operands.push_back(
970 HexagonOperand::CreateToken(getContext(), RParen, Begin));
971 return false;
972 }
973 break;
974 }
975 Operands.push_back(
976 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
977 return false;
978 }
979 return splitIdentifier(Operands);
980}
981
982bool HexagonAsmParser::isLabel(AsmToken &Token) {
983 AsmLexer &Lexer = getLexer();
984 AsmToken const &Second = Lexer.getTok();
985 AsmToken Third = Lexer.peekTok();
986 StringRef String = Token.getString();
987 if (Token.is(AsmToken::TokenKind::LCurly) ||
988 Token.is(AsmToken::TokenKind::RCurly))
989 return false;
990 // special case for parsing vwhist256:sat
991 if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
992 Third.getString().lower() == "sat")
993 return false;
994 if (!Token.is(AsmToken::TokenKind::Identifier))
995 return true;
996 if (!matchRegister(String.lower()))
997 return true;
998 assert(Second.is(AsmToken::Colon));
999 StringRef Raw(String.data(), Third.getString().data() - String.data() +
1000 Third.getString().size());
1001 std::string Collapsed = std::string(Raw);
1002 llvm::erase_if(Collapsed, isSpace);
1003 StringRef Whole = Collapsed;
1004 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
1005 if (!matchRegister(DotSplit.first.lower()))
1006 return true;
1007 return false;
1008}
1009
1010bool HexagonAsmParser::tokenIsStartOfStatement(AsmToken::TokenKind Token) {
1011 return Token == AsmToken::LCurly || Token == AsmToken::RCurly;
1012}
1013
1014bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
1015 SMLoc &Loc) {
1016 if (!Contigious && ErrorNoncontigiousRegister) {
1017 Error(Loc, "Register name is not contigious");
1018 return true;
1019 }
1020 if (!Contigious && WarnNoncontigiousRegister)
1021 Warning(Loc, "Register name is not contigious");
1022 return false;
1023}
1024
1025bool HexagonAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1026 SMLoc &EndLoc) {
1027 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
1028}
1029
1030ParseStatus HexagonAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1031 SMLoc &EndLoc) {
1032 AsmLexer &Lexer = getLexer();
1033 StartLoc = getLexer().getLoc();
1034 SmallVector<AsmToken, 5> Lookahead;
1035 StringRef RawString(Lexer.getTok().getString().data(), 0);
1036 bool Again = Lexer.is(AsmToken::Identifier);
1037 bool NeededWorkaround = false;
1038 while (Again) {
1039 AsmToken const &Token = Lexer.getTok();
1040 RawString = StringRef(RawString.data(), Token.getString().data() -
1041 RawString.data() +
1042 Token.getString().size());
1043 Lookahead.push_back(Token);
1044 Lexer.Lex();
1045 bool Contigious = Lexer.getTok().getString().data() ==
1046 Lookahead.back().getString().data() +
1047 Lookahead.back().getString().size();
1048 bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1049 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1050 Lexer.is(AsmToken::Colon);
1051 bool Workaround =
1052 Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
1053 Again = (Contigious && Type) || (Workaround && Type);
1054 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1055 }
1056 std::string Collapsed = std::string(RawString);
1057 llvm::erase_if(Collapsed, isSpace);
1058 StringRef FullString = Collapsed;
1059 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
1060 MCRegister DotReg = matchRegister(DotSplit.first.lower());
1061 if (DotReg && RegisterMatchesArch(DotReg)) {
1062 if (DotSplit.second.empty()) {
1063 Reg = DotReg;
1064 EndLoc = Lexer.getLoc();
1065 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1066 return ParseStatus::NoMatch;
1067 return ParseStatus::Success;
1068 } else {
1069 Reg = DotReg;
1070 size_t First = RawString.find('.');
1071 StringRef DotString (RawString.data() + First, RawString.size() - First);
1072 Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1073 EndLoc = Lexer.getLoc();
1074 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1075 return ParseStatus::NoMatch;
1076 return ParseStatus::Success;
1077 }
1078 }
1079 std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
1080 MCRegister ColonReg = matchRegister(ColonSplit.first.lower());
1081 if (ColonReg && RegisterMatchesArch(DotReg)) {
1082 do {
1083 Lexer.UnLex(Lookahead.pop_back_val());
1084 } while (!Lookahead.empty() && !Lexer.is(AsmToken::Colon));
1085 Reg = ColonReg;
1086 EndLoc = Lexer.getLoc();
1087 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1088 return ParseStatus::NoMatch;
1089 return ParseStatus::Success;
1090 }
1091 while (!Lookahead.empty()) {
1092 Lexer.UnLex(Lookahead.pop_back_val());
1093 }
1094 return ParseStatus::NoMatch;
1095}
1096
1097bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1098 if (previousEqual(Operands, 0, "call"))
1099 return true;
1100 if (previousEqual(Operands, 0, "jump"))
1101 if (!getLexer().getTok().is(AsmToken::Colon))
1102 return true;
1103 if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1104 return true;
1105 if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1106 (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1107 return true;
1108 return false;
1109}
1110
1111bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
1113 AsmLexer &Lexer = getLexer();
1114 bool Done = false;
1115 static char const *Comma = ",";
1116 do {
1117 Tokens.emplace_back(Lexer.getTok());
1118 Lex();
1119 switch (Tokens.back().getKind()) {
1120 case AsmToken::TokenKind::Hash:
1121 if (Tokens.size() > 1)
1122 if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1123 Tokens.insert(Tokens.end() - 2,
1124 AsmToken(AsmToken::TokenKind::Comma, Comma));
1125 Done = true;
1126 }
1127 break;
1128 case AsmToken::TokenKind::RCurly:
1129 case AsmToken::TokenKind::EndOfStatement:
1130 case AsmToken::TokenKind::Eof:
1131 Done = true;
1132 break;
1133 default:
1134 break;
1135 }
1136 } while (!Done);
1137 while (!Tokens.empty()) {
1138 Lexer.UnLex(Tokens.back());
1139 Tokens.pop_back();
1140 }
1141 SMLoc Loc = Lexer.getLoc();
1142 return getParser().parseExpression(Expr, Loc);
1143}
1144
1145bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1146 if (implicitExpressionLocation(Operands)) {
1147 MCAsmParser &Parser = getParser();
1148 SMLoc Loc = Parser.getLexer().getLoc();
1149 MCExpr const *Expr = nullptr;
1150 bool Error = parseExpression(Expr);
1151 Expr = HexagonMCExpr::create(Expr, getContext());
1152 if (!Error)
1153 Operands.push_back(
1154 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1155 return Error;
1156 }
1157 return parseOperand(Operands);
1158}
1159
1160/// Parse an instruction.
1161bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1162 MCAsmParser &Parser = getParser();
1163 AsmLexer &Lexer = getLexer();
1164 while (true) {
1165 AsmToken const &Token = Parser.getTok();
1166 switch (Token.getKind()) {
1167 case AsmToken::Eof:
1169 Lex();
1170 return false;
1171 }
1172 case AsmToken::LCurly: {
1173 if (!Operands.empty())
1174 return true;
1175 Operands.push_back(HexagonOperand::CreateToken(
1176 getContext(), Token.getString(), Token.getLoc()));
1177 Lex();
1178 return false;
1179 }
1180 case AsmToken::RCurly: {
1181 if (Operands.empty()) {
1182 Operands.push_back(HexagonOperand::CreateToken(
1183 getContext(), Token.getString(), Token.getLoc()));
1184 Lex();
1185 }
1186 return false;
1187 }
1188 case AsmToken::Comma: {
1189 Lex();
1190 continue;
1191 }
1197 case AsmToken::LessLess: {
1198 Operands.push_back(HexagonOperand::CreateToken(
1199 getContext(), Token.getString().substr(0, 1), Token.getLoc()));
1200 Operands.push_back(HexagonOperand::CreateToken(
1201 getContext(), Token.getString().substr(1, 1), Token.getLoc()));
1202 Lex();
1203 continue;
1204 }
1205 case AsmToken::Hash: {
1206 bool MustNotExtend = false;
1207 bool ImplicitExpression = implicitExpressionLocation(Operands);
1208 SMLoc ExprLoc = Lexer.getLoc();
1209 if (!ImplicitExpression)
1210 Operands.push_back(HexagonOperand::CreateToken(
1211 getContext(), Token.getString(), Token.getLoc()));
1212 Lex();
1213 bool MustExtend = false;
1214 bool HiOnly = false;
1215 bool LoOnly = false;
1216 if (Lexer.is(AsmToken::Hash)) {
1217 Lex();
1218 MustExtend = true;
1219 } else if (ImplicitExpression)
1220 MustNotExtend = true;
1221 AsmToken const &Token = Parser.getTok();
1222 if (Token.is(AsmToken::Identifier)) {
1223 StringRef String = Token.getString();
1224 if (String.lower() == "hi") {
1225 HiOnly = true;
1226 } else if (String.lower() == "lo") {
1227 LoOnly = true;
1228 }
1229 if (HiOnly || LoOnly) {
1230 AsmToken LParen = Lexer.peekTok();
1231 if (!LParen.is(AsmToken::LParen)) {
1232 HiOnly = false;
1233 LoOnly = false;
1234 } else {
1235 Lex();
1236 }
1237 }
1238 }
1239 MCExpr const *Expr = nullptr;
1240 if (parseExpression(Expr))
1241 return true;
1242 int64_t Value;
1243 MCContext &Context = Parser.getContext();
1244 assert(Expr != nullptr);
1245 if (Expr->evaluateAsAbsolute(Value)) {
1246 if (HiOnly)
1249 if (HiOnly || LoOnly)
1251 Expr, MCConstantExpr::create(0xffff, Context), Context);
1252 } else {
1253 MCValue Value;
1254 if (Expr->evaluateAsRelocatable(Value, nullptr)) {
1255 if (!Value.isAbsolute()) {
1256 switch (HexagonMCExpr::VariantKind(Value.getSpecifier())) {
1259 // Don't lazy extend these expression variants
1260 MustNotExtend = !MustExtend;
1261 break;
1262 default:
1263 break;
1264 }
1265 }
1266 }
1267 }
1268 Expr = HexagonMCExpr::create(Expr, Context);
1269 HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
1270 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
1271 std::unique_ptr<HexagonOperand> Operand =
1272 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1273 Operands.push_back(std::move(Operand));
1274 continue;
1275 }
1276 default:
1277 break;
1278 }
1279 if (parseExpressionOrOperand(Operands))
1280 return true;
1281 }
1282}
1283
1284bool HexagonAsmParser::parseInstruction(ParseInstructionInfo &Info,
1285 StringRef Name, AsmToken ID,
1287 getLexer().UnLex(ID);
1288 return parseInstruction(Operands);
1289}
1290
1291static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
1292 MCOperand &MO2) {
1293 MCInst TmpInst;
1294 TmpInst.setOpcode(opCode);
1295 TmpInst.addOperand(Rdd);
1296 TmpInst.addOperand(MO1);
1297 TmpInst.addOperand(MO2);
1298
1299 return TmpInst;
1300}
1301
1302// Define this matcher function after the auto-generated include so we
1303// have the match class enum definitions.
1304unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1305 unsigned Kind) {
1306 HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1307
1308 switch (Kind) {
1309 case MCK_0: {
1310 int64_t Value;
1311 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1312 ? Match_Success
1313 : Match_InvalidOperand;
1314 }
1315 case MCK_1: {
1316 int64_t Value;
1317 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1318 ? Match_Success
1319 : Match_InvalidOperand;
1320 }
1321 }
1322 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1323 StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1324 if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1325 return Match_Success;
1326 if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1327 return Match_Success;
1328 }
1329
1330 LLVM_DEBUG(dbgs() << "Unmatched Operand:");
1331 LLVM_DEBUG(Op->dump());
1332 LLVM_DEBUG(dbgs() << "\n");
1333
1334 return Match_InvalidOperand;
1335}
1336
1337// FIXME: Calls to OutOfRange should propagate failure up to parseStatement.
1338bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1339 std::string errStr;
1340 raw_string_ostream ES(errStr);
1341 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1342 if (Max >= 0)
1343 ES << "0-" << Max;
1344 else
1345 ES << Max << "-" << (-Max - 1);
1346 return Parser.printError(IDLoc, ES.str());
1347}
1348
1349int HexagonAsmParser::processInstruction(MCInst &Inst,
1350 OperandVector const &Operands,
1351 SMLoc IDLoc) {
1352 MCContext &Context = getParser().getContext();
1353 const MCRegisterInfo *RI = getContext().getRegisterInfo();
1354 const std::string r = "r";
1355 const std::string Colon = ":";
1356 using RegPairVals = std::pair<unsigned, unsigned>;
1357 auto GetRegPair = [this, r](RegPairVals RegPair) {
1358 const std::string R1 = r + utostr(RegPair.first);
1359 const std::string R2 = r + utostr(RegPair.second);
1360
1361 return std::make_pair(matchRegister(R1), matchRegister(R2));
1362 };
1363 auto GetScalarRegs = [RI, GetRegPair](MCRegister RegPair) {
1364 const unsigned Lower = RI->getEncodingValue(RegPair);
1365 const RegPairVals RegPair_ = std::make_pair(Lower + 1, Lower);
1366
1367 return GetRegPair(RegPair_);
1368 };
1369 auto GetVecRegs = [GetRegPair](MCRegister VecRegPair) {
1370 const RegPairVals RegPair =
1372
1373 return GetRegPair(RegPair);
1374 };
1375
1376 bool is32bit = false; // used to distinguish between CONST32 and CONST64
1377 switch (Inst.getOpcode()) {
1378 default:
1379 if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
1380 SMDiagnostic Diag = getSourceManager().GetMessage(
1381 IDLoc, SourceMgr::DK_Error,
1382 "Found pseudo instruction with no expansion");
1383 Diag.print("", errs());
1384 report_fatal_error("Invalid pseudo instruction");
1385 }
1386 break;
1387
1388 case Hexagon::J2_trap1:
1389 if (!getSTI().hasFeature(Hexagon::ArchV65)) {
1390 MCOperand &Rx = Inst.getOperand(0);
1391 MCOperand &Ry = Inst.getOperand(1);
1392 if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {
1393 Error(IDLoc, "trap1 can only have register r0 as operand");
1394 return Match_InvalidOperand;
1395 }
1396 }
1397 break;
1398
1399 case Hexagon::A2_iconst: {
1400 Inst.setOpcode(Hexagon::A2_addi);
1401 MCOperand Reg = Inst.getOperand(0);
1402 MCOperand S27 = Inst.getOperand(1);
1405 Inst.clear();
1406 Inst.addOperand(Reg);
1407 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1408 Inst.addOperand(S27);
1409 break;
1410 }
1411 case Hexagon::M4_mpyrr_addr:
1412 case Hexagon::S4_addi_asl_ri:
1413 case Hexagon::S4_addi_lsr_ri:
1414 case Hexagon::S4_andi_asl_ri:
1415 case Hexagon::S4_andi_lsr_ri:
1416 case Hexagon::S4_ori_asl_ri:
1417 case Hexagon::S4_ori_lsr_ri:
1418 case Hexagon::S4_or_andix:
1419 case Hexagon::S4_subi_asl_ri:
1420 case Hexagon::S4_subi_lsr_ri: {
1421 MCOperand &Ry = Inst.getOperand(0);
1422 MCOperand &src = Inst.getOperand(2);
1423 if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1424 return Match_InvalidOperand;
1425 break;
1426 }
1427
1428 case Hexagon::C2_cmpgei: {
1429 MCOperand &MO = Inst.getOperand(2);
1433 Context));
1434 Inst.setOpcode(Hexagon::C2_cmpgti);
1435 break;
1436 }
1437
1438 case Hexagon::C2_cmpgeui: {
1439 MCOperand &MO = Inst.getOperand(2);
1440 int64_t Value;
1441 bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
1442 (void)Success;
1443 assert(Success && "Assured by matcher");
1444 if (Value == 0) {
1445 MCInst TmpInst;
1446 MCOperand &Pd = Inst.getOperand(0);
1447 MCOperand &Rt = Inst.getOperand(1);
1448 TmpInst.setOpcode(Hexagon::C2_cmpeq);
1449 TmpInst.addOperand(Pd);
1450 TmpInst.addOperand(Rt);
1451 TmpInst.addOperand(Rt);
1452 Inst = TmpInst;
1453 } else {
1457 Context));
1458 Inst.setOpcode(Hexagon::C2_cmpgtui);
1459 }
1460 break;
1461 }
1462
1463 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1464 case Hexagon::A2_tfrp: {
1465 MCOperand &MO = Inst.getOperand(1);
1466 const std::pair<MCRegister, MCRegister> RegPair =
1467 GetScalarRegs(MO.getReg());
1468 MO.setReg(RegPair.first);
1469 Inst.addOperand(MCOperand::createReg(RegPair.second));
1470 Inst.setOpcode(Hexagon::A2_combinew);
1471 break;
1472 }
1473
1474 case Hexagon::A2_tfrpt:
1475 case Hexagon::A2_tfrpf: {
1476 MCOperand &MO = Inst.getOperand(2);
1477 const std::pair<MCRegister, MCRegister> RegPair =
1478 GetScalarRegs(MO.getReg());
1479 MO.setReg(RegPair.first);
1480 Inst.addOperand(MCOperand::createReg(RegPair.second));
1481 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1482 ? Hexagon::C2_ccombinewt
1483 : Hexagon::C2_ccombinewf);
1484 break;
1485 }
1486 case Hexagon::A2_tfrptnew:
1487 case Hexagon::A2_tfrpfnew: {
1488 MCOperand &MO = Inst.getOperand(2);
1489 const std::pair<MCRegister, MCRegister> RegPair =
1490 GetScalarRegs(MO.getReg());
1491 MO.setReg(RegPair.first);
1492 Inst.addOperand(MCOperand::createReg(RegPair.second));
1493 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1494 ? Hexagon::C2_ccombinewnewt
1495 : Hexagon::C2_ccombinewnewf);
1496 break;
1497 }
1498
1499 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
1500 case Hexagon::V6_vassignp: {
1501 MCOperand &MO = Inst.getOperand(1);
1502 const std::pair<MCRegister, MCRegister> RegPair = GetVecRegs(MO.getReg());
1503 MO.setReg(RegPair.first);
1504 Inst.addOperand(MCOperand::createReg(RegPair.second));
1505 Inst.setOpcode(Hexagon::V6_vcombine);
1506 break;
1507 }
1508
1509 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1510 case Hexagon::CONST32:
1511 is32bit = true;
1512 [[fallthrough]];
1513 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1514 case Hexagon::CONST64:
1515 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1516 if (!Parser.getStreamer().hasRawTextSupport()) {
1517 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1518 MCOperand &MO_1 = Inst.getOperand(1);
1519 MCOperand &MO_0 = Inst.getOperand(0);
1520
1521 // push section onto section stack
1522 MES->pushSection();
1523
1524 std::string myCharStr;
1525 MCSectionELF *mySection;
1526
1527 // check if this as an immediate or a symbol
1528 int64_t Value;
1529 bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1530 if (Absolute) {
1531 // Create a new section - one for each constant
1532 // Some or all of the zeros are replaced with the given immediate.
1533 if (is32bit) {
1534 std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1535 myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1536 .drop_back(myImmStr.size())
1537 .str() +
1538 myImmStr;
1539 } else {
1540 std::string myImmStr = utohexstr(Value);
1541 myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1542 .drop_back(myImmStr.size())
1543 .str() +
1544 myImmStr;
1545 }
1546
1547 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1549 } else if (MO_1.isExpr()) {
1550 // .lita - for expressions
1551 myCharStr = ".lita";
1552 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1554 } else
1555 llvm_unreachable("unexpected type of machine operand!");
1556
1557 MES->switchSection(mySection);
1558 unsigned byteSize = is32bit ? 4 : 8;
1559 getStreamer().emitCodeAlignment(Align(byteSize), getSTI(), byteSize);
1560
1561 MCSymbol *Sym;
1562
1563 // for symbols, get rid of prepended ".gnu.linkonce.lx."
1564
1565 // emit symbol if needed
1566 if (Absolute) {
1567 Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1568 if (Sym->isUndefined()) {
1569 getStreamer().emitLabel(Sym);
1570 getStreamer().emitSymbolAttribute(Sym, MCSA_Global);
1571 getStreamer().emitIntValue(Value, byteSize);
1572 }
1573 } else if (MO_1.isExpr()) {
1574 const char *StringStart = nullptr;
1575 const char *StringEnd = nullptr;
1576 if (*Operands[4]->getStartLoc().getPointer() == '#') {
1577 StringStart = Operands[5]->getStartLoc().getPointer();
1578 StringEnd = Operands[6]->getStartLoc().getPointer();
1579 } else { // no pound
1580 StringStart = Operands[4]->getStartLoc().getPointer();
1581 StringEnd = Operands[5]->getStartLoc().getPointer();
1582 }
1583
1584 unsigned size = StringEnd - StringStart;
1585 std::string DotConst = ".CONST_";
1586 Sym = getContext().getOrCreateSymbol(DotConst +
1587 StringRef(StringStart, size));
1588
1589 if (Sym->isUndefined()) {
1590 // case where symbol is not yet defined: emit symbol
1591 getStreamer().emitLabel(Sym);
1592 getStreamer().emitSymbolAttribute(Sym, MCSA_Local);
1593 getStreamer().emitValue(MO_1.getExpr(), 4);
1594 }
1595 } else
1596 llvm_unreachable("unexpected type of machine operand!");
1597
1598 MES->popSection();
1599
1600 if (Sym) {
1601 MCInst TmpInst;
1602 if (is32bit) // 32 bit
1603 TmpInst.setOpcode(Hexagon::L2_loadrigp);
1604 else // 64 bit
1605 TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1606
1607 TmpInst.addOperand(MO_0);
1610 Inst = TmpInst;
1611 }
1612 }
1613 break;
1614
1615 // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1616 case Hexagon::A2_tfrpi: {
1617 MCOperand &Rdd = Inst.getOperand(0);
1618 MCOperand &MO = Inst.getOperand(1);
1619 int64_t Value;
1620 int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1621 MCOperand imm(MCOperand::createExpr(
1623 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1624 break;
1625 }
1626
1627 // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1628 case Hexagon::TFRI64_V4: {
1629 MCOperand &Rdd = Inst.getOperand(0);
1630 MCOperand &MO = Inst.getOperand(1);
1631 int64_t Value;
1632 if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1633 int s8 = Hi_32(Value);
1634 if (!isInt<8>(s8))
1635 OutOfRange(IDLoc, s8, -128);
1637 MCConstantExpr::create(s8, Context), Context))); // upper 32
1638 auto Expr = HexagonMCExpr::create(
1642 MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
1643 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1644 } else {
1646 MCConstantExpr::create(0, Context), Context))); // upper 32
1647 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1648 }
1649 break;
1650 }
1651
1652 // Handle $Rdd = combine(##imm, #imm)"
1653 case Hexagon::TFRI64_V2_ext: {
1654 MCOperand &Rdd = Inst.getOperand(0);
1655 MCOperand &MO1 = Inst.getOperand(1);
1656 MCOperand &MO2 = Inst.getOperand(2);
1657 int64_t Value;
1658 if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1659 int s8 = Value;
1660 if (s8 < -128 || s8 > 127)
1661 OutOfRange(IDLoc, s8, -128);
1662 }
1663 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1664 break;
1665 }
1666
1667 // Handle $Rdd = combine(#imm, ##imm)"
1668 case Hexagon::A4_combineii: {
1669 MCOperand &Rdd = Inst.getOperand(0);
1670 MCOperand &MO1 = Inst.getOperand(1);
1671 int64_t Value;
1672 if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1673 int s8 = Value;
1674 if (s8 < -128 || s8 > 127)
1675 OutOfRange(IDLoc, s8, -128);
1676 }
1677 MCOperand &MO2 = Inst.getOperand(2);
1678 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1679 break;
1680 }
1681
1682 case Hexagon::S2_tableidxb_goodsyntax:
1683 Inst.setOpcode(Hexagon::S2_tableidxb);
1684 break;
1685
1686 case Hexagon::S2_tableidxh_goodsyntax: {
1687 MCInst TmpInst;
1688 MCOperand &Rx = Inst.getOperand(0);
1689 MCOperand &Rs = Inst.getOperand(2);
1690 MCOperand &Imm4 = Inst.getOperand(3);
1691 MCOperand &Imm6 = Inst.getOperand(4);
1695 Context));
1696 TmpInst.setOpcode(Hexagon::S2_tableidxh);
1697 TmpInst.addOperand(Rx);
1698 TmpInst.addOperand(Rx);
1699 TmpInst.addOperand(Rs);
1700 TmpInst.addOperand(Imm4);
1701 TmpInst.addOperand(Imm6);
1702 Inst = TmpInst;
1703 break;
1704 }
1705
1706 case Hexagon::S2_tableidxw_goodsyntax: {
1707 MCInst TmpInst;
1708 MCOperand &Rx = Inst.getOperand(0);
1709 MCOperand &Rs = Inst.getOperand(2);
1710 MCOperand &Imm4 = Inst.getOperand(3);
1711 MCOperand &Imm6 = Inst.getOperand(4);
1715 Context));
1716 TmpInst.setOpcode(Hexagon::S2_tableidxw);
1717 TmpInst.addOperand(Rx);
1718 TmpInst.addOperand(Rx);
1719 TmpInst.addOperand(Rs);
1720 TmpInst.addOperand(Imm4);
1721 TmpInst.addOperand(Imm6);
1722 Inst = TmpInst;
1723 break;
1724 }
1725
1726 case Hexagon::S2_tableidxd_goodsyntax: {
1727 MCInst TmpInst;
1728 MCOperand &Rx = Inst.getOperand(0);
1729 MCOperand &Rs = Inst.getOperand(2);
1730 MCOperand &Imm4 = Inst.getOperand(3);
1731 MCOperand &Imm6 = Inst.getOperand(4);
1735 Context));
1736 TmpInst.setOpcode(Hexagon::S2_tableidxd);
1737 TmpInst.addOperand(Rx);
1738 TmpInst.addOperand(Rx);
1739 TmpInst.addOperand(Rs);
1740 TmpInst.addOperand(Imm4);
1741 TmpInst.addOperand(Imm6);
1742 Inst = TmpInst;
1743 break;
1744 }
1745
1746 case Hexagon::M2_mpyui:
1747 Inst.setOpcode(Hexagon::M2_mpyi);
1748 break;
1749 case Hexagon::M2_mpysmi: {
1750 MCInst TmpInst;
1751 MCOperand &Rd = Inst.getOperand(0);
1752 MCOperand &Rs = Inst.getOperand(1);
1753 MCOperand &Imm = Inst.getOperand(2);
1754 int64_t Value;
1755 MCExpr const &Expr = *Imm.getExpr();
1756 bool Absolute = Expr.evaluateAsAbsolute(Value);
1757 if (!Absolute)
1758 return Match_InvalidOperand;
1759 if (!HexagonMCInstrInfo::mustExtend(Expr) &&
1760 ((Value <= -256) || Value >= 256))
1761 return Match_InvalidOperand;
1762 if (Value < 0 && Value > -256) {
1763 Imm.setExpr(HexagonMCExpr::create(
1765 TmpInst.setOpcode(Hexagon::M2_mpysin);
1766 } else
1767 TmpInst.setOpcode(Hexagon::M2_mpysip);
1768 TmpInst.addOperand(Rd);
1769 TmpInst.addOperand(Rs);
1770 TmpInst.addOperand(Imm);
1771 Inst = TmpInst;
1772 break;
1773 }
1774
1775 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1776 MCOperand &Imm = Inst.getOperand(2);
1777 MCInst TmpInst;
1778 int64_t Value;
1779 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1780 if (!Absolute)
1781 return Match_InvalidOperand;
1782 if (Value == 0) { // convert to $Rd = $Rs
1783 TmpInst.setOpcode(Hexagon::A2_tfr);
1784 MCOperand &Rd = Inst.getOperand(0);
1785 MCOperand &Rs = Inst.getOperand(1);
1786 TmpInst.addOperand(Rd);
1787 TmpInst.addOperand(Rs);
1788 } else {
1789 Imm.setExpr(HexagonMCExpr::create(
1790 MCBinaryExpr::createSub(Imm.getExpr(),
1792 Context));
1793 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1794 MCOperand &Rd = Inst.getOperand(0);
1795 MCOperand &Rs = Inst.getOperand(1);
1796 TmpInst.addOperand(Rd);
1797 TmpInst.addOperand(Rs);
1798 TmpInst.addOperand(Imm);
1799 }
1800 Inst = TmpInst;
1801 break;
1802 }
1803
1804 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1805 MCOperand &Rdd = Inst.getOperand(0);
1806 MCOperand &Rss = Inst.getOperand(1);
1807 MCOperand &Imm = Inst.getOperand(2);
1808 int64_t Value;
1809 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1810 if (!Absolute)
1811 return Match_InvalidOperand;
1812 if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1813 MCInst TmpInst;
1814 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1815 std::string R1 = r + utostr(RegPairNum + 1);
1816 StringRef Reg1(R1);
1817 Rss.setReg(matchRegister(Reg1));
1818 // Add a new operand for the second register in the pair.
1819 std::string R2 = r + utostr(RegPairNum);
1820 StringRef Reg2(R2);
1821 TmpInst.setOpcode(Hexagon::A2_combinew);
1822 TmpInst.addOperand(Rdd);
1823 TmpInst.addOperand(Rss);
1824 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1825 Inst = TmpInst;
1826 } else {
1827 Imm.setExpr(HexagonMCExpr::create(
1828 MCBinaryExpr::createSub(Imm.getExpr(),
1830 Context));
1831 Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1832 }
1833 break;
1834 }
1835
1836 case Hexagon::A4_boundscheck: {
1837 MCOperand &Rs = Inst.getOperand(1);
1838 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1839 if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1840 Inst.setOpcode(Hexagon::A4_boundscheck_hi);
1841 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1842 StringRef RegPair = Name;
1843 Rs.setReg(matchRegister(RegPair));
1844 } else { // raw:lo
1845 Inst.setOpcode(Hexagon::A4_boundscheck_lo);
1846 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1847 StringRef RegPair = Name;
1848 Rs.setReg(matchRegister(RegPair));
1849 }
1850 break;
1851 }
1852
1853 case Hexagon::A2_addsp: {
1854 MCOperand &Rs = Inst.getOperand(1);
1855 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1856 if (RegNum & 1) { // Odd mapped to raw:hi
1857 Inst.setOpcode(Hexagon::A2_addsph);
1858 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1859 StringRef RegPair = Name;
1860 Rs.setReg(matchRegister(RegPair));
1861 } else { // Even mapped raw:lo
1862 Inst.setOpcode(Hexagon::A2_addspl);
1863 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1864 StringRef RegPair = Name;
1865 Rs.setReg(matchRegister(RegPair));
1866 }
1867 break;
1868 }
1869
1870 case Hexagon::M2_vrcmpys_s1: {
1871 MCOperand &Rt = Inst.getOperand(2);
1872 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1873 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1874 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
1875 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1876 StringRef RegPair = Name;
1877 Rt.setReg(matchRegister(RegPair));
1878 } else { // Even mapped sat:raw:lo
1879 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
1880 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1881 StringRef RegPair = Name;
1882 Rt.setReg(matchRegister(RegPair));
1883 }
1884 break;
1885 }
1886
1887 case Hexagon::M2_vrcmpys_acc_s1: {
1888 MCInst TmpInst;
1889 MCOperand &Rxx = Inst.getOperand(0);
1890 MCOperand &Rss = Inst.getOperand(2);
1891 MCOperand &Rt = Inst.getOperand(3);
1892 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1893 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1894 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
1895 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1896 StringRef RegPair = Name;
1897 Rt.setReg(matchRegister(RegPair));
1898 } else { // Even mapped sat:raw:lo
1899 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1900 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1901 StringRef RegPair = Name;
1902 Rt.setReg(matchRegister(RegPair));
1903 }
1904 // Registers are in different positions
1905 TmpInst.addOperand(Rxx);
1906 TmpInst.addOperand(Rxx);
1907 TmpInst.addOperand(Rss);
1908 TmpInst.addOperand(Rt);
1909 Inst = TmpInst;
1910 break;
1911 }
1912
1913 case Hexagon::M2_vrcmpys_s1rp: {
1914 MCOperand &Rt = Inst.getOperand(2);
1915 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1916 if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
1917 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1918 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1919 StringRef RegPair = Name;
1920 Rt.setReg(matchRegister(RegPair));
1921 } else { // Even mapped rnd:sat:raw:lo
1922 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1923 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1924 StringRef RegPair = Name;
1925 Rt.setReg(matchRegister(RegPair));
1926 }
1927 break;
1928 }
1929
1930 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1931 MCOperand &Imm = Inst.getOperand(2);
1932 int64_t Value;
1933 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1934 if (!Absolute)
1935 return Match_InvalidOperand;
1936 if (Value == 0)
1937 Inst.setOpcode(Hexagon::S2_vsathub);
1938 else {
1939 Imm.setExpr(HexagonMCExpr::create(
1940 MCBinaryExpr::createSub(Imm.getExpr(),
1942 Context));
1943 Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
1944 }
1945 break;
1946 }
1947
1948 case Hexagon::S5_vasrhrnd_goodsyntax: {
1949 MCOperand &Rdd = Inst.getOperand(0);
1950 MCOperand &Rss = Inst.getOperand(1);
1951 MCOperand &Imm = Inst.getOperand(2);
1952 int64_t Value;
1953 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1954 if (!Absolute)
1955 return Match_InvalidOperand;
1956 if (Value == 0) {
1957 MCInst TmpInst;
1958 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1959 std::string R1 = r + utostr(RegPairNum + 1);
1960 StringRef Reg1(R1);
1961 Rss.setReg(matchRegister(Reg1));
1962 // Add a new operand for the second register in the pair.
1963 std::string R2 = r + utostr(RegPairNum);
1964 StringRef Reg2(R2);
1965 TmpInst.setOpcode(Hexagon::A2_combinew);
1966 TmpInst.addOperand(Rdd);
1967 TmpInst.addOperand(Rss);
1968 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1969 Inst = TmpInst;
1970 } else {
1971 Imm.setExpr(HexagonMCExpr::create(
1972 MCBinaryExpr::createSub(Imm.getExpr(),
1974 Context));
1975 Inst.setOpcode(Hexagon::S5_vasrhrnd);
1976 }
1977 break;
1978 }
1979
1980 case Hexagon::A2_not: {
1981 MCInst TmpInst;
1982 MCOperand &Rd = Inst.getOperand(0);
1983 MCOperand &Rs = Inst.getOperand(1);
1984 TmpInst.setOpcode(Hexagon::A2_subri);
1985 TmpInst.addOperand(Rd);
1988 TmpInst.addOperand(Rs);
1989 Inst = TmpInst;
1990 break;
1991 }
1992 case Hexagon::PS_loadrubabs:
1994 Inst.setOpcode(Hexagon::L2_loadrubgp);
1995 break;
1996 case Hexagon::PS_loadrbabs:
1998 Inst.setOpcode(Hexagon::L2_loadrbgp);
1999 break;
2000 case Hexagon::PS_loadruhabs:
2002 Inst.setOpcode(Hexagon::L2_loadruhgp);
2003 break;
2004 case Hexagon::PS_loadrhabs:
2006 Inst.setOpcode(Hexagon::L2_loadrhgp);
2007 break;
2008 case Hexagon::PS_loadriabs:
2010 Inst.setOpcode(Hexagon::L2_loadrigp);
2011 break;
2012 case Hexagon::PS_loadrdabs:
2014 Inst.setOpcode(Hexagon::L2_loadrdgp);
2015 break;
2016 case Hexagon::PS_storerbabs:
2018 Inst.setOpcode(Hexagon::S2_storerbgp);
2019 break;
2020 case Hexagon::PS_storerhabs:
2022 Inst.setOpcode(Hexagon::S2_storerhgp);
2023 break;
2024 case Hexagon::PS_storerfabs:
2026 Inst.setOpcode(Hexagon::S2_storerfgp);
2027 break;
2028 case Hexagon::PS_storeriabs:
2030 Inst.setOpcode(Hexagon::S2_storerigp);
2031 break;
2032 case Hexagon::PS_storerdabs:
2034 Inst.setOpcode(Hexagon::S2_storerdgp);
2035 break;
2036 case Hexagon::PS_storerbnewabs:
2038 Inst.setOpcode(Hexagon::S2_storerbnewgp);
2039 break;
2040 case Hexagon::PS_storerhnewabs:
2042 Inst.setOpcode(Hexagon::S2_storerhnewgp);
2043 break;
2044 case Hexagon::PS_storerinewabs:
2046 Inst.setOpcode(Hexagon::S2_storerinewgp);
2047 break;
2048 case Hexagon::A2_zxtb: {
2049 Inst.setOpcode(Hexagon::A2_andir);
2050 Inst.addOperand(
2052 break;
2053 }
2054 } // switch
2055
2056 return Match_Success;
2057}
2058
2059MCRegister HexagonAsmParser::matchRegister(StringRef Name) {
2060 if (MCRegister Reg = MatchRegisterName(Name))
2061 return Reg;
2062 return MatchRegisterAltName(Name);
2063}
static MCRegister MatchRegisterName(StringRef Name)
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
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:665
static constexpr unsigned long long mask(BlockVerifier::State S)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:211
#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:480
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:1067
@ SHF_WRITE
Definition ELF.h:1064
@ SHT_PROGBITS
Definition ELF.h:965
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:1685
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:2208
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:572
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
@ MCSA_Local
.local (ELF)
@ MCSA_Global
.type _foo, @gnu_unique_object
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...