22 #define DEBUG_TYPE "m68k-asm-parser"
28 cl::desc(
"Enable specifying registers without the % prefix"),
38 #define GET_ASSEMBLER_HEADER
39 #include "M68kGenAsmMatcher.inc"
46 bool parseRegisterName(
unsigned int &RegNo,
SMLoc Loc,
63 MRI = getContext().getRegisterInfo();
65 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
69 unsigned Kind)
override;
70 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
72 SMLoc &EndLoc)
override;
75 bool ParseDirective(
AsmToken DirectiveID)
override;
76 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
79 bool MatchingInlineAsm)
override;
90 RegIndirectDisplacement,
91 RegIndirectDisplacementIndex,
141 template <
unsigned N>
bool isAddrN()
const;
147 SMLoc getStartLoc()
const override {
return Start; }
148 SMLoc getEndLoc()
const override {
return End; }
152 bool isMem()
const override {
return false; }
153 bool isMemOp()
const {
return Kind == KindTy::MemOp; }
158 bool isReg()
const override;
161 unsigned getReg()
const override;
162 void addRegOperands(
MCInst &Inst,
unsigned N)
const;
164 static std::unique_ptr<M68kOperand> createMemOp(M68kMemOp
MemOp,
SMLoc Start,
168 bool isToken()
const override;
170 static std::unique_ptr<M68kOperand> createToken(
StringRef Token,
SMLoc Start,
174 bool isImm()
const override;
175 void addImmOperands(
MCInst &Inst,
unsigned N)
const;
177 static std::unique_ptr<M68kOperand> createImm(
const MCExpr *Expr,
SMLoc Start,
181 bool isMoveMask()
const;
182 void addMoveMaskOperands(
MCInst &Inst,
unsigned N)
const;
186 bool isAddr8()
const {
return isAddrN<8>(); }
187 bool isAddr16()
const {
return isAddrN<16>(); }
188 bool isAddr32()
const {
return isAddrN<32>(); }
189 void addAddrOperands(
MCInst &Inst,
unsigned N)
const;
193 void addARIOperands(
MCInst &Inst,
unsigned N)
const;
197 void addARIDOperands(
MCInst &Inst,
unsigned N)
const;
201 void addARIIOperands(
MCInst &Inst,
unsigned N)
const;
204 bool isARIPD()
const;
205 void addARIPDOperands(
MCInst &Inst,
unsigned N)
const;
208 bool isARIPI()
const;
209 void addARIPIOperands(
MCInst &Inst,
unsigned N)
const;
213 void addPCDOperands(
MCInst &Inst,
unsigned N)
const;
217 void addPCIOperands(
MCInst &Inst,
unsigned N)
const;
226 #define GET_MATCHER_IMPLEMENTATION
227 #include "M68kGenAsmMatcher.inc"
230 static unsigned RegistersByIndex[] = {
231 M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5,
232 M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3,
233 M68k::A4, M68k::A5, M68k::A6, M68k::SP,
236 sizeof(RegistersByIndex) /
sizeof(RegistersByIndex[0]));
237 return RegistersByIndex[RegisterIndex];
266 OS <<
"RegMask(" <<
format(
"%04x", RegMask) <<
")";
269 OS <<
'%' << OuterReg;
271 case Kind::RegIndirect:
272 OS <<
"(%" << OuterReg <<
')';
274 case Kind::RegPostIncrement:
275 OS <<
"(%" << OuterReg <<
")+";
277 case Kind::RegPreDecrement:
278 OS <<
"-(%" << OuterReg <<
")";
280 case Kind::RegIndirectDisplacement:
281 OS << OuterDisp <<
"(%" << OuterReg <<
")";
283 case Kind::RegIndirectDisplacementIndex:
284 OS << OuterDisp <<
"(%" << OuterReg <<
", " << InnerReg <<
"." <<
Size
285 <<
", " << InnerDisp <<
")";
290 void M68kOperand::addExpr(
MCInst &Inst,
const MCExpr *Expr) {
291 if (
auto Const = dyn_cast<MCConstantExpr>(Expr)) {
306 return MemOp.OuterReg;
309 void M68kOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
311 assert((
N == 1) &&
"can only handle one register operand");
316 std::unique_ptr<M68kOperand> M68kOperand::createMemOp(M68kMemOp
MemOp,
318 auto Op = std::make_unique<M68kOperand>(KindTy::MemOp, Start, End);
324 bool M68kOperand::isToken()
const {
return Kind == KindTy::Token; }
325 StringRef M68kOperand::getToken()
const {
330 std::unique_ptr<M68kOperand> M68kOperand::createToken(
StringRef Token,
332 auto Op = std::make_unique<M68kOperand>(KindTy::Token, Start, End);
339 void M68kOperand::addImmOperands(
MCInst &Inst,
unsigned N)
const {
341 assert((
N == 1) &&
"can only handle one register operand");
343 M68kOperand::addExpr(Inst, Expr);
346 std::unique_ptr<M68kOperand> M68kOperand::createImm(
const MCExpr *Expr,
348 auto Op = std::make_unique<M68kOperand>(
KindTy::Imm, Start, End);
354 bool M68kOperand::isMoveMask()
const {
358 if (
MemOp.Op == M68kMemOp::Kind::RegMask)
369 void M68kOperand::addMoveMaskOperands(
MCInst &Inst,
unsigned N)
const {
370 assert(isMoveMask() &&
"wrong operand kind");
371 assert((
N == 1) &&
"can only handle one immediate operand");
381 bool M68kOperand::isAddr()
const {
386 template <
unsigned N>
bool M68kOperand::isAddrN()
const {
389 if (
MemOp.OuterDisp->evaluateAsAbsolute(Res))
390 return isInt<N>(Res);
395 void M68kOperand::addAddrOperands(
MCInst &Inst,
unsigned N)
const {
396 M68kOperand::addExpr(Inst,
MemOp.OuterDisp);
400 bool M68kOperand::isARI()
const {
401 return isMemOp() &&
MemOp.Op == M68kMemOp::Kind::RegIndirect &&
402 M68k::AR32RegClass.contains(
MemOp.OuterReg);
404 void M68kOperand::addARIOperands(
MCInst &Inst,
unsigned N)
const {
409 bool M68kOperand::isARID()
const {
410 return isMemOp() &&
MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacement &&
411 M68k::AR32RegClass.contains(
MemOp.OuterReg);
413 void M68kOperand::addARIDOperands(
MCInst &Inst,
unsigned N)
const {
414 M68kOperand::addExpr(Inst,
MemOp.OuterDisp);
419 bool M68kOperand::isARII()
const {
421 MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacementIndex &&
422 M68k::AR32RegClass.contains(
MemOp.OuterReg);
424 void M68kOperand::addARIIOperands(
MCInst &Inst,
unsigned N)
const {
425 M68kOperand::addExpr(Inst,
MemOp.OuterDisp);
431 bool M68kOperand::isARIPD()
const {
432 return isMemOp() &&
MemOp.Op == M68kMemOp::Kind::RegPreDecrement &&
433 M68k::AR32RegClass.contains(
MemOp.OuterReg);
435 void M68kOperand::addARIPDOperands(
MCInst &Inst,
unsigned N)
const {
440 bool M68kOperand::isARIPI()
const {
441 return isMemOp() &&
MemOp.Op == M68kMemOp::Kind::RegPostIncrement &&
442 M68k::AR32RegClass.contains(
MemOp.OuterReg);
444 void M68kOperand::addARIPIOperands(
MCInst &Inst,
unsigned N)
const {
449 bool M68kOperand::isPCD()
const {
450 return isMemOp() &&
MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacement &&
451 MemOp.OuterReg == M68k::PC;
453 void M68kOperand::addPCDOperands(
MCInst &Inst,
unsigned N)
const {
454 M68kOperand::addExpr(Inst,
MemOp.OuterDisp);
458 bool M68kOperand::isPCI()
const {
460 MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacementIndex &&
461 MemOp.OuterReg == M68k::PC;
463 void M68kOperand::addPCIOperands(
MCInst &Inst,
unsigned N)
const {
464 M68kOperand::addExpr(Inst,
MemOp.OuterDisp);
503 bool M68kOperand::isAReg()
const {
509 bool M68kOperand::isDReg()
const {
517 M68kOperand &Operand = (M68kOperand &)
Op;
522 if (Operand.isReg() &&
524 return Match_Success;
530 if (Operand.isReg() &&
532 return Match_Success;
537 if (Operand.isReg() &&
539 return Match_Success;
546 if (Operand.isReg() &&
548 return Match_Success;
553 if (Operand.isReg() &&
554 ((Operand.getReg() == M68k::A0) || (Operand.getReg() == M68k::A1))) {
555 return Match_Success;
560 if (Operand.isReg() &&
561 ((Operand.getReg() == M68k::D0) || (Operand.getReg() == M68k::D1))) {
562 return Match_Success;
567 if (Operand.isReg() &&
568 ((Operand.getReg() == M68k::D0) || (Operand.getReg() == M68k::D1) ||
569 (Operand.getReg() == M68k::A0) || (Operand.getReg() == M68k::A1))) {
570 return Match_Success;
575 return Match_InvalidOperand;
578 bool M68kAsmParser::parseRegisterName(
unsigned &RegNo,
SMLoc Loc,
580 auto RegisterNameLower = RegisterName.
lower();
583 if (RegisterNameLower ==
"ccr") {
589 if (RegisterNameLower.size() == 2) {
591 switch (RegisterNameLower[0]) {
594 if (isdigit(RegisterNameLower[1])) {
595 unsigned IndexOffset = (RegisterNameLower[0] ==
'a') ? 8 : 0;
596 unsigned RegIndex = (unsigned)(RegisterNameLower[1] -
'0');
606 if (RegisterNameLower[1] ==
'p') {
609 }
else if (RegisterNameLower[1] ==
'r') {
616 if (RegisterNameLower[1] ==
'c') {
628 bool HasPercent =
false;
635 PercentToken = Lex();
642 getLexer().UnLex(PercentToken);
648 if (!parseRegisterName(RegNo, Parser.
getLexer().
getLoc(), RegisterName)) {
650 getLexer().UnLex(PercentToken);
659 bool M68kAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
661 auto Result = tryParseRegister(RegNo, StartLoc, EndLoc);
663 return Error(StartLoc,
"expected register");
672 StartLoc = getLexer().getLoc();
673 auto Result = parseRegister(RegNo);
674 EndLoc = getLexer().getLoc();
678 bool M68kAsmParser::isExpr() {
695 SMLoc Start = getLexer().getLoc();
701 if (getParser().parseExpression(Expr, End)) {
705 Operands.push_back(M68kOperand::createImm(Expr, Start, End));
710 SMLoc Start = getLexer().getLoc();
721 bool HasDisplacement =
false;
725 }
else if (isExpr()) {
729 HasDisplacement =
true;
733 if (HasDisplacement) {
736 M68kOperand::createMemOp(
MemOp, Start, getLexer().getLoc()));
739 Error(getLexer().getLoc(),
"expected (");
748 if (!HasDisplacement && isExpr()) {
752 HasDisplacement =
true;
758 M68kOperand::createMemOp(
MemOp, Start, getLexer().getLoc()));
771 Error(getLexer().getLoc(),
"expected register");
786 Error(getLexer().getLoc(),
"expected register");
798 Error(getLexer().getLoc(),
"expected )");
809 SMLoc End = getLexer().getLoc();
811 unsigned OpCount = IsPD + IsPI + (
HasIndex || HasDisplacement);
813 Error(Start,
"only one of post-increment, pre-decrement or displacement "
819 MemOp.Op = M68kMemOp::Kind::RegPreDecrement;
821 MemOp.Op = M68kMemOp::Kind::RegPostIncrement;
823 MemOp.Op = M68kMemOp::Kind::RegIndirectDisplacementIndex;
824 }
else if (HasDisplacement) {
825 MemOp.Op = M68kMemOp::Kind::RegIndirectDisplacement;
827 MemOp.Op = M68kMemOp::Kind::RegIndirect;
830 Operands.push_back(M68kOperand::createMemOp(
MemOp, Start, End));
836 SMLoc Start = getLexer().getLoc();
837 M68kMemOp
MemOp(M68kMemOp::Kind::RegMask);
841 bool IsFirstRegister =
842 (
MemOp.Op == M68kMemOp::Kind::RegMask) && (
MemOp.RegMask == 0);
844 unsigned FirstRegister;
845 auto Result = parseRegister(FirstRegister);
850 Error(getLexer().getLoc(),
"expected start register");
854 unsigned LastRegister = FirstRegister;
857 Result = parseRegister(LastRegister);
859 Error(getLexer().getLoc(),
"expected end register");
867 uint16_t NumNewBits = LastRegisterIndex - FirstRegisterIndex + 1;
868 uint16_t NewMaskBits = ((1 << NumNewBits) - 1) << FirstRegisterIndex;
870 if (IsFirstRegister && (FirstRegister == LastRegister)) {
874 MemOp.OuterReg = FirstRegister;
879 MemOp.Op = M68kMemOp::Kind::RegMask;
882 if (
MemOp.RegMask == 0) {
883 Error(getLexer().getLoc(),
884 "special registers cannot be used in register masks");
889 if ((FirstRegisterIndex >= 16) || (LastRegisterIndex >= 16)) {
890 Error(getLexer().getLoc(),
891 "special registers cannot be used in register masks");
895 if (NewMaskBits &
MemOp.RegMask) {
896 Error(getLexer().getLoc(),
"conflicting masked registers");
900 MemOp.RegMask |= NewMaskBits;
911 M68kOperand::createMemOp(
MemOp, Start, getLexer().getLoc()));
915 void M68kAsmParser::eatComma() {
923 SMLoc Start = getLexer().getLoc();
924 Operands.push_back(M68kOperand::createToken(
Name, Start, Start));
934 auto MatchResult = MatchOperandParserImpl(
Operands,
Name);
940 SMLoc Loc = getLexer().getLoc();
942 return Error(Loc,
"unexpected token parsing operands");
950 bool M68kAsmParser::ParseDirective(
AsmToken DirectiveID) {
return true; }
952 bool M68kAsmParser::invalidOperand(
SMLoc const &Loc,
955 SMLoc ErrorLoc = Loc;
956 char const *Diag = 0;
960 Diag =
"too few operands for instruction.";
963 if (
Op.getStartLoc() !=
SMLoc()) {
964 ErrorLoc =
Op.getStartLoc();
970 Diag =
"invalid operand for instruction";
973 return Error(ErrorLoc, Diag);
976 bool M68kAsmParser::missingFeature(
llvm::SMLoc const &Loc,
978 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
981 bool M68kAsmParser::emit(
MCInst &Inst,
SMLoc const &Loc,
989 bool M68kAsmParser::MatchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
993 bool MatchingInlineAsm) {
995 unsigned MatchResult =
998 switch (MatchResult) {
1000 return emit(Inst, Loc, Out);
1001 case Match_MissingFeature:
1003 case Match_InvalidOperand:
1005 case Match_MnemonicFail:
1006 return Error(Loc,
"invalid instruction");
1019 OS <<
"token '" << Token <<
"'";
1023 OS <<
"immediate " <<
Imm;