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