LLVM: lib/Target/X86/AsmParser/X86AsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

45#include

46#include

47#include

48

49using namespace llvm;

50

52 "x86-experimental-lvi-inline-asm-hardening",

53 cl::desc("Harden inline assembly code that may be vulnerable to Load Value"

54 " Injection (LVI). This feature is experimental."), cl::Hidden);

55

57 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {

58 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";

59 return true;

60 }

61 return false;

62}

63

64namespace {

65

66

67#define GET_X86_SSE2AVX_TABLE

68#include "X86GenInstrMapping.inc"

69

70static const char OpPrecedence[] = {

71 0,

72 1,

73 2,

74 4,

75 4,

76 5,

77 5,

78 6,

79 6,

80 6,

81 7,

82 8,

83 9,

84 10,

85 0,

86 0,

87 3,

88 3,

89 3,

90 3,

91 3,

92 3

93};

94

96 ParseInstructionInfo *InstInfo;

97 bool Code16GCC;

98 unsigned ForcedDataPrefix = 0;

99

100 enum OpcodePrefix {

101 OpcodePrefix_Default,

102 OpcodePrefix_REX,

103 OpcodePrefix_REX2,

104 OpcodePrefix_VEX,

105 OpcodePrefix_VEX2,

106 OpcodePrefix_VEX3,

107 OpcodePrefix_EVEX,

108 };

109

110 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;

111

112 enum DispEncoding {

113 DispEncoding_Default,

114 DispEncoding_Disp8,

115 DispEncoding_Disp32,

116 };

117

118 DispEncoding ForcedDispEncoding = DispEncoding_Default;

119

120

121 bool UseApxExtendedReg = false;

122

123 bool ForcedNoFlag = false;

124

125private:

126 SMLoc consumeToken() {

127 MCAsmParser &Parser = getParser();

129 Parser.Lex();

131 }

132

135 }

136

137 X86TargetStreamer &getTargetStreamer() {

138 assert(getParser().getStreamer().getTargetStreamer() &&

139 "do not have a target streamer");

140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();

141 return static_cast<X86TargetStreamer &>(TS);

142 }

143

144 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,

145 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,

146 bool matchingInlineAsm, unsigned VariantID = 0) {

147

148 if (Code16GCC)

149 SwitchMode(X86::Is32Bit);

150 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,

151 MissingFeatures, matchingInlineAsm,

152 VariantID);

153 if (Code16GCC)

154 SwitchMode(X86::Is16Bit);

155 return rv;

156 }

157

158 enum InfixCalculatorTok {

159 IC_OR = 0,

160 IC_XOR,

161 IC_AND,

162 IC_LSHIFT,

163 IC_RSHIFT,

164 IC_PLUS,

165 IC_MINUS,

166 IC_MULTIPLY,

167 IC_DIVIDE,

168 IC_MOD,

169 IC_NOT,

170 IC_NEG,

171 IC_RPAREN,

172 IC_LPAREN,

173 IC_IMM,

174 IC_REGISTER,

175 IC_EQ,

176 IC_NE,

177 IC_LT,

178 IC_LE,

179 IC_GT,

180 IC_GE

181 };

182

183 enum IntelOperatorKind {

184 IOK_INVALID = 0,

185 IOK_LENGTH,

186 IOK_SIZE,

187 IOK_TYPE,

188 };

189

190 enum MasmOperatorKind {

191 MOK_INVALID = 0,

192 MOK_LENGTHOF,

193 MOK_SIZEOF,

194 MOK_TYPE,

195 };

196

197 class InfixCalculator {

198 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;

201

202 bool isUnaryOperator(InfixCalculatorTok Op) const {

203 return Op == IC_NEG || Op == IC_NOT;

204 }

205

206 public:

207 int64_t popOperand() {

208 assert (!PostfixStack.empty() && "Poped an empty stack!");

209 ICToken Op = PostfixStack.pop_back_val();

210 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))

211 return -1;

212 return Op.second;

213 }

214 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {

215 assert ((Op == IC_IMM || Op == IC_REGISTER) &&

216 "Unexpected operand!");

217 PostfixStack.push_back(std::make_pair(Op, Val));

218 }

219

220 void popOperator() { InfixOperatorStack.pop_back(); }

221 void pushOperator(InfixCalculatorTok Op) {

222

223 if (InfixOperatorStack.empty()) {

224 InfixOperatorStack.push_back(Op);

225 return;

226 }

227

228

229

230

231 unsigned Idx = InfixOperatorStack.size() - 1;

232 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];

233 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {

234 InfixOperatorStack.push_back(Op);

235 return;

236 }

237

238

239

240 unsigned ParenCount = 0;

241 while (true) {

242

243 if (InfixOperatorStack.empty())

244 break;

245

246 Idx = InfixOperatorStack.size() - 1;

247 StackOp = InfixOperatorStack[Idx];

248 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))

249 break;

250

251

252

253 if (!ParenCount && StackOp == IC_LPAREN)

254 break;

255

256 if (StackOp == IC_RPAREN) {

257 ++ParenCount;

258 InfixOperatorStack.pop_back();

259 } else if (StackOp == IC_LPAREN) {

260 --ParenCount;

261 InfixOperatorStack.pop_back();

262 } else {

263 InfixOperatorStack.pop_back();

264 PostfixStack.push_back(std::make_pair(StackOp, 0));

265 }

266 }

267

268 InfixOperatorStack.push_back(Op);

269 }

270

271 int64_t execute() {

272

273 while (!InfixOperatorStack.empty()) {

274 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();

275 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)

276 PostfixStack.push_back(std::make_pair(StackOp, 0));

277 }

278

279 if (PostfixStack.empty())

280 return 0;

281

283 for (const ICToken &Op : PostfixStack) {

284 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {

286 } else if (isUnaryOperator(Op.first)) {

287 assert (OperandStack.size() > 0 && "Too few operands.");

288 ICToken Operand = OperandStack.pop_back_val();

289 assert (Operand.first == IC_IMM &&

290 "Unary operation with a register!");

291 switch (Op.first) {

292 default:

294 break;

295 case IC_NEG:

296 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));

297 break;

298 case IC_NOT:

299 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));

300 break;

301 }

302 } else {

303 assert (OperandStack.size() > 1 && "Too few operands.");

304 int64_t Val;

307 switch (Op.first) {

308 default:

310 break;

311 case IC_PLUS:

312 Val = Op1.second + Op2.second;

313 OperandStack.push_back(std::make_pair(IC_IMM, Val));

314 break;

315 case IC_MINUS:

316 Val = Op1.second - Op2.second;

317 OperandStack.push_back(std::make_pair(IC_IMM, Val));

318 break;

319 case IC_MULTIPLY:

320 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&

321 "Multiply operation with an immediate and a register!");

322 Val = Op1.second * Op2.second;

323 OperandStack.push_back(std::make_pair(IC_IMM, Val));

324 break;

325 case IC_DIVIDE:

326 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&

327 "Divide operation with an immediate and a register!");

328 assert (Op2.second != 0 && "Division by zero!");

329 Val = Op1.second / Op2.second;

330 OperandStack.push_back(std::make_pair(IC_IMM, Val));

331 break;

332 case IC_MOD:

333 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&

334 "Modulo operation with an immediate and a register!");

335 Val = Op1.second % Op2.second;

336 OperandStack.push_back(std::make_pair(IC_IMM, Val));

337 break;

338 case IC_OR:

339 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&

340 "Or operation with an immediate and a register!");

341 Val = Op1.second | Op2.second;

342 OperandStack.push_back(std::make_pair(IC_IMM, Val));

343 break;

344 case IC_XOR:

345 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&

346 "Xor operation with an immediate and a register!");

347 Val = Op1.second ^ Op2.second;

348 OperandStack.push_back(std::make_pair(IC_IMM, Val));

349 break;

350 case IC_AND:

351 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&

352 "And operation with an immediate and a register!");

353 Val = Op1.second & Op2.second;

354 OperandStack.push_back(std::make_pair(IC_IMM, Val));

355 break;

356 case IC_LSHIFT:

357 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&

358 "Left shift operation with an immediate and a register!");

359 Val = Op1.second << Op2.second;

360 OperandStack.push_back(std::make_pair(IC_IMM, Val));

361 break;

362 case IC_RSHIFT:

363 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&

364 "Right shift operation with an immediate and a register!");

365 Val = Op1.second >> Op2.second;

366 OperandStack.push_back(std::make_pair(IC_IMM, Val));

367 break;

368 case IC_EQ:

369 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&

370 "Equals operation with an immediate and a register!");

371 Val = (Op1.second == Op2.second) ? -1 : 0;

372 OperandStack.push_back(std::make_pair(IC_IMM, Val));

373 break;

374 case IC_NE:

375 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&

376 "Not-equals operation with an immediate and a register!");

377 Val = (Op1.second != Op2.second) ? -1 : 0;

378 OperandStack.push_back(std::make_pair(IC_IMM, Val));

379 break;

380 case IC_LT:

381 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&

382 "Less-than operation with an immediate and a register!");

383 Val = (Op1.second < Op2.second) ? -1 : 0;

384 OperandStack.push_back(std::make_pair(IC_IMM, Val));

385 break;

386 case IC_LE:

387 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&

388 "Less-than-or-equal operation with an immediate and a "

389 "register!");

390 Val = (Op1.second <= Op2.second) ? -1 : 0;

391 OperandStack.push_back(std::make_pair(IC_IMM, Val));

392 break;

393 case IC_GT:

394 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&

395 "Greater-than operation with an immediate and a register!");

396 Val = (Op1.second > Op2.second) ? -1 : 0;

397 OperandStack.push_back(std::make_pair(IC_IMM, Val));

398 break;

399 case IC_GE:

400 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&

401 "Greater-than-or-equal operation with an immediate and a "

402 "register!");

403 Val = (Op1.second >= Op2.second) ? -1 : 0;

404 OperandStack.push_back(std::make_pair(IC_IMM, Val));

405 break;

406 }

407 }

408 }

409 assert (OperandStack.size() == 1 && "Expected a single result.");

411 }

412 };

413

414 enum IntelExprState {

415 IES_INIT,

416 IES_OR,

417 IES_XOR,

418 IES_AND,

419 IES_EQ,

420 IES_NE,

421 IES_LT,

422 IES_LE,

423 IES_GT,

424 IES_GE,

425 IES_LSHIFT,

426 IES_RSHIFT,

427 IES_PLUS,

428 IES_MINUS,

429 IES_OFFSET,

430 IES_CAST,

431 IES_NOT,

432 IES_MULTIPLY,

433 IES_DIVIDE,

434 IES_MOD,

435 IES_LBRAC,

436 IES_RBRAC,

437 IES_LPAREN,

438 IES_RPAREN,

439 IES_REGISTER,

440 IES_INTEGER,

441 IES_ERROR

442 };

443

444 class IntelExprStateMachine {

445 IntelExprState State = IES_INIT, PrevState = IES_ERROR;

446 MCRegister BaseReg, IndexReg, TmpReg;

447 unsigned Scale = 0;

448 int64_t Imm = 0;

449 const MCExpr *Sym = nullptr;

450 StringRef SymName;

451 InfixCalculator IC;

452 InlineAsmIdentifierInfo Info;

453 short BracCount = 0;

454 bool MemExpr = false;

455 bool BracketUsed = false;

456 bool OffsetOperator = false;

457 bool AttachToOperandIdx = false;

458 bool IsPIC = false;

459 SMLoc OffsetOperatorLoc;

460 AsmTypeInfo CurType;

461

462 bool setSymRef(const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {

463 if (Sym) {

464 ErrMsg = "cannot use more than one symbol in memory operand";

465 return true;

466 }

467 Sym = Val;

468 SymName = ID;

469 return false;

470 }

471

472 public:

473 IntelExprStateMachine() = default;

474

475 void addImm(int64_t imm) { Imm += imm; }

476 short getBracCount() const { return BracCount; }

477 bool isMemExpr() const { return MemExpr; }

478 bool isBracketUsed() const { return BracketUsed; }

479 bool isOffsetOperator() const { return OffsetOperator; }

480 SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }

481 MCRegister getBaseReg() const { return BaseReg; }

482 MCRegister getIndexReg() const { return IndexReg; }

483 unsigned getScale() const { return Scale; }

484 const MCExpr *getSym() const { return Sym; }

485 StringRef getSymName() const { return SymName; }

486 StringRef getType() const { return CurType.Name; }

487 unsigned getSize() const { return CurType.Size; }

488 unsigned getElementSize() const { return CurType.ElementSize; }

489 unsigned getLength() const { return CurType.Length; }

490 int64_t getImm() { return Imm + IC.execute(); }

491 bool isValidEndState() const {

492 return State == IES_RBRAC || State == IES_RPAREN ||

493 State == IES_INTEGER || State == IES_REGISTER ||

494 State == IES_OFFSET;

495 }

496

497

498

499

500

501 void setAppendAfterOperand() { AttachToOperandIdx = true; }

502

503 bool isPIC() const { return IsPIC; }

504 void setPIC() { IsPIC = true; }

505

506 bool hadError() const { return State == IES_ERROR; }

507 const InlineAsmIdentifierInfo &getIdentifierInfo() const { return Info; }

508

509 bool regsUseUpError(StringRef &ErrMsg) {

510

511

512 if (IsPIC && AttachToOperandIdx)

513 ErrMsg = "Don't use 2 or more regs for mem offset in PIC model!";

514 else

515 ErrMsg = "BaseReg/IndexReg already set!";

516 return true;

517 }

518

519 void onOr() {

520 IntelExprState CurrState = State;

521 switch (State) {

522 default:

523 State = IES_ERROR;

524 break;

525 case IES_INTEGER:

526 case IES_RPAREN:

527 case IES_REGISTER:

528 State = IES_OR;

529 IC.pushOperator(IC_OR);

530 break;

531 }

532 PrevState = CurrState;

533 }

534 void onXor() {

535 IntelExprState CurrState = State;

536 switch (State) {

537 default:

538 State = IES_ERROR;

539 break;

540 case IES_INTEGER:

541 case IES_RPAREN:

542 case IES_REGISTER:

543 State = IES_XOR;

544 IC.pushOperator(IC_XOR);

545 break;

546 }

547 PrevState = CurrState;

548 }

549 void onAnd() {

550 IntelExprState CurrState = State;

551 switch (State) {

552 default:

553 State = IES_ERROR;

554 break;

555 case IES_INTEGER:

556 case IES_RPAREN:

557 case IES_REGISTER:

558 State = IES_AND;

559 IC.pushOperator(IC_AND);

560 break;

561 }

562 PrevState = CurrState;

563 }

564 void onEq() {

565 IntelExprState CurrState = State;

566 switch (State) {

567 default:

568 State = IES_ERROR;

569 break;

570 case IES_INTEGER:

571 case IES_RPAREN:

572 case IES_REGISTER:

573 State = IES_EQ;

574 IC.pushOperator(IC_EQ);

575 break;

576 }

577 PrevState = CurrState;

578 }

579 void onNE() {

580 IntelExprState CurrState = State;

581 switch (State) {

582 default:

583 State = IES_ERROR;

584 break;

585 case IES_INTEGER:

586 case IES_RPAREN:

587 case IES_REGISTER:

588 State = IES_NE;

589 IC.pushOperator(IC_NE);

590 break;

591 }

592 PrevState = CurrState;

593 }

594 void onLT() {

595 IntelExprState CurrState = State;

596 switch (State) {

597 default:

598 State = IES_ERROR;

599 break;

600 case IES_INTEGER:

601 case IES_RPAREN:

602 case IES_REGISTER:

603 State = IES_LT;

604 IC.pushOperator(IC_LT);

605 break;

606 }

607 PrevState = CurrState;

608 }

609 void onLE() {

610 IntelExprState CurrState = State;

611 switch (State) {

612 default:

613 State = IES_ERROR;

614 break;

615 case IES_INTEGER:

616 case IES_RPAREN:

617 case IES_REGISTER:

618 State = IES_LE;

619 IC.pushOperator(IC_LE);

620 break;

621 }

622 PrevState = CurrState;

623 }

624 void onGT() {

625 IntelExprState CurrState = State;

626 switch (State) {

627 default:

628 State = IES_ERROR;

629 break;

630 case IES_INTEGER:

631 case IES_RPAREN:

632 case IES_REGISTER:

633 State = IES_GT;

634 IC.pushOperator(IC_GT);

635 break;

636 }

637 PrevState = CurrState;

638 }

639 void onGE() {

640 IntelExprState CurrState = State;

641 switch (State) {

642 default:

643 State = IES_ERROR;

644 break;

645 case IES_INTEGER:

646 case IES_RPAREN:

647 case IES_REGISTER:

648 State = IES_GE;

649 IC.pushOperator(IC_GE);

650 break;

651 }

652 PrevState = CurrState;

653 }

654 void onLShift() {

655 IntelExprState CurrState = State;

656 switch (State) {

657 default:

658 State = IES_ERROR;

659 break;

660 case IES_INTEGER:

661 case IES_RPAREN:

662 case IES_REGISTER:

663 State = IES_LSHIFT;

664 IC.pushOperator(IC_LSHIFT);

665 break;

666 }

667 PrevState = CurrState;

668 }

669 void onRShift() {

670 IntelExprState CurrState = State;

671 switch (State) {

672 default:

673 State = IES_ERROR;

674 break;

675 case IES_INTEGER:

676 case IES_RPAREN:

677 case IES_REGISTER:

678 State = IES_RSHIFT;

679 IC.pushOperator(IC_RSHIFT);

680 break;

681 }

682 PrevState = CurrState;

683 }

684 bool onPlus(StringRef &ErrMsg) {

685 IntelExprState CurrState = State;

686 switch (State) {

687 default:

688 State = IES_ERROR;

689 break;

690 case IES_INTEGER:

691 case IES_RPAREN:

692 case IES_REGISTER:

693 case IES_OFFSET:

694 State = IES_PLUS;

695 IC.pushOperator(IC_PLUS);

696 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {

697

698

699 if (!BaseReg) {

700 BaseReg = TmpReg;

701 } else {

702 if (IndexReg)

703 return regsUseUpError(ErrMsg);

704 IndexReg = TmpReg;

705 Scale = 0;

706 }

707 }

708 break;

709 }

710 PrevState = CurrState;

711 return false;

712 }

713 bool onMinus(StringRef &ErrMsg) {

714 IntelExprState CurrState = State;

715 switch (State) {

716 default:

717 State = IES_ERROR;

718 break;

719 case IES_OR:

720 case IES_XOR:

721 case IES_AND:

722 case IES_EQ:

723 case IES_NE:

724 case IES_LT:

725 case IES_LE:

726 case IES_GT:

727 case IES_GE:

728 case IES_LSHIFT:

729 case IES_RSHIFT:

730 case IES_PLUS:

731 case IES_NOT:

732 case IES_MULTIPLY:

733 case IES_DIVIDE:

734 case IES_MOD:

735 case IES_LPAREN:

736 case IES_RPAREN:

737 case IES_LBRAC:

738 case IES_RBRAC:

739 case IES_INTEGER:

740 case IES_REGISTER:

741 case IES_INIT:

742 case IES_OFFSET:

743 State = IES_MINUS;

744

745 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||

746 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||

747 CurrState == IES_OFFSET)

748 IC.pushOperator(IC_MINUS);

749 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {

750

751 ErrMsg = "Scale can't be negative";

752 return true;

753 } else

754 IC.pushOperator(IC_NEG);

755 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {

756

757

758 if (!BaseReg) {

759 BaseReg = TmpReg;

760 } else {

761 if (IndexReg)

762 return regsUseUpError(ErrMsg);

763 IndexReg = TmpReg;

764 Scale = 0;

765 }

766 }

767 break;

768 }

769 PrevState = CurrState;

770 return false;

771 }

772 void onNot() {

773 IntelExprState CurrState = State;

774 switch (State) {

775 default:

776 State = IES_ERROR;

777 break;

778 case IES_OR:

779 case IES_XOR:

780 case IES_AND:

781 case IES_EQ:

782 case IES_NE:

783 case IES_LT:

784 case IES_LE:

785 case IES_GT:

786 case IES_GE:

787 case IES_LSHIFT:

788 case IES_RSHIFT:

789 case IES_PLUS:

790 case IES_MINUS:

791 case IES_NOT:

792 case IES_MULTIPLY:

793 case IES_DIVIDE:

794 case IES_MOD:

795 case IES_LPAREN:

796 case IES_LBRAC:

797 case IES_INIT:

798 State = IES_NOT;

799 IC.pushOperator(IC_NOT);

800 break;

801 }

802 PrevState = CurrState;

803 }

804 bool onRegister(MCRegister Reg, StringRef &ErrMsg) {

805 IntelExprState CurrState = State;

806 switch (State) {

807 default:

808 State = IES_ERROR;

809 break;

810 case IES_PLUS:

811 case IES_LPAREN:

812 case IES_LBRAC:

813 State = IES_REGISTER;

814 TmpReg = Reg;

815 IC.pushOperand(IC_REGISTER);

816 break;

817 case IES_MULTIPLY:

818

819 if (PrevState == IES_INTEGER) {

820 if (IndexReg)

821 return regsUseUpError(ErrMsg);

822 State = IES_REGISTER;

823 IndexReg = Reg;

824

825 Scale = IC.popOperand();

827 return true;

828 IC.pushOperand(IC_IMM);

829 IC.popOperator();

830 } else {

831 State = IES_ERROR;

832 }

833 break;

834 }

835 PrevState = CurrState;

836 return false;

837 }

838 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,

839 const InlineAsmIdentifierInfo &IDInfo,

840 const AsmTypeInfo &Type, bool ParsingMSInlineAsm,

841 StringRef &ErrMsg) {

842

843 if (ParsingMSInlineAsm)

845 return onInteger(IDInfo.Enum.EnumVal, ErrMsg);

846

848 return onInteger(CE->getValue(), ErrMsg);

849 PrevState = State;

850 switch (State) {

851 default:

852 State = IES_ERROR;

853 break;

854 case IES_CAST:

855 case IES_PLUS:

856 case IES_MINUS:

857 case IES_NOT:

858 case IES_INIT:

859 case IES_LBRAC:

860 case IES_LPAREN:

861 if (setSymRef(SymRef, SymRefName, ErrMsg))

862 return true;

863 MemExpr = true;

864 State = IES_INTEGER;

865 IC.pushOperand(IC_IMM);

866 if (ParsingMSInlineAsm)

867 Info = IDInfo;

868 setTypeInfo(Type);

869 break;

870 }

871 return false;

872 }

873 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {

874 IntelExprState CurrState = State;

875 switch (State) {

876 default:

877 State = IES_ERROR;

878 break;

879 case IES_PLUS:

880 case IES_MINUS:

881 case IES_NOT:

882 case IES_OR:

883 case IES_XOR:

884 case IES_AND:

885 case IES_EQ:

886 case IES_NE:

887 case IES_LT:

888 case IES_LE:

889 case IES_GT:

890 case IES_GE:

891 case IES_LSHIFT:

892 case IES_RSHIFT:

893 case IES_DIVIDE:

894 case IES_MOD:

895 case IES_MULTIPLY:

896 case IES_LPAREN:

897 case IES_INIT:

898 case IES_LBRAC:

899 State = IES_INTEGER;

900 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {

901

902 if (IndexReg)

903 return regsUseUpError(ErrMsg);

904 IndexReg = TmpReg;

905 Scale = TmpInt;

907 return true;

908

909 IC.popOperator();

910 } else {

911 IC.pushOperand(IC_IMM, TmpInt);

912 }

913 break;

914 }

915 PrevState = CurrState;

916 return false;

917 }

918 void onStar() {

919 PrevState = State;

920 switch (State) {

921 default:

922 State = IES_ERROR;

923 break;

924 case IES_INTEGER:

925 case IES_REGISTER:

926 case IES_RPAREN:

927 State = IES_MULTIPLY;

928 IC.pushOperator(IC_MULTIPLY);

929 break;

930 }

931 }

932 void onDivide() {

933 PrevState = State;

934 switch (State) {

935 default:

936 State = IES_ERROR;

937 break;

938 case IES_INTEGER:

939 case IES_RPAREN:

940 State = IES_DIVIDE;

941 IC.pushOperator(IC_DIVIDE);

942 break;

943 }

944 }

945 void onMod() {

946 PrevState = State;

947 switch (State) {

948 default:

949 State = IES_ERROR;

950 break;

951 case IES_INTEGER:

952 case IES_RPAREN:

953 State = IES_MOD;

954 IC.pushOperator(IC_MOD);

955 break;

956 }

957 }

958 bool onLBrac() {

959 if (BracCount)

960 return true;

961 PrevState = State;

962 switch (State) {

963 default:

964 State = IES_ERROR;

965 break;

966 case IES_RBRAC:

967 case IES_INTEGER:

968 case IES_RPAREN:

969 State = IES_PLUS;

970 IC.pushOperator(IC_PLUS);

971 CurType.Length = 1;

972 CurType.Size = CurType.ElementSize;

973 break;

974 case IES_INIT:

975 case IES_CAST:

976 assert(!BracCount && "BracCount should be zero on parsing's start");

977 State = IES_LBRAC;

978 break;

979 }

980 MemExpr = true;

981 BracketUsed = true;

982 BracCount++;

983 return false;

984 }

985 bool onRBrac(StringRef &ErrMsg) {

986 IntelExprState CurrState = State;

987 switch (State) {

988 default:

989 State = IES_ERROR;

990 break;

991 case IES_INTEGER:

992 case IES_OFFSET:

993 case IES_REGISTER:

994 case IES_RPAREN:

995 if (BracCount-- != 1) {

996 ErrMsg = "unexpected bracket encountered";

997 return true;

998 }

999 State = IES_RBRAC;

1000 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {

1001

1002

1003 if (!BaseReg) {

1004 BaseReg = TmpReg;

1005 } else {

1006 if (IndexReg)

1007 return regsUseUpError(ErrMsg);

1008 IndexReg = TmpReg;

1009 Scale = 0;

1010 }

1011 }

1012 break;

1013 }

1014 PrevState = CurrState;

1015 return false;

1016 }

1017 void onLParen() {

1018 IntelExprState CurrState = State;

1019 switch (State) {

1020 default:

1021 State = IES_ERROR;

1022 break;

1023 case IES_PLUS:

1024 case IES_MINUS:

1025 case IES_NOT:

1026 case IES_OR:

1027 case IES_XOR:

1028 case IES_AND:

1029 case IES_EQ:

1030 case IES_NE:

1031 case IES_LT:

1032 case IES_LE:

1033 case IES_GT:

1034 case IES_GE:

1035 case IES_LSHIFT:

1036 case IES_RSHIFT:

1037 case IES_MULTIPLY:

1038 case IES_DIVIDE:

1039 case IES_MOD:

1040 case IES_LPAREN:

1041 case IES_INIT:

1042 case IES_LBRAC:

1043 State = IES_LPAREN;

1044 IC.pushOperator(IC_LPAREN);

1045 break;

1046 }

1047 PrevState = CurrState;

1048 }

1049 bool onRParen(StringRef &ErrMsg) {

1050 IntelExprState CurrState = State;

1051 switch (State) {

1052 default:

1053 State = IES_ERROR;

1054 break;

1055 case IES_INTEGER:

1056 case IES_OFFSET:

1057 case IES_REGISTER:

1058 case IES_RBRAC:

1059 case IES_RPAREN:

1060 State = IES_RPAREN;

1061

1062

1063

1064

1065 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {

1066

1067

1068 if (!BaseReg) {

1069 BaseReg = TmpReg;

1070 } else {

1071 if (IndexReg)

1072 return regsUseUpError(ErrMsg);

1073 IndexReg = TmpReg;

1074 Scale = 0;

1075 }

1076 }

1077 IC.pushOperator(IC_RPAREN);

1078 break;

1079 }

1080 PrevState = CurrState;

1081 return false;

1082 }

1083 bool onOffset(const MCExpr *Val, SMLoc OffsetLoc, StringRef ID,

1084 const InlineAsmIdentifierInfo &IDInfo,

1085 bool ParsingMSInlineAsm, StringRef &ErrMsg) {

1086 PrevState = State;

1087 switch (State) {

1088 default:

1089 ErrMsg = "unexpected offset operator expression";

1090 return true;

1091 case IES_PLUS:

1092 case IES_INIT:

1093 case IES_LBRAC:

1094 if (setSymRef(Val, ID, ErrMsg))

1095 return true;

1096 OffsetOperator = true;

1097 OffsetOperatorLoc = OffsetLoc;

1098 State = IES_OFFSET;

1099

1100

1101 IC.pushOperand(IC_IMM);

1102 if (ParsingMSInlineAsm) {

1103 Info = IDInfo;

1104 }

1105 break;

1106 }

1107 return false;

1108 }

1109 void onCast(AsmTypeInfo Info) {

1110 PrevState = State;

1111 switch (State) {

1112 default:

1113 State = IES_ERROR;

1114 break;

1115 case IES_LPAREN:

1116 setTypeInfo(Info);

1117 State = IES_CAST;

1118 break;

1119 }

1120 }

1121 void setTypeInfo(AsmTypeInfo Type) { CurType = Type; }

1122 };

1123

1124 bool Error(SMLoc L, const Twine &Msg, SMRange Range = {},

1125 bool MatchingInlineAsm = false) {

1126 MCAsmParser &Parser = getParser();

1127 if (MatchingInlineAsm) {

1128 return false;

1129 }

1131 }

1132

1133 bool MatchRegisterByName(MCRegister &RegNo, StringRef RegName, SMLoc StartLoc,

1134 SMLoc EndLoc);

1135 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,

1136 bool RestoreOnFailure);

1137

1138 std::unique_ptr DefaultMemSIOperand(SMLoc Loc);

1139 std::unique_ptr DefaultMemDIOperand(SMLoc Loc);

1140 bool IsSIReg(MCRegister Reg);

1141 MCRegister GetSIDIForRegClass(unsigned RegClassID, bool IsSIReg);

1142 void

1143 AddDefaultSrcDestOperands(OperandVector &Operands,

1144 std::unique_ptrllvm::MCParsedAsmOperand &&Src,

1145 std::unique_ptrllvm::MCParsedAsmOperand &&Dst);

1146 bool VerifyAndAdjustOperands(OperandVector &OrigOperands,

1148 bool parseOperand(OperandVector &Operands, StringRef Name);

1150 bool parseIntelOperand(OperandVector &Operands, StringRef Name);

1151 bool ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,

1152 InlineAsmIdentifierInfo &Info, SMLoc &End);

1153 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);

1154 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);

1155 unsigned ParseIntelInlineAsmOperator(unsigned OpKind);

1156 unsigned IdentifyMasmOperator(StringRef Name);

1157 bool ParseMasmOperator(unsigned OpKind, int64_t &Val);

1158 bool ParseRoundingModeOp(SMLoc Start, OperandVector &Operands);

1160 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,

1161 bool &ParseError, SMLoc &End);

1162 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,

1163 bool &ParseError, SMLoc &End);

1164 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,

1165 SMLoc End);

1166 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);

1167 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,

1168 InlineAsmIdentifierInfo &Info,

1169 bool IsUnevaluatedOperand, SMLoc &End,

1170 bool IsParsingOffsetOperator = false);

1172 IntelExprStateMachine &SM);

1173

1174 bool ParseMemOperand(MCRegister SegReg, const MCExpr *Disp, SMLoc StartLoc,

1176

1177 X86::CondCode ParseConditionCode(StringRef CCode);

1178

1179 bool ParseIntelMemoryOperandSize(unsigned &Size, StringRef *SizeStr);

1180 bool CreateMemForMSInlineAsm(MCRegister SegReg, const MCExpr *Disp,

1181 MCRegister BaseReg, MCRegister IndexReg,

1182 unsigned Scale, bool NonAbsMem, SMLoc Start,

1183 SMLoc End, unsigned Size, StringRef Identifier,

1184 const InlineAsmIdentifierInfo &Info,

1186

1187 bool parseDirectiveArch();

1188 bool parseDirectiveNops(SMLoc L);

1189 bool parseDirectiveEven(SMLoc L);

1190 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);

1191

1192

1193 bool parseDirectiveFPOProc(SMLoc L);

1194 bool parseDirectiveFPOSetFrame(SMLoc L);

1195 bool parseDirectiveFPOPushReg(SMLoc L);

1196 bool parseDirectiveFPOStackAlloc(SMLoc L);

1197 bool parseDirectiveFPOStackAlign(SMLoc L);

1198 bool parseDirectiveFPOEndPrologue(SMLoc L);

1199 bool parseDirectiveFPOEndProc(SMLoc L);

1200

1201

1202 bool parseSEHRegisterNumber(unsigned RegClassID, MCRegister &RegNo);

1203 bool parseDirectiveSEHPushReg(SMLoc);

1204 bool parseDirectiveSEHSetFrame(SMLoc);

1205 bool parseDirectiveSEHSaveReg(SMLoc);

1206 bool parseDirectiveSEHSaveXMM(SMLoc);

1207 bool parseDirectiveSEHPushFrame(SMLoc);

1208

1209 unsigned checkTargetMatchPredicate(MCInst &Inst) override;

1210

1211 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);

1212 bool processInstruction(MCInst &Inst, const OperandVector &Ops);

1213

1214

1215 void emitWarningForSpecialLVIInstruction(SMLoc Loc);

1216 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);

1217 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);

1218

1219

1220

1222

1223 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

1225 uint64_t &ErrorInfo,

1226 bool MatchingInlineAsm) override;

1227

1228 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,

1229 MCStreamer &Out, bool MatchingInlineAsm);

1230

1231 bool ErrorMissingFeature(SMLoc IDLoc, const FeatureBitset &MissingFeatures,

1232 bool MatchingInlineAsm);

1233

1234 bool matchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, MCInst &Inst,

1236 uint64_t &ErrorInfo, bool MatchingInlineAsm);

1237

1238 bool matchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, MCInst &Inst,

1240 uint64_t &ErrorInfo,

1241 bool MatchingInlineAsm);

1242

1243 bool omitRegisterFromClobberLists(MCRegister Reg) override;

1244

1245

1246

1247

1248 bool HandleAVX512Operand(OperandVector &Operands);

1249

1250 bool ParseZ(std::unique_ptr &Z, SMLoc StartLoc);

1251

1252 bool is64BitMode() const {

1253

1254 return getSTI().hasFeature(X86::Is64Bit);

1255 }

1256 bool is32BitMode() const {

1257

1258 return getSTI().hasFeature(X86::Is32Bit);

1259 }

1260 bool is16BitMode() const {

1261

1262 return getSTI().hasFeature(X86::Is16Bit);

1263 }

1264 void SwitchMode(unsigned mode) {

1265 MCSubtargetInfo &STI = copySTI();

1266 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});

1267 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;

1268 FeatureBitset FB = ComputeAvailableFeatures(

1270 setAvailableFeatures(FB);

1271

1273 }

1274

1275 unsigned getPointerWidth() {

1276 if (is16BitMode()) return 16;

1277 if (is32BitMode()) return 32;

1278 if (is64BitMode()) return 64;

1280 }

1281

1282 bool isParsingIntelSyntax() {

1283 return getParser().getAssemblerDialect();

1284 }

1285

1286

1287

1288

1289#define GET_ASSEMBLER_HEADER

1290#include "X86GenAsmMatcher.inc"

1291

1292

1293

1294public:

1295 enum X86MatchResultTy {

1296 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,

1297#define GET_OPERAND_DIAGNOSTIC_TYPES

1298#include "X86GenAsmMatcher.inc"

1299 };

1300

1301 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,

1302 const MCInstrInfo &mii, const MCTargetOptions &Options)

1303 : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr),

1304 Code16GCC(false) {

1305

1307

1308

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

1310 }

1311

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

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

1314 SMLoc &EndLoc) override;

1315

1316 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;

1317

1318 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,

1319 SMLoc NameLoc, OperandVector &Operands) override;

1320

1321 bool ParseDirective(AsmToken DirectiveID) override;

1322};

1323}

1324

1325#define GET_REGISTER_MATCHER

1326#define GET_SUBTARGET_FEATURE_NAME

1327#include "X86GenAsmMatcher.inc"

1328

1330 MCRegister IndexReg, unsigned Scale,

1331 bool Is64BitMode,

1333

1334

1335

1336

1337 if (BaseReg &&

1338 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||

1339 X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) ||

1340 X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) ||

1341 X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) {

1342 ErrMsg = "invalid base+index expression";

1343 return true;

1344 }

1345

1346 if (IndexReg &&

1347 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||

1348 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||

1349 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||

1350 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||

1351 X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||

1352 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||

1353 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) {

1354 ErrMsg = "invalid base+index expression";

1355 return true;

1356 }

1357

1358 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||

1359 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||

1360 IndexReg == X86::RSP) {

1361 ErrMsg = "invalid base+index expression";

1362 return true;

1363 }

1364

1365

1366

1367 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&

1368 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&

1369 BaseReg != X86::SI && BaseReg != X86::DI))) {

1370 ErrMsg = "invalid 16-bit base register";

1371 return true;

1372 }

1373

1374 if (!BaseReg &&

1375 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {

1376 ErrMsg = "16-bit memory operand may not include only index register";

1377 return true;

1378 }

1379

1380 if (BaseReg && IndexReg) {

1381 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&

1382 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||

1383 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||

1384 IndexReg == X86::EIZ)) {

1385 ErrMsg = "base register is 64-bit, but index register is not";

1386 return true;

1387 }

1388 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&

1389 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||

1390 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||

1391 IndexReg == X86::RIZ)) {

1392 ErrMsg = "base register is 32-bit, but index register is not";

1393 return true;

1394 }

1395 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {

1396 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||

1397 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {

1398 ErrMsg = "base register is 16-bit, but index register is not";

1399 return true;

1400 }

1401 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||

1402 (IndexReg != X86::SI && IndexReg != X86::DI)) {

1403 ErrMsg = "invalid 16-bit base/index register combination";

1404 return true;

1405 }

1406 }

1407 }

1408

1409

1410 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {

1411 ErrMsg = "IP-relative addressing requires 64-bit mode";

1412 return true;

1413 }

1414

1416}

1417

1420

1421

1422 RegName.consume_front("%");

1423

1425

1426

1427 if (!RegNo)

1429

1430

1431

1432 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&

1433 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))

1434 RegNo = MCRegister();

1435

1436 if (!is64BitMode()) {

1437

1438

1439

1440 if (RegNo == X86::RIZ || RegNo == X86::RIP ||

1441 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||

1444 return Error(StartLoc,

1445 "register %" + RegName + " is only available in 64-bit mode",

1446 SMRange(StartLoc, EndLoc));

1447 }

1448 }

1449

1451 UseApxExtendedReg = true;

1452

1453

1454

1455 if (!RegNo && RegName.starts_with("db")) {

1456 if (RegName.size() == 3) {

1458 case '0':

1459 RegNo = X86::DR0;

1460 break;

1461 case '1':

1462 RegNo = X86::DR1;

1463 break;

1464 case '2':

1465 RegNo = X86::DR2;

1466 break;

1467 case '3':

1468 RegNo = X86::DR3;

1469 break;

1470 case '4':

1471 RegNo = X86::DR4;

1472 break;

1473 case '5':

1474 RegNo = X86::DR5;

1475 break;

1476 case '6':

1477 RegNo = X86::DR6;

1478 break;

1479 case '7':

1480 RegNo = X86::DR7;

1481 break;

1482 case '8':

1483 RegNo = X86::DR8;

1484 break;

1485 case '9':

1486 RegNo = X86::DR9;

1487 break;

1488 }

1489 } else if (RegName.size() == 4 && RegName[2] == '1') {

1491 case '0':

1492 RegNo = X86::DR10;

1493 break;

1494 case '1':

1495 RegNo = X86::DR11;

1496 break;

1497 case '2':

1498 RegNo = X86::DR12;

1499 break;

1500 case '3':

1501 RegNo = X86::DR13;

1502 break;

1503 case '4':

1504 RegNo = X86::DR14;

1505 break;

1506 case '5':

1507 RegNo = X86::DR15;

1508 break;

1509 }

1510 }

1511 }

1512

1513 if (!RegNo) {

1514 if (isParsingIntelSyntax())

1515 return true;

1516 return Error(StartLoc, "invalid register name", SMRange(StartLoc, EndLoc));

1517 }

1518 return false;

1519}

1520

1521bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,

1522 SMLoc &EndLoc, bool RestoreOnFailure) {

1523 MCAsmParser &Parser = getParser();

1524 AsmLexer &Lexer = getLexer();

1525 RegNo = MCRegister();

1526

1528 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {

1529 if (RestoreOnFailure) {

1530 while (!Tokens.empty()) {

1532 }

1533 }

1534 };

1535

1536 const AsmToken &PercentTok = Parser.getTok();

1537 StartLoc = PercentTok.getLoc();

1538

1539

1540

1543 Parser.Lex();

1544 }

1545

1546 const AsmToken &Tok = Parser.getTok();

1548

1550 OnFailure();

1551 if (isParsingIntelSyntax()) return true;

1552 return Error(StartLoc, "invalid register name",

1553 SMRange(StartLoc, EndLoc));

1554 }

1555

1556 if (MatchRegisterByName(RegNo, Tok.getString(), StartLoc, EndLoc)) {

1557 OnFailure();

1558 return true;

1559 }

1560

1561

1562 if (RegNo == X86::ST0) {

1564 Parser.Lex();

1565

1566

1568 return false;

1569

1571 Parser.Lex();

1572

1573 const AsmToken &IntTok = Parser.getTok();

1575 OnFailure();

1576 return Error(IntTok.getLoc(), "expected stack index");

1577 }

1579 case 0: RegNo = X86::ST0; break;

1580 case 1: RegNo = X86::ST1; break;

1581 case 2: RegNo = X86::ST2; break;

1582 case 3: RegNo = X86::ST3; break;

1583 case 4: RegNo = X86::ST4; break;

1584 case 5: RegNo = X86::ST5; break;

1585 case 6: RegNo = X86::ST6; break;

1586 case 7: RegNo = X86::ST7; break;

1587 default:

1588 OnFailure();

1589 return Error(IntTok.getLoc(), "invalid stack index");

1590 }

1591

1592

1594 Parser.Lex();

1596 OnFailure();

1598 }

1599

1601 Parser.Lex();

1602 return false;

1603 }

1604

1606

1607 if (!RegNo) {

1608 OnFailure();

1609 if (isParsingIntelSyntax()) return true;

1610 return Error(StartLoc, "invalid register name",

1611 SMRange(StartLoc, EndLoc));

1612 }

1613

1614 Parser.Lex();

1615 return false;

1616}

1617

1618bool X86AsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,

1619 SMLoc &EndLoc) {

1620 return ParseRegister(Reg, StartLoc, EndLoc, false);

1621}

1622

1623ParseStatus X86AsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

1624 SMLoc &EndLoc) {

1625 bool Result = ParseRegister(Reg, StartLoc, EndLoc, true);

1626 bool PendingErrors = getParser().hasPendingError();

1627 getParser().clearPendingErrors();

1628 if (PendingErrors)

1630 if (Result)

1633}

1634

1635std::unique_ptr X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {

1636 bool Parse32 = is32BitMode() || Code16GCC;

1637 MCRegister Basereg =

1638 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);

1641 Basereg, 0, 1,

1642 Loc, Loc, 0);

1643}

1644

1645std::unique_ptr X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {

1646 bool Parse32 = is32BitMode() || Code16GCC;

1647 MCRegister Basereg =

1648 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);

1651 Basereg, 0, 1,

1652 Loc, Loc, 0);

1653}

1654

1655bool X86AsmParser::IsSIReg(MCRegister Reg) {

1656 switch (Reg.id()) {

1657 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");

1658 case X86::RSI:

1659 case X86::ESI:

1660 case X86::SI:

1661 return true;

1662 case X86::RDI:

1663 case X86::EDI:

1664 case X86::DI:

1665 return false;

1666 }

1667}

1668

1669MCRegister X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, bool IsSIReg) {

1670 switch (RegClassID) {

1672 case X86::GR64RegClassID:

1673 return IsSIReg ? X86::RSI : X86::RDI;

1674 case X86::GR32RegClassID:

1675 return IsSIReg ? X86::ESI : X86::EDI;

1676 case X86::GR16RegClassID:

1677 return IsSIReg ? X86::SI : X86::DI;

1678 }

1679}

1680

1681void X86AsmParser::AddDefaultSrcDestOperands(

1682 OperandVector& Operands, std::unique_ptrllvm::MCParsedAsmOperand &&Src,

1683 std::unique_ptrllvm::MCParsedAsmOperand &&Dst) {

1684 if (isParsingIntelSyntax()) {

1685 Operands.push_back(std::move(Dst));

1686 Operands.push_back(std::move(Src));

1687 }

1688 else {

1689 Operands.push_back(std::move(Src));

1690 Operands.push_back(std::move(Dst));

1691 }

1692}

1693

1694bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,

1696

1697 if (OrigOperands.size() > 1) {

1698

1699 assert(OrigOperands.size() == FinalOperands.size() + 1 &&

1700 "Operand size mismatch");

1701

1703

1704 int RegClassID = -1;

1705 for (unsigned int i = 0; i < FinalOperands.size(); ++i) {

1706 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);

1707 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);

1708

1709 if (FinalOp.isReg() &&

1711

1712 return false;

1713

1714 if (FinalOp.isMem()) {

1715

1716 if (!OrigOp.isMem())

1717

1718 return false;

1719

1720 MCRegister OrigReg = OrigOp.Mem.BaseReg;

1721 MCRegister FinalReg = FinalOp.Mem.BaseReg;

1722

1723

1724

1725 if (RegClassID != -1 &&

1726 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {

1728 "mismatching source and destination index registers");

1729 }

1730

1731 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))

1732 RegClassID = X86::GR64RegClassID;

1733 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))

1734 RegClassID = X86::GR32RegClassID;

1735 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))

1736 RegClassID = X86::GR16RegClassID;

1737 else

1738

1739

1740 return false;

1741

1742 bool IsSI = IsSIReg(FinalReg);

1743 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);

1744

1745 if (FinalReg != OrigReg) {

1746 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";

1747 Warnings.push_back(std::make_pair(

1749 "memory operand is only for determining the size, " + RegName +

1750 " will be used for the location"));

1751 }

1752

1756 }

1757 }

1758

1759

1760

1761 for (auto &WarningMsg : Warnings) {

1762 Warning(WarningMsg.first, WarningMsg.second);

1763 }

1764

1765

1766 for (unsigned int i = 0; i < FinalOperands.size(); ++i)

1768 }

1769

1770 for (auto &Op : FinalOperands)

1772

1773 return false;

1774}

1775

1776bool X86AsmParser::parseOperand(OperandVector &Operands, StringRef Name) {

1777 if (isParsingIntelSyntax())

1778 return parseIntelOperand(Operands, Name);

1779

1780 return parseATTOperand(Operands);

1781}

1782

1783bool X86AsmParser::CreateMemForMSInlineAsm(

1784 MCRegister SegReg, const MCExpr *Disp, MCRegister BaseReg,

1785 MCRegister IndexReg, unsigned Scale, bool NonAbsMem, SMLoc Start, SMLoc End,

1786 unsigned Size, StringRef Identifier, const InlineAsmIdentifierInfo &Info,

1788

1789

1791

1792

1794 End, Size, Identifier,

1795 Info.Label.Decl));

1796 return false;

1797 }

1798

1799

1800

1801 unsigned FrontendSize = 0;

1802 void *Decl = nullptr;

1803 bool IsGlobalLV = false;

1805

1806 FrontendSize = Info.Var.Type * 8;

1807 Decl = Info.Var.Decl;

1808 IsGlobalLV = Info.Var.IsGlobalLV;

1809 }

1810

1811

1812 if (IsGlobalLV) {

1813 if (BaseReg || IndexReg) {

1815 End, Size, Identifier, Decl, 0,

1816 BaseReg && IndexReg));

1817 return false;

1818 }

1819 if (NonAbsMem)

1820 BaseReg = 1;

1821 }

1823 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,

1825 X86::RIP, Identifier, Decl, FrontendSize));

1826 return false;

1827}

1828

1829

1830

1831

1832bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,

1833 IntelExprStateMachine &SM,

1834 bool &ParseError, SMLoc &End) {

1835

1836

1837 if (Name != Name.lower() && Name != Name.upper() &&

1838 !getParser().isParsingMasm())

1839 return false;

1840 if (Name.equals_insensitive("not")) {

1841 SM.onNot();

1842 } else if (Name.equals_insensitive("or")) {

1843 SM.onOr();

1844 } else if (Name.equals_insensitive("shl")) {

1845 SM.onLShift();

1846 } else if (Name.equals_insensitive("shr")) {

1847 SM.onRShift();

1848 } else if (Name.equals_insensitive("xor")) {

1849 SM.onXor();

1850 } else if (Name.equals_insensitive("and")) {

1851 SM.onAnd();

1852 } else if (Name.equals_insensitive("mod")) {

1853 SM.onMod();

1854 } else if (Name.equals_insensitive("offset")) {

1855 SMLoc OffsetLoc = getTok().getLoc();

1856 const MCExpr *Val = nullptr;

1857 StringRef ID;

1858 InlineAsmIdentifierInfo Info;

1860 if (ParseError)

1861 return true;

1862 StringRef ErrMsg;

1864 SM.onOffset(Val, OffsetLoc, ID, Info, isParsingMSInlineAsm(), ErrMsg);

1865 if (ParseError)

1867 } else {

1868 return false;

1869 }

1870 if (Name.equals_insensitive("offset"))

1871 End = consumeToken();

1872 return true;

1873}

1874bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,

1875 IntelExprStateMachine &SM,

1876 bool &ParseError, SMLoc &End) {

1877 if (Name.equals_insensitive("eq")) {

1878 SM.onEq();

1879 } else if (Name.equals_insensitive("ne")) {

1880 SM.onNE();

1881 } else if (Name.equals_insensitive("lt")) {

1882 SM.onLT();

1883 } else if (Name.equals_insensitive("le")) {

1884 SM.onLE();

1885 } else if (Name.equals_insensitive("gt")) {

1886 SM.onGT();

1887 } else if (Name.equals_insensitive("ge")) {

1888 SM.onGE();

1889 } else {

1890 return false;

1891 }

1892 End = consumeToken();

1893 return true;

1894}

1895

1896

1897

1899 IntelExprStateMachine &SM) {

1901 return;

1902

1903 SM.setAppendAfterOperand();

1904}

1905

1906bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {

1907 MCAsmParser &Parser = getParser();

1908 StringRef ErrMsg;

1909

1911

1912 if (getContext().getObjectFileInfo()->isPositionIndependent())

1913 SM.setPIC();

1914

1915 bool Done = false;

1916 while (Done) {

1917

1918

1919 const AsmToken &Tok = Parser.getTok();

1920

1921 bool UpdateLocLex = true;

1923

1924 switch (TK) {

1925 default:

1926 if ((Done = SM.isValidEndState()))

1927 break;

1928 return Error(Tok.getLoc(), "unknown token in expression");

1930 return Error(getLexer().getErrLoc(), getLexer().getErr());

1931 break;

1933

1934 UpdateLocLex = false;

1935 if (ParseIntelDotOperator(SM, End))

1936 return true;

1937 break;

1940 if ((Done = SM.isValidEndState()))

1941 break;

1942 return Error(Tok.getLoc(), "unknown token in expression");

1943 }

1944

1945 Lex();

1946 UpdateLocLex = false;

1947 if (ParseIntelDotOperator(SM, End))

1948 return true;

1949 break;

1952 if ((Done = SM.isValidEndState()))

1953 break;

1954 return Error(Tok.getLoc(), "unknown token in expression");

1955 }

1956 [[fallthrough]];

1959

1960 SMLoc ValueLoc = Tok.getLoc();

1961 int64_t Res;

1962 const MCExpr *Val;

1964 return true;

1965 UpdateLocLex = false;

1966 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))

1967 return Error(ValueLoc, "expected absolute value");

1968 if (SM.onInteger(Res, ErrMsg))

1969 return Error(ValueLoc, ErrMsg);

1970 break;

1971 }

1972 [[fallthrough]];

1973 }

1976 SMLoc IdentLoc = Tok.getLoc();

1978 UpdateLocLex = false;

1980 size_t DotOffset = Identifier.find_first_of('.');

1982 consumeToken();

1984 StringRef Dot = Identifier.substr(DotOffset, 1);

1985 StringRef RHS = Identifier.substr(DotOffset + 1);

1986 if (RHS.empty()) {

1988 }

1990 if (LHS.empty()) {

1992 }

1993 break;

1994 }

1995 }

1996

1998 const AsmToken &NextTok = getLexer().peekTok();

2001 AsmTypeInfo Info;

2003 return Error(Tok.getLoc(), "unknown type");

2004 SM.onCast(Info);

2005

2006 consumeToken();

2007 End = consumeToken();

2008 break;

2009 }

2010 }

2011

2012 MCRegister Reg;

2014 if (!ParseRegister(Reg, IdentLoc, End, true)) {

2015 if (SM.onRegister(Reg, ErrMsg))

2016 return Error(IdentLoc, ErrMsg);

2017 break;

2018 }

2020 const std::pair<StringRef, StringRef> IDField =

2022 const StringRef ID = IDField.first, Field = IDField.second;

2024 if (Field.empty() &&

2025 !MatchRegisterByName(Reg, ID, IdentLoc, IDEndLoc)) {

2026 if (SM.onRegister(Reg, ErrMsg))

2027 return Error(IdentLoc, ErrMsg);

2028

2029 AsmFieldInfo Info;

2032 return Error(FieldStartLoc, "unknown offset");

2033 else if (SM.onPlus(ErrMsg))

2034 return Error(getTok().getLoc(), ErrMsg);

2035 else if (SM.onInteger(Info.Offset, ErrMsg))

2036 return Error(IdentLoc, ErrMsg);

2037 SM.setTypeInfo(Info.Type);

2038

2039 End = consumeToken();

2040 break;

2041 }

2042 }

2043 }

2044

2046 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {

2047 if (ParseError)

2048 return true;

2049 break;

2050 }

2052 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {

2053 if (ParseError)

2054 return true;

2055 break;

2056 }

2057

2058 InlineAsmIdentifierInfo Info;

2059 AsmFieldInfo FieldInfo;

2060 const MCExpr *Val;

2061 if (isParsingMSInlineAsm() || Parser.isParsingMasm()) {

2062

2065 if (ParseIntelDotOperator(SM, End))

2066 return true;

2067 break;

2068 }

2069 }

2070 if (isParsingMSInlineAsm()) {

2071

2072 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {

2073 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {

2074 if (SM.onInteger(Val, ErrMsg))

2075 return Error(IdentLoc, ErrMsg);

2076 } else {

2077 return true;

2078 }

2079 break;

2080 }

2081

2082

2084 return Error(IdentLoc, "expected identifier");

2085 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))

2086 return true;

2087 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,

2088 true, ErrMsg))

2089 return Error(IdentLoc, ErrMsg);

2090 break;

2091 }

2093 if (unsigned OpKind = IdentifyMasmOperator(Identifier)) {

2094 int64_t Val;

2095 if (ParseMasmOperator(OpKind, Val))

2096 return true;

2097 if (SM.onInteger(Val, ErrMsg))

2098 return Error(IdentLoc, ErrMsg);

2099 break;

2100 }

2101 if (!getParser().lookUpType(Identifier, FieldInfo.Type)) {

2102

2103 Lex();

2104 bool EndDot = parseOptionalToken(AsmToken::Dot);

2106 getTok().getString().starts_with("."))) {

2107 getParser().parseIdentifier(Identifier);

2108 if (!EndDot)

2110 EndDot = Identifier.consume_back(".");

2111 if (getParser().lookUpField(FieldInfo.Type.Name, Identifier,

2112 FieldInfo)) {

2113 SMLoc IDEnd =

2115 return Error(IdentLoc, "Unable to lookup field reference!",

2116 SMRange(IdentLoc, IDEnd));

2117 }

2118 if (!EndDot)

2120 }

2121 if (SM.onInteger(FieldInfo.Offset, ErrMsg))

2122 return Error(IdentLoc, ErrMsg);

2123 break;

2124 }

2125 }

2126 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.Type)) {

2127 return Error(Tok.getLoc(), "Unexpected identifier!");

2128 } else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,

2129 false, ErrMsg)) {

2130 return Error(IdentLoc, ErrMsg);

2131 }

2132 break;

2133 }

2135

2136 SMLoc Loc = getTok().getLoc();

2137 int64_t IntVal = getTok().getIntVal();

2138 End = consumeToken();

2139 UpdateLocLex = false;

2141 StringRef IDVal = getTok().getString();

2142 if (IDVal == "f" || IDVal == "b") {

2144 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");

2146 const MCExpr *Val =

2149 return Error(Loc, "invalid reference to undefined symbol");

2151 InlineAsmIdentifierInfo Info;

2152 AsmTypeInfo Type;

2153 if (SM.onIdentifierExpr(Val, Identifier, Info, Type,

2154 isParsingMSInlineAsm(), ErrMsg))

2155 return Error(Loc, ErrMsg);

2156 End = consumeToken();

2157 } else {

2158 if (SM.onInteger(IntVal, ErrMsg))

2159 return Error(Loc, ErrMsg);

2160 }

2161 } else {

2162 if (SM.onInteger(IntVal, ErrMsg))

2163 return Error(Loc, ErrMsg);

2164 }

2165 break;

2166 }

2168 if (SM.onPlus(ErrMsg))

2169 return Error(getTok().getLoc(), ErrMsg);

2170 break;

2172 if (SM.onMinus(ErrMsg))

2173 return Error(getTok().getLoc(), ErrMsg);

2174 break;

2183 SM.onLShift(); break;

2185 SM.onRShift(); break;

2187 if (SM.onLBrac())

2188 return Error(Tok.getLoc(), "unexpected bracket encountered");

2189 tryParseOperandIdx(PrevTK, SM);

2190 break;

2192 if (SM.onRBrac(ErrMsg)) {

2194 }

2195 break;

2198 if (SM.onRParen(ErrMsg)) {

2200 }

2201 break;

2202 }

2203 if (SM.hadError())

2204 return Error(Tok.getLoc(), "unknown token in expression");

2205

2206 if (Done && UpdateLocLex)

2207 End = consumeToken();

2208

2209 PrevTK = TK;

2210 }

2211 return false;

2212}

2213

2214void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,

2215 SMLoc Start, SMLoc End) {

2216 SMLoc Loc = Start;

2217 unsigned ExprLen = End.getPointer() - Start.getPointer();

2218

2219 if (SM.getSym() && !SM.isOffsetOperator()) {

2220 StringRef SymName = SM.getSymName();

2221 if (unsigned Len = SymName.data() - Start.getPointer())

2225

2226

2227 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {

2228 if (ExprLen)

2230 return;

2231 }

2232 }

2233

2234 StringRef BaseRegStr;

2235 StringRef IndexRegStr;

2236 StringRef OffsetNameStr;

2237 if (SM.getBaseReg())

2239 if (SM.getIndexReg())

2241 if (SM.isOffsetOperator())

2242 OffsetNameStr = SM.getSymName();

2243

2244 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,

2245 SM.getImm(), SM.isMemExpr());

2246 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);

2247}

2248

2249

2250bool X86AsmParser::ParseIntelInlineAsmIdentifier(

2251 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,

2252 bool IsUnevaluatedOperand, SMLoc &End, bool IsParsingOffsetOperator) {

2253 MCAsmParser &Parser = getParser();

2254 assert(isParsingMSInlineAsm() && "Expected to be parsing inline assembly.");

2255 Val = nullptr;

2256

2257 StringRef LineBuf(Identifier.data());

2258 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);

2259

2260 const AsmToken &Tok = Parser.getTok();

2261 SMLoc Loc = Tok.getLoc();

2262

2263

2264

2265 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();

2266 do {

2268 getLexer().Lex();

2269 } while (End.getPointer() < EndPtr);

2271

2272

2273

2276 "frontend claimed part of a token?");

2277

2278

2279

2281 StringRef InternalName =

2282 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),

2283 Loc, false);

2284 assert(InternalName.size() && "We should have an internal name here.");

2285

2286

2287 if (!IsParsingOffsetOperator)

2289 InternalName);

2290 else

2293 return false;

2294

2298 return false;

2299}

2300

2301

2302bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) {

2303 MCAsmParser &Parser = getParser();

2304 const AsmToken &Tok = Parser.getTok();

2305

2306 const SMLoc consumedToken = consumeToken();

2308 return Error(Tok.getLoc(), "Expected an identifier after {");

2310 int rndMode = StringSwitch(Tok.getIdentifier())

2311 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)

2312 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)

2313 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)

2314 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)

2315 .Default(-1);

2316 if (-1 == rndMode)

2317 return Error(Tok.getLoc(), "Invalid rounding mode.");

2318 Parser.Lex();

2320 return Error(Tok.getLoc(), "Expected - at this point");

2321 Parser.Lex();

2322 Parser.Lex();

2324 return Error(Tok.getLoc(), "Expected } at this point");

2326 Parser.Lex();

2327 const MCExpr *RndModeOp =

2330 return false;

2331 }

2333 Parser.Lex();

2335 return Error(Tok.getLoc(), "Expected } at this point");

2336 Parser.Lex();

2338 return false;

2339 }

2340 return Error(Tok.getLoc(), "unknown token in expression");

2341}

2342

2343

2344

2345bool X86AsmParser::parseCFlagsOp(OperandVector &Operands) {

2346 MCAsmParser &Parser = getParser();

2347 AsmToken Tok = Parser.getTok();

2350 return Error(Tok.getLoc(), "Expected { at this point");

2351 Parser.Lex();

2352 Tok = Parser.getTok();

2354 return Error(Tok.getLoc(), "Expected dfv at this point");

2355 Parser.Lex();

2356 Tok = Parser.getTok();

2358 return Error(Tok.getLoc(), "Expected = at this point");

2359 Parser.Lex();

2360

2361 Tok = Parser.getTok();

2362 SMLoc End;

2367 Parser.Lex();

2368 return false;

2369 }

2370 unsigned CFlags = 0;

2371 for (unsigned I = 0; I < 4; ++I) {

2372 Tok = Parser.getTok();

2373 unsigned CFlag = StringSwitch(Tok.getIdentifier().lower())

2374 .Case("of", 0x8)

2375 .Case("sf", 0x4)

2376 .Case("zf", 0x2)

2377 .Case("cf", 0x1)

2378 .Default(~0U);

2379 if (CFlag == ~0U)

2380 return Error(Tok.getLoc(), "Invalid conditional flags");

2381

2382 if (CFlags & CFlag)

2383 return Error(Tok.getLoc(), "Duplicated conditional flag");

2384 CFlags |= CFlag;

2385

2386 Parser.Lex();

2387 Tok = Parser.getTok();

2392 Parser.Lex();

2393 return false;

2394 } else if (I == 3) {

2395 return Error(Tok.getLoc(), "Expected } at this point");

2397 return Error(Tok.getLoc(), "Expected } or , at this point");

2398 }

2399 Parser.Lex();

2400 }

2402}

2403

2404

2405bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,

2406 SMLoc &End) {

2407 const AsmToken &Tok = getTok();

2408 AsmFieldInfo Info;

2409

2410

2411 StringRef DotDispStr = Tok.getString();

2413 bool TrailingDot = false;

2414

2415

2417 APInt DotDisp;

2419 return Error(Tok.getLoc(), "Unexpected offset");

2421 } else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&

2424 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');

2425 const StringRef Base = BaseMember.first, Member = BaseMember.second;

2426 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&

2427 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&

2428 getParser().lookUpField(DotDispStr, Info) &&

2429 (!SemaCallback ||

2430 SemaCallback->LookupInlineAsmField(Base, Member, Info.Offset)))

2431 return Error(Tok.getLoc(), "Unable to lookup field reference!");

2432 } else {

2433 return Error(Tok.getLoc(), "Unexpected token type!");

2434 }

2435

2436

2438 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();

2440 Lex();

2441 if (TrailingDot)

2443 SM.addImm(Info.Offset);

2444 SM.setTypeInfo(Info.Type);

2445 return false;

2446}

2447

2448

2449

2450bool X86AsmParser::ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,

2451 InlineAsmIdentifierInfo &Info,

2452 SMLoc &End) {

2453

2454 SMLoc Start = Lex().getLoc();

2455 ID = getTok().getString();

2456 if (!isParsingMSInlineAsm()) {

2459 getParser().parsePrimaryExpr(Val, End, nullptr))

2460 return Error(Start, "unexpected token!");

2461 } else if (ParseIntelInlineAsmIdentifier(Val, ID, Info, false, End, true)) {

2462 return Error(Start, "unable to lookup expression");

2464 return Error(Start, "offset operator cannot yet handle constants");

2465 }

2466 return false;

2467}

2468

2469

2470

2471unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {

2472 return StringSwitch(Name)

2473 .Cases({"TYPE", "type"}, IOK_TYPE)

2474 .Cases({"SIZE", "size"}, IOK_SIZE)

2475 .Cases({"LENGTH", "length"}, IOK_LENGTH)

2477}

2478

2479

2480

2481

2482

2483

2484

2485unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {

2486 MCAsmParser &Parser = getParser();

2487 const AsmToken &Tok = Parser.getTok();

2488 Parser.Lex();

2489

2490 const MCExpr *Val = nullptr;

2491 InlineAsmIdentifierInfo Info;

2494 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,

2495 true, End))

2496 return 0;

2497

2499 Error(Start, "unable to lookup expression");

2500 return 0;

2501 }

2502

2503 unsigned CVal = 0;

2504 switch(OpKind) {

2506 case IOK_LENGTH: CVal = Info.Var.Length; break;

2507 case IOK_SIZE: CVal = Info.Var.Size; break;

2508 case IOK_TYPE: CVal = Info.Var.Type; break;

2509 }

2510

2511 return CVal;

2512}

2513

2514

2515

2516unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {

2517 return StringSwitch(Name.lower())

2518 .Case("type", MOK_TYPE)

2519 .Cases({"size", "sizeof"}, MOK_SIZEOF)

2520 .Cases({"length", "lengthof"}, MOK_LENGTHOF)

2522}

2523

2524

2525

2526

2527

2528

2529

2530bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {

2531 MCAsmParser &Parser = getParser();

2533 Parser.Lex();

2534

2535 Val = 0;

2536 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {

2537

2539 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.getTok();

2540 AsmTypeInfo Type;

2543 Val = Type.Size;

2544

2545

2546 if (InParens)

2549 if (InParens)

2551 }

2552 }

2553

2554 if (!Val) {

2555 IntelExprStateMachine SM;

2557 if (ParseIntelExpression(SM, End))

2558 return true;

2559

2560 switch (OpKind) {

2561 default:

2563 case MOK_SIZEOF:

2564 Val = SM.getSize();

2565 break;

2566 case MOK_LENGTHOF:

2567 Val = SM.getLength();

2568 break;

2569 case MOK_TYPE:

2570 Val = SM.getElementSize();

2571 break;

2572 }

2573

2574 if (!Val)

2575 return Error(OpLoc, "expression has unknown type", SMRange(Start, End));

2576 }

2577

2578 return false;

2579}

2580

2581bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size,

2582 StringRef *SizeStr) {

2583 Size = StringSwitch(getTok().getString())

2584 .Cases({"BYTE", "byte"}, 8)

2585 .Cases({"WORD", "word"}, 16)

2586 .Cases({"DWORD", "dword"}, 32)

2587 .Cases({"FLOAT", "float"}, 32)

2588 .Cases({"LONG", "long"}, 32)

2589 .Cases({"FWORD", "fword"}, 48)

2590 .Cases({"DOUBLE", "double"}, 64)

2591 .Cases({"QWORD", "qword"}, 64)

2592 .Cases({"MMWORD", "mmword"}, 64)

2593 .Cases({"XWORD", "xword"}, 80)

2594 .Cases({"TBYTE", "tbyte"}, 80)

2595 .Cases({"XMMWORD", "xmmword"}, 128)

2596 .Cases({"YMMWORD", "ymmword"}, 256)

2597 .Cases({"ZMMWORD", "zmmword"}, 512)

2600 if (SizeStr)

2601 *SizeStr = getTok().getString();

2602 const AsmToken &Tok = Lex();

2604 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");

2605 Lex();

2606 }

2607 return false;

2608}

2609

2611 if (X86MCRegisterClasses[X86::GR8RegClassID].contains(RegNo))

2612 return 8;

2613 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(RegNo))

2614 return 16;

2615 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo))

2616 return 32;

2617 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))

2618 return 64;

2619

2620 return 0;

2621}

2622

2623bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {

2624 MCAsmParser &Parser = getParser();

2625 const AsmToken &Tok = Parser.getTok();

2626 SMLoc Start, End;

2627

2628

2629 unsigned Size;

2630 StringRef SizeStr;

2631 if (ParseIntelMemoryOperandSize(Size, &SizeStr))

2632 return true;

2633 bool PtrInOperand = bool(Size);

2634

2636

2637

2639 return ParseRoundingModeOp(Start, Operands);

2640

2641

2642 MCRegister RegNo;

2644 if (RegNo == X86::RIP)

2645 return Error(Start, "rip can only be used as a base register");

2646

2648 if (PtrInOperand) {

2650 return Error(Start, "expected memory operand after 'ptr', "

2651 "found register operand instead");

2652

2653

2654

2659 Start,

2660 "cannot cast register '" +

2662 "'; its size is not easily defined.");

2665 Start,

2666 std::to_string(RegSize) + "-bit register '" +

2668 "' cannot be used as a " + std::to_string(Size) + "-bit " +

2669 SizeStr.upper());

2670 }

2672 return false;

2673 }

2674

2675 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))

2676 return Error(Start, "invalid segment register");

2677

2678 Start = Lex().getLoc();

2679 }

2680

2681

2682 IntelExprStateMachine SM;

2683 if (ParseIntelExpression(SM, End))

2684 return true;

2685

2686 if (isParsingMSInlineAsm())

2687 RewriteIntelExpression(SM, Start, Tok.getLoc());

2688

2689 int64_t Imm = SM.getImm();

2690 const MCExpr *Disp = SM.getSym();

2692 if (Disp && Imm)

2694 if (!Disp)

2695 Disp = ImmDisp;

2696

2697

2698

2699 if (!SM.isMemExpr() && !RegNo) {

2700 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {

2701 const InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();

2703

2704

2706 SM.getSymName(), Info.Var.Decl,

2707 Info.Var.IsGlobalLV));

2708 return false;

2709 }

2710 }

2711

2713 return false;

2714 }

2715

2716 StringRef ErrMsg;

2717 MCRegister BaseReg = SM.getBaseReg();

2718 MCRegister IndexReg = SM.getIndexReg();

2719 if (IndexReg && BaseReg == X86::RIP)

2721 unsigned Scale = SM.getScale();

2722 if (!PtrInOperand)

2723 Size = SM.getElementSize() << 3;

2724

2725 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&

2726 (IndexReg == X86::ESP || IndexReg == X86::RSP))

2728

2729

2730

2731 if (Scale == 0 &&

2732 !(X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||

2733 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||

2734 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg)) &&

2735 (X86MCRegisterClasses[X86::VR128XRegClassID].contains(BaseReg) ||

2736 X86MCRegisterClasses[X86::VR256XRegClassID].contains(BaseReg) ||

2737 X86MCRegisterClasses[X86::VR512RegClassID].contains(BaseReg)))

2739

2740 if (Scale != 0 &&

2741 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg))

2742 return Error(Start, "16-bit addresses cannot have a scale");

2743

2744

2745 if (Scale == 0)

2746 Scale = 1;

2747

2748

2749

2750

2751 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&

2752 (IndexReg == X86::BX || IndexReg == X86::BP))

2754

2755 if ((BaseReg || IndexReg) &&

2757 ErrMsg))

2758 return Error(Start, ErrMsg);

2759 bool IsUnconditionalBranch =

2760 Name.equals_insensitive("jmp") || Name.equals_insensitive("call");

2761 if (isParsingMSInlineAsm())

2762 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,

2763 IsUnconditionalBranch && is64BitMode(),

2764 Start, End, Size, SM.getSymName(),

2765 SM.getIdentifierInfo(), Operands);

2766

2767

2768

2769 MCRegister DefaultBaseReg;

2770 bool MaybeDirectBranchDest = true;

2771

2773 if (is64BitMode() &&

2774 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {

2775 DefaultBaseReg = X86::RIP;

2776 }

2777 if (IsUnconditionalBranch) {

2778 if (PtrInOperand) {

2779 MaybeDirectBranchDest = false;

2780 if (is64BitMode())

2781 DefaultBaseReg = X86::RIP;

2782 } else if (!BaseReg && !IndexReg && Disp &&

2784 if (is64BitMode()) {

2785 if (SM.getSize() == 8) {

2786 MaybeDirectBranchDest = false;

2787 DefaultBaseReg = X86::RIP;

2788 }

2789 } else {

2790 if (SM.getSize() == 4 || SM.getSize() == 2)

2791 MaybeDirectBranchDest = false;

2792 }

2793 }

2794 }

2795 } else if (IsUnconditionalBranch) {

2796

2797 if (!PtrInOperand && SM.isOffsetOperator())

2799 Start, "`OFFSET` operator cannot be used in an unconditional branch");

2800 if (PtrInOperand || SM.isBracketUsed())

2801 MaybeDirectBranchDest = false;

2802 }

2803

2804 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))

2806 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,

2807 Size, DefaultBaseReg, StringRef(), nullptr,

2808 0, false, MaybeDirectBranchDest));

2809 else

2811 getPointerWidth(), Disp, Start, End, Size, StringRef(),

2812 nullptr, 0, false,

2813 MaybeDirectBranchDest));

2814 return false;

2815}

2816

2817bool X86AsmParser::parseATTOperand(OperandVector &Operands) {

2818 MCAsmParser &Parser = getParser();

2819 switch (getLexer().getKind()) {

2821

2823 Parser.Lex();

2824 const MCExpr *Val;

2825

2826

2829 "expected immediate expression") ||

2830 getParser().parseExpression(Val, End) ||

2831 check(isa(Val), L, "expected immediate expression"))

2832 return true;

2834 return false;

2835 }

2838 return ParseRoundingModeOp(Start, Operands);

2839 }

2840 default: {

2841

2842

2843

2844

2845

2846 SMLoc Loc = Parser.getTok().getLoc(), EndLoc;

2847 const MCExpr *Expr = nullptr;

2848 MCRegister Reg;

2850

2852 return true;

2854

2855 Expr = nullptr;

2856 Reg = RE->getReg();

2857

2858

2859 if (Reg == X86::EIZ || Reg == X86::RIZ)

2861 Loc, "%eiz and %riz can only be used as index registers",

2862 SMRange(Loc, EndLoc));

2863 if (Reg == X86::RIP)

2864 return Error(Loc, "%rip can only be used as a base register",

2865 SMRange(Loc, EndLoc));

2866

2869 return false;

2870 }

2871 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg))

2872 return Error(Loc, "invalid segment register");

2873

2874

2877 }

2878 }

2879

2880 return ParseMemOperand(Reg, Expr, Loc, EndLoc, Operands);

2881 }

2882 }

2883}

2884

2885

2886

2887X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {

2888 return StringSwitchX86::CondCode(CC)

2891 .Cases({"b", "nae"}, X86::COND_B)

2892 .Cases({"ae", "nb"}, X86::COND_AE)

2893 .Cases({"e", "z"}, X86::COND_E)

2894 .Cases({"ne", "nz"}, X86::COND_NE)

2895 .Cases({"be", "na"}, X86::COND_BE)

2896 .Cases({"a", "nbe"}, X86::COND_A)

2899 .Cases({"p", "pe"}, X86::COND_P)

2900 .Cases({"np", "po"}, X86::COND_NP)

2901 .Cases({"l", "nge"}, X86::COND_L)

2902 .Cases({"ge", "nl"}, X86::COND_GE)

2903 .Cases({"le", "ng"}, X86::COND_LE)

2904 .Cases({"g", "nle"}, X86::COND_G)

2906}

2907

2908

2909

2910bool X86AsmParser::ParseZ(std::unique_ptr &Z, SMLoc StartLoc) {

2911 MCAsmParser &Parser = getParser();

2912

2913

2914

2916 (getLexer().getTok().getIdentifier() == "z")))

2917 return false;

2918 Parser.Lex();

2919

2921 return Error(getLexer().getLoc(), "Expected } at this point");

2922 Parser.Lex();

2923

2925 return false;

2926}

2927

2928

2929bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {

2930 MCAsmParser &Parser = getParser();

2932

2933 const SMLoc consumedToken = consumeToken();

2934

2936

2937 if (getLexer().getTok().getIntVal() != 1)

2938 return TokError("Expected 1to at this point");

2939 StringRef Prefix = getLexer().getTok().getString();

2940 Parser.Lex();

2942 return TokError("Expected 1to at this point");

2943

2945 StringRef BroadcastString = (Prefix + getLexer().getTok().getIdentifier())

2947 if (!BroadcastString.starts_with("1to"))

2948 return TokError("Expected 1to at this point");

2949 const char *BroadcastPrimitive =

2950 StringSwitch<const char *>(BroadcastString)

2951 .Case("1to2", "{1to2}")

2952 .Case("1to4", "{1to4}")

2953 .Case("1to8", "{1to8}")

2954 .Case("1to16", "{1to16}")

2955 .Case("1to32", "{1to32}")

2956 .Default(nullptr);

2957 if (!BroadcastPrimitive)

2958 return TokError("Invalid memory broadcast primitive.");

2959 Parser.Lex();

2961 return TokError("Expected } at this point");

2962 Parser.Lex();

2964 consumedToken));

2965

2966

2967 return false;

2968 } else {

2969

2970

2971

2972 std::unique_ptr Z;

2973 if (ParseZ(Z, consumedToken))

2974 return true;

2975

2976

2977

2979 SMLoc StartLoc = Z ? consumeToken() : consumedToken;

2980

2981

2982 MCRegister RegNo;

2983 SMLoc RegLoc;

2984 if (!parseRegister(RegNo, RegLoc, StartLoc) &&

2985 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {

2986 if (RegNo == X86::K0)

2987 return Error(RegLoc, "Register k0 can't be used as write mask");

2989 return Error(getLexer().getLoc(), "Expected } at this point");

2994 } else

2995 return Error(getLexer().getLoc(),

2996 "Expected an op-mask register at this point");

2997

2999

3000

3001 if (ParseZ(Z, consumeToken()) || !Z)

3002 return Error(getLexer().getLoc(),

3003 "Expected a {z} mark at this point");

3004

3005 }

3006

3007

3008

3009 if (Z)

3010 Operands.push_back(std::move(Z));

3011 }

3012 }

3013 }

3014 return false;

3015}

3016

3017

3018

3019bool X86AsmParser::ParseMemOperand(MCRegister SegReg, const MCExpr *Disp,

3020 SMLoc StartLoc, SMLoc EndLoc,

3022 MCAsmParser &Parser = getParser();

3023 SMLoc Loc;

3024

3025

3026

3027

3028

3029

3030

3031

3032

3033

3034

3035

3036

3037

3038

3039

3040 auto isAtMemOperand = [this]() {

3042 return false;

3043 AsmToken Buf[2];

3044 StringRef Id;

3045 auto TokCount = this->getLexer().peekTokens(Buf, true);

3046 if (TokCount == 0)

3047 return false;

3048 switch (Buf[0].getKind()) {

3051 return true;

3052

3055 if ((TokCount > 1) &&

3058 Id = StringRef(Buf[0].getLoc().getPointer(),

3059 Buf[1].getIdentifier().size() + 1);

3060 break;

3064 break;

3065 default:

3066 return false;

3067 }

3068

3069 if (Id.empty()) {

3074 }

3075 }

3076 return false;

3077 };

3078

3079 if (!Disp) {

3080

3081 if (!isAtMemOperand()) {

3083 return true;

3085 } else {

3086

3088 }

3089 }

3090

3091

3092

3093

3095 if (!SegReg)

3098 else

3100 0, 0, 1, StartLoc, EndLoc));

3101 return false;

3102 }

3103

3104

3105

3106 MCRegister BaseReg, IndexReg;

3107 unsigned Scale = 1;

3108 SMLoc BaseLoc = getLexer().getLoc();

3109 const MCExpr *E;

3110 StringRef ErrMsg;

3111

3112

3115 check(isa<X86MCExpr>(E), BaseLoc, "expected register here"))

3116 return true;

3117

3118

3120 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)

3121 return Error(BaseLoc, "eiz and riz can only be used as index registers",

3122 SMRange(BaseLoc, EndLoc));

3123 }

3124

3126

3127

3128

3129

3130

3131

3134 return true;

3135

3137

3138

3139 int64_t ScaleVal;

3140 if (E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))

3141 return Error(Loc, "expected absolute expression");

3142 if (ScaleVal != 1)

3143 Warning(Loc, "scale factor without index register is ignored");

3144 Scale = 1;

3145 } else {

3147

3148 if (BaseReg == X86::RIP)

3149 return Error(Loc,

3150 "%rip as base register can not have an index register");

3151 if (IndexReg == X86::RIP)

3152 return Error(Loc, "%rip is not allowed as an index register");

3153

3155

3156

3157

3158

3160 int64_t ScaleVal;

3163 return Error(Loc, "expected scale expression");

3164 Scale = (unsigned)ScaleVal;

3165

3166 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&

3167 Scale != 1)

3168 return Error(Loc, "scale factor in 16-bit address must be 1");

3170 return Error(Loc, ErrMsg);

3171 }

3172 }

3173 }

3174 }

3175 }

3176

3177

3178 if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))

3179 return true;

3180

3181

3182

3183

3184 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&

3188 return false;

3189 }

3190

3192 ErrMsg))

3193 return Error(BaseLoc, ErrMsg);

3194

3195

3196

3197

3198

3199

3200 if (BaseReg || IndexReg) {

3202 auto Imm = CE->getValue();

3203 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||

3204 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);

3205 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);

3206 if (Is64) {

3208 return Error(BaseLoc, "displacement " + Twine(Imm) +

3209 " is not within [-2147483648, 2147483647]");

3210 } else if (!Is16) {

3211 if (isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {

3212 Warning(BaseLoc, "displacement " + Twine(Imm) +

3213 " shortened to 32-bit signed " +

3214 Twine(static_cast<int32_t>(Imm)));

3215 }

3216 } else if (isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {

3217 Warning(BaseLoc, "displacement " + Twine(Imm) +

3218 " shortened to 16-bit signed " +

3219 Twine(static_cast<int16_t>(Imm)));

3220 }

3221 }

3222 }

3223

3224 if (SegReg || BaseReg || IndexReg)

3226 BaseReg, IndexReg, Scale, StartLoc,

3227 EndLoc));

3228 else

3231 return false;

3232}

3233

3234

3235bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {

3236 MCAsmParser &Parser = getParser();

3237

3242 MCRegister RegNo;

3243 if (parseRegister(RegNo, StartLoc, EndLoc))

3244 return true;

3246 return false;

3247 }

3249}

3250

3251bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,

3253 MCAsmParser &Parser = getParser();

3254 InstInfo = &Info;

3255

3256

3257 ForcedOpcodePrefix = OpcodePrefix_Default;

3258 ForcedDispEncoding = DispEncoding_Default;

3259 UseApxExtendedReg = false;

3260 ForcedNoFlag = false;

3261

3262

3263 while (true) {

3264 if (Name == "{") {

3266 return Error(Parser.getTok().getLoc(), "Unexpected token after '{'");

3268 Parser.Lex();

3271 Parser.Lex();

3272

3273 if (Prefix == "rex")

3274 ForcedOpcodePrefix = OpcodePrefix_REX;

3275 else if (Prefix == "rex2")

3276 ForcedOpcodePrefix = OpcodePrefix_REX2;

3277 else if (Prefix == "vex")

3278 ForcedOpcodePrefix = OpcodePrefix_VEX;

3279 else if (Prefix == "vex2")

3280 ForcedOpcodePrefix = OpcodePrefix_VEX2;

3281 else if (Prefix == "vex3")

3282 ForcedOpcodePrefix = OpcodePrefix_VEX3;

3283 else if (Prefix == "evex")

3284 ForcedOpcodePrefix = OpcodePrefix_EVEX;

3285 else if (Prefix == "disp8")

3286 ForcedDispEncoding = DispEncoding_Disp8;

3287 else if (Prefix == "disp32")

3288 ForcedDispEncoding = DispEncoding_Disp32;

3289 else if (Prefix == "nf")

3290 ForcedNoFlag = true;

3291 else

3292 return Error(NameLoc, "unknown prefix");

3293

3296 Parser.Lex();

3298 } else {

3301

3303 Parser.Lex();

3304 }

3305 continue;

3306 }

3307

3308 if (isParsingMSInlineAsm()) {

3309 if (Name.equals_insensitive("vex"))

3310 ForcedOpcodePrefix = OpcodePrefix_VEX;

3311 else if (Name.equals_insensitive("vex2"))

3312 ForcedOpcodePrefix = OpcodePrefix_VEX2;

3313 else if (Name.equals_insensitive("vex3"))

3314 ForcedOpcodePrefix = OpcodePrefix_VEX3;

3315 else if (Name.equals_insensitive("evex"))

3316 ForcedOpcodePrefix = OpcodePrefix_EVEX;

3317

3318 if (ForcedOpcodePrefix != OpcodePrefix_Default) {

3321

3324 Parser.Lex();

3325 }

3326 }

3327 break;

3328 }

3329

3330

3331 if (Name.consume_back(".d32")) {

3332 ForcedDispEncoding = DispEncoding_Disp32;

3333 } else if (Name.consume_back(".d8")) {

3334 ForcedDispEncoding = DispEncoding_Disp8;

3335 }

3336

3337 StringRef PatchedName = Name;

3338

3339

3340 if (isParsingIntelSyntax() &&

3341 (PatchedName == "jmp" || PatchedName == "jc" || PatchedName == "jnc" ||

3342 PatchedName == "jcxz" || PatchedName == "jecxz" ||

3347 : NextTok == "short") {

3348 SMLoc NameEndLoc =

3350

3351 Parser.Lex();

3352

3353

3354

3356 NextTok.size() + 1);

3357 }

3358 }

3359

3360

3362 PatchedName != "setzub" && PatchedName != "setzunb" &&

3363 PatchedName != "setb" && PatchedName != "setnb")

3364 PatchedName = PatchedName.substr(0, Name.size()-1);

3365

3366 unsigned ComparisonPredicate = ~0U;

3367

3368

3374 bool IsVCMP = PatchedName[0] == 'v';

3375 unsigned CCIdx = IsVCMP ? 4 : 3;

3376 unsigned suffixLength = PatchedName.ends_with("bf16") ? 5 : 2;

3377 unsigned CC = StringSwitch(

3378 PatchedName.slice(CCIdx, PatchedName.size() - suffixLength))

3379 .Case("eq", 0x00)

3380 .Case("eq_oq", 0x00)

3381 .Case("lt", 0x01)

3382 .Case("lt_os", 0x01)

3383 .Case("le", 0x02)

3384 .Case("le_os", 0x02)

3385 .Case("unord", 0x03)

3386 .Case("unord_q", 0x03)

3387 .Case("neq", 0x04)

3388 .Case("neq_uq", 0x04)

3389 .Case("nlt", 0x05)

3390 .Case("nlt_us", 0x05)

3391 .Case("nle", 0x06)

3392 .Case("nle_us", 0x06)

3393 .Case("ord", 0x07)

3394 .Case("ord_q", 0x07)

3395

3396 .Case("eq_uq", 0x08)

3397 .Case("nge", 0x09)

3398 .Case("nge_us", 0x09)

3399 .Case("ngt", 0x0A)

3400 .Case("ngt_us", 0x0A)

3401 .Case("false", 0x0B)

3402 .Case("false_oq", 0x0B)

3403 .Case("neq_oq", 0x0C)

3404 .Case("ge", 0x0D)

3405 .Case("ge_os", 0x0D)

3406 .Case("gt", 0x0E)

3407 .Case("gt_os", 0x0E)

3408 .Case("true", 0x0F)

3409 .Case("true_uq", 0x0F)

3410 .Case("eq_os", 0x10)

3411 .Case("lt_oq", 0x11)

3412 .Case("le_oq", 0x12)

3413 .Case("unord_s", 0x13)

3414 .Case("neq_us", 0x14)

3415 .Case("nlt_uq", 0x15)

3416 .Case("nle_uq", 0x16)

3417 .Case("ord_s", 0x17)

3418 .Case("eq_us", 0x18)

3419 .Case("nge_uq", 0x19)

3420 .Case("ngt_uq", 0x1A)

3421 .Case("false_os", 0x1B)

3422 .Case("neq_os", 0x1C)

3423 .Case("ge_oq", 0x1D)

3424 .Case("gt_oq", 0x1E)

3425 .Case("true_us", 0x1F)

3426 .Default(~0U);

3427 if (CC != ~0U && (IsVCMP || CC < 8) &&

3428 (IsVCMP || PatchedName.back() != 'h')) {

3429 if (PatchedName.ends_with("ss"))

3430 PatchedName = IsVCMP ? "vcmpss" : "cmpss";

3431 else if (PatchedName.ends_with("sd"))

3432 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";

3433 else if (PatchedName.ends_with("ps"))

3434 PatchedName = IsVCMP ? "vcmpps" : "cmpps";

3435 else if (PatchedName.ends_with("pd"))

3436 PatchedName = IsVCMP ? "vcmppd" : "cmppd";

3437 else if (PatchedName.ends_with("sh"))

3438 PatchedName = "vcmpsh";

3439 else if (PatchedName.ends_with("ph"))

3440 PatchedName = "vcmpph";

3441 else if (PatchedName.ends_with("bf16"))

3442 PatchedName = "vcmpbf16";

3443 else

3445

3446 ComparisonPredicate = CC;

3447 }

3448 }

3449

3450

3452 (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||

3453 PatchedName.back() == 'd' || PatchedName.back() == 'q')) {

3454 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;

3455 unsigned CC = StringSwitch(

3456 PatchedName.slice(5, PatchedName.size() - SuffixSize))

3457 .Case("eq", 0x0)

3458 .Case("lt", 0x1)

3459 .Case("le", 0x2)

3460

3461 .Case("neq", 0x4)

3462 .Case("nlt", 0x5)

3463 .Case("nle", 0x6)

3464

3465 .Default(~0U);

3466 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {

3467 switch (PatchedName.back()) {

3469 case 'b': PatchedName = SuffixSize == 2 ? "vpcmpub" : "vpcmpb"; break;

3470 case 'w': PatchedName = SuffixSize == 2 ? "vpcmpuw" : "vpcmpw"; break;

3471 case 'd': PatchedName = SuffixSize == 2 ? "vpcmpud" : "vpcmpd"; break;

3472 case 'q': PatchedName = SuffixSize == 2 ? "vpcmpuq" : "vpcmpq"; break;

3473 }

3474

3475 ComparisonPredicate = CC;

3476 }

3477 }

3478

3479

3481 (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||

3482 PatchedName.back() == 'd' || PatchedName.back() == 'q')) {

3483 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;

3484 unsigned CC = StringSwitch(

3485 PatchedName.slice(5, PatchedName.size() - SuffixSize))

3486 .Case("lt", 0x0)

3487 .Case("le", 0x1)

3488 .Case("gt", 0x2)

3489 .Case("ge", 0x3)

3490 .Case("eq", 0x4)

3491 .Case("neq", 0x5)

3492 .Case("false", 0x6)

3493 .Case("true", 0x7)

3494 .Default(~0U);

3495 if (CC != ~0U) {

3496 switch (PatchedName.back()) {

3498 case 'b': PatchedName = SuffixSize == 2 ? "vpcomub" : "vpcomb"; break;

3499 case 'w': PatchedName = SuffixSize == 2 ? "vpcomuw" : "vpcomw"; break;

3500 case 'd': PatchedName = SuffixSize == 2 ? "vpcomud" : "vpcomd"; break;

3501 case 'q': PatchedName = SuffixSize == 2 ? "vpcomuq" : "vpcomq"; break;

3502 }

3503

3504 ComparisonPredicate = CC;

3505 }

3506 }

3507

3508

3509

3510

3511

3512

3513

3514

3515 bool IsPrefix =

3516 StringSwitch(Name)

3517 .Cases({"cs", "ds", "es", "fs", "gs", "ss"}, true)

3518 .Cases({"rex64", "data32", "data16", "addr32", "addr16"}, true)

3519 .Cases({"xacquire", "xrelease"}, true)

3520 .Cases({"acquire", "release"}, isParsingIntelSyntax())

3522

3523 auto isLockRepeatNtPrefix = [](StringRef N) {

3524 return StringSwitch(N)

3525 .Cases({"lock", "rep", "repe", "repz", "repne", "repnz", "notrack"},

3526 true)

3528 };

3529

3530 bool CurlyAsEndOfStatement = false;

3531

3533 while (isLockRepeatNtPrefix(Name.lower())) {

3535 StringSwitch(Name)

3543

3544

3545

3547 break;

3548 }

3549

3551 Parser.Lex();

3552

3553

3554 while (Name.starts_with(";") || Name.starts_with("\n") ||

3555 Name.starts_with("#") || Name.starts_with("\t") ||

3556 Name.starts_with("/")) {

3557

3559 Parser.Lex();

3560 }

3561 }

3562

3563 if (Flags)

3564 PatchedName = Name;

3565

3566

3567 if (PatchedName == "data16" && is16BitMode()) {

3568 return Error(NameLoc, "redundant data16 prefix");

3569 }

3570 if (PatchedName == "data32") {

3571 if (is32BitMode())

3572 return Error(NameLoc, "redundant data32 prefix");

3573 if (is64BitMode())

3574 return Error(NameLoc, "'data32' is not supported in 64-bit mode");

3575

3576 PatchedName = "data16";

3577

3580 getLexer().Lex();

3581

3582

3583 if (Next == "callw")

3584 Next = "calll";

3585 if (Next == "ljmpw")

3586 Next = "ljmpl";

3587

3589 PatchedName = Name;

3590 ForcedDataPrefix = X86::Is32Bit;

3591 IsPrefix = false;

3592 }

3593 }

3594

3596

3597

3598 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {

3602 }

3603

3604

3605 if ((Name.starts_with("ccmp") || Name.starts_with("ctest")) &&

3606 parseCFlagsOp(Operands))

3607 return true;

3608

3609

3610

3611

3612

3614

3617

3618

3619 while (true) {

3620 if (parseOperand(Operands, Name))

3621 return true;

3622 if (HandleAVX512Operand(Operands))

3623 return true;

3624

3625

3627 Parser.Lex();

3628 else

3629 break;

3630 }

3631

3632

3633

3634 CurlyAsEndOfStatement =

3635 isParsingIntelSyntax() && isParsingMSInlineAsm() &&

3638 return TokError("unexpected token in argument list");

3639 }

3640

3641

3642 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {

3646 }

3647

3648

3651 Parser.Lex();

3652 else if (CurlyAsEndOfStatement)

3653

3655 getLexer().getTok().getLoc(), 0);

3656

3657

3658

3659

3660 bool IsFp =

3661 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";

3662 if (IsFp && Operands.size() == 1) {

3663 const char *Repl = StringSwitch<const char *>(Name)

3664 .Case("fsub", "fsubp")

3665 .Case("fdiv", "fdivp")

3666 .Case("fsubr", "fsubrp")

3667 .Case("fdivr", "fdivrp");

3668 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);

3669 }

3670

3671 if ((Name == "mov" || Name == "movw" || Name == "movl") &&

3672 (Operands.size() == 3)) {

3673 X86Operand &Op1 = (X86Operand &)*Operands[1];

3674 X86Operand &Op2 = (X86Operand &)*Operands[2];

3676

3677

3679 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(

3681 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||

3682 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {

3683

3684 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {

3685 Name = is16BitMode() ? "movw" : "movl";

3687 }

3688

3689 MCRegister Reg =

3692 }

3693 }

3694

3695

3696

3697

3698 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||

3699 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&

3700 Operands.size() == 3) {

3701 X86Operand &Op = (X86Operand &)*Operands.back();

3702 if (Op.isDXReg())

3704 Op.getEndLoc());

3705 }

3706

3707 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||

3708 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&

3709 Operands.size() == 3) {

3710 X86Operand &Op = (X86Operand &)*Operands[1];

3711 if (Op.isDXReg())

3713 Op.getEndLoc());

3714 }

3715

3717 bool HadVerifyError = false;

3718

3719

3720 if (Name.starts_with("ins") &&

3721 (Operands.size() == 1 || Operands.size() == 3) &&

3722 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||

3723 Name == "ins")) {

3724

3725 AddDefaultSrcDestOperands(TmpOperands,

3727 DefaultMemDIOperand(NameLoc));

3728 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);

3729 }

3730

3731

3732 if (Name.starts_with("outs") &&

3733 (Operands.size() == 1 || Operands.size() == 3) &&

3734 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||

3735 Name == "outsd" || Name == "outs")) {

3736 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),

3738 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);

3739 }

3740

3741

3742

3743

3744 if (Name.starts_with("lods") &&

3745 (Operands.size() == 1 || Operands.size() == 2) &&

3746 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||

3747 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {

3748 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));

3749 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);

3750 }

3751

3752

3753

3754

3755 if (Name.starts_with("stos") &&

3756 (Operands.size() == 1 || Operands.size() == 2) &&

3757 (Name == "stos" || Name == "stosb" || Name == "stosw" ||

3758 Name == "stosl" || Name == "stosd" || Name == "stosq")) {

3759 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));

3760 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);

3761 }

3762

3763

3764

3765

3766 if (Name.starts_with("scas") &&

3767 (Operands.size() == 1 || Operands.size() == 2) &&

3768 (Name == "scas" || Name == "scasb" || Name == "scasw" ||

3769 Name == "scasl" || Name == "scasd" || Name == "scasq")) {

3770 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));

3771 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);

3772 }

3773

3774

3775 if (Name.starts_with("cmps") &&

3776 (Operands.size() == 1 || Operands.size() == 3) &&

3777 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||

3778 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {

3779 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),

3780 DefaultMemSIOperand(NameLoc));

3781 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);

3782 }

3783

3784

3785 if (((Name.starts_with("movs") &&

3786 (Name == "movs" || Name == "movsb" || Name == "movsw" ||

3787 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||

3788 (Name.starts_with("smov") &&

3789 (Name == "smov" || Name == "smovb" || Name == "smovw" ||

3790 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&

3791 (Operands.size() == 1 || Operands.size() == 3)) {

3792 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())

3794 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),

3795 DefaultMemDIOperand(NameLoc));

3796 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);

3797 }

3798

3799

3800 if (HadVerifyError) {

3801 return HadVerifyError;

3802 }

3803

3804

3805 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {

3806 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);

3808 Warning(Op1.getStartLoc(), "memory operand is only for determining the "

3809 "size, (R|E)BX will be used for the location");

3811 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");

3812 }

3813 }

3814

3815 if (Flags)

3817 return false;

3818}

3819

3822 unsigned Opcode = Inst.getOpcode();

3824 if (I == Table.end() || I->OldOpc != Opcode)

3825 return false;

3826

3828

3829

3830 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||

3831 X86::isPBLENDVB(Opcode))

3833

3834 return true;

3835}

3836

3837bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {

3839 return true;

3840

3841 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&

3843 return true;

3844

3846 return true;

3847

3848 auto replaceWithCCMPCTEST = [&](unsigned Opcode) -> bool {

3849 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {

3854 return true;

3855 }

3856 return false;

3857 };

3858

3860 default: return false;

3861 case X86::JMP_1:

3862

3863

3864

3865 if (ForcedDispEncoding == DispEncoding_Disp32) {

3866 Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);

3867 return true;

3868 }

3869

3870 return false;

3871 case X86::JCC_1:

3872

3873

3874

3875 if (ForcedDispEncoding == DispEncoding_Disp32) {

3876 Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);

3877 return true;

3878 }

3879

3880 return false;

3881 case X86::INT: {

3882

3883

3885 return false;

3888 return true;

3889 }

3890

3891

3892#define FROM_TO(FROM, TO) \

3893 case X86::FROM: \

3894 return replaceWithCCMPCTEST(X86::TO);

3895 FROM_TO(CMP64rr, CCMP64rr)

3896 FROM_TO(CMP64mi32, CCMP64mi32)

3897 FROM_TO(CMP64mi8, CCMP64mi8)

3898 FROM_TO(CMP64mr, CCMP64mr)

3899 FROM_TO(CMP64ri32, CCMP64ri32)

3900 FROM_TO(CMP64ri8, CCMP64ri8)

3901 FROM_TO(CMP64rm, CCMP64rm)

3902

3903 FROM_TO(CMP32rr, CCMP32rr)

3904 FROM_TO(CMP32mi, CCMP32mi)

3905 FROM_TO(CMP32mi8, CCMP32mi8)

3906 FROM_TO(CMP32mr, CCMP32mr)

3907 FROM_TO(CMP32ri, CCMP32ri)

3908 FROM_TO(CMP32ri8, CCMP32ri8)

3909 FROM_TO(CMP32rm, CCMP32rm)

3910

3911 FROM_TO(CMP16rr, CCMP16rr)

3912 FROM_TO(CMP16mi, CCMP16mi)

3913 FROM_TO(CMP16mi8, CCMP16mi8)

3914 FROM_TO(CMP16mr, CCMP16mr)

3915 FROM_TO(CMP16ri, CCMP16ri)

3916 FROM_TO(CMP16ri8, CCMP16ri8)

3917 FROM_TO(CMP16rm, CCMP16rm)

3918

3919 FROM_TO(CMP8rr, CCMP8rr)

3920 FROM_TO(CMP8mi, CCMP8mi)

3921 FROM_TO(CMP8mr, CCMP8mr)

3922 FROM_TO(CMP8ri, CCMP8ri)

3923 FROM_TO(CMP8rm, CCMP8rm)

3924

3925 FROM_TO(TEST64rr, CTEST64rr)

3926 FROM_TO(TEST64mi32, CTEST64mi32)

3927 FROM_TO(TEST64mr, CTEST64mr)

3928 FROM_TO(TEST64ri32, CTEST64ri32)

3929

3930 FROM_TO(TEST32rr, CTEST32rr)

3931 FROM_TO(TEST32mi, CTEST32mi)

3932 FROM_TO(TEST32mr, CTEST32mr)

3933 FROM_TO(TEST32ri, CTEST32ri)

3934

3935 FROM_TO(TEST16rr, CTEST16rr)

3936 FROM_TO(TEST16mi, CTEST16mi)

3937 FROM_TO(TEST16mr, CTEST16mr)

3938 FROM_TO(TEST16ri, CTEST16ri)

3939

3940 FROM_TO(TEST8rr, CTEST8rr)

3941 FROM_TO(TEST8mi, CTEST8mi)

3942 FROM_TO(TEST8mr, CTEST8mr)

3943 FROM_TO(TEST8ri, CTEST8ri)

3944#undef FROM_TO

3945 }

3946}

3947

3948bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {

3949 using namespace X86;

3950 const MCRegisterInfo *MRI = getContext().getRegisterInfo();

3951 unsigned Opcode = Inst.getOpcode();

3952 uint64_t TSFlags = MII.get(Opcode).TSFlags;

3953 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||

3954 isVFMADDCSH(Opcode)) {

3956 for (unsigned i = 2; i < Inst.getNumOperands(); i++)

3958 return Warning(Ops[0]->getStartLoc(), "Destination register should be "

3959 "distinct from source registers");

3960 } else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||

3961 isVFMULCSH(Opcode)) {

3963

3964

3965

3966

3967

3968 for (unsigned i = ((TSFlags & X86II::EVEX_K) ? 2 : 1);

3971 return Warning(Ops[0]->getStartLoc(), "Destination register should be "

3972 "distinct from source registers");

3973 } else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||

3974 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||

3975 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {

3976 MCRegister Src2 =

3979 unsigned Src2Enc = MRI->getEncodingValue(Src2);

3980 if (Src2Enc % 4 != 0) {

3982 unsigned GroupStart = (Src2Enc / 4) * 4;

3983 unsigned GroupEnd = GroupStart + 3;

3984 return Warning(Ops[0]->getStartLoc(),

3985 "source register '" + RegName + "' implicitly denotes '" +

3986 RegName.take_front(3) + Twine(GroupStart) + "' to '" +

3987 RegName.take_front(3) + Twine(GroupEnd) +

3988 "' source group");

3989 }

3990 } else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||

3991 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||

3992 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||

3993 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {

3995 if (HasEVEX) {

3997 unsigned Index = MRI->getEncodingValue(

3999 if (Dest == Index)

4000 return Warning(Ops[0]->getStartLoc(), "index and destination registers "

4001 "should be distinct");

4002 } else {

4005 unsigned Index = MRI->getEncodingValue(

4007 if (Dest == Mask || Dest == Index || Mask == Index)

4008 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "

4009 "registers should be distinct");

4010 }

4011 } else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||

4012 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||

4013 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {

4017 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)

4018 return Error(Ops[0]->getStartLoc(), "all tmm registers must be distinct");

4019 }

4020

4021

4022

4023

4024

4025

4026

4029 MCRegister HReg;

4032 for (unsigned i = 0; i != NumOps; ++i) {

4033 const MCOperand &MO = Inst.getOperand(i);

4034 if (!MO.isReg())

4035 continue;

4037 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)

4038 HReg = Reg;

4041 UsesRex = true;

4042 }

4043

4044 if (HReg &&

4045 (Enc == X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||

4046 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {

4048 return Error(Ops[0]->getStartLoc(),

4049 "can't encode '" + RegName.str() +

4050 "' in an instruction requiring EVEX/REX2/REX prefix");

4051 }

4052 }

4053

4054 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {

4056 if (!MO.isReg() || MO.getReg() != X86::RIP)

4058 Ops[0]->getStartLoc(),

4059 Twine((Inst.getOpcode() == X86::PREFETCHIT0 ? "'prefetchit0'"

4060 : "'prefetchit1'")) +

4061 " only supports RIP-relative address");

4062 }

4063 return false;

4064}

4065

4066void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {

4067 Warning(Loc, "Instruction may be vulnerable to LVI and "

4068 "requires manual mitigation");

4069 Note(SMLoc(), "See https://software.intel.com/"

4070 "security-software-guidance/insights/"

4071 "deep-dive-load-value-injection#specialinstructions"

4072 " for more information");

4073}

4074

4075

4076

4077

4078

4079

4080

4081

4082

4083

4084void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {

4085

4086

4087

4089 case X86::RET16:

4090 case X86::RET32:

4091 case X86::RET64:

4092 case X86::RETI16:

4093 case X86::RETI32:

4094 case X86::RETI64: {

4095 MCInst ShlInst, FenceInst;

4096 bool Parse32 = is32BitMode() || Code16GCC;

4097 MCRegister Basereg =

4098 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);

4101 Basereg, 0,

4102 1, SMLoc{}, SMLoc{}, 0);

4103 ShlInst.setOpcode(X86::SHL64mi);

4104 ShlMemOp->addMemOperands(ShlInst, 5);

4106 FenceInst.setOpcode(X86::LFENCE);

4109 return;

4110 }

4111 case X86::JMP16m:

4112 case X86::JMP32m:

4113 case X86::JMP64m:

4114 case X86::CALL16m:

4115 case X86::CALL32m:

4116 case X86::CALL64m:

4117 emitWarningForSpecialLVIInstruction(Inst.getLoc());

4118 return;

4119 }

4120}

4121

4122

4123

4124

4125

4126

4127

4128

4129void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,

4130 MCStreamer &Out) {

4134

4135

4136

4137 switch (Opcode) {

4138 case X86::CMPSB:

4139 case X86::CMPSW:

4140 case X86::CMPSL:

4141 case X86::CMPSQ:

4142 case X86::SCASB:

4143 case X86::SCASW:

4144 case X86::SCASL:

4145 case X86::SCASQ:

4146 emitWarningForSpecialLVIInstruction(Inst.getLoc());

4147 return;

4148 }

4149 } else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {

4150

4151

4152 emitWarningForSpecialLVIInstruction(Inst.getLoc());

4153 return;

4154 }

4155

4156 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());

4157

4158

4159

4161 return;

4162

4163

4165 MCInst FenceInst;

4166 FenceInst.setOpcode(X86::LFENCE);

4168 }

4169}

4170

4171void X86AsmParser::emitInstruction(MCInst &Inst, OperandVector &Operands,

4172 MCStreamer &Out) {

4174 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))

4175 applyLVICFIMitigation(Inst, Out);

4176

4178

4180 getSTI().hasFeature(X86::FeatureLVILoadHardening))

4181 applyLVILoadHardeningMitigation(Inst, Out);

4182}

4183

4185 unsigned Result = 0;

4187 if (Prefix.isPrefix()) {

4188 Result = Prefix.getPrefix();

4190 }

4191 return Result;

4192}

4193

4194bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

4196 MCStreamer &Out, uint64_t &ErrorInfo,

4197 bool MatchingInlineAsm) {

4198 assert(!Operands.empty() && "Unexpect empty operand list!");

4199 assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!");

4200

4201

4202 MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands,

4203 Out, MatchingInlineAsm);

4204 unsigned Prefixes = getPrefixes(Operands);

4205

4206 MCInst Inst;

4207

4208

4209

4210 if (ForcedOpcodePrefix == OpcodePrefix_REX)

4212 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)

4214 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)

4216 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)

4218 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)

4220 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)

4222

4223

4224 if (ForcedDispEncoding == DispEncoding_Disp8)

4226 else if (ForcedDispEncoding == DispEncoding_Disp32)

4228

4229 if (Prefixes)

4231

4232 return isParsingIntelSyntax()

4233 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,

4234 ErrorInfo, MatchingInlineAsm)

4235 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,

4236 ErrorInfo, MatchingInlineAsm);

4237}

4238

4239void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,

4241 bool MatchingInlineAsm) {

4242

4243

4244

4245 const char *Repl = StringSwitch<const char *>(Op.getToken())

4246 .Case("finit", "fninit")

4247 .Case("fsave", "fnsave")

4248 .Case("fstcw", "fnstcw")

4249 .Case("fstcww", "fnstcw")

4250 .Case("fstenv", "fnstenv")

4251 .Case("fstsw", "fnstsw")

4252 .Case("fstsww", "fnstsw")

4253 .Case("fclex", "fnclex")

4254 .Default(nullptr);

4255 if (Repl) {

4256 MCInst Inst;

4259 if (!MatchingInlineAsm)

4262 }

4263}

4264

4265bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,

4266 const FeatureBitset &MissingFeatures,

4267 bool MatchingInlineAsm) {

4268 assert(MissingFeatures.any() && "Unknown missing feature!");

4269 SmallString<126> Msg;

4270 raw_svector_ostream OS(Msg);

4271 OS << "instruction requires:";

4272 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {

4273 if (MissingFeatures[i])

4275 }

4276 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);

4277}

4278

4279unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {

4281 const MCInstrDesc &MCID = MII.get(Opc);

4282 uint64_t TSFlags = MCID.TSFlags;

4283

4285 return Match_Unsupported;

4286 if (ForcedNoFlag == !(TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))

4287 return Match_Unsupported;

4288

4289 switch (ForcedOpcodePrefix) {

4290 case OpcodePrefix_Default:

4291 break;

4292 case OpcodePrefix_REX:

4293 case OpcodePrefix_REX2:

4295 return Match_Unsupported;

4296 break;

4297 case OpcodePrefix_VEX:

4298 case OpcodePrefix_VEX2:

4299 case OpcodePrefix_VEX3:

4301 return Match_Unsupported;

4302 break;

4303 case OpcodePrefix_EVEX:

4305 !X86::isCMP(Opc) && !X86::isTEST(Opc))

4306 return Match_Unsupported;

4308 return Match_Unsupported;

4309 break;

4310 }

4311

4313 (ForcedOpcodePrefix != OpcodePrefix_VEX &&

4314 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&

4315 ForcedOpcodePrefix != OpcodePrefix_VEX3))

4316 return Match_Unsupported;

4317

4318 return Match_Success;

4319}

4320

4321bool X86AsmParser::matchAndEmitATTInstruction(

4322 SMLoc IDLoc, unsigned &Opcode, MCInst &Inst, OperandVector &Operands,

4323 MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) {

4324 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);

4325 SMRange EmptyRange;

4326

4327

4328 if (ForcedDataPrefix == X86::Is32Bit)

4329 SwitchMode(X86::Is32Bit);

4330

4331 FeatureBitset MissingFeatures;

4332 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,

4333 MissingFeatures, MatchingInlineAsm,

4334 isParsingIntelSyntax());

4335 if (ForcedDataPrefix == X86::Is32Bit) {

4336 SwitchMode(X86::Is16Bit);

4337 ForcedDataPrefix = 0;

4338 }

4339 switch (OriginalError) {

4341 case Match_Success:

4342 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))

4343 return true;

4344

4345

4346

4347 if (!MatchingInlineAsm)

4348 while (processInstruction(Inst, Operands))

4349 ;

4350

4352 if (!MatchingInlineAsm)

4355 return false;

4356 case Match_InvalidImmUnsignedi4: {

4357 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();

4358 if (ErrorLoc == SMLoc())

4359 ErrorLoc = IDLoc;

4360 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",

4361 EmptyRange, MatchingInlineAsm);

4362 }

4363 case Match_MissingFeature:

4364 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);

4365 case Match_InvalidOperand:

4366 case Match_MnemonicFail:

4367 case Match_Unsupported:

4368 break;

4369 }

4370 if (Op.getToken().empty()) {

4371 Error(IDLoc, "instruction must have size higher than 0", EmptyRange,

4372 MatchingInlineAsm);

4373 return true;

4374 }

4375

4376

4377

4378

4379

4380

4381

4382 StringRef Base = Op.getToken();

4383 SmallString<16> Tmp;

4384 Tmp += Base;

4385 Tmp += ' ';

4386 Op.setTokenValue(Tmp);

4387

4388

4389

4390

4391

4392

4393

4394 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";

4395

4396 const char *MemSize = Base[0] != 'f' ? "\x08\x10\x20\x40" : "\x20\x40\x50\0";

4397

4398

4399 uint64_t ErrorInfoIgnore;

4400 FeatureBitset ErrorInfoMissingFeatures;

4401 unsigned Match[4];

4402

4403

4404

4405

4406

4407

4408 bool HasVectorReg = false;

4409 X86Operand *MemOp = nullptr;

4410 for (const auto &Op : Operands) {

4411 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());

4413 HasVectorReg = true;

4414 else if (X86Op->isMem()) {

4415 MemOp = X86Op;

4416 assert(MemOp->Mem.Size == 0 && "Memory size always 0 under ATT syntax");

4417

4418

4419 break;

4420 }

4421 }

4422

4423 for (unsigned I = 0, E = std::size(Match); I != E; ++I) {

4424 Tmp.back() = Suffixes[I];

4425 if (MemOp && HasVectorReg)

4426 MemOp->Mem.Size = MemSize[I];

4427 Match[I] = Match_MnemonicFail;

4428 if (MemOp || !HasVectorReg) {

4429 Match[I] =

4430 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,

4431 MatchingInlineAsm, isParsingIntelSyntax());

4432

4433 if (Match[I] == Match_MissingFeature)

4434 ErrorInfoMissingFeatures = MissingFeatures;

4435 }

4436 }

4437

4438

4439 Op.setTokenValue(Base);

4440

4441

4442

4443

4444 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);

4445 if (NumSuccessfulMatches == 1) {

4446 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))

4447 return true;

4448

4449

4450

4451 if (!MatchingInlineAsm)

4452 while (processInstruction(Inst, Operands))

4453 ;

4454

4456 if (!MatchingInlineAsm)

4459 return false;

4460 }

4461

4462

4463

4464

4465

4466 if (NumSuccessfulMatches > 1) {

4467 char MatchChars[4];

4468 unsigned NumMatches = 0;

4469 for (unsigned I = 0, E = std::size(Match); I != E; ++I)

4470 if (Match[I] == Match_Success)

4471 MatchChars[NumMatches++] = Suffixes[I];

4472

4473 SmallString<126> Msg;

4474 raw_svector_ostream OS(Msg);

4475 OS << "ambiguous instructions require an explicit suffix (could be ";

4476 for (unsigned i = 0; i != NumMatches; ++i) {

4477 if (i != 0)

4478 OS << ", ";

4479 if (i + 1 == NumMatches)

4480 OS << "or ";

4481 OS << "'" << Base << MatchChars[i] << "'";

4482 }

4483 OS << ")";

4484 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);

4485 return true;

4486 }

4487

4488

4489

4490

4491

4492 if (llvm::count(Match, Match_MnemonicFail) == 4) {

4493 if (OriginalError == Match_MnemonicFail)

4494 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",

4495 Op.getLocRange(), MatchingInlineAsm);

4496

4497 if (OriginalError == Match_Unsupported)

4498 return Error(IDLoc, "unsupported instruction", EmptyRange,

4499 MatchingInlineAsm);

4500

4501 assert(OriginalError == Match_InvalidOperand && "Unexpected error");

4502

4503 if (ErrorInfo != ~0ULL) {

4504 if (ErrorInfo >= Operands.size())

4505 return Error(IDLoc, "too few operands for instruction", EmptyRange,

4506 MatchingInlineAsm);

4507

4508 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];

4510 SMRange OperandRange = Operand.getLocRange();

4511 return Error(Operand.getStartLoc(), "invalid operand for instruction",

4512 OperandRange, MatchingInlineAsm);

4513 }

4514 }

4515

4516 return Error(IDLoc, "invalid operand for instruction", EmptyRange,

4517 MatchingInlineAsm);

4518 }

4519

4520

4521 if (llvm::count(Match, Match_Unsupported) == 1) {

4522 return Error(IDLoc, "unsupported instruction", EmptyRange,

4523 MatchingInlineAsm);

4524 }

4525

4526

4527

4528 if (llvm::count(Match, Match_MissingFeature) == 1) {

4529 ErrorInfo = Match_MissingFeature;

4530 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,

4531 MatchingInlineAsm);

4532 }

4533

4534

4535

4536 if (llvm::count(Match, Match_InvalidOperand) == 1) {

4537 return Error(IDLoc, "invalid operand for instruction", EmptyRange,

4538 MatchingInlineAsm);

4539 }

4540

4541

4542 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",

4543 EmptyRange, MatchingInlineAsm);

4544 return true;

4545}

4546

4547bool X86AsmParser::matchAndEmitIntelInstruction(

4548 SMLoc IDLoc, unsigned &Opcode, MCInst &Inst, OperandVector &Operands,

4549 MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) {

4550 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);

4551 SMRange EmptyRange;

4552

4553 X86Operand *UnsizedMemOp = nullptr;

4554 for (const auto &Op : Operands) {

4555 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());

4557 UnsizedMemOp = X86Op;

4558

4559

4560 break;

4561 }

4562 }

4563

4564

4565

4566 StringRef Mnemonic = (static_cast<X86Operand &>(*Operands[0])).getToken();

4567 if (UnsizedMemOp) {

4568 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push", "pop"};

4569 for (const char *Instr : PtrSizedInstrs) {

4570 if (Mnemonic == Instr) {

4571 UnsizedMemOp->Mem.Size = getPointerWidth();

4572 break;

4573 }

4574 }

4575 }

4576

4577 SmallVector<unsigned, 8> Match;

4578 FeatureBitset ErrorInfoMissingFeatures;

4579 FeatureBitset MissingFeatures;

4580 StringRef Base = (static_cast<X86Operand &>(*Operands[0])).getToken();

4581

4582

4583

4584 if (Mnemonic == "push" && Operands.size() == 2) {

4585 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());

4586 if (X86Op->isImm()) {

4587

4589 unsigned Size = getPointerWidth();

4590 if (CE &&

4592 SmallString<16> Tmp;

4593 Tmp += Base;

4594 Tmp += (is64BitMode())

4595 ? "q"

4596 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";

4597 Op.setTokenValue(Tmp);

4598

4599 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,

4600 MissingFeatures, MatchingInlineAsm,

4601 false ));

4602 Op.setTokenValue(Base);

4603 }

4604 }

4605 }

4606

4607

4608

4609

4610 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {

4611 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};

4612 for (unsigned Size : MopSizes) {

4614 uint64_t ErrorInfoIgnore;

4615 unsigned LastOpcode = Inst.getOpcode();

4616 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,

4617 MissingFeatures, MatchingInlineAsm,

4618 isParsingIntelSyntax());

4619 if (Match.empty() || LastOpcode != Inst.getOpcode())

4621

4622

4623 if (Match.back() == Match_MissingFeature)

4624 ErrorInfoMissingFeatures = MissingFeatures;

4625 }

4626

4627

4628 UnsizedMemOp->Mem.Size = 0;

4629 }

4630

4631

4632

4633

4634 if (Match.empty()) {

4635 Match.push_back(MatchInstruction(

4636 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,

4637 isParsingIntelSyntax()));

4638

4639 if (Match.back() == Match_MissingFeature)

4640 ErrorInfoMissingFeatures = MissingFeatures;

4641 }

4642

4643

4644 if (UnsizedMemOp)

4645 UnsizedMemOp->Mem.Size = 0;

4646

4647

4648 if (Match.back() == Match_MnemonicFail) {

4649 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",

4650 Op.getLocRange(), MatchingInlineAsm);

4651 }

4652

4653 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);

4654

4655

4656

4657 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&

4660 unsigned M = MatchInstruction(

4661 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,

4662 isParsingIntelSyntax());

4663 if (M == Match_Success)

4664 NumSuccessfulMatches = 1;

4665

4666

4667

4671 }

4672

4673

4674

4675

4676 if (NumSuccessfulMatches == 1) {

4677 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))

4678 return true;

4679

4680

4681

4682 if (!MatchingInlineAsm)

4683 while (processInstruction(Inst, Operands))

4684 ;

4686 if (!MatchingInlineAsm)

4689 return false;

4690 } else if (NumSuccessfulMatches > 1) {

4691 assert(UnsizedMemOp &&

4692 "multiple matches only possible with unsized memory operands");

4694 "ambiguous operand size for instruction '" + Mnemonic + "\'",

4696 }

4697

4698

4699 if (llvm::count(Match, Match_Unsupported) == 1) {

4700 return Error(IDLoc, "unsupported instruction", EmptyRange,

4701 MatchingInlineAsm);

4702 }

4703

4704

4705

4706 if (llvm::count(Match, Match_MissingFeature) == 1) {

4707 ErrorInfo = Match_MissingFeature;

4708 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,

4709 MatchingInlineAsm);

4710 }

4711

4712

4713

4714 if (llvm::count(Match, Match_InvalidOperand) == 1) {

4715 return Error(IDLoc, "invalid operand for instruction", EmptyRange,

4716 MatchingInlineAsm);

4717 }

4718

4719 if (llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {

4720 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();

4721 if (ErrorLoc == SMLoc())

4722 ErrorLoc = IDLoc;

4723 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",

4724 EmptyRange, MatchingInlineAsm);

4725 }

4726

4727

4728 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,

4729 MatchingInlineAsm);

4730}

4731

4732bool X86AsmParser::omitRegisterFromClobberLists(MCRegister Reg) {

4733 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg);

4734}

4735

4736bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {

4737 MCAsmParser &Parser = getParser();

4740 return parseDirectiveArch();

4742 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());

4743 else if (IDVal.starts_with(".att_syntax")) {

4746 Parser.Lex();

4748 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "

4749 "supported: registers must have a "

4750 "'%' prefix in .att_syntax");

4751 }

4752 getParser().setAssemblerDialect(0);

4753 return false;

4754 } else if (IDVal.starts_with(".intel_syntax")) {

4755 getParser().setAssemblerDialect(1);

4758 Parser.Lex();

4760 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "

4761 "supported: registers must not have "

4762 "a '%' prefix in .intel_syntax");

4763 }

4764 return false;

4765 } else if (IDVal == ".nops")

4766 return parseDirectiveNops(DirectiveID.getLoc());

4767 else if (IDVal == ".even")

4768 return parseDirectiveEven(DirectiveID.getLoc());

4769 else if (IDVal == ".cv_fpo_proc")

4770 return parseDirectiveFPOProc(DirectiveID.getLoc());

4771 else if (IDVal == ".cv_fpo_setframe")

4772 return parseDirectiveFPOSetFrame(DirectiveID.getLoc());

4773 else if (IDVal == ".cv_fpo_pushreg")

4774 return parseDirectiveFPOPushReg(DirectiveID.getLoc());

4775 else if (IDVal == ".cv_fpo_stackalloc")

4776 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());

4777 else if (IDVal == ".cv_fpo_stackalign")

4778 return parseDirectiveFPOStackAlign(DirectiveID.getLoc());

4779 else if (IDVal == ".cv_fpo_endprologue")

4780 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());

4781 else if (IDVal == ".cv_fpo_endproc")

4782 return parseDirectiveFPOEndProc(DirectiveID.getLoc());

4783 else if (IDVal == ".seh_pushreg" ||

4785 return parseDirectiveSEHPushReg(DirectiveID.getLoc());

4786 else if (IDVal == ".seh_setframe" ||

4788 return parseDirectiveSEHSetFrame(DirectiveID.getLoc());

4789 else if (IDVal == ".seh_savereg" ||

4791 return parseDirectiveSEHSaveReg(DirectiveID.getLoc());

4792 else if (IDVal == ".seh_savexmm" ||

4794 return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());

4795 else if (IDVal == ".seh_pushframe" ||

4797 return parseDirectiveSEHPushFrame(DirectiveID.getLoc());

4798

4799 return true;

4800}

4801

4802bool X86AsmParser::parseDirectiveArch() {

4803

4804 getParser().parseStringToEndOfStatement();

4805 return false;

4806}

4807

4808

4809

4810bool X86AsmParser::parseDirectiveNops(SMLoc L) {

4811 int64_t NumBytes = 0, Control = 0;

4812 SMLoc NumBytesLoc, ControlLoc;

4813 const MCSubtargetInfo& STI = getSTI();

4814 NumBytesLoc = getTok().getLoc();

4815 if (getParser().checkForValidSection() ||

4816 getParser().parseAbsoluteExpression(NumBytes))

4817 return true;

4818

4820 ControlLoc = getTok().getLoc();

4821 if (getParser().parseAbsoluteExpression(Control))

4822 return true;

4823 }

4824 if (getParser().parseEOL())

4825 return true;

4826

4827 if (NumBytes <= 0) {

4828 Error(NumBytesLoc, "'.nops' directive with non-positive size");

4829 return false;

4830 }

4831

4832 if (Control < 0) {

4833 Error(ControlLoc, "'.nops' directive with negative NOP size");

4834 return false;

4835 }

4836

4837

4838 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);

4839

4840 return false;

4841}

4842

4843

4844

4845bool X86AsmParser::parseDirectiveEven(SMLoc L) {

4846 if (parseEOL())

4847 return false;

4848

4849 const MCSection *Section = getStreamer().getCurrentSectionOnly();

4850 if (!Section) {

4851 getStreamer().initSections(false, getSTI());

4852 Section = getStreamer().getCurrentSectionOnly();

4853 }

4854 if (getContext().getAsmInfo()->useCodeAlign(*Section))

4855 getStreamer().emitCodeAlignment(Align(2), &getSTI(), 0);

4856 else

4857 getStreamer().emitValueToAlignment(Align(2), 0, 1, 0);

4858 return false;

4859}

4860

4861

4862

4863bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {

4864 MCAsmParser &Parser = getParser();

4865 Code16GCC = false;

4866 if (IDVal == ".code16") {

4867 Parser.Lex();

4868 if (!is16BitMode()) {

4869 SwitchMode(X86::Is16Bit);

4870 getTargetStreamer().emitCode16();

4871 }

4872 } else if (IDVal == ".code16gcc") {

4873

4874 Parser.Lex();

4875 Code16GCC = true;

4876 if (!is16BitMode()) {

4877 SwitchMode(X86::Is16Bit);

4878 getTargetStreamer().emitCode16();

4879 }

4880 } else if (IDVal == ".code32") {

4881 Parser.Lex();

4882 if (!is32BitMode()) {

4883 SwitchMode(X86::Is32Bit);

4884 getTargetStreamer().emitCode32();

4885 }

4886 } else if (IDVal == ".code64") {

4887 Parser.Lex();

4888 if (!is64BitMode()) {

4889 SwitchMode(X86::Is64Bit);

4890 getTargetStreamer().emitCode64();

4891 }

4892 } else {

4893 Error(L, "unknown directive " + IDVal);

4894 return false;

4895 }

4896

4897 return false;

4898}

4899

4900

4901bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {

4902 MCAsmParser &Parser = getParser();

4903 StringRef ProcName;

4904 int64_t ParamsSize;

4906 return Parser.TokError("expected symbol name");

4907 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))

4908 return true;

4909 if (isUIntN(32, ParamsSize))

4910 return Parser.TokError("parameters size out of range");

4911 if (parseEOL())

4912 return true;

4914 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);

4915}

4916

4917

4918bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {

4919 MCRegister Reg;

4920 SMLoc DummyLoc;

4921 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())

4922 return true;

4923 return getTargetStreamer().emitFPOSetFrame(Reg, L);

4924}

4925

4926

4927bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {

4928 MCRegister Reg;

4929 SMLoc DummyLoc;

4930 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())

4931 return true;

4932 return getTargetStreamer().emitFPOPushReg(Reg, L);

4933}

4934

4935

4936bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {

4937 MCAsmParser &Parser = getParser();

4940 return true;

4941 return getTargetStreamer().emitFPOStackAlloc(Offset, L);

4942}

4943

4944

4945bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {

4946 MCAsmParser &Parser = getParser();

4949 return true;

4950 return getTargetStreamer().emitFPOStackAlign(Offset, L);

4951}

4952

4953

4954bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {

4955 MCAsmParser &Parser = getParser();

4957 return true;

4958 return getTargetStreamer().emitFPOEndPrologue(L);

4959}

4960

4961

4962bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {

4963 MCAsmParser &Parser = getParser();

4965 return true;

4966 return getTargetStreamer().emitFPOEndProc(L);

4967}

4968

4969bool X86AsmParser::parseSEHRegisterNumber(unsigned RegClassID,

4970 MCRegister &RegNo) {

4971 SMLoc startLoc = getLexer().getLoc();

4972 const MCRegisterInfo *MRI = getContext().getRegisterInfo();

4973

4974

4976 SMLoc endLoc;

4977 if (parseRegister(RegNo, startLoc, endLoc))

4978 return true;

4979

4980 if (!X86MCRegisterClasses[RegClassID].contains(RegNo)) {

4981 return Error(startLoc,

4982 "register is not supported for use with this directive");

4983 }

4984 } else {

4985

4986

4987 int64_t EncodedReg;

4988 if (getParser().parseAbsoluteExpression(EncodedReg))

4989 return true;

4990

4991

4992

4993 RegNo = MCRegister();

4994 for (MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {

4995 if (MRI->getEncodingValue(Reg) == EncodedReg) {

4996 RegNo = Reg;

4997 break;

4998 }

4999 }

5000 if (!RegNo) {

5001 return Error(startLoc,

5002 "incorrect register number for use with this directive");

5003 }

5004 }

5005

5006 return false;

5007}

5008

5009bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {

5010 MCRegister Reg;

5011 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))

5012 return true;

5013

5015 return TokError("expected end of directive");

5016

5017 getParser().Lex();

5018 getStreamer().emitWinCFIPushReg(Reg, Loc);

5019 return false;

5020}

5021

5022bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {

5023 MCRegister Reg;

5024 int64_t Off;

5025 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))

5026 return true;

5028 return TokError("you must specify a stack pointer offset");

5029

5030 getParser().Lex();

5031 if (getParser().parseAbsoluteExpression(Off))

5032 return true;

5033

5035 return TokError("expected end of directive");

5036

5037 getParser().Lex();

5038 getStreamer().emitWinCFISetFrame(Reg, Off, Loc);

5039 return false;

5040}

5041

5042bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {

5043 MCRegister Reg;

5044 int64_t Off;

5045 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))

5046 return true;

5048 return TokError("you must specify an offset on the stack");

5049

5050 getParser().Lex();

5051 if (getParser().parseAbsoluteExpression(Off))

5052 return true;

5053

5055 return TokError("expected end of directive");

5056

5057 getParser().Lex();

5058 getStreamer().emitWinCFISaveReg(Reg, Off, Loc);

5059 return false;

5060}

5061

5062bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {

5063 MCRegister Reg;

5064 int64_t Off;

5065 if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))

5066 return true;

5068 return TokError("you must specify an offset on the stack");

5069

5070 getParser().Lex();

5071 if (getParser().parseAbsoluteExpression(Off))

5072 return true;

5073

5075 return TokError("expected end of directive");

5076

5077 getParser().Lex();

5078 getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);

5079 return false;

5080}

5081

5082bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {

5083 bool Code = false;

5084 StringRef CodeID;

5086 SMLoc startLoc = getLexer().getLoc();

5087 getParser().Lex();

5088 if (!getParser().parseIdentifier(CodeID)) {

5089 if (CodeID != "code")

5090 return Error(startLoc, "expected @code");

5091 Code = true;

5092 }

5093 }

5094

5096 return TokError("expected end of directive");

5097

5098 getParser().Lex();

5099 getStreamer().emitWinCFIPushFrame(Code, Loc);

5100 return false;

5101}

5102

5103

5108

5109#define GET_MATCHER_IMPLEMENTATION

5110#include "X86GenAsmMatcher.inc"

unsigned const MachineRegisterInfo * MRI

static MCRegister MatchRegisterName(StringRef Name)

static const char * getSubtargetFeatureName(uint64_t Val)

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

static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)

Function Alias Analysis false

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

Analysis containing CSE Info

amode Optimize addressing mode

Value * getPointer(Value *Ptr)

static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)

const size_t AbstractManglingParser< Derived, Alloc >::NumOps

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

static bool IsVCMP(unsigned Opcode)

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

OptimizedStructLayoutField Field

static StringRef getName(Value *V)

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

This file defines the SmallString class.

This file defines the SmallVector class.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

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

static SymbolRef::Type getType(const Symbol *Sym)

#define LLVM_C_ABI

LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...

static cl::opt< bool > LVIInlineAsmHardening("x86-experimental-lvi-inline-asm-hardening", cl::desc("Harden inline assembly code that may be vulnerable to Load Value" " Injection (LVI). This feature is experimental."), cl::Hidden)

static bool checkScale(unsigned Scale, StringRef &ErrMsg)

Definition X86AsmParser.cpp:56

LLVM_C_ABI void LLVMInitializeX86AsmParser()

Definition X86AsmParser.cpp:5104

static bool convertSSEToAVX(MCInst &Inst)

Definition X86AsmParser.cpp:3820

static unsigned getPrefixes(OperandVector &Operands)

Definition X86AsmParser.cpp:4184

static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)

Definition X86AsmParser.cpp:1329

#define FROM_TO(FROM, TO)

uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)

Definition X86AsmParser.cpp:2610

static unsigned getSize(unsigned Kind)

uint64_t getZExtValue() const

Get zero extended value.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

void UnLex(AsmToken const &Token)

bool isNot(AsmToken::TokenKind K) const

Check if the current token has kind K.

LLVM_ABI SMLoc getLoc() const

int64_t getIntVal() const

bool isNot(TokenKind K) 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

LLVM_ABI SMLoc getEndLoc() const

StringRef getIdentifier() const

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

constexpr size_t size() const

bool Error(SMLoc L, const Twine &Msg, SMRange Range={})

Return an error at the location L, with the message Msg.

bool parseIntToken(int64_t &V, const Twine &ErrMsg="expected integer")

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 bool isParsingMasm() const

virtual bool parseIdentifier(StringRef &Res)=0

Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.

bool parseOptionalToken(AsmToken::TokenKind T)

Attempt to parse and consume token, returning true on success.

virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0

Parse a primary expression.

virtual const AsmToken & Lex()=0

Get the next AsmToken in the stream, possibly handling file inclusion first.

bool TokError(const Twine &Msg, SMRange Range={})

Report an error at the current lexer location.

virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0

virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const

virtual bool parseAbsoluteExpression(int64_t &Res)=0

Parse an expression which must evaluate to an absolute value.

virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const

bool parseTokenLoc(SMLoc &Loc)

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

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

@ SymbolRef

References to labels and assigned expressions.

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

unsigned getNumOperands() const

unsigned getFlags() const

unsigned getOpcode() const

void setFlags(unsigned F)

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

const MCOperand & getOperand(unsigned i) const

bool mayLoad() const

Return true if this instruction could possibly read memory.

bool isCall() const

Return true if the instruction is a call.

bool isTerminator() const

Returns true if this instruction part of the terminator for a basic block.

static MCOperand createImm(int64_t Val)

MCRegister getReg() const

Returns the register number.

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Wrapper class representing physical registers. Should be passed by value.

virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)

Emit the given Instruction into the current section.

const FeatureBitset & getFeatureBits() const

FeatureBitset ToggleFeature(uint64_t FB)

Toggle a feature and return the re-computed feature bits.

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

StringRef getName() const

getName - Get the symbol name.

bool isVariable() const

isVariable - Check if this is a variable symbol.

const MCExpr * getVariableValue() const

Get the expression of the variable symbol.

MCTargetAsmParser - Generic interface to target specific assembly parsers.

static constexpr StatusTy Failure

static constexpr StatusTy Success

static constexpr StatusTy NoMatch

constexpr unsigned id() const

Represents a location in source code.

static SMLoc getFromPointer(const char *Ptr)

constexpr const char * getPointer() const

constexpr bool isValid() const

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.

static constexpr size_t npos

bool consume_back(StringRef Suffix)

Returns true if this StringRef has the given suffix and removes that suffix.

bool getAsInteger(unsigned Radix, T &Result) const

Parse the current string as an integer of the specified radix.

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

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

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

LLVM_ABI std::string upper() const

Convert the given ASCII string to uppercase.

char back() const

back - Get the last character in the string.

StringRef slice(size_t Start, size_t End) const

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

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

bool consume_front(StringRef Prefix)

Returns true if this StringRef has the given prefix and removes that prefix.

LLVM_ABI std::string lower() const

bool ends_with(StringRef Suffix) const

Check if this string ends with the given Suffix.

StringRef drop_back(size_t N=1) const

Return a StringRef equal to 'this' but with the last N elements dropped.

bool equals_insensitive(StringRef RHS) const

Check for string equality, ignoring case.

static const char * getRegisterName(MCRegister Reg)

static const X86MCExpr * create(MCRegister Reg, MCContext &Ctx)

#define llvm_unreachable(msg)

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

constexpr char Align[]

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

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

unsigned ID

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

std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant

Alias for the std::variant specialization base class of DbgVariable.

@ CE

Windows NT (Windows on ARM)

@ X86

Windows x64, Windows Itanium (IA-64)

bool isX86_64NonExtLowByteReg(MCRegister Reg)

@ EVEX

EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...

@ VEX

VEX - encoding using 0xC4/0xC5.

@ XOP

XOP - Opcode prefix used by XOP instructions.

@ ExplicitVEXPrefix

For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.

bool canUseApxExtendedReg(const MCInstrDesc &Desc)

bool isX86_64ExtendedReg(MCRegister Reg)

bool isApxExtendedReg(MCRegister Reg)

void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)

bool optimizeShiftRotateWithImmediateOne(MCInst &MI)

bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)

NodeAddr< CodeNode * > Code

Context & getContext() const

BaseReg

Stack frame base register. Bit 0 of FREInfo.Info.

This is an optimization pass for GlobalISel generic memory operations.

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.

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.

MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)

Target & getTheX86_32Target()

constexpr bool isUIntN(unsigned N, uint64_t x)

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

SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

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

constexpr bool isUInt(uint64_t x)

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

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

auto lower_bound(R &&Range, T &&Value)

Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

FunctionAddr VTableAddr Next

auto count(R &&Range, const E &Element)

Wrapper function around std::count to count the number of times an element Element occurs in the give...

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

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

constexpr bool isIntN(unsigned N, int64_t x)

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

Target & getTheX86_64Target()

StringRef toStringRef(bool B)

Construct a string ref from a boolean.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

bool isKind(IdKind kind) const

SmallVectorImpl< AsmRewrite > * AsmRewrites

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

X86Operand - Instances of this class represent a parsed X86 machine instruction.

SMLoc getStartLoc() const override

getStartLoc - Get the location of the first token of this operand.

bool isImm() const override

isImm - Is this an immediate operand?

static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)

static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)

static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)

static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)

SMRange getLocRange() const

getLocRange - Get the range between the first and last token of this operand.

SMLoc getEndLoc() const override

getEndLoc - Get the location of the last token of this operand.

bool isReg() const override

isReg - Is this a register operand?

bool isMem() const override

isMem - Is this a memory operand?

static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)

Create an absolute memory operand.

static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)

bool isMemUnsized() const

const MCExpr * getImm() const

unsigned getMemFrontendSize() const

MCRegister getReg() const override