llvm.org GIT mirror llvm / 515d509
More bits of the ARM target assembler for llvm-mc, code added to parse labels as expressions, code for parsing a few arm specific directives (still needs the MCStreamer calls for these). Some clean up of the operand parsing code and adding some comments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84201 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 11 years ago
1 changed file(s) with 130 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
5454 bool ParseOperand(ARMOperand &Op);
5555
5656 bool ParseDirectiveWord(unsigned Size, SMLoc L);
57
58 bool ParseDirectiveThumb(SMLoc L);
59
60 bool ParseDirectiveThumbFunc(SMLoc L);
61
62 bool ParseDirectiveCode(SMLoc L);
63
64 bool ParseDirectiveSyntax(SMLoc L);
5765
5866 // TODO - For now hacked versions of the next two are in here in this file to
5967 // allow some parser testing until the table gen versions are implemented.
229237 return false;
230238 }
231239
232 // Try to parse a register list. The first token must be a '{' when called
233 // for now.
240 // Parse a register list, return false if successful else return true or an
241 // error. The first token must be a '{' when called.
234242 bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
235243 assert(getLexer().getTok().is(AsmToken::LCurly) &&
236244 "Token is not an Left Curly Brace");
276284 return false;
277285 }
278286
279 // Try to parse an arm memory expression. It must start with a '[' token.
287 // Parse an arm memory expression, return false if successful else return true
288 // or an error. The first token must be a '[' when called.
280289 // TODO Only preindexing and postindexing addressing are started, unindexed
281290 // with option, etc are still to do.
282291 bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
464473 return false;
465474 }
466475
467 // A hack to allow some testing
476 // A hack to allow some testing, to be replaced by a real table gen version.
468477 int ARMAsmParser::MatchRegisterName(const StringRef &Name) {
469478 if (Name == "r0" || Name == "R0")
470479 return 0;
503512 return -1;
504513 }
505514
506 // A hack to allow some testing
515 // A hack to allow some testing, to be replaced by a real table gen version.
507516 bool ARMAsmParser::MatchInstruction(SmallVectorImpl &Operands,
508517 MCInst &Inst) {
509518 struct ARMOperand Op0 = Operands[0];
515524 Mnemonic == "ldmfd" ||
516525 Mnemonic == "ldr" ||
517526 Mnemonic == "mov" ||
518 Mnemonic == "sub")
527 Mnemonic == "sub" ||
528 Mnemonic == "bl" ||
529 Mnemonic == "push" ||
530 Mnemonic == "blx" ||
531 Mnemonic == "pop")
519532 return false;
520533
521534 return true;
522535 }
523536
524 // TODO - this is a work in progress
537 // Parse a arm instruction operand. For now this parses the operand regardless
538 // of the mnemonic.
525539 bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
526540 switch (getLexer().getKind()) {
527541 case AsmToken::Identifier:
528542 if (!ParseRegister(Op))
529543 return false;
530 // TODO parse other operands that start with an identifier like labels
531 return Error(getLexer().getTok().getLoc(), "labels not yet supported");
544 // This was not a register so parse other operands that start with an
545 // identifier (like labels) as expressions and create them as immediates.
546 const MCExpr *IdVal;
547 if (getParser().ParseExpression(IdVal))
548 return true;
549 Op = ARMOperand::CreateImm(IdVal);
550 return false;
532551 case AsmToken::LBrac:
533 if (!ParseMemory(Op))
534 return false;
552 return ParseMemory(Op);
535553 case AsmToken::LCurly:
536 if (!ParseRegisterList(Op))
537 return false;
554 return ParseRegisterList(Op);
538555 case AsmToken::Hash:
539556 // #42 -> immediate.
540557 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
541558 getLexer().Lex();
542 const MCExpr *Val;
543 if (getParser().ParseExpression(Val))
559 const MCExpr *ImmVal;
560 if (getParser().ParseExpression(ImmVal))
544561 return true;
545 Op = ARMOperand::CreateImm(Val);
562 Op = ARMOperand::CreateImm(ImmVal);
546563 return false;
547564 default:
548565 return Error(getLexer().getTok().getLoc(), "unexpected token in operand");
549566 }
550567 }
551568
569 // Parse an arm instruction mnemonic followed by its operands.
552570 bool ARMAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) {
553571 SmallVector Operands;
554572
578596 return true;
579597 }
580598
599 /// ParseDirective parses the arm specific directives
581600 bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
582601 StringRef IDVal = DirectiveID.getIdentifier();
583602 if (IDVal == ".word")
584603 return ParseDirectiveWord(4, DirectiveID.getLoc());
604 else if (IDVal == ".thumb")
605 return ParseDirectiveThumb(DirectiveID.getLoc());
606 else if (IDVal == ".thumb_func")
607 return ParseDirectiveThumbFunc(DirectiveID.getLoc());
608 else if (IDVal == ".code")
609 return ParseDirectiveCode(DirectiveID.getLoc());
610 else if (IDVal == ".syntax")
611 return ParseDirectiveSyntax(DirectiveID.getLoc());
585612 return true;
586613 }
587614
610637 return false;
611638 }
612639
640 /// ParseDirectiveThumb
641 /// ::= .thumb
642 bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
643 if (getLexer().isNot(AsmToken::EndOfStatement))
644 return Error(L, "unexpected token in directive");
645 getLexer().Lex();
646
647 // TODO: set thumb mode
648 // TODO: tell the MC streamer the mode
649 // getParser().getStreamer().Emit???();
650 return false;
651 }
652
653 /// ParseDirectiveThumbFunc
654 /// ::= .thumbfunc symbol_name
655 bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
656 const AsmToken &Tok = getLexer().getTok();
657 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
658 return Error(L, "unexpected token in .syntax directive");
659 StringRef SymbolName = getLexer().getTok().getIdentifier();
660 getLexer().Lex(); // Consume the identifier token.
661
662 if (getLexer().isNot(AsmToken::EndOfStatement))
663 return Error(L, "unexpected token in directive");
664 getLexer().Lex();
665
666 // TODO: mark symbol as a thumb symbol
667 // getParser().getStreamer().Emit???();
668 return false;
669 }
670
671 /// ParseDirectiveSyntax
672 /// ::= .syntax unified | divided
673 bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
674 const AsmToken &Tok = getLexer().getTok();
675 if (Tok.isNot(AsmToken::Identifier))
676 return Error(L, "unexpected token in .syntax directive");
677 const StringRef &Mode = Tok.getString();
678 bool unified_syntax;
679 if (Mode == "unified" || Mode == "UNIFIED") {
680 getLexer().Lex();
681 unified_syntax = true;
682 }
683 else if (Mode == "divided" || Mode == "DIVIDED") {
684 getLexer().Lex();
685 unified_syntax = false;
686 }
687 else
688 return Error(L, "unrecognized syntax mode in .syntax directive");
689
690 if (getLexer().isNot(AsmToken::EndOfStatement))
691 return Error(getLexer().getTok().getLoc(), "unexpected token in directive");
692 getLexer().Lex();
693
694 // TODO tell the MC streamer the mode
695 // getParser().getStreamer().Emit???();
696 return false;
697 }
698
699 /// ParseDirectiveCode
700 /// ::= .code 16 | 32
701 bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
702 const AsmToken &Tok = getLexer().getTok();
703 if (Tok.isNot(AsmToken::Integer))
704 return Error(L, "unexpected token in .code directive");
705 int64_t Val = getLexer().getTok().getIntVal();
706 bool thumb_mode;
707 if (Val == 16) {
708 getLexer().Lex();
709 thumb_mode = true;
710 }
711 else if (Val == 32) {
712 getLexer().Lex();
713 thumb_mode = false;
714 }
715 else
716 return Error(L, "invalid operand to .code directive");
717
718 if (getLexer().isNot(AsmToken::EndOfStatement))
719 return Error(getLexer().getTok().getLoc(), "unexpected token in directive");
720 getLexer().Lex();
721
722 // TODO tell the MC streamer the mode
723 // getParser().getStreamer().Emit???();
724 return false;
725 }
726
613727 // Force static initialization.
614728 extern "C" void LLVMInitializeARMAsmParser() {
615729 RegisterAsmParser X(TheARMTarget);