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 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
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,...