LLVM: lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

53#include

54#include

55#include

56#include

57#include

58#include

59#include

60

61#define DEBUG_TYPE "mcasmparser"

62

63using namespace llvm;

64

66 "mwarn-missing-parenthesis",

67 cl::desc("Warn for missing parenthesis around predicate registers"),

70 "merror-missing-parenthesis",

71 cl::desc("Error for missing parenthesis around predicate registers"),

74 "mwarn-sign-mismatch",

75 cl::desc("Warn for mismatching a signed and unsigned value"),

78 "mwarn-noncontigious-register",

79 cl::desc("Warn for register names that aren't contigious"), cl::init(true));

81 "merror-noncontigious-register",

82 cl::desc("Error for register names that aren't contigious"),

85namespace {

86

87struct HexagonOperand;

88

90

94 }

95

96 MCAsmParser &Parser;

97 MCInst MCB;

98 bool InBrackets;

99

100 MCAsmParser &getParser() const { return Parser; }

101 MCAssembler *getAssembler() const {

102 MCAssembler *Assembler = nullptr;

103

104 if (!Parser.getStreamer().hasRawTextSupport()) {

105 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());

107 }

108 return Assembler;

109 }

110

111 AsmLexer &getLexer() const { return Parser.getLexer(); }

112

113 bool equalIsAsmAssignment() override { return false; }

114 bool isLabel(AsmToken &Token) override;

116

117 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }

118 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }

119 bool ParseDirectiveFalign(unsigned Size, SMLoc L);

120

121 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;

122 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

123 SMLoc &EndLoc) override;

124 bool ParseDirectiveSubsection(SMLoc L);

125 bool ParseDirectiveComm(bool IsLocal, SMLoc L);

126

127 bool parseDirectiveAttribute(SMLoc L);

128

129 bool RegisterMatchesArch(MCRegister MatchNum) const;

130

131 bool matchBundleOptions();

132 bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);

133 bool finishBundle(SMLoc IDLoc, MCStreamer &Out);

134 void canonicalizeImmediates(MCInst &MCI);

135 bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,

136 OperandVector &InstOperands, uint64_t &ErrorInfo,

137 bool MatchingInlineAsm);

138 void eatToEndOfPacket();

139 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

141 uint64_t &ErrorInfo,

142 bool MatchingInlineAsm) override;

143

144 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,

145 unsigned Kind) override;

146 bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);

147 int processInstruction(MCInst &Inst, OperandVector const &Operands,

148 SMLoc IDLoc);

149

150 MCRegister matchRegister(StringRef Name);

151

152

153

154

155#define GET_ASSEMBLER_HEADER

156#include "HexagonGenAsmMatcher.inc"

157

158

159

160public:

164 InBrackets(false) {

166 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));

167

171

173

175 getTargetStreamer().emitTargetAttributes(*STI);

176 }

177

181 bool implicitExpressionLocation(OperandVector &Operands);

182 bool parseExpressionOrOperand(OperandVector &Operands);

183 bool parseExpression(MCExpr const *&Expr);

184

185 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,

186 SMLoc NameLoc, OperandVector &Operands) override {

188 }

189

190 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,

192

193 bool ParseDirective(AsmToken DirectiveID) override;

194};

195

196

197

199 enum KindTy { Token, Immediate, Register } Kind;

200 MCContext &Context;

201

202 SMLoc StartLoc, EndLoc;

203

204 struct TokTy {

205 const char *Data;

206 unsigned Length;

207 };

208

209 struct RegTy {

210 MCRegister RegNum;

211 };

212

213 struct ImmTy {

214 const MCExpr *Val;

215 };

216

217 union {

218 struct TokTy Tok;

219 struct RegTy Reg;

220 struct ImmTy Imm;

221 };

222

223 HexagonOperand(KindTy K, MCContext &Context) : Kind(K), Context(Context) {}

224

225public:

226 HexagonOperand(const HexagonOperand &o)

227 : MCParsedAsmOperand(), Context(o.Context) {

228 Kind = o.Kind;

229 StartLoc = o.StartLoc;

230 EndLoc = o.EndLoc;

231 switch (Kind) {

232 case Register:

234 break;

235 case Immediate:

237 break;

238 case Token:

239 Tok = o.Tok;

240 break;

241 }

242 }

243

244

245 SMLoc getStartLoc() const override { return StartLoc; }

246

247

248 SMLoc getEndLoc() const override { return EndLoc; }

249

250 MCRegister getReg() const override {

251 assert(Kind == Register && "Invalid access!");

252 return Reg.RegNum;

253 }

254

255 const MCExpr *getImm() const {

256 assert(Kind == Immediate && "Invalid access!");

257 return Imm.Val;

258 }

259

260 bool isToken() const override { return Kind == Token; }

261 bool isImm() const override { return Kind == Immediate; }

263 bool isReg() const override { return Kind == Register; }

264

265 bool CheckImmRange(int immBits, int zeroBits, bool isSigned,

266 bool isRelocatable, bool Extendable) const {

267 if (Kind == Immediate) {

270 return false;

271 int64_t Res;

272 if (myMCExpr->evaluateAsAbsolute(Res)) {

273 int bits = immBits + zeroBits;

274

275

276 if (Res & ((1 << zeroBits) - 1))

277 return false;

279 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))

280 return true;

281 } else {

282 if (bits == 64)

283 return true;

284 if (Res >= 0)

285 return ((uint64_t)Res < (uint64_t)(1ULL << bits));

286 else {

287 const int64_t high_bit_set = 1ULL << 63;

288 const uint64_t mask = (high_bit_set >> (63 - bits));

289 return (((uint64_t)Res & mask) == mask);

290 }

291 }

293 return true;

296 return true;

297 }

298 return false;

299 }

300

301 bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }

302 bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }

303 bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }

304 bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }

305

306 bool ism32_0Imm() const { return true; }

307

308 bool isf32Imm() const { return false; }

309 bool isf64Imm() const { return false; }

310 bool iss32_0Imm() const { return true; }

311 bool iss31_1Imm() const { return true; }

312 bool iss30_2Imm() const { return true; }

313 bool iss29_3Imm() const { return true; }

314 bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }

315 bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }

316 bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, false); }

317 bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }

318 bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }

319 bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }

320 bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }

321 bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }

322 bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }

323 bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }

324 bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }

325 bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }

326 bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }

327 bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }

328

329 bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }

330 bool isu32_0Imm() const { return true; }

331 bool isu31_1Imm() const { return true; }

332 bool isu30_2Imm() const { return true; }

333 bool isu29_3Imm() const { return true; }

334 bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }

335 bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }

336 bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }

337 bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }

338 bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }

339 bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }

340 bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }

341 bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }

342 bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }

343 bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }

344 bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }

345 bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }

346 bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }

347 bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }

348 bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }

349 bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }

350 bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }

351 bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }

352 bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }

353 bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }

354 bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }

355 bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }

356 bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }

357

358 bool isn1Const() const {

359 if (!isImm())

360 return false;

362 if (getImm()->evaluateAsAbsolute(Value))

363 return false;

364 return Value == -1;

365 }

366 bool issgp10Const() const {

368 return false;

369 return getReg() == Hexagon::SGP1_0;

370 }

371 bool iss11_0Imm() const {

372 return CheckImmRange(11 + 26, 0, true, true, true);

373 }

374 bool iss11_1Imm() const {

375 return CheckImmRange(11 + 26, 1, true, true, true);

376 }

377 bool iss11_2Imm() const {

378 return CheckImmRange(11 + 26, 2, true, true, true);

379 }

380 bool iss11_3Imm() const {

381 return CheckImmRange(11 + 26, 3, true, true, true);

382 }

383 bool isu32_0MustExt() const { return isImm(); }

384

385 void addRegOperands(MCInst &Inst, unsigned N) const {

386 assert(N == 1 && "Invalid number of operands!");

388 }

389

390 void addImmOperands(MCInst &Inst, unsigned N) const {

391 assert(N == 1 && "Invalid number of operands!");

393 }

394

395 void addSignedImmOperands(MCInst &Inst, unsigned N) const {

396 assert(N == 1 && "Invalid number of operands!");

397 HexagonMCExpr *Expr =

402 return;

403 }

407 if ((Extended < 0) != (Value < 0))

412 }

413

414 void addn1ConstOperands(MCInst &Inst, unsigned N) const {

415 addImmOperands(Inst, N);

416 }

417 void addsgp10ConstOperands(MCInst &Inst, unsigned N) const {

418 addRegOperands(Inst, N);

419 }

420

422 assert(Kind == Token && "Invalid access!");

423 return StringRef(Tok.Data, Tok.Length);

424 }

425

426 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;

427

428 static std::unique_ptr CreateToken(MCContext &Context,

429 StringRef Str, SMLoc S) {

430 HexagonOperand *Op = new HexagonOperand(Token, Context);

431 Op->Tok.Data = Str.data();

432 Op->Tok.Length = Str.size();

433 Op->StartLoc = S;

434 Op->EndLoc = S;

435 return std::unique_ptr(Op);

436 }

437

438 static std::unique_ptr

439 CreateReg(MCContext &Context, MCRegister Reg, SMLoc S, SMLoc E) {

440 HexagonOperand *Op = new HexagonOperand(Register, Context);

441 Op->Reg.RegNum = Reg;

442 Op->StartLoc = S;

443 Op->EndLoc = E;

444 return std::unique_ptr(Op);

445 }

446

447 static std::unique_ptr

448 CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {

449 HexagonOperand *Op = new HexagonOperand(Immediate, Context);

450 Op->Imm.Val = Val;

451 Op->StartLoc = S;

452 Op->EndLoc = E;

453 return std::unique_ptr(Op);

454 }

455};

456

457}

458

460 switch (Kind) {

461 case Immediate:

462 HexagonMCAsmInfo(Triple()).printExpr(OS, *getImm());

463 break;

465 OS << "<register R";

467 break;

468 case Token:

469 OS << "'" << getToken() << "'";

470 break;

471 }

472}

473

474bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {

478

480

481

482 const MCRegisterInfo *RI = getContext().getRegisterInfo();

483 MCSubtargetInfo const &STI = getSTI();

484

485 MCInst OrigBundle = MCB;

486 HexagonMCChecker Check(getContext(), MII, STI, MCB, *RI, true);

487

490

491 if (CheckOk) {

495

496 return false;

497 }

498

500

502 } else

503 return true;

504

505 return false;

506}

507

508bool HexagonAsmParser::matchBundleOptions() {

509 MCAsmParser &Parser = getParser();

510 while (true) {

512 return false;

513 Lex();

514 char const *MemNoShuffMsg =

515 "invalid instruction packet: mem_noshuf specifier not "

516 "supported with this architecture";

519 if (Option.compare_insensitive("endloop01") == 0) {

522 } else if (Option.compare_insensitive("endloop0") == 0) {

524 } else if (Option.compare_insensitive("endloop1") == 0) {

526 } else if (Option.compare_insensitive("mem_noshuf") == 0) {

527 if (getSTI().hasFeature(Hexagon::FeatureMemNoShuf))

529 else

530 return getParser().Error(IDLoc, MemNoShuffMsg);

531 } else if (Option.compare_insensitive("mem_no_order") == 0) {

532

533 } else

534 return getParser().Error(IDLoc, llvm::Twine("'") + Option +

535 "' is not a valid bundle option");

536 Lex();

537 }

538}

539

540

541

542

543void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {

544 MCInst NewInst;

546 for (MCOperand &I : MCI)

547 if (I.isImm()) {

548 int64_t Value(I.getImm());

551 } else {

554 Warning(MCI.getLoc(), "Signed/Unsigned mismatch");

556 }

557 MCI = NewInst;

558}

559

560bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,

562 uint64_t &ErrorInfo,

563 bool MatchingInlineAsm) {

564

565 int result =

566 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);

567 if (result == Match_Success) {

569 canonicalizeImmediates(MCI);

570 result = processInstruction(MCI, InstOperands, IDLoc);

571

575

577 }

578

579

580

581

582

583 switch (result) {

584 default:

585 break;

586 case Match_Success:

587 return false;

588 case Match_MissingFeature:

589 return Error(IDLoc, "invalid instruction");

590 case Match_MnemonicFail:

591 return Error(IDLoc, "unrecognized instruction");

592 case Match_InvalidOperand:

593 [[fallthrough]];

594 case Match_InvalidTiedOperand:

595 SMLoc ErrorLoc = IDLoc;

596 if (ErrorInfo != ~0U) {

597 if (ErrorInfo >= InstOperands.size())

598 return Error(IDLoc, "too few operands for instruction");

599

600 ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))

601 ->getStartLoc();

602 if (ErrorLoc == SMLoc())

603 ErrorLoc = IDLoc;

604 }

605 return Error(ErrorLoc, "invalid operand for instruction");

606 }

608}

609

610void HexagonAsmParser::eatToEndOfPacket() {

612 AsmLexer &Lexer = getLexer();

614 Lexer.Lex();

615 Lexer.Lex();

616 InBrackets = false;

617}

618

619bool HexagonAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

621 MCStreamer &Out,

622 uint64_t &ErrorInfo,

623 bool MatchingInlineAsm) {

624 if (!InBrackets) {

627 }

628 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);

629 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {

630 assert(Operands.size() == 1 && "Brackets should be by themselves");

631 if (InBrackets) {

632 getParser().Error(IDLoc, "Already in a packet");

633 InBrackets = false;

634 return true;

635 }

636 InBrackets = true;

637 return false;

638 }

639 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {

640 assert(Operands.size() == 1 && "Brackets should be by themselves");

641 if (!InBrackets) {

642 getParser().Error(IDLoc, "Not in a packet");

643 return true;

644 }

645 InBrackets = false;

646 if (matchBundleOptions())

647 return true;

648 return finishBundle(IDLoc, Out);

649 }

650 MCInst *SubInst = getParser().getContext().createMCInst();

651 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,

652 MatchingInlineAsm)) {

653 if (InBrackets)

654 eatToEndOfPacket();

655 return true;

656 }

658 getParser().getContext(), MII, MCB, *SubInst);

660 if (!InBrackets)

661 return finishBundle(IDLoc, Out);

662 return false;

663}

664

665

666

667bool HexagonAsmParser::parseDirectiveAttribute(SMLoc L) {

668 MCAsmParser &Parser = getParser();

669 int64_t Tag;

675 if (!Ret)

676 return Error(TagLoc, "attribute name not recognized: " + Name);

677 Tag = *Ret;

678 Parser.Lex();

679 } else {

680 const MCExpr *AttrExpr;

681

684 return true;

685

687 if (check(!CE, TagLoc, "expected numeric constant"))

688 return true;

689

690 Tag = CE->getValue();

691 }

692

694 return true;

695

696

697 int64_t IntegerValue = 0;

698 SMLoc ValueExprLoc = Parser.getTok().getLoc();

699 const MCExpr *ValueExpr;

701 return true;

702

704 if (!CE)

705 return Error(ValueExprLoc, "expected numeric constant");

706 IntegerValue = CE->getValue();

707

709 return true;

710

711 getTargetStreamer().emitAttribute(Tag, IntegerValue);

712 return false;

713}

714

715

716bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {

718 if (IDVal.lower() == ".falign")

719 return ParseDirectiveFalign(256, DirectiveID.getLoc());

720 if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))

721 return ParseDirectiveComm(true, DirectiveID.getLoc());

722 if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))

723 return ParseDirectiveComm(false, DirectiveID.getLoc());

724 if (IDVal.lower() == ".subsection")

725 return ParseDirectiveSubsection(DirectiveID.getLoc());

726 if (IDVal == ".attribute")

727 return parseDirectiveAttribute(DirectiveID.getLoc());

728

729 return true;

730}

731bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {

732 const MCExpr *Subsection = nullptr;

733 int64_t Res;

734

736 "Invalid subsection directive");

737 getParser().parseExpression(Subsection);

738

739 if (!Subsection->evaluateAsAbsolute(Res))

740 return Error(L, "Cannot evaluate subsection number");

741

743 return TokError("unexpected token in directive");

744

745

746

747

748

749 if ((Res < 0) && (Res > -8193))

750 Res += 8192;

751 getStreamer().switchSection(getStreamer().getCurrentSectionOnly(), Res);

752 return false;

753}

754

755

756bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {

757

758 int64_t MaxBytesToFill = 15;

759

760

762 const MCExpr *Value;

763 SMLoc ExprLoc = L;

764

765

766 if (!getParser().parseExpression(Value)) {

767

769 uint64_t IntValue = MCE->getValue();

771 return Error(ExprLoc, "literal value out of range (256) for falign");

772 MaxBytesToFill = IntValue;

773 Lex();

774 } else {

775 return Error(ExprLoc, "not a valid expression for falign directive");

776 }

777 }

778

779 getTargetStreamer().emitFAlign(16, MaxBytesToFill);

780 Lex();

781

782 return false;

783}

784

785

786

787

788

789

790

791bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {

792

793

794 if (getStreamer().hasRawTextSupport())

795 return true;

796

797 StringRef Name;

798 if (getParser().parseIdentifier(Name))

799 return TokError("expected identifier in directive");

800

802

804 return TokError("unexpected token in directive");

805 Lex();

806

807 int64_t Size;

808 SMLoc SizeLoc = getLexer().getLoc();

809 if (getParser().parseAbsoluteExpression(Size))

810 return true;

811

813 SMLoc ByteAlignmentLoc;

815 Lex();

816 ByteAlignmentLoc = getLexer().getLoc();

817 if (getParser().parseAbsoluteExpression(ByteAlignment))

818 return true;

820 return Error(ByteAlignmentLoc, "alignment must be a power of 2");

821 }

822

823 int64_t AccessAlignment = 0;

825

826

827 SMLoc AccessAlignmentLoc;

828 Lex();

829 AccessAlignmentLoc = getLexer().getLoc();

830 if (getParser().parseAbsoluteExpression(AccessAlignment))

831 return true;

832

834 return Error(AccessAlignmentLoc, "access alignment must be a power of 2");

835 }

836

838 return TokError("unexpected token in '.comm' or '.lcomm' directive");

839

840 Lex();

841

842

843

844 if (Size < 0)

845 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "

846 "be less than zero");

847

848

849

850

851 if (ByteAlignment < 0)

852 return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "

853 "alignment, can't be less than zero");

854

856 return Error(Loc, "invalid symbol redefinition");

857

858 HexagonMCELFStreamer &HexagonELFStreamer =

859 static_cast<HexagonMCELFStreamer &>(getStreamer());

860 if (IsLocal) {

862 Sym, Size, Align(ByteAlignment), AccessAlignment);

863 return false;

864 }

865

867 AccessAlignment);

868 return false;

869}

870

871

872bool HexagonAsmParser::RegisterMatchesArch(MCRegister MatchNum) const {

873 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))

874 if (!getSTI().hasFeature(Hexagon::ArchV62))

875 return false;

876 return true;

877}

878

879

880

881

886

887#define GET_MATCHER_IMPLEMENTATION

888#define GET_REGISTER_MATCHER

889#include "HexagonGenAsmMatcher.inc"

890

893 if (Index >= Operands.size())

894 return false;

897 return false;

898 return static_cast<HexagonOperand &>(Operand).getToken().equals_insensitive(

900}

901

909

910bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {

911 AsmToken const &Token = getParser().getTok();

913 SMLoc Loc = Token.getLoc();

914 Lex();

915 do {

916 std::pair<StringRef, StringRef> HeadTail = String.split('.');

917 if (!HeadTail.first.empty())

919 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));

920 if (!HeadTail.second.empty())

921 Operands.push_back(HexagonOperand::CreateToken(

922 getContext(), String.substr(HeadTail.first.size(), 1), Loc));

923 String = HeadTail.second;

924 } while (String.empty());

925 return false;

926}

927

928bool HexagonAsmParser::parseOperand(OperandVector &Operands) {

930 SMLoc Begin;

931 SMLoc End;

932 AsmLexer &Lexer = getLexer();

933 if (!parseRegister(Register, Begin, End)) {

936 default:

937 break;

938 case Hexagon::P0:

939 case Hexagon::P1:

940 case Hexagon::P2:

941 case Hexagon::P3:

944 Warning(Begin, "Missing parenthesis around predicate register");

945 static char const *LParen = "(";

946 static char const *RParen = ")";

948 HexagonOperand::CreateToken(getContext(), LParen, Begin));

951 const AsmToken &MaybeDotNew = Lexer.getTok();

952 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&

954 splitIdentifier(Operands);

956 HexagonOperand::CreateToken(getContext(), RParen, Begin));

957 return false;

958 }

962 Warning(Begin, "Missing parenthesis around predicate register");

963 static char const *LParen = "(";

964 static char const *RParen = ")";

965 Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(

969 const AsmToken &MaybeDotNew = Lexer.getTok();

970 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&

972 splitIdentifier(Operands);

974 HexagonOperand::CreateToken(getContext(), RParen, Begin));

975 return false;

976 }

977 break;

978 }

981 return false;

982 }

983 return splitIdentifier(Operands);

984}

985

986bool HexagonAsmParser::isLabel(AsmToken &Token) {

987 AsmLexer &Lexer = getLexer();

988 AsmToken const &Second = Lexer.getTok();

989 AsmToken Third = Lexer.peekTok();

991 if (Token.is(AsmToken::TokenKind::LCurly) ||

992 Token.is(AsmToken::TokenKind::RCurly))

993 return false;

994

997 return false;

998 if (!Token.is(AsmToken::TokenKind::Identifier))

999 return true;

1000 if (!matchRegister(String.lower()))

1001 return true;

1005 std::string Collapsed = std::string(Raw);

1007 StringRef Whole = Collapsed;

1008 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');

1009 if (!matchRegister(DotSplit.first.lower()))

1010 return true;

1011 return false;

1012}

1013

1014bool HexagonAsmParser::tokenIsStartOfStatement(AsmToken::TokenKind Token) {

1016}

1017

1018bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,

1019 SMLoc &Loc) {

1021 Error(Loc, "Register name is not contigious");

1022 return true;

1023 }

1025 Warning(Loc, "Register name is not contigious");

1026 return false;

1027}

1028

1029bool HexagonAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,

1030 SMLoc &EndLoc) {

1031 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();

1032}

1033

1034ParseStatus HexagonAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

1035 SMLoc &EndLoc) {

1036 AsmLexer &Lexer = getLexer();

1037 StartLoc = getLexer().getLoc();

1041 bool NeededWorkaround = false;

1042 while (Again) {

1043 AsmToken const &Token = Lexer.getTok();

1044 RawString = StringRef(RawString.data(), Token.getString().data() -

1045 RawString.data() +

1048 Lexer.Lex();

1050 Lookahead.back().getString().data() +

1051 Lookahead.back().getString().size();

1055 bool Workaround =

1057 Again = (Contigious && Type) || (Workaround && Type);

1058 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));

1059 }

1060 std::string Collapsed = std::string(RawString);

1062 StringRef FullString = Collapsed;

1063 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');

1064 MCRegister DotReg = matchRegister(DotSplit.first.lower());

1065 if (DotReg && RegisterMatchesArch(DotReg)) {

1066 if (DotSplit.second.empty()) {

1067 Reg = DotReg;

1068 EndLoc = Lexer.getLoc();

1069 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))

1072 } else {

1073 Reg = DotReg;

1074 size_t First = RawString.find('.');

1075 StringRef DotString (RawString.data() + First, RawString.size() - First);

1077 EndLoc = Lexer.getLoc();

1078 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))

1081 }

1082 }

1083 std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');

1084 MCRegister ColonReg = matchRegister(ColonSplit.first.lower());

1085 if (ColonReg && RegisterMatchesArch(DotReg)) {

1086 do {

1089 Reg = ColonReg;

1090 EndLoc = Lexer.getLoc();

1091 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))

1094 }

1095 while (!Lookahead.empty()) {

1097 }

1099}

1100

1101bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {

1103 return true;

1106 return true;

1108 return true;

1111 return true;

1112 return false;

1113}

1114

1115bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {

1117 AsmLexer &Lexer = getLexer();

1118 bool Done = false;

1119 static char const *Comma = ",";

1120 do {

1122 Lex();

1123 switch (Tokens.back().getKind()) {

1124 case AsmToken::TokenKind::Hash:

1125 if (Tokens.size() > 1)

1126 if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {

1128 AsmToken(AsmToken::TokenKind::Comma, Comma));

1129 Done = true;

1130 }

1131 break;

1132 case AsmToken::TokenKind::RCurly:

1133 case AsmToken::TokenKind::EndOfStatement:

1134 case AsmToken::TokenKind::Eof:

1135 Done = true;

1136 break;

1137 default:

1138 break;

1139 }

1140 } while (Done);

1141 while (!Tokens.empty()) {

1144 }

1145 SMLoc Loc = Lexer.getLoc();

1146 return getParser().parseExpression(Expr, Loc);

1147}

1148

1149bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {

1150 if (implicitExpressionLocation(Operands)) {

1151 MCAsmParser &Parser = getParser();

1153 MCExpr const *Expr = nullptr;

1154 bool Error = parseExpression(Expr);

1158 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));

1160 }

1161 return parseOperand(Operands);

1162}

1163

1164

1165bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {

1166 MCAsmParser &Parser = getParser();

1167 AsmLexer &Lexer = getLexer();

1168 while (true) {

1169 AsmToken const &Token = Parser.getTok();

1170 switch (Token.getKind()) {

1173 Lex();

1174 return false;

1175 }

1177 if (!Operands.empty())

1178 return true;

1179 Operands.push_back(HexagonOperand::CreateToken(

1181 Lex();

1182 return false;

1183 }

1185 if (Operands.empty()) {

1186 Operands.push_back(HexagonOperand::CreateToken(

1188 Lex();

1189 }

1190 return false;

1191 }

1193 Lex();

1194 continue;

1195 }

1202 Operands.push_back(HexagonOperand::CreateToken(

1204 Operands.push_back(HexagonOperand::CreateToken(

1206 Lex();

1207 continue;

1208 }

1210 bool MustNotExtend = false;

1211 bool ImplicitExpression = implicitExpressionLocation(Operands);

1212 SMLoc ExprLoc = Lexer.getLoc();

1213 if (!ImplicitExpression)

1214 Operands.push_back(HexagonOperand::CreateToken(

1216 Lex();

1217 bool MustExtend = false;

1218 bool HiOnly = false;

1219 bool LoOnly = false;

1221 Lex();

1222 MustExtend = true;

1223 } else if (ImplicitExpression)

1224 MustNotExtend = true;

1225 AsmToken const &Token = Parser.getTok();

1228 if (String.lower() == "hi") {

1229 HiOnly = true;

1230 } else if (String.lower() == "lo") {

1231 LoOnly = true;

1232 }

1233 if (HiOnly || LoOnly) {

1234 AsmToken LParen = Lexer.peekTok();

1236 HiOnly = false;

1237 LoOnly = false;

1238 } else {

1239 Lex();

1240 }

1241 }

1242 }

1243 MCExpr const *Expr = nullptr;

1244 if (parseExpression(Expr))

1245 return true;

1248 assert(Expr != nullptr);

1249 if (Expr->evaluateAsAbsolute(Value)) {

1250 if (HiOnly)

1253 if (HiOnly || LoOnly)

1256 } else {

1259 if (Value.isAbsolute()) {

1263

1264 MustNotExtend = !MustExtend;

1265 break;

1266 default:

1267 break;

1268 }

1269 }

1270 }

1271 }

1275 std::unique_ptr Operand =

1276 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);

1277 Operands.push_back(std::move(Operand));

1278 continue;

1279 }

1280 default:

1281 break;

1282 }

1283 if (parseExpressionOrOperand(Operands))

1284 return true;

1285 }

1286}

1287

1288bool HexagonAsmParser::parseInstruction(ParseInstructionInfo &Info,

1289 StringRef Name, AsmToken ID,

1291 getLexer().UnLex(ID);

1292 return parseInstruction(Operands);

1293}

1294

1302

1303 return TmpInst;

1304}

1305

1306

1307

1308unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,

1309 unsigned Kind) {

1310 HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);

1311

1312 switch (Kind) {

1313 case MCK_0: {

1315 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0

1316 ? Match_Success

1317 : Match_InvalidOperand;

1318 }

1319 case MCK_1: {

1321 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1

1322 ? Match_Success

1323 : Match_InvalidOperand;

1324 }

1325 }

1326 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {

1327 StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);

1328 if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)

1329 return Match_Success;

1330 if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)

1331 return Match_Success;

1332 }

1333

1337

1338 return Match_InvalidOperand;

1339}

1340

1341

1342bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {

1343 std::string errStr;

1344 raw_string_ostream ES(errStr);

1345 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";

1346 if (Max >= 0)

1347 ES << "0-" << Max;

1348 else

1349 ES << Max << "-" << (-Max - 1);

1350 return Parser.printError(IDLoc, ES.str());

1351}

1352

1353int HexagonAsmParser::processInstruction(MCInst &Inst,

1355 SMLoc IDLoc) {

1356 MCContext &Context = getParser().getContext();

1357 const MCRegisterInfo *RI = getContext().getRegisterInfo();

1358 const std::string r = "r";

1359 const std::string Colon = ":";

1360 using RegPairVals = std::pair<unsigned, unsigned>;

1361 auto GetRegPair = [this, r](RegPairVals RegPair) {

1362 const std::string R1 = r + utostr(RegPair.first);

1363 const std::string R2 = r + utostr(RegPair.second);

1364

1365 return std::make_pair(matchRegister(R1), matchRegister(R2));

1366 };

1367 auto GetScalarRegs = [RI, GetRegPair](MCRegister RegPair) {

1369 const RegPairVals RegPair_ = std::make_pair(Lower + 1, Lower);

1370

1371 return GetRegPair(RegPair_);

1372 };

1373 auto GetVecRegs = [GetRegPair](MCRegister VecRegPair) {

1374 const RegPairVals RegPair =

1376

1377 return GetRegPair(RegPair);

1378 };

1379

1380 bool is32bit = false;

1382 default:

1384 SMDiagnostic Diag = getSourceManager().GetMessage(

1386 "Found pseudo instruction with no expansion");

1389 }

1390 break;

1391

1392 case Hexagon::J2_trap1:

1393 if (!getSTI().hasFeature(Hexagon::ArchV65)) {

1396 if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {

1397 Error(IDLoc, "trap1 can only have register r0 as operand");

1398 return Match_InvalidOperand;

1399 }

1400 }

1401 break;

1402

1403 case Hexagon::A2_iconst: {

1404 Inst.setOpcode(Hexagon::A2_addi);

1413 break;

1414 }

1415 case Hexagon::M4_mpyrr_addr:

1416 case Hexagon::S4_addi_asl_ri:

1417 case Hexagon::S4_addi_lsr_ri:

1418 case Hexagon::S4_andi_asl_ri:

1419 case Hexagon::S4_andi_lsr_ri:

1420 case Hexagon::S4_ori_asl_ri:

1421 case Hexagon::S4_ori_lsr_ri:

1422 case Hexagon::S4_or_andix:

1423 case Hexagon::S4_subi_asl_ri:

1424 case Hexagon::S4_subi_lsr_ri: {

1426 MCOperand &src = Inst.getOperand(2);

1428 return Match_InvalidOperand;

1429 break;

1430 }

1431

1432 case Hexagon::C2_cmpgei: {

1438 Inst.setOpcode(Hexagon::C2_cmpgti);

1439 break;

1440 }

1441

1442 case Hexagon::C2_cmpgeui: {

1448 if (Value == 0) {

1449 MCInst TmpInst;

1452 TmpInst.setOpcode(Hexagon::C2_cmpeq);

1456 Inst = TmpInst;

1457 } else {

1462 Inst.setOpcode(Hexagon::C2_cmpgtui);

1463 }

1464 break;

1465 }

1466

1467

1468 case Hexagon::A2_tfrp: {

1470 const std::pair<MCRegister, MCRegister> RegPair =

1471 GetScalarRegs(MO.getReg());

1472 MO.setReg(RegPair.first);

1474 Inst.setOpcode(Hexagon::A2_combinew);

1475 break;

1476 }

1477

1478 case Hexagon::A2_tfrpt:

1479 case Hexagon::A2_tfrpf: {

1481 const std::pair<MCRegister, MCRegister> RegPair =

1482 GetScalarRegs(MO.getReg());

1483 MO.setReg(RegPair.first);

1486 ? Hexagon::C2_ccombinewt

1487 : Hexagon::C2_ccombinewf);

1488 break;

1489 }

1490 case Hexagon::A2_tfrptnew:

1491 case Hexagon::A2_tfrpfnew: {

1493 const std::pair<MCRegister, MCRegister> RegPair =

1494 GetScalarRegs(MO.getReg());

1495 MO.setReg(RegPair.first);

1498 ? Hexagon::C2_ccombinewnewt

1499 : Hexagon::C2_ccombinewnewf);

1500 break;

1501 }

1502

1503

1504 case Hexagon::V6_vassignp: {

1506 const std::pair<MCRegister, MCRegister> RegPair = GetVecRegs(MO.getReg());

1507 MO.setReg(RegPair.first);

1509 Inst.setOpcode(Hexagon::V6_vcombine);

1510 break;

1511 }

1512

1513

1514 case Hexagon::CONST32:

1515 is32bit = true;

1516 [[fallthrough]];

1517

1518 case Hexagon::CONST64:

1519

1521 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());

1522 MCOperand &MO_1 = Inst.getOperand(1);

1523 MCOperand &MO_0 = Inst.getOperand(0);

1524

1525

1527

1528 std::string myCharStr;

1529 MCSectionELF *mySection;

1530

1531

1534 if (Absolute) {

1535

1536

1537 if (is32bit) {

1538 std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));

1539 myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")

1540 .drop_back(myImmStr.size())

1541 .str() +

1542 myImmStr;

1543 } else {

1545 myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")

1546 .drop_back(myImmStr.size())

1547 .str() +

1548 myImmStr;

1549 }

1550

1553 } else if (MO_1.isExpr()) {

1554

1555 myCharStr = ".lita";

1558 } else

1560

1562 unsigned byteSize = is32bit ? 4 : 8;

1564

1566

1567

1568

1569

1570 if (Absolute) {

1571 Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));

1573 getStreamer().emitLabel(Sym);

1574 getStreamer().emitSymbolAttribute(Sym, MCSA_Global);

1576 }

1577 } else if (MO_1.isExpr()) {

1578 const char *StringStart = nullptr;

1579 const char *StringEnd = nullptr;

1580 if (*Operands[4]->getStartLoc().getPointer() == '#') {

1581 StringStart = Operands[5]->getStartLoc().getPointer();

1582 StringEnd = Operands[6]->getStartLoc().getPointer();

1583 } else {

1584 StringStart = Operands[4]->getStartLoc().getPointer();

1585 StringEnd = Operands[5]->getStartLoc().getPointer();

1586 }

1587

1588 unsigned size = StringEnd - StringStart;

1589 std::string DotConst = ".CONST_";

1590 Sym = getContext().getOrCreateSymbol(DotConst +

1591 StringRef(StringStart, size));

1592

1594

1595 getStreamer().emitLabel(Sym);

1596 getStreamer().emitSymbolAttribute(Sym, MCSA_Local);

1597 getStreamer().emitValue(MO_1.getExpr(), 4);

1598 }

1599 } else

1601

1603

1604 if (Sym) {

1605 MCInst TmpInst;

1606 if (is32bit)

1607 TmpInst.setOpcode(Hexagon::L2_loadrigp);

1608 else

1609 TmpInst.setOpcode(Hexagon::L2_loadrdgp);

1610

1614 Inst = TmpInst;

1615 }

1616 }

1617 break;

1618

1619

1620 case Hexagon::A2_tfrpi: {

1621 MCOperand &Rdd = Inst.getOperand(0);

1624 int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;

1627 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);

1628 break;

1629 }

1630

1631

1632 case Hexagon::TFRI64_V4: {

1633 MCOperand &Rdd = Inst.getOperand(0);

1636 if (MO.getExpr()->evaluateAsAbsolute(Value)) {

1639 OutOfRange(IDLoc, s8, -128);

1647 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);

1648 } else {

1651 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);

1652 }

1653 break;

1654 }

1655

1656

1657 case Hexagon::TFRI64_V2_ext: {

1658 MCOperand &Rdd = Inst.getOperand(0);

1659 MCOperand &MO1 = Inst.getOperand(1);

1660 MCOperand &MO2 = Inst.getOperand(2);

1662 if (MO2.getExpr()->evaluateAsAbsolute(Value)) {

1664 if (s8 < -128 || s8 > 127)

1665 OutOfRange(IDLoc, s8, -128);

1666 }

1667 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);

1668 break;

1669 }

1670

1671

1672 case Hexagon::A4_combineii: {

1673 MCOperand &Rdd = Inst.getOperand(0);

1674 MCOperand &MO1 = Inst.getOperand(1);

1676 if (MO1.getExpr()->evaluateAsAbsolute(Value)) {

1678 if (s8 < -128 || s8 > 127)

1679 OutOfRange(IDLoc, s8, -128);

1680 }

1681 MCOperand &MO2 = Inst.getOperand(2);

1682 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);

1683 break;

1684 }

1685

1686 case Hexagon::S2_tableidxb_goodsyntax:

1687 Inst.setOpcode(Hexagon::S2_tableidxb);

1688 break;

1689

1690 case Hexagon::S2_tableidxh_goodsyntax: {

1691 MCInst TmpInst;

1694 MCOperand &Imm4 = Inst.getOperand(3);

1695 MCOperand &Imm6 = Inst.getOperand(4);

1700 TmpInst.setOpcode(Hexagon::S2_tableidxh);

1706 Inst = TmpInst;

1707 break;

1708 }

1709

1710 case Hexagon::S2_tableidxw_goodsyntax: {

1711 MCInst TmpInst;

1714 MCOperand &Imm4 = Inst.getOperand(3);

1715 MCOperand &Imm6 = Inst.getOperand(4);

1720 TmpInst.setOpcode(Hexagon::S2_tableidxw);

1726 Inst = TmpInst;

1727 break;

1728 }

1729

1730 case Hexagon::S2_tableidxd_goodsyntax: {

1731 MCInst TmpInst;

1734 MCOperand &Imm4 = Inst.getOperand(3);

1735 MCOperand &Imm6 = Inst.getOperand(4);

1740 TmpInst.setOpcode(Hexagon::S2_tableidxd);

1746 Inst = TmpInst;

1747 break;

1748 }

1749

1750 case Hexagon::M2_mpyui:

1751 Inst.setOpcode(Hexagon::M2_mpyi);

1752 break;

1753 case Hexagon::M2_mpysmi: {

1754 MCInst TmpInst;

1759 MCExpr const &Expr = *Imm.getExpr();

1761 if (!Absolute)

1762 return Match_InvalidOperand;

1765 return Match_InvalidOperand;

1769 TmpInst.setOpcode(Hexagon::M2_mpysin);

1770 } else

1771 TmpInst.setOpcode(Hexagon::M2_mpysip);

1775 Inst = TmpInst;

1776 break;

1777 }

1778

1779 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {

1781 MCInst TmpInst;

1784 if (!Absolute)

1785 return Match_InvalidOperand;

1786 if (Value == 0) {

1787 TmpInst.setOpcode(Hexagon::A2_tfr);

1792 } else {

1797 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);

1803 }

1804 Inst = TmpInst;

1805 break;

1806 }

1807

1808 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {

1809 MCOperand &Rdd = Inst.getOperand(0);

1810 MCOperand &Rss = Inst.getOperand(1);

1814 if (!Absolute)

1815 return Match_InvalidOperand;

1816 if (Value == 0) {

1817 MCInst TmpInst;

1819 std::string R1 = r + utostr(RegPairNum + 1);

1820 StringRef Reg1(R1);

1821 Rss.setReg(matchRegister(Reg1));

1822

1823 std::string R2 = r + utostr(RegPairNum);

1824 StringRef Reg2(R2);

1825 TmpInst.setOpcode(Hexagon::A2_combinew);

1829 Inst = TmpInst;

1830 } else {

1835 Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);

1836 }

1837 break;

1838 }

1839

1840 case Hexagon::A4_boundscheck: {

1843 if (RegNum & 1) {

1844 Inst.setOpcode(Hexagon::A4_boundscheck_hi);

1845 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);

1846 StringRef RegPair = Name;

1847 Rs.setReg(matchRegister(RegPair));

1848 } else {

1849 Inst.setOpcode(Hexagon::A4_boundscheck_lo);

1850 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);

1851 StringRef RegPair = Name;

1852 Rs.setReg(matchRegister(RegPair));

1853 }

1854 break;

1855 }

1856

1857 case Hexagon::A2_addsp: {

1860 if (RegNum & 1) {

1861 Inst.setOpcode(Hexagon::A2_addsph);

1862 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);

1863 StringRef RegPair = Name;

1864 Rs.setReg(matchRegister(RegPair));

1865 } else {

1866 Inst.setOpcode(Hexagon::A2_addspl);

1867 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);

1868 StringRef RegPair = Name;

1869 Rs.setReg(matchRegister(RegPair));

1870 }

1871 break;

1872 }

1873

1874 case Hexagon::M2_vrcmpys_s1: {

1877 if (RegNum & 1) {

1878 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);

1879 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);

1880 StringRef RegPair = Name;

1881 Rt.setReg(matchRegister(RegPair));

1882 } else {

1883 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);

1884 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);

1885 StringRef RegPair = Name;

1886 Rt.setReg(matchRegister(RegPair));

1887 }

1888 break;

1889 }

1890

1891 case Hexagon::M2_vrcmpys_acc_s1: {

1892 MCInst TmpInst;

1893 MCOperand &Rxx = Inst.getOperand(0);

1894 MCOperand &Rss = Inst.getOperand(2);

1897 if (RegNum & 1) {

1898 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);

1899 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);

1900 StringRef RegPair = Name;

1901 Rt.setReg(matchRegister(RegPair));

1902 } else {

1903 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);

1904 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);

1905 StringRef RegPair = Name;

1906 Rt.setReg(matchRegister(RegPair));

1907 }

1908

1913 Inst = TmpInst;

1914 break;

1915 }

1916

1917 case Hexagon::M2_vrcmpys_s1rp: {

1920 if (RegNum & 1) {

1921 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);

1922 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);

1923 StringRef RegPair = Name;

1924 Rt.setReg(matchRegister(RegPair));

1925 } else {

1926 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);

1927 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);

1928 StringRef RegPair = Name;

1929 Rt.setReg(matchRegister(RegPair));

1930 }

1931 break;

1932 }

1933

1934 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {

1938 if (!Absolute)

1939 return Match_InvalidOperand;

1941 Inst.setOpcode(Hexagon::S2_vsathub);

1942 else {

1947 Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);

1948 }

1949 break;

1950 }

1951

1952 case Hexagon::S5_vasrhrnd_goodsyntax: {

1953 MCOperand &Rdd = Inst.getOperand(0);

1954 MCOperand &Rss = Inst.getOperand(1);

1958 if (!Absolute)

1959 return Match_InvalidOperand;

1960 if (Value == 0) {

1961 MCInst TmpInst;

1963 std::string R1 = r + utostr(RegPairNum + 1);

1964 StringRef Reg1(R1);

1965 Rss.setReg(matchRegister(Reg1));

1966

1967 std::string R2 = r + utostr(RegPairNum);

1968 StringRef Reg2(R2);

1969 TmpInst.setOpcode(Hexagon::A2_combinew);

1973 Inst = TmpInst;

1974 } else {

1979 Inst.setOpcode(Hexagon::S5_vasrhrnd);

1980 }

1981 break;

1982 }

1983

1984 case Hexagon::A2_not: {

1985 MCInst TmpInst;

1988 TmpInst.setOpcode(Hexagon::A2_subri);

1993 Inst = TmpInst;

1994 break;

1995 }

1996 case Hexagon::PS_loadrubabs:

1998 Inst.setOpcode(Hexagon::L2_loadrubgp);

1999 break;

2000 case Hexagon::PS_loadrbabs:

2002 Inst.setOpcode(Hexagon::L2_loadrbgp);

2003 break;

2004 case Hexagon::PS_loadruhabs:

2006 Inst.setOpcode(Hexagon::L2_loadruhgp);

2007 break;

2008 case Hexagon::PS_loadrhabs:

2010 Inst.setOpcode(Hexagon::L2_loadrhgp);

2011 break;

2012 case Hexagon::PS_loadriabs:

2014 Inst.setOpcode(Hexagon::L2_loadrigp);

2015 break;

2016 case Hexagon::PS_loadrdabs:

2018 Inst.setOpcode(Hexagon::L2_loadrdgp);

2019 break;

2020 case Hexagon::PS_storerbabs:

2022 Inst.setOpcode(Hexagon::S2_storerbgp);

2023 break;

2024 case Hexagon::PS_storerhabs:

2026 Inst.setOpcode(Hexagon::S2_storerhgp);

2027 break;

2028 case Hexagon::PS_storerfabs:

2030 Inst.setOpcode(Hexagon::S2_storerfgp);

2031 break;

2032 case Hexagon::PS_storeriabs:

2034 Inst.setOpcode(Hexagon::S2_storerigp);

2035 break;

2036 case Hexagon::PS_storerdabs:

2038 Inst.setOpcode(Hexagon::S2_storerdgp);

2039 break;

2040 case Hexagon::PS_storerbnewabs:

2042 Inst.setOpcode(Hexagon::S2_storerbnewgp);

2043 break;

2044 case Hexagon::PS_storerhnewabs:

2046 Inst.setOpcode(Hexagon::S2_storerhnewgp);

2047 break;

2048 case Hexagon::PS_storerinewabs:

2050 Inst.setOpcode(Hexagon::S2_storerinewgp);

2051 break;

2052 case Hexagon::A2_zxtb: {

2053 Inst.setOpcode(Hexagon::A2_andir);

2056 break;

2057 }

2058 }

2059

2060 return Match_Success;

2061}

2062

2063MCRegister HexagonAsmParser::matchRegister(StringRef Name) {

2065 return Reg;

2067}

static MCRegister MatchRegisterName(StringRef Name)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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)

static constexpr unsigned long long mask(BlockVerifier::State S)

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Analysis containing CSE Info

#define LLVM_EXTERNAL_VISIBILITY

static bool isSigned(unsigned int Opcode)

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.

Definition HexagonAsmParser.cpp:883

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)

Definition HexagonAsmParser.cpp:891

static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1, MCOperand &MO2)

Definition HexagonAsmParser.cpp:1295

static bool previousIsLoop(OperandVector &Operands, size_t Index)

Definition HexagonAsmParser.cpp:902

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)

Promote Memory to Register

static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

static bool isReg(const MCInst &MI, unsigned OpNo)

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines the SmallVector class.

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

SMLoc getLoc() const

Get the current source location.

const AsmToken peekTok(bool ShouldSkipSpace=true)

Look ahead at the next token to be lexed.

void UnLex(AsmToken const &Token)

const AsmToken & getTok() const

Get the current (last) lexed token.

bool is(AsmToken::TokenKind K) const

Check if the current token has kind K.

const AsmToken & Lex()

Consume the next token from the input stream and return it.

LLVM_ABI SMLoc getLoc() const

StringRef getString() const

Get the string for the current token, this includes all characters (for example, the quotes on string...

bool is(TokenKind K) const

TokenKind getKind() const

StringRef getIdentifier() const

Get the identifier string for the current token, which should be an identifier or a string.

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

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...

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.

virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0

Parse an arbitrary expression.

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)

static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const

Try to evaluate the expression to a relocatable value, i.e.

@ Unary

Unary expressions.

@ SymbolRef

References to labels and assigned expressions.

@ Binary

Binary expressions.

LLVM_ABI bool evaluateAsAbsolute(int64_t &Res) const

Try to evaluate the expression to an absolute value.

Instances of this class represent a single low-level machine instruction.

unsigned getOpcode() const

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.

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

const MCOperand & getOperand(unsigned i) const

Interface to description of machine instruction set.

MCAssembler & getAssembler()

Instances of this class represent operands of the MCInst class.

static MCOperand createExpr(const MCExpr *Val)

void setExpr(const MCExpr *Val)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

void setReg(MCRegister Reg)

Set the register number.

MCRegister getReg() const

Returns the register number.

const MCExpr * getExpr() const

static MCOperand createInst(const MCInst *Val)

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

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.

MCTargetStreamer * getTargetStreamer()

void pushSection()

Save the current and previous section on the section stack.

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())

bool isUndefined() const

isUndefined - Check if this symbol undefined (i.e., implicitly defined).

MCTargetAsmParser - Generic interface to target specific assembly parsers.

Target specific streamer interface.

MCStreamer & getStreamer()

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)

StringRef - Represent a constant reference to a string, i.e.

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

LLVM_ABI std::string upper() const

Convert the given ASCII string to uppercase.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

LLVM_ABI std::string lower() const

bool equals_insensitive(StringRef RHS) const

Check for string equality, ignoring case.

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)

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.

void setOuterLoop(MCInst &MCI)

bool isOuterLoop(MCInst const &MCI)

size_t bundleSize(MCInst const &MCI)

void setS27_2_reloc(MCExpr const &Expr, bool Val=true)

void setInnerLoop(MCInst &MCI)

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)

bool isPseudo(uint64_t TSFlags)

initializer< Ty > init(const Ty &Val)

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

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.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

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 - Return the argument parameter cast to the specified type.

constexpr bool isUIntN(unsigned N, uint64_t x)

Checks if an unsigned integer fits into the given (dynamic) bit width.

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.)

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.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

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.

FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)

format_hex - Output N as a fixed width hexadecimal.

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.

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

void erase_if(Container &C, UnaryPredicate P)

Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...

constexpr bool isIntN(unsigned N, int64_t x)

Checks if an signed integer fits into the given (dynamic) bit width.

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.

@ MCSA_Global

.type _foo, @gnu_unique_object

RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...