LLVM: lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

37#include

38#include

39#include

40#include

41#include

42#include

43#include

44

45using namespace llvm;

46

47

48

49static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,

50 bool AllowSymbol = false) {

52 int64_t Value = CE->getValue();

53 return Value >= MinValue && Value <= MaxValue;

54 }

55 return AllowSymbol;

56}

57

58namespace {

59

60enum RegisterKind {

61 GR32Reg,

62 GRH32Reg,

63 GR64Reg,

64 GR128Reg,

65 FP16Reg,

66 FP32Reg,

67 FP64Reg,

68 FP128Reg,

69 VR16Reg,

70 VR32Reg,

71 VR64Reg,

72 VR128Reg,

73 AR32Reg,

74 CR64Reg,

75};

76

77enum MemoryKind {

78 BDMem,

79 BDXMem,

80 BDLMem,

81 BDRMem,

82 BDVMem,

83 LXAMem

84};

85

87private:

88 enum OperandKind {

89 KindInvalid,

90 KindToken,

91 KindReg,

92 KindImm,

93 KindImmTLS,

94 KindMem

95 };

96

97 OperandKind Kind;

98 SMLoc StartLoc, EndLoc;

99

100

101 struct TokenOp {

102 const char *Data;

103 unsigned Length;

104 };

105

106

107

108

109

110

111

112

113

114

115 struct RegOp {

116 RegisterKind Kind;

117 unsigned Num;

118 };

119

120

121

122

123

124 struct MemOp {

125 unsigned Base : 12;

126 unsigned Index : 12;

127 unsigned MemKind : 4;

128 unsigned RegKind : 4;

129 const MCExpr *Disp;

130 union {

131 const MCExpr *Imm;

132 unsigned Reg;

133 } Length;

134 };

135

136

137

138 struct ImmTLSOp {

139 const MCExpr *Imm;

140 const MCExpr *Sym;

141 };

142

143 union {

144 TokenOp Token;

145 RegOp Reg;

146 const MCExpr *Imm;

147 ImmTLSOp ImmTLS;

148 MemOp Mem;

149 };

150

151 void addExpr(MCInst &Inst, const MCExpr *Expr) const {

152

153 if (!Expr)

157 else

159 }

160

161public:

162 SystemZOperand(OperandKind Kind, SMLoc StartLoc, SMLoc EndLoc)

163 : Kind(Kind), StartLoc(StartLoc), EndLoc(EndLoc) {}

164

165

166 static std::unique_ptr createInvalid(SMLoc StartLoc,

167 SMLoc EndLoc) {

168 return std::make_unique(KindInvalid, StartLoc, EndLoc);

169 }

170

171 static std::unique_ptr createToken(StringRef Str, SMLoc Loc) {

172 auto Op = std::make_unique(KindToken, Loc, Loc);

173 Op->Token.Data = Str.data();

174 Op->Token.Length = Str.size();

175 return Op;

176 }

177

178 static std::unique_ptr

179 createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {

180 auto Op = std::make_unique(KindReg, StartLoc, EndLoc);

181 Op->Reg.Kind = Kind;

182 Op->Reg.Num = Num;

183 return Op;

184 }

185

186 static std::unique_ptr

187 createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {

188 auto Op = std::make_unique(KindImm, StartLoc, EndLoc);

189 Op->Imm = Expr;

190 return Op;

191 }

192

193 static std::unique_ptr

194 createMem(MemoryKind MemKind, RegisterKind RegKind, unsigned Base,

195 const MCExpr *Disp, unsigned Index, const MCExpr *LengthImm,

196 unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {

197 auto Op = std::make_unique(KindMem, StartLoc, EndLoc);

198 Op->Mem.MemKind = MemKind;

199 Op->Mem.RegKind = RegKind;

202 Op->Mem.Disp = Disp;

203 if (MemKind == BDLMem)

204 Op->Mem.Length.Imm = LengthImm;

205 if (MemKind == BDRMem)

206 Op->Mem.Length.Reg = LengthReg;

207 return Op;

208 }

209

210 static std::unique_ptr

211 createImmTLS(const MCExpr *Imm, const MCExpr *Sym,

212 SMLoc StartLoc, SMLoc EndLoc) {

213 auto Op = std::make_unique(KindImmTLS, StartLoc, EndLoc);

214 Op->ImmTLS.Imm = Imm;

215 Op->ImmTLS.Sym = Sym;

216 return Op;

217 }

218

219

220 bool isToken() const override {

221 return Kind == KindToken;

222 }

224 assert(Kind == KindToken && "Not a token");

225 return StringRef(Token.Data, Token.Length);

226 }

227

228

229 bool isReg() const override {

230 return Kind == KindReg;

231 }

232 bool isReg(RegisterKind RegKind) const {

233 return Kind == KindReg && Reg.Kind == RegKind;

234 }

235 MCRegister getReg() const override {

236 assert(Kind == KindReg && "Not a register");

237 return Reg.Num;

238 }

239

240

241 bool isImm() const override {

242 return Kind == KindImm;

243 }

244 bool isImm(int64_t MinValue, int64_t MaxValue) const {

245 return Kind == KindImm && inRange(Imm, MinValue, MaxValue, true);

246 }

247 const MCExpr *getImm() const {

248 assert(Kind == KindImm && "Not an immediate");

249 return Imm;

250 }

251

252

253 bool isImmTLS() const {

254 return Kind == KindImmTLS;

255 }

256

257 const ImmTLSOp getImmTLS() const {

258 assert(Kind == KindImmTLS && "Not a TLS immediate");

259 return ImmTLS;

260 }

261

262

263 bool isMem() const override {

264 return Kind == KindMem;

265 }

266 bool isMem(MemoryKind MemKind) const {

267 return (Kind == KindMem &&

268 (Mem.MemKind == MemKind ||

269

270

271 (Mem.MemKind == BDMem && MemKind == BDXMem)));

272 }

273 bool isMem(MemoryKind MemKind, RegisterKind RegKind) const {

274 return isMem(MemKind) && Mem.RegKind == RegKind;

275 }

276 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind) const {

277 return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff, true);

278 }

279 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {

280 return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287, true);

281 }

282 bool isMemDisp12Len4(RegisterKind RegKind) const {

283 return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x10);

284 }

285 bool isMemDisp12Len8(RegisterKind RegKind) const {

286 return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x100);

287 }

288

289 const MemOp& getMem() const {

290 assert(Kind == KindMem && "Not a Mem operand");

291 return Mem;

292 }

293

294

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

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

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

298

299

300

301 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }

302

303

304

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

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

308 }

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

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

311 addExpr(Inst, getImm());

312 }

313 void addBDAddrOperands(MCInst &Inst, unsigned N) const {

314 assert(N == 2 && "Invalid number of operands");

315 assert(isMem(BDMem) && "Invalid operand type");

317 addExpr(Inst, Mem.Disp);

318 }

319 void addBDXAddrOperands(MCInst &Inst, unsigned N) const {

320 assert(N == 3 && "Invalid number of operands");

321 assert(isMem(BDXMem) && "Invalid operand type");

323 addExpr(Inst, Mem.Disp);

325 }

326 void addBDLAddrOperands(MCInst &Inst, unsigned N) const {

327 assert(N == 3 && "Invalid number of operands");

328 assert(isMem(BDLMem) && "Invalid operand type");

330 addExpr(Inst, Mem.Disp);

331 addExpr(Inst, Mem.Length.Imm);

332 }

333 void addBDRAddrOperands(MCInst &Inst, unsigned N) const {

334 assert(N == 3 && "Invalid number of operands");

335 assert(isMem(BDRMem) && "Invalid operand type");

337 addExpr(Inst, Mem.Disp);

339 }

340 void addBDVAddrOperands(MCInst &Inst, unsigned N) const {

341 assert(N == 3 && "Invalid number of operands");

342 assert(isMem(BDVMem) && "Invalid operand type");

344 addExpr(Inst, Mem.Disp);

346 }

347 void addLXAAddrOperands(MCInst &Inst, unsigned N) const {

348 assert(N == 3 && "Invalid number of operands");

349 assert(isMem(LXAMem) && "Invalid operand type");

351 addExpr(Inst, Mem.Disp);

353 }

354 void addImmTLSOperands(MCInst &Inst, unsigned N) const {

355 assert(N == 2 && "Invalid number of operands");

356 assert(Kind == KindImmTLS && "Invalid operand type");

357 addExpr(Inst, ImmTLS.Imm);

358 if (ImmTLS.Sym)

359 addExpr(Inst, ImmTLS.Sym);

360 }

361

362

363 bool isGR32() const { return isReg(GR32Reg); }

364 bool isGRH32() const { return isReg(GRH32Reg); }

365 bool isGRX32() const { return false; }

366 bool isGR64() const { return isReg(GR64Reg); }

367 bool isGR128() const { return isReg(GR128Reg); }

368 bool isADDR32() const { return isReg(GR32Reg); }

369 bool isADDR64() const { return isReg(GR64Reg); }

370 bool isADDR128() const { return false; }

371 bool isFP16() const { return isReg(FP16Reg); }

372 bool isFP32() const { return isReg(FP32Reg); }

373 bool isFP64() const { return isReg(FP64Reg); }

374 bool isFP128() const { return isReg(FP128Reg); }

375 bool isVR16() const { return isReg(VR16Reg); }

376 bool isVR32() const { return isReg(VR32Reg); }

377 bool isVR64() const { return isReg(VR64Reg); }

378 bool isVF128() const { return false; }

379 bool isVR128() const { return isReg(VR128Reg); }

380 bool isAR32() const { return isReg(AR32Reg); }

381 bool isCR64() const { return isReg(CR64Reg); }

382 bool isAnyReg() const { return (isReg() || isImm(0, 15)); }

383 bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, GR32Reg); }

384 bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, GR32Reg); }

385 bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, GR64Reg); }

386 bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, GR64Reg); }

387 bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, GR64Reg); }

388 bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, GR64Reg); }

389 bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(GR64Reg); }

390 bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(GR64Reg); }

391 bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, GR64Reg); }

392 bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, GR64Reg); }

393 bool isLXAAddr64Disp20() const { return isMemDisp20(LXAMem, GR64Reg); }

394 bool isU1Imm() const { return isImm(0, 1); }

395 bool isU2Imm() const { return isImm(0, 3); }

396 bool isU3Imm() const { return isImm(0, 7); }

397 bool isU4Imm() const { return isImm(0, 15); }

398 bool isU8Imm() const { return isImm(0, 255); }

399 bool isS8Imm() const { return isImm(-128, 127); }

400 bool isU12Imm() const { return isImm(0, 4095); }

401 bool isU16Imm() const { return isImm(0, 65535); }

402 bool isS16Imm() const { return isImm(-32768, 32767); }

403 bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }

404 bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }

405 bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); }

406};

407

409#define GET_ASSEMBLER_HEADER

410#include "SystemZGenAsmMatcher.inc"

411

412private:

414

415

416

417

419

420 enum RegisterGroup {

421 RegGR,

422 RegFP,

423 RegV,

424 RegAR,

425 RegCR

426 };

427 struct Register {

428 RegisterGroup Group;

429 unsigned Num;

430 SMLoc StartLoc, EndLoc;

431 };

432

433 SystemZTargetStreamer &getTargetStreamer() {

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

435 "do not have a target streamer");

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

437 return static_cast<SystemZTargetStreamer &>(TS);

438 }

439

440 bool parseRegister(Register &Reg, bool RequirePercent,

441 bool RestoreOnFailure = false);

442

443 bool parseIntegerRegister(Register &Reg, RegisterGroup Group);

444

445 ParseStatus parseRegister(OperandVector &Operands, RegisterKind Kind);

446

447 ParseStatus parseAnyRegister(OperandVector &Operands);

448

449 bool parseAddress(bool &HaveReg1, Register &Reg1, bool &HaveReg2,

450 Register &Reg2, const MCExpr *&Disp, const MCExpr *&Length,

451 bool HasLength = false, bool HasVectorIndex = false);

452 bool parseAddressRegister(Register &Reg);

453

454 bool parseDirectiveInsn(SMLoc L);

455 bool parseDirectiveMachine(SMLoc L);

456 bool parseGNUAttribute(SMLoc L);

457

458 ParseStatus parseAddress(OperandVector &Operands, MemoryKind MemKind,

459 RegisterKind RegKind);

460

461 ParseStatus parsePCRel(OperandVector &Operands, int64_t MinVal,

462 int64_t MaxVal, bool AllowTLS);

463

464 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483 unsigned getMAIAssemblerDialect() {

484 return Parser.getContext().getAsmInfo()->getAssemblerDialect();

485 }

486

487

488

489 inline bool isHLASMAlpha(char C) {

491 }

492

493

494 inline bool isHLASMAlnum(char C) { return isHLASMAlpha(C) || isDigit(C); }

495

496

497 inline bool isParsingHLASM() { return getMAIAssemblerDialect() == AD_HLASM; }

498

499

500 inline bool isParsingGNU() { return getMAIAssemblerDialect() == AD_GNU; }

501

502public:

503 SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,

504 const MCInstrInfo &MII, const MCTargetOptions &Options)

505 : MCTargetAsmParser(Options, sti, MII), Parser(parser) {

507

508

510

511

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

513 }

514

515

516 ParseStatus parseDirective(AsmToken DirectiveID) override;

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

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

519 bool RequirePercent, bool RestoreOnFailure);

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

521 SMLoc &EndLoc) override;

522 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,

523 SMLoc NameLoc, OperandVector &Operands) override;

524 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

526 uint64_t &ErrorInfo,

527 bool MatchingInlineAsm) override;

528 bool isLabel(AsmToken &Token) override;

529

530

532 return parseRegister(Operands, GR32Reg);

533 }

534 ParseStatus parseGRH32(OperandVector &Operands) {

535 return parseRegister(Operands, GRH32Reg);

536 }

537 ParseStatus parseGRX32(OperandVector &Operands) {

538 llvm_unreachable("GRX32 should only be used for pseudo instructions");

539 }

541 return parseRegister(Operands, GR64Reg);

542 }

543 ParseStatus parseGR128(OperandVector &Operands) {

544 return parseRegister(Operands, GR128Reg);

545 }

546 ParseStatus parseADDR32(OperandVector &Operands) {

547

548 return parseRegister(Operands, GR32Reg);

549 }

550 ParseStatus parseADDR64(OperandVector &Operands) {

551

552 return parseRegister(Operands, GR64Reg);

553 }

554 ParseStatus parseADDR128(OperandVector &Operands) {

556 }

558 return parseRegister(Operands, FP16Reg);

559 }

561 return parseRegister(Operands, FP32Reg);

562 }

564 return parseRegister(Operands, FP64Reg);

565 }

566 ParseStatus parseFP128(OperandVector &Operands) {

567 return parseRegister(Operands, FP128Reg);

568 }

570 return parseRegister(Operands, VR16Reg);

571 }

573 return parseRegister(Operands, VR32Reg);

574 }

576 return parseRegister(Operands, VR64Reg);

577 }

578 ParseStatus parseVF128(OperandVector &Operands) {

580 }

581 ParseStatus parseVR128(OperandVector &Operands) {

582 return parseRegister(Operands, VR128Reg);

583 }

585 return parseRegister(Operands, AR32Reg);

586 }

588 return parseRegister(Operands, CR64Reg);

589 }

590 ParseStatus parseAnyReg(OperandVector &Operands) {

591 return parseAnyRegister(Operands);

592 }

593 ParseStatus parseBDAddr32(OperandVector &Operands) {

594 return parseAddress(Operands, BDMem, GR32Reg);

595 }

596 ParseStatus parseBDAddr64(OperandVector &Operands) {

597 return parseAddress(Operands, BDMem, GR64Reg);

598 }

599 ParseStatus parseBDXAddr64(OperandVector &Operands) {

600 return parseAddress(Operands, BDXMem, GR64Reg);

601 }

602 ParseStatus parseBDLAddr64(OperandVector &Operands) {

603 return parseAddress(Operands, BDLMem, GR64Reg);

604 }

605 ParseStatus parseBDRAddr64(OperandVector &Operands) {

606 return parseAddress(Operands, BDRMem, GR64Reg);

607 }

608 ParseStatus parseBDVAddr64(OperandVector &Operands) {

609 return parseAddress(Operands, BDVMem, GR64Reg);

610 }

611 ParseStatus parseLXAAddr64(OperandVector &Operands) {

612 return parseAddress(Operands, LXAMem, GR64Reg);

613 }

614 ParseStatus parsePCRel12(OperandVector &Operands) {

615 return parsePCRel(Operands, -(1LL << 12), (1LL << 12) - 1, false);

616 }

617 ParseStatus parsePCRel16(OperandVector &Operands) {

618 return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);

619 }

620 ParseStatus parsePCRel24(OperandVector &Operands) {

621 return parsePCRel(Operands, -(1LL << 24), (1LL << 24) - 1, false);

622 }

623 ParseStatus parsePCRel32(OperandVector &Operands) {

624 return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);

625 }

626 ParseStatus parsePCRelTLS16(OperandVector &Operands) {

627 return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);

628 }

629 ParseStatus parsePCRelTLS32(OperandVector &Operands) {

630 return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);

631 }

632};

633

634}

635

636#define GET_REGISTER_MATCHER

637#define GET_SUBTARGET_FEATURE_NAME

638#define GET_MATCHER_IMPLEMENTATION

639#define GET_MNEMONIC_SPELL_CHECKER

640#include "SystemZGenAsmMatcher.inc"

641

642

643

650

651

654 return LHS.Format < RHS;

655 }

657 return LHS < RHS.Format;

658 }

660 return LHS.Format < RHS.Format;

661 }

662};

663

664

666

667 { "e", SystemZ::InsnE, 1,

668 { MCK_U16Imm } },

669 { "ri", SystemZ::InsnRI, 3,

670 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },

671 { "rie", SystemZ::InsnRIE, 4,

672 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },

673 { "ril", SystemZ::InsnRIL, 3,

674 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },

675 { "rilu", SystemZ::InsnRILU, 3,

676 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },

677 { "ris", SystemZ::InsnRIS, 5,

678 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },

679 { "rr", SystemZ::InsnRR, 3,

680 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },

681 { "rre", SystemZ::InsnRRE, 3,

682 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },

683 { "rrf", SystemZ::InsnRRF, 5,

684 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },

685 { "rrs", SystemZ::InsnRRS, 5,

686 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },

687 { "rs", SystemZ::InsnRS, 4,

688 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },

689 { "rse", SystemZ::InsnRSE, 4,

690 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },

691 { "rsi", SystemZ::InsnRSI, 4,

692 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },

693 { "rsy", SystemZ::InsnRSY, 4,

694 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },

695 { "rx", SystemZ::InsnRX, 3,

696 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },

697 { "rxe", SystemZ::InsnRXE, 3,

698 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },

699 { "rxf", SystemZ::InsnRXF, 4,

700 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },

701 { "rxy", SystemZ::InsnRXY, 3,

702 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },

703 { "s", SystemZ::InsnS, 2,

704 { MCK_U32Imm, MCK_BDAddr64Disp12 } },

705 { "si", SystemZ::InsnSI, 3,

706 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },

707 { "sil", SystemZ::InsnSIL, 3,

708 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },

709 { "siy", SystemZ::InsnSIY, 3,

710 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },

711 { "ss", SystemZ::InsnSS, 4,

712 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },

713 { "sse", SystemZ::InsnSSE, 3,

714 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },

715 { "ssf", SystemZ::InsnSSF, 4,

716 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },

717 { "vri", SystemZ::InsnVRI, 6,

718 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },

719 { "vrr", SystemZ::InsnVRR, 7,

720 { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,

721 MCK_U4Imm } },

722 { "vrs", SystemZ::InsnVRS, 5,

723 { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },

724 { "vrv", SystemZ::InsnVRV, 4,

725 { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },

726 { "vrx", SystemZ::InsnVRX, 4,

727 { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },

728 { "vsi", SystemZ::InsnVSI, 4,

729 { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }

730};

731

733 switch (Kind) {

734 case KindToken:

735 OS << "Token:" << getToken();

736 break;

737 case KindReg:

739 break;

740 case KindImm:

741 OS << "Imm:";

743 break;

744 case KindImmTLS:

745 OS << "ImmTLS:";

746 MAI.printExpr(OS, *getImmTLS().Imm);

747 if (getImmTLS().Sym) {

748 OS << ", ";

749 MAI.printExpr(OS, *getImmTLS().Sym);

750 }

751 break;

752 case KindMem: {

753 const MemOp &Op = getMem();

754 OS << "Mem:";

756 if (Op.Base) {

757 OS << "(";

758 if (Op.MemKind == BDLMem) {

760 OS << ',';

761 } else if (Op.MemKind == BDRMem)

763 if (Op.Index)

766 OS << ")";

767 }

768 break;

769 }

770 case KindInvalid:

771 break;

772 }

773}

774

775

776bool SystemZAsmParser::parseRegister(Register &Reg, bool RequirePercent,

777 bool RestoreOnFailure) {

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

780

781 Reg.StartLoc = PercentTok.getLoc();

782

784 return Error(PercentTok.getLoc(), "register expected");

785

786 if (HasPercent) {

787 Parser.Lex();

788 }

789

790

792 if (RestoreOnFailure && HasPercent)

793 getLexer().UnLex(PercentTok);

795 HasPercent ? "invalid register" : "register expected");

796 }

797

798

800 if (Name.size() < 2) {

801 if (RestoreOnFailure && HasPercent)

802 getLexer().UnLex(PercentTok);

803 return Error(Reg.StartLoc, "invalid register");

804 }

806

807

808 if (Name.substr(1).getAsInteger(10, Reg.Num)) {

809 if (RestoreOnFailure && HasPercent)

810 getLexer().UnLex(PercentTok);

811 return Error(Reg.StartLoc, "invalid register");

812 }

813

814

815 if (Prefix == 'r' && Reg.Num < 16)

816 Reg.Group = RegGR;

817 else if (Prefix == 'f' && Reg.Num < 16)

818 Reg.Group = RegFP;

819 else if (Prefix == 'v' && Reg.Num < 32)

820 Reg.Group = RegV;

821 else if (Prefix == 'a' && Reg.Num < 16)

822 Reg.Group = RegAR;

823 else if (Prefix == 'c' && Reg.Num < 16)

824 Reg.Group = RegCR;

825 else {

826 if (RestoreOnFailure && HasPercent)

827 getLexer().UnLex(PercentTok);

828 return Error(Reg.StartLoc, "invalid register");

829 }

830

832 Parser.Lex();

833 return false;

834}

835

836

837ParseStatus SystemZAsmParser::parseRegister(OperandVector &Operands,

838 RegisterKind Kind) {

840 RegisterGroup Group;

841 switch (Kind) {

842 case GR32Reg:

843 case GRH32Reg:

844 case GR64Reg:

845 case GR128Reg:

846 Group = RegGR;

847 break;

848 case FP16Reg:

849 case FP32Reg:

850 case FP64Reg:

851 case FP128Reg:

852 Group = RegFP;

853 break;

854 case VR16Reg:

855 case VR32Reg:

856 case VR64Reg:

857 case VR128Reg:

858 Group = RegV;

859 break;

860 case AR32Reg:

861 Group = RegAR;

862 break;

863 case CR64Reg:

864 Group = RegCR;

865 break;

866 }

867

868

870 if (parseRegister(Reg, true))

872

873

874

875 switch (Group) {

876 case RegGR:

877 case RegFP:

878 case RegAR:

879 case RegCR:

880 if (Group != Reg.Group)

881 return Error(Reg.StartLoc, "invalid operand for instruction");

882 break;

883 case RegV:

884 if (Reg.Group != RegV && Reg.Group != RegFP)

885 return Error(Reg.StartLoc, "invalid operand for instruction");

886 break;

887 }

889 if (parseIntegerRegister(Reg, Group))

891 }

892

893 else

895

896

897

898 const unsigned *Regs;

899 switch (Kind) {

914 }

915

916 if (Regs[Reg.Num] == 0)

917 return Error(Reg.StartLoc, "invalid register pair");

918

920 SystemZOperand::createReg(Kind, Regs[Reg.Num], Reg.StartLoc, Reg.EndLoc));

922}

923

924

925ParseStatus SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {

927

928

933

935 int64_t Value = CE->getValue();

937 return Error(StartLoc, "invalid register");

938 }

939

940 SMLoc EndLoc =

942

943 Operands.push_back(SystemZOperand::createImm(Register, StartLoc, EndLoc));

944 }

945 else {

946 if (isParsingHLASM())

948

950 if (parseRegister(Reg, true))

952

953 if (Reg.Num > 15)

954 return Error(StartLoc, "invalid register");

955

956

957 RegisterKind Kind;

958 unsigned RegNo;

959 if (Reg.Group == RegGR) {

960 Kind = GR64Reg;

962 }

963 else if (Reg.Group == RegFP) {

964 Kind = FP64Reg;

966 }

967 else if (Reg.Group == RegV) {

968 Kind = VR128Reg;

970 }

971 else if (Reg.Group == RegAR) {

972 Kind = AR32Reg;

974 }

975 else if (Reg.Group == RegCR) {

976 Kind = CR64Reg;

978 }

979 else {

981 }

982

983 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,

984 Reg.StartLoc, Reg.EndLoc));

985 }

987}

988

989bool SystemZAsmParser::parseIntegerRegister(Register &Reg,

990 RegisterGroup Group) {

992

995 return true;

996

998 if (!CE)

999 return true;

1000

1001 int64_t MaxRegNum = (Group == RegV) ? 31 : 15;

1002 int64_t Value = CE->getValue();

1005 return true;

1006 }

1007

1008

1010 Reg.Group = Group;

1012

1013

1014 return false;

1015}

1016

1017

1018bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,

1019 bool &HaveReg2, Register &Reg2,

1020 const MCExpr *&Disp, const MCExpr *&Length,

1021 bool HasLength, bool HasVectorIndex) {

1022

1023 if (getParser().parseExpression(Disp))

1024 return true;

1025

1026

1027 HaveReg1 = false;

1028 HaveReg2 = false;

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049 RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;

1050

1052 Parser.Lex();

1053

1055

1056 HaveReg1 = true;

1057 if (parseRegister(Reg1, true))

1058 return true;

1059 }

1060

1061

1062

1063

1065 if (HasLength) {

1066

1067

1068 if (getParser().parseExpression(Length))

1069 return true;

1070 } else {

1071

1072

1073

1074

1075 HaveReg1 = true;

1076 if (parseIntegerRegister(Reg1, RegGroup))

1077 return true;

1078 }

1079 } else {

1080

1081

1082 if (HasLength) {

1083 if (getParser().parseExpression(Length))

1084 return true;

1085 }

1086 }

1087

1088

1090 Parser.Lex();

1091 HaveReg2 = true;

1092

1094 if (parseIntegerRegister(Reg2, RegGR))

1095 return true;

1096 } else if (isParsingGNU()) {

1098 if (parseRegister(Reg2, true))

1099 return true;

1100 } else {

1101

1102 Reg2.Num = 0;

1103 Reg2.Group = RegGR;

1104 Reg2.StartLoc = Reg2.EndLoc = Parser.getTok().getLoc();

1105 }

1106 }

1107 }

1108

1109

1111 return Error(Parser.getTok().getLoc(), "unexpected token in address");

1112 Parser.Lex();

1113 }

1114 return false;

1115}

1116

1117

1118bool

1119SystemZAsmParser::parseAddressRegister(Register &Reg) {

1120 if (Reg.Group == RegV) {

1121 Error(Reg.StartLoc, "invalid use of vector addressing");

1122 return true;

1123 }

1124 if (Reg.Group != RegGR) {

1125 Error(Reg.StartLoc, "invalid address register");

1126 return true;

1127 }

1128 return false;

1129}

1130

1131

1132

1133ParseStatus SystemZAsmParser::parseAddress(OperandVector &Operands,

1134 MemoryKind MemKind,

1135 RegisterKind RegKind) {

1137 unsigned Base = 0, Index = 0, LengthReg = 0;

1139 bool HaveReg1, HaveReg2;

1140 const MCExpr *Disp;

1141 const MCExpr *Length;

1142

1143 bool HasLength = (MemKind == BDLMem) ? true : false;

1144 bool HasVectorIndex = (MemKind == BDVMem) ? true : false;

1145 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length, HasLength,

1146 HasVectorIndex))

1148

1149 const unsigned *Regs;

1150 switch (RegKind) {

1154 }

1155

1156 switch (MemKind) {

1157 case BDMem:

1158

1159 if (HaveReg1) {

1160 if (parseAddressRegister(Reg1))

1162 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];

1163 }

1164

1165 if (HaveReg2)

1166 return Error(StartLoc, "invalid use of indexed addressing");

1167 break;

1168 case BDXMem:

1169 case LXAMem:

1170

1171 if (HaveReg1) {

1172 const unsigned *IndexRegs = Regs;

1173 if (MemKind == LXAMem)

1175

1176 if (parseAddressRegister(Reg1))

1178

1179

1180

1181 if (HaveReg2 || isParsingHLASM())

1182 Index = Reg1.Num == 0 ? 0 : IndexRegs[Reg1.Num];

1183 else

1184 Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];

1185 }

1186

1187 if (HaveReg2) {

1188 if (parseAddressRegister(Reg2))

1190 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];

1191 }

1192 break;

1193 case BDLMem:

1194

1195 if (HaveReg2) {

1196 if (parseAddressRegister(Reg2))

1198 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];

1199 }

1200

1201 if (HaveReg1 && HaveReg2)

1202 return Error(StartLoc, "invalid use of indexed addressing");

1203

1205 return Error(StartLoc, "missing length in address");

1206 break;

1207 case BDRMem:

1208

1209 if (!HaveReg1 || Reg1.Group != RegGR)

1210 return Error(StartLoc, "invalid operand for instruction");

1212

1213 if (HaveReg2) {

1214 if (parseAddressRegister(Reg2))

1216 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];

1217 }

1218 break;

1219 case BDVMem:

1220

1221 if (!HaveReg1 || Reg1.Group != RegV)

1222 return Error(StartLoc, "vector index required in address");

1224

1225

1226 if (isParsingGNU() && !HaveReg2)

1227 return Error(Reg1.StartLoc, "invalid use of vector addressing");

1228

1229 if (HaveReg2) {

1230 if (parseAddressRegister(Reg2))

1232 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];

1233 }

1234 break;

1235 }

1236

1237 SMLoc EndLoc =

1239 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp,

1240 Index, Length, LengthReg,

1241 StartLoc, EndLoc));

1243}

1244

1245ParseStatus SystemZAsmParser::parseDirective(AsmToken DirectiveID) {

1247

1248 if (IDVal == ".insn")

1249 return parseDirectiveInsn(DirectiveID.getLoc());

1250 if (IDVal == ".machine")

1251 return parseDirectiveMachine(DirectiveID.getLoc());

1252 if (IDVal.starts_with(".gnu_attribute"))

1253 return parseGNUAttribute(DirectiveID.getLoc());

1254

1256}

1257

1258

1259

1260bool SystemZAsmParser::parseDirectiveInsn(SMLoc L) {

1261 MCAsmParser &Parser = getParser();

1262

1263

1267 return Error(ErrorLoc, "expected instruction format");

1268

1270

1271

1272 auto EntryRange =

1274 Format, CompareInsn());

1275

1276

1277 if (EntryRange.first == EntryRange.second)

1278 return Error(ErrorLoc, "unrecognized format");

1279

1280 struct InsnMatchEntry *Entry = EntryRange.first;

1281

1282

1284

1285

1286 for (int I = 0; I < Entry->NumOperands; I++) {

1287 MatchClassKind Kind = Entry->OperandKinds[I];

1288

1290

1291

1293 return Error(StartLoc, "unexpected token in directive");

1294 Lex();

1295

1296

1297 ParseStatus ResTy;

1298 if (Kind == MCK_AnyReg)

1299 ResTy = parseAnyReg(Operands);

1300 else if (Kind == MCK_VR128)

1301 ResTy = parseVR128(Operands);

1302 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)

1303 ResTy = parseBDXAddr64(Operands);

1304 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)

1305 ResTy = parseBDAddr64(Operands);

1306 else if (Kind == MCK_BDVAddr64Disp12)

1307 ResTy = parseBDVAddr64(Operands);

1308 else if (Kind == MCK_LXAAddr64Disp20)

1309 ResTy = parseLXAAddr64(Operands);

1310 else if (Kind == MCK_PCRel32)

1311 ResTy = parsePCRel32(Operands);

1312 else if (Kind == MCK_PCRel16)

1313 ResTy = parsePCRel16(Operands);

1314 else {

1315

1316 const MCExpr *Expr;

1318

1319

1321 return Error(StartLoc, "unexpected token in directive");

1322

1323 SMLoc EndLoc =

1325

1326 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));

1328 }

1329

1331 return true;

1332 }

1333

1334

1335 MCInst Inst = MCInstBuilder(Entry->Opcode);

1336

1337 for (size_t I = 0; I < Operands.size(); I++) {

1338 MCParsedAsmOperand &Operand = *Operands[I];

1339 MatchClassKind Kind = Entry->OperandKinds[I];

1340

1341

1342 unsigned Res = validateOperandClass(Operand, Kind, *STI);

1343 if (Res != Match_Success)

1344 return Error(Operand.getStartLoc(), "unexpected operand type");

1345

1346

1347 SystemZOperand &ZOperand = static_cast<SystemZOperand &>(Operand);

1348 if (ZOperand.isReg())

1349 ZOperand.addRegOperands(Inst, 1);

1350 else if (ZOperand.isMem(BDMem))

1351 ZOperand.addBDAddrOperands(Inst, 2);

1352 else if (ZOperand.isMem(BDXMem))

1353 ZOperand.addBDXAddrOperands(Inst, 3);

1354 else if (ZOperand.isMem(BDVMem))

1355 ZOperand.addBDVAddrOperands(Inst, 3);

1356 else if (ZOperand.isMem(LXAMem))

1357 ZOperand.addLXAAddrOperands(Inst, 3);

1358 else if (ZOperand.isImm())

1359 ZOperand.addImmOperands(Inst, 1);

1360 else

1362 }

1363

1364

1366

1367 return false;

1368}

1369

1370

1371

1372bool SystemZAsmParser::parseDirectiveMachine(SMLoc L) {

1373 MCAsmParser &Parser = getParser();

1376 return TokError("unexpected token in '.machine' directive");

1377

1380

1381 Parser.Lex();

1382 if (parseEOL())

1383 return true;

1384

1385

1386 if (Id == "push") {

1387

1388 MachineStack.push_back(getAvailableFeatures());

1389 } else if (Id == "pop") {

1390

1391 if (MachineStack.empty())

1392 return Error(IdLoc,

1393 "pop without corresponding push in '.machine' directive");

1394 setAvailableFeatures(MachineStack.back());

1396 } else {

1397

1398

1399 MCSubtargetInfo &STI = copySTI();

1401 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));

1402 }

1403 getTargetStreamer().emitMachine(Id);

1404

1405 return false;

1406}

1407

1408bool SystemZAsmParser::parseGNUAttribute(SMLoc L) {

1409 int64_t Tag;

1410 int64_t IntegerValue;

1412 return Error(L, "malformed .gnu_attribute directive");

1413

1414

1415 if (Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))

1416 return Error(L, "unrecognized .gnu_attribute tag/value pair.");

1417

1419

1420 return parseEOL();

1421}

1422

1423bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,

1424 SMLoc &EndLoc, bool RequirePercent,

1425 bool RestoreOnFailure) {

1427 if (parseRegister(Reg, RequirePercent, RestoreOnFailure))

1428 return true;

1429 if (Reg.Group == RegGR)

1431 else if (Reg.Group == RegFP)

1433 else if (Reg.Group == RegV)

1435 else if (Reg.Group == RegAR)

1437 else if (Reg.Group == RegCR)

1439 StartLoc = Reg.StartLoc;

1440 EndLoc = Reg.EndLoc;

1441 return false;

1442}

1443

1444bool SystemZAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,

1445 SMLoc &EndLoc) {

1446 return ParseRegister(Reg, StartLoc, EndLoc, false,

1447 false);

1448}

1449

1450ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,

1451 SMLoc &EndLoc) {

1452 bool Result = ParseRegister(Reg, StartLoc, EndLoc, false,

1453 true);

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

1455 getParser().clearPendingErrors();

1456 if (PendingErrors)

1458 if (Result)

1461}

1462

1463bool SystemZAsmParser::parseInstruction(ParseInstructionInfo &Info,

1464 StringRef Name, SMLoc NameLoc,

1466

1467

1468

1469 applyMnemonicAliases(Name, getAvailableFeatures(), getMAIAssemblerDialect());

1470

1471 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));

1472

1473

1475

1476 if (parseOperand(Operands, Name)) {

1477 return true;

1478 }

1479

1480

1482 Parser.Lex();

1483

1487 "No space allowed between comma that separates operand entries");

1488

1489 if (parseOperand(Operands, Name)) {

1490 return true;

1491 }

1492 }

1493

1494

1495

1496

1497

1499

1500 StringRef Remark(getLexer().LexUntilEndOfStatement());

1501 Parser.Lex();

1502

1503

1504

1505

1506

1507

1508

1509

1511

1512 getStreamer().AddComment(Remark);

1513 }

1514

1516 SMLoc Loc = getLexer().getLoc();

1517 return Error(Loc, "unexpected token in argument list");

1518 }

1519 }

1520

1521

1522 Parser.Lex();

1523 return false;

1524}

1525

1526bool SystemZAsmParser::parseOperand(OperandVector &Operands,

1527 StringRef Mnemonic) {

1528

1529

1530

1531

1532

1533 FeatureBitset AvailableFeatures = getAvailableFeatures();

1534 FeatureBitset All;

1535 All.set();

1536 setAvailableFeatures(All);

1537 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);

1538 setAvailableFeatures(AvailableFeatures);

1540 return false;

1541

1542

1543

1544

1546 return true;

1547

1548

1549

1550

1551

1554 if (parseRegister(Reg, true))

1555 return true;

1556 Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));

1557 return false;

1558 }

1559

1560

1561

1562

1565 bool HaveReg1, HaveReg2;

1566 const MCExpr *Expr;

1567 const MCExpr *Length;

1568 if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length,

1569 true, true))

1570 return true;

1571

1572

1573 if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV

1574 && parseAddressRegister(Reg1))

1575 return true;

1576 if (HaveReg2 && parseAddressRegister(Reg2))

1577 return true;

1578

1579 SMLoc EndLoc =

1581 if (HaveReg1 || HaveReg2 || Length)

1582 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));

1583 else

1584 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));

1585 return false;

1586}

1587

1588bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

1590 MCStreamer &Out,

1591 uint64_t &ErrorInfo,

1592 bool MatchingInlineAsm) {

1593 MCInst Inst;

1594 unsigned MatchResult;

1595

1596 unsigned Dialect = getMAIAssemblerDialect();

1597

1598 FeatureBitset MissingFeatures;

1599 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,

1600 MatchingInlineAsm, Dialect);

1601 switch (MatchResult) {

1602 case Match_Success:

1605 return false;

1606

1607 case Match_MissingFeature: {

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

1609

1610

1611 std::string Msg = "instruction requires:";

1612 for (unsigned I = 0, E = MissingFeatures.size(); I != E; ++I) {

1613 if (MissingFeatures[I]) {

1614 Msg += " ";

1616 }

1617 }

1618 return Error(IDLoc, Msg);

1619 }

1620

1621 case Match_InvalidOperand: {

1622 SMLoc ErrorLoc = IDLoc;

1623 if (ErrorInfo != ~0ULL) {

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

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

1626

1627 ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();

1628 if (ErrorLoc == SMLoc())

1629 ErrorLoc = IDLoc;

1630 }

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

1632 }

1633

1634 case Match_MnemonicFail: {

1635 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());

1636 std::string Suggestion = SystemZMnemonicSpellCheck(

1637 ((SystemZOperand &)*Operands[0]).getToken(), FBS, Dialect);

1638 return Error(IDLoc, "invalid instruction" + Suggestion,

1639 ((SystemZOperand &)*Operands[0]).getLocRange());

1640 }

1641 }

1642

1644}

1645

1646ParseStatus SystemZAsmParser::parsePCRel(OperandVector &Operands,

1647 int64_t MinVal, int64_t MaxVal,

1648 bool AllowTLS) {

1650 MCStreamer &Out = getStreamer();

1651 const MCExpr *Expr;

1653 if (getParser().parseExpression(Expr))

1655

1656 auto IsOutOfRangeConstant = [&](const MCExpr *E, bool Negate) -> bool {

1658 int64_t Value = CE->getValue();

1659 if (Negate)

1662 return true;

1663 }

1664 return false;

1665 };

1666

1667

1668

1670 if (isParsingHLASM())

1671 return Error(StartLoc, "Expected PC-relative expression");

1672 if (IsOutOfRangeConstant(CE, false))

1673 return Error(StartLoc, "offset out of range");

1674 int64_t Value = CE->getValue();

1679 }

1680

1681

1682

1684 if (IsOutOfRangeConstant(BE->getLHS(), false) ||

1685 IsOutOfRangeConstant(BE->getRHS(),

1687 return Error(StartLoc, "offset out of range");

1688

1689

1690 const MCExpr *Sym = nullptr;

1692 Parser.Lex();

1693

1696

1699 if (Name == "tls_gdcall")

1701 else if (Name == "tls_ldcall")

1703 else

1705 Parser.Lex();

1706

1709 Parser.Lex();

1710

1713

1716 Kind, Ctx);

1717 Parser.Lex();

1718 }

1719

1720 SMLoc EndLoc =

1722

1723 if (AllowTLS)

1724 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,

1725 StartLoc, EndLoc));

1726 else

1727 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));

1728

1730}

1731

1732bool SystemZAsmParser::isLabel(AsmToken &Token) {

1733 if (isParsingGNU())

1734 return true;

1735

1736

1737

1738

1739

1740

1741

1742

1743

1744

1745

1746

1747 StringRef RawLabel = Token.getString();

1748 SMLoc Loc = Token.getLoc();

1749

1750

1751 if (!RawLabel.size())

1752 return Error(Loc, "HLASM Label cannot be empty");

1753

1754

1755 if (RawLabel.size() > 63)

1756 return Error(Loc, "Maximum length for HLASM Label is 63 characters");

1757

1758

1759 if (!isHLASMAlpha(RawLabel[0]))

1760 return Error(Loc, "HLASM Label has to start with an alphabetic "

1761 "character or the underscore character");

1762

1763

1764

1765

1766 for (unsigned I = 1; I < RawLabel.size(); ++I)

1767 if (!isHLASMAlnum(RawLabel[I]))

1768 return Error(Loc, "HLASM Label has to be alphanumeric");

1769

1770 return true;

1771}

1772

1773

1774

static const char * getSubtargetFeatureName(uint64_t Val)

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

static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)

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

#define LLVM_EXTERNAL_VISIBILITY

Promote Memory to Register

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

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

This file defines the SmallVector class.

static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue, bool AllowSymbol=false)

Definition SystemZAsmParser.cpp:49

LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmParser()

Definition SystemZAsmParser.cpp:1776

static struct InsnMatchEntry InsnMatchTable[]

Definition SystemZAsmParser.cpp:665

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

LLVM_ABI SMLoc getLoc() 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

StringRef getIdentifier() const

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

constexpr size_t size() const

This class is intended to be used as a base class for asm properties and features specific to the tar...

void printExpr(raw_ostream &, const MCExpr &) const

virtual void Initialize(MCAsmParser &Parser)

Initialize the extension for parsing using the given Parser.

Generic assembler parser interface, for use by target specific assembly parsers.

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 parseIdentifier(StringRef &Res)=0

Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.

virtual const AsmToken & Lex()=0

Get the next AsmToken in the stream, possibly handling file inclusion first.

virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0

bool parseGNUAttribute(SMLoc L, int64_t &Tag, int64_t &IntegerValue)

Parse a .gnu_attribute.

MCStreamer & getStreamer()

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

LLVM_ABI MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

Base class for the full range of assembler expressions which are needed for parsing.

void addOperand(const MCOperand Op)

static MCOperand createExpr(const MCExpr *Val)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.

virtual SMLoc getStartLoc() const =0

getStartLoc - Get the location of the first token of this operand.

virtual void emitGNUAttribute(unsigned Tag, unsigned Value)

Emit a .gnu_attribute directive.

virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)

Emit the given Instruction into the current section.

virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())

Emit a label for Symbol into the current section.

const FeatureBitset & getFeatureBits() const

void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)

Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())

MCTargetAsmParser - Generic interface to target specific assembly parsers.

constexpr bool isFailure() const

static constexpr StatusTy Failure

constexpr bool isSuccess() const

static constexpr StatusTy Success

static constexpr StatusTy NoMatch

static SMLoc getFromPointer(const char *Ptr)

constexpr const char * getPointer() const

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr size_t size() const

size - Get the string size.

static const char * getRegisterName(MCRegister Reg)

LLVM Value Representation.

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

#define llvm_unreachable(msg)

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

@ C

The default llvm calling convention, compatible with C.

const unsigned GR64Regs[16]

const unsigned VR128Regs[32]

const unsigned VR16Regs[32]

const unsigned GR128Regs[16]

const unsigned GRH32Regs[16]

const unsigned FP32Regs[16]

const unsigned FP16Regs[16]

const unsigned GR32Regs[16]

const unsigned FP64Regs[16]

const unsigned VR64Regs[32]

const unsigned FP128Regs[16]

const unsigned AR32Regs[16]

const unsigned VR32Regs[32]

const unsigned CR64Regs[16]

@ CE

Windows NT (Windows on ARM)

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

Target & getTheSystemZTarget()

FunctionAddr VTableAddr Value

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)

static bool isMem(const MachineInstr &MI, unsigned Op)

LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")

getToken - This function extracts one token from source, ignoring any leading characters that appear ...

decltype(auto) dyn_cast(const From &Val)

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

SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector

bool isAlpha(char C)

Checks if character C is a valid letter as classified by "C" locale.

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

bool isDigit(char C)

Checks if character C is one of the 10 decimal digits.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

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

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

bool operator()(const InsnMatchEntry &LHS, StringRef RHS)

Definition SystemZAsmParser.cpp:653

Definition SystemZAsmParser.cpp:644

MatchClassKind OperandKinds[7]

Definition SystemZAsmParser.cpp:648

StringRef Format

Definition SystemZAsmParser.cpp:645

int32_t NumOperands

Definition SystemZAsmParser.cpp:647

uint64_t Opcode

Definition SystemZAsmParser.cpp:646

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