280 return false; 281 } 282 case AsmToken::Integer: 283 Res = MCConstantExpr::Create(getTok().getIntVal(), getContext()); 284 EndLoc = Lexer.getLoc(); 285 Lex(); // Eat token. 286 return false; 287 case AsmToken::LParen: 288 Lex(); // Eat the '('. 289 return ParseParenExpr(Res, EndLoc); 290 case AsmToken::Minus: 291 Lex(); // Eat the operator. 292 if (ParsePrimaryExpr(Res, EndLoc)) 293 return true; 294 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 295 return false; 296 case AsmToken::Plus: 297 Lex(); // Eat the operator. 298 if (ParsePrimaryExpr(Res, EndLoc)) 299 return true; 300 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 301 return false; 302 case AsmToken::Tilde: 303 Lex(); // Eat the operator. 304 if (ParsePrimaryExpr(Res, EndLoc)) 305 return true; 306 Res = MCUnaryExpr::CreateNot(Res, getContext()); 307 return false; 308 } 309} 310 311bool AsmParser::ParseExpression(const MCExpr *&Res) { 312 SMLoc EndLoc; 313 return ParseExpression(Res, EndLoc); 314} 315 316/// ParseExpression - Parse an expression and return it. 317/// 318/// expr ::= expr +,- expr -> lowest. 319/// expr ::= expr |,^,&,! expr -> middle. 320/// expr ::= expr *,/,%,<<,>> expr -> highest. 321/// expr ::= primaryexpr 322/// 323bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 324 // Parse the expression. 325 Res = 0; 326 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc)) 327 return true; 328 329 // Try to constant fold it up front, if possible. 330 int64_t Value; 331 if (Res->EvaluateAsAbsolute(Value)) 332 Res = MCConstantExpr::Create(Value, getContext()); 333 334 return false; 335} 336 337bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 338 Res = 0; 339 return ParseParenExpr(Res, EndLoc) || 340 ParseBinOpRHS(1, Res, EndLoc); 341} 342 343bool AsmParser::ParseAbsoluteExpression(int64_t &Res) { 344 const MCExpr *Expr; 345 346 SMLoc StartLoc = Lexer.getLoc(); 347 if (ParseExpression(Expr)) 348 return true; 349 350 if (!Expr->EvaluateAsAbsolute(Res)) 351 return Error(StartLoc, "expected absolute expression"); 352 353 return false; 354} 355 356static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 357 MCBinaryExpr::Opcode &Kind) { 358 switch (K) { 359 default: 360 return 0; // not a binop. 361 362 // Lowest Precedence: &&, || 363 case AsmToken::AmpAmp: 364 Kind = MCBinaryExpr::LAnd; 365 return 1; 366 case AsmToken::PipePipe: 367 Kind = MCBinaryExpr::LOr; 368 return 1; 369 370 // Low Precedence: +, -, ==, !=, <>, <, <=, >, >= 371 case AsmToken::Plus: 372 Kind = MCBinaryExpr::Add; 373 return 2; 374 case AsmToken::Minus: 375 Kind = MCBinaryExpr::Sub; 376 return 2; 377 case AsmToken::EqualEqual: 378 Kind = MCBinaryExpr::EQ; 379 return 2; 380 case AsmToken::ExclaimEqual: 381 case AsmToken::LessGreater: 382 Kind = MCBinaryExpr::NE; 383 return 2; 384 case AsmToken::Less: 385 Kind = MCBinaryExpr::LT; 386 return 2; 387 case AsmToken::LessEqual: 388 Kind = MCBinaryExpr::LTE; 389 return 2; 390 case AsmToken::Greater: 391 Kind = MCBinaryExpr::GT; 392 return 2; 393 case AsmToken::GreaterEqual: 394 Kind = MCBinaryExpr::GTE; 395 return 2; 396 397 // Intermediate Precedence: |, &, ^ 398 // 399 // FIXME: gas seems to support '!' as an infix operator? 400 case AsmToken::Pipe: 401 Kind = MCBinaryExpr::Or; 402 return 3; 403 case AsmToken::Caret: 404 Kind = MCBinaryExpr::Xor; 405 return 3; 406 case AsmToken::Amp: 407 Kind = MCBinaryExpr::And; 408 return 3; 409 410 // Highest Precedence: *, /, %, <<, >> 411 case AsmToken::Star: 412 Kind = MCBinaryExpr::Mul; 413 return 4; 414 case AsmToken::Slash: 415 Kind = MCBinaryExpr::Div; 416 return 4; 417 case AsmToken::Percent: 418 Kind = MCBinaryExpr::Mod; 419 return 4; 420 case AsmToken::LessLess: 421 Kind = MCBinaryExpr::Shl; 422 return 4; 423 case AsmToken::GreaterGreater: 424 Kind = MCBinaryExpr::Shr; 425 return 4; 426 } 427} 428 429 430/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. 431/// Res contains the LHS of the expression on input. 432bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 433 SMLoc &EndLoc) { 434 while (1) { 435 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 436 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 437 438 // If the next token is lower precedence than we are allowed to eat, return 439 // successfully with what we ate already. 440 if (TokPrec < Precedence) 441 return false; 442 443 Lex(); 444 445 // Eat the next primary expression. 446 const MCExpr *RHS; 447 if (ParsePrimaryExpr(RHS, EndLoc)) return true; 448 449 // If BinOp binds less tightly with RHS than the operator after RHS, let 450 // the pending operator take RHS as its LHS. 451 MCBinaryExpr::Opcode Dummy; 452 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 453 if (TokPrec < NextTokPrec) { 454 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true; 455 } 456 457 // Merge LHS and RHS according to operator. 458 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 459 } 460} 461 462 463 464 465/// ParseStatement: 466/// ::= EndOfStatement 467/// ::= Label* Directive ...Operands... EndOfStatement 468/// ::= Label* Identifier OperandList* EndOfStatement 469bool AsmParser::ParseStatement() { 470 if (Lexer.is(AsmToken::EndOfStatement)) { 471 Lex(); 472 return false; 473 } 474 475 // Statements always start with an identifier. 476 AsmToken ID = getTok(); 477 SMLoc IDLoc = ID.getLoc(); 478 StringRef IDVal; 479 if (ParseIdentifier(IDVal)) 480 return TokError("unexpected token at start of statement"); 481 482 // FIXME: Recurse on local labels? 483 484 // See what kind of statement we have. 485 switch (Lexer.getKind()) { 486 case AsmToken::Colon: { 487 // identifier ':' -> Label. 488 Lex(); 489 490 // Diagnose attempt to use a variable as a label. 491 // 492 // FIXME: Diagnostics. Note the location of the definition as a label. 493 // FIXME: This doesn't diagnose assignment to a symbol which has been 494 // implicitly marked as external. 495 MCSymbol *Sym = CreateSymbol(IDVal); 496 if (!Sym->isUndefined()) 497 return Error(IDLoc, "invalid symbol redefinition"); 498 499 // Emit the label. 500 Out.EmitLabel(Sym); 501 502 return ParseStatement(); 503 } 504 505 case AsmToken::Equal: 506 // identifier '=' ... -> assignment statement 507 Lex(); 508 509 return ParseAssignment(IDVal); 510 511 default: // Normal instruction or directive. 512 break; 513 } 514 515 // Otherwise, we have a normal instruction or directive. 516 if (IDVal[0] == '.') { 517 // FIXME: This should be driven based on a hash lookup and callback. 518 if (IDVal == ".section") 519 return ParseDirectiveDarwinSection(); 520 if (IDVal == ".text") 521 // FIXME: This changes behavior based on the -static flag to the 522 // assembler. 523 return ParseDirectiveSectionSwitch("__TEXT", "__text", 524 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); 525 if (IDVal == ".const") 526 return ParseDirectiveSectionSwitch("__TEXT", "__const"); 527 if (IDVal == ".static_const") 528 return ParseDirectiveSectionSwitch("__TEXT", "__static_const"); 529 if (IDVal == ".cstring") 530 return ParseDirectiveSectionSwitch("__TEXT","__cstring", 531 MCSectionMachO::S_CSTRING_LITERALS); 532 if (IDVal == ".literal4") 533 return ParseDirectiveSectionSwitch("__TEXT", "__literal4", 534 MCSectionMachO::S_4BYTE_LITERALS, 535 4); 536 if (IDVal == ".literal8") 537 return ParseDirectiveSectionSwitch("__TEXT", "__literal8", 538 MCSectionMachO::S_8BYTE_LITERALS, 539 8); 540 if (IDVal == ".literal16") 541 return ParseDirectiveSectionSwitch("__TEXT","__literal16", 542 MCSectionMachO::S_16BYTE_LITERALS, 543 16); 544 if (IDVal == ".constructor") 545 return ParseDirectiveSectionSwitch("__TEXT","__constructor"); 546 if (IDVal == ".destructor") 547 return ParseDirectiveSectionSwitch("__TEXT","__destructor"); 548 if (IDVal == ".fvmlib_init0") 549 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0"); 550 if (IDVal == ".fvmlib_init1") 551 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1"); 552 553 // FIXME: The assembler manual claims that this has the self modify code 554 // flag, at least on x86-32, but that does not appear to be correct. 555 if (IDVal == ".symbol_stub") 556 return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub", 557 MCSectionMachO::S_SYMBOL_STUBS | 558 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 559 // FIXME: Different on PPC and ARM. 560 0, 16); 561 // FIXME: PowerPC only? 562 if (IDVal == ".picsymbol_stub") 563 return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub", 564 MCSectionMachO::S_SYMBOL_STUBS | 565 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 566 0, 26); 567 if (IDVal == ".data") 568 return ParseDirectiveSectionSwitch("__DATA", "__data"); 569 if (IDVal == ".static_data") 570 return ParseDirectiveSectionSwitch("__DATA", "__static_data"); 571 572 // FIXME: The section names of these two are misspelled in the assembler 573 // manual. 574 if (IDVal == ".non_lazy_symbol_pointer") 575 return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr", 576 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 577 4); 578 if (IDVal == ".lazy_symbol_pointer") 579 return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr", 580 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 581 4); 582 583 if (IDVal == ".dyld") 584 return ParseDirectiveSectionSwitch("__DATA", "__dyld"); 585 if (IDVal == ".mod_init_func") 586 return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func", 587 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 588 4); 589 if (IDVal == ".mod_term_func") 590 return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func", 591 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 592 4); 593 if (IDVal == ".const_data") 594 return ParseDirectiveSectionSwitch("__DATA", "__const"); 595 596 597 if (IDVal == ".objc_class") 598 return ParseDirectiveSectionSwitch("__OBJC", "__class", 599 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 600 if (IDVal == ".objc_meta_class") 601 return ParseDirectiveSectionSwitch("__OBJC", "__meta_class", 602 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 603 if (IDVal == ".objc_cat_cls_meth") 604 return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth", 605 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 606 if (IDVal == ".objc_cat_inst_meth") 607 return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth", 608 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 609 if (IDVal == ".objc_protocol") 610 return ParseDirectiveSectionSwitch("__OBJC", "__protocol", 611 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 612 if (IDVal == ".objc_string_object") 613 return ParseDirectiveSectionSwitch("__OBJC", "__string_object", 614 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 615 if (IDVal == ".objc_cls_meth") 616 return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth", 617 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 618 if (IDVal == ".objc_inst_meth") 619 return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth", 620 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 621 if (IDVal == ".objc_cls_refs") 622 return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs", 623 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 624 MCSectionMachO::S_LITERAL_POINTERS, 625 4); 626 if (IDVal == ".objc_message_refs") 627 return ParseDirectiveSectionSwitch("__OBJC", "__message_refs", 628 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 629 MCSectionMachO::S_LITERAL_POINTERS, 630 4); 631 if (IDVal == ".objc_symbols") 632 return ParseDirectiveSectionSwitch("__OBJC", "__symbols", 633 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 634 if (IDVal == ".objc_category") 635 return ParseDirectiveSectionSwitch("__OBJC", "__category", 636 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 637 if (IDVal == ".objc_class_vars") 638 return ParseDirectiveSectionSwitch("__OBJC", "__class_vars", 639 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 640 if (IDVal == ".objc_instance_vars") 641 return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars", 642 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 643 if (IDVal == ".objc_module_info") 644 return ParseDirectiveSectionSwitch("__OBJC", "__module_info", 645 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 646 if (IDVal == ".objc_class_names") 647 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 648 MCSectionMachO::S_CSTRING_LITERALS); 649 if (IDVal == ".objc_meth_var_types") 650 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 651 MCSectionMachO::S_CSTRING_LITERALS); 652 if (IDVal == ".objc_meth_var_names") 653 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 654 MCSectionMachO::S_CSTRING_LITERALS); 655 if (IDVal == ".objc_selector_strs") 656 return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs", 657 MCSectionMachO::S_CSTRING_LITERALS); 658 659 // Assembler features 660 if (IDVal == ".set") 661 return ParseDirectiveSet(); 662 663 // Data directives 664 665 if (IDVal == ".ascii") 666 return ParseDirectiveAscii(false); 667 if (IDVal == ".asciz") 668 return ParseDirectiveAscii(true); 669 670 if (IDVal == ".byte") 671 return ParseDirectiveValue(1); 672 if (IDVal == ".short") 673 return ParseDirectiveValue(2); 674 if (IDVal == ".long") 675 return ParseDirectiveValue(4); 676 if (IDVal == ".quad") 677 return ParseDirectiveValue(8); 678 679 // FIXME: Target hooks for IsPow2. 680 if (IDVal == ".align") 681 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 682 if (IDVal == ".align32") 683 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 684 if (IDVal == ".balign") 685 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 686 if (IDVal == ".balignw") 687 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 688 if (IDVal == ".balignl") 689 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 690 if (IDVal == ".p2align") 691 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 692 if (IDVal == ".p2alignw") 693 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 694 if (IDVal == ".p2alignl") 695 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 696 697 if (IDVal == ".org") 698 return ParseDirectiveOrg(); 699 700 if (IDVal == ".fill") 701 return ParseDirectiveFill(); 702 if (IDVal == ".space") 703 return ParseDirectiveSpace(); 704 705 // Symbol attribute directives 706 707 if (IDVal == ".globl" || IDVal == ".global") 708 return ParseDirectiveSymbolAttribute(MCSA_Global); 709 if (IDVal == ".hidden") 710 return ParseDirectiveSymbolAttribute(MCSA_Hidden); 711 if (IDVal == ".indirect_symbol") 712 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); 713 if (IDVal == ".internal") 714 return ParseDirectiveSymbolAttribute(MCSA_Internal); 715 if (IDVal == ".lazy_reference") 716 return ParseDirectiveSymbolAttribute(MCSA_LazyReference); 717 if (IDVal == ".no_dead_strip") 718 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 719 if (IDVal == ".private_extern") 720 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); 721 if (IDVal == ".protected") 722 return ParseDirectiveSymbolAttribute(MCSA_Protected); 723 if (IDVal == ".reference") 724 return ParseDirectiveSymbolAttribute(MCSA_Reference); 725 if (IDVal == ".weak") 726 return ParseDirectiveSymbolAttribute(MCSA_Weak); 727 if (IDVal == ".weak_definition") 728 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); 729 if (IDVal == ".weak_reference") 730 return ParseDirectiveSymbolAttribute(MCSA_WeakReference); 731 732 if (IDVal == ".comm") 733 return ParseDirectiveComm(/*IsLocal=*/false); 734 if (IDVal == ".lcomm") 735 return ParseDirectiveComm(/*IsLocal=*/true); 736 if (IDVal == ".zerofill") 737 return ParseDirectiveDarwinZerofill(); 738 if (IDVal == ".desc") 739 return ParseDirectiveDarwinSymbolDesc(); 740 if (IDVal == ".lsym") 741 return ParseDirectiveDarwinLsym(); 742 743 if (IDVal == ".subsections_via_symbols") 744 return ParseDirectiveDarwinSubsectionsViaSymbols(); 745 if (IDVal == ".abort") 746 return ParseDirectiveAbort(); 747 if (IDVal == ".include") 748 return ParseDirectiveInclude(); 749 if (IDVal == ".dump") 750 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true); 751 if (IDVal == ".load") 752 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false); 753 754 // Look up the handler in the handler table, 755 bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal]; 756 if (Handler) 757 return (this->*Handler)(IDVal, IDLoc); 758 759 // Target hook for parsing target specific directives. 760 if (!getTargetParser().ParseDirective(ID)) 761 return false; 762 763 Warning(IDLoc, "ignoring directive for now"); 764 EatToEndOfStatement(); 765 return false; 766 } 767 768 769 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; 770 if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands)) 771 // FIXME: Leaking ParsedOperands on failure. 772 return true; 773 774 if (Lexer.isNot(AsmToken::EndOfStatement)) 775 // FIXME: Leaking ParsedOperands on failure. 776 return TokError("unexpected token in argument list"); 777 778 // Eat the end of statement marker. 779 Lex(); 780 781 782 MCInst Inst; 783 784 bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst); 785 786 // Free any parsed operands. 787 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) 788 delete ParsedOperands[i]; 789 790 if (MatchFail) { 791 // FIXME: We should give nicer diagnostics about the exact failure. 792 Error(IDLoc, "unrecognized instruction"); 793 return true; 794 } 795 796 // Instruction is good, process it. 797 Out.EmitInstruction(Inst); 798 799 // Skip to end of line for now. 800 return false; 801} 802 803bool AsmParser::ParseAssignment(const StringRef &Name) { 804 // FIXME: Use better location, we should use proper tokens. 805 SMLoc EqualLoc = Lexer.getLoc(); 806 807 const MCExpr *Value; 808 SMLoc StartLoc = Lexer.getLoc(); 809 if (ParseExpression(Value)) 810 return true; 811 812 if (Lexer.isNot(AsmToken::EndOfStatement)) 813 return TokError("unexpected token in assignment"); 814 815 // Eat the end of statement marker. 816 Lex(); 817 818 // Validate that the LHS is allowed to be a variable (either it has not been 819 // used as a symbol, or it is an absolute symbol). 820 MCSymbol *Sym = getContext().LookupSymbol(Name); 821 if (Sym) { 822 // Diagnose assignment to a label. 823 // 824 // FIXME: Diagnostics. Note the location of the definition as a label. 825 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 826 if (!Sym->isUndefined() && !Sym->isAbsolute()) 827 return Error(EqualLoc, "redefinition of '" + Name + "'"); 828 else if (!Sym->isVariable()) 829 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 830 else if (!isa<MCConstantExpr>(Sym->getValue())) 831 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 832 Name + "'"); 833 } else 834 Sym = CreateSymbol(Name); 835 836 // FIXME: Handle '.'. 837 838 // Do the assignment. 839 Out.EmitAssignment(Sym, Value); 840 841 return false; 842} 843 844/// ParseIdentifier: 845/// ::= identifier 846/// ::= string 847bool AsmParser::ParseIdentifier(StringRef &Res) { 848 if (Lexer.isNot(AsmToken::Identifier) && 849 Lexer.isNot(AsmToken::String)) 850 return true; 851 852 Res = getTok().getIdentifier(); 853 854 Lex(); // Consume the identifier token. 855 856 return false; 857} 858 859/// ParseDirectiveSet: 860/// ::= .set identifier ',' expression 861bool AsmParser::ParseDirectiveSet() { 862 StringRef Name; 863 864 if (ParseIdentifier(Name)) 865 return TokError("expected identifier after '.set' directive"); 866 867 if (Lexer.isNot(AsmToken::Comma)) 868 return TokError("unexpected token in '.set'"); 869 Lex(); 870 871 return ParseAssignment(Name); 872} 873 874/// ParseDirectiveSection: 875/// ::= .section identifier (',' identifier)* 876/// FIXME: This should actually parse out the segment, section, attributes and 877/// sizeof_stub fields. 878bool AsmParser::ParseDirectiveDarwinSection() { 879 SMLoc Loc = Lexer.getLoc(); 880 881 StringRef SectionName; 882 if (ParseIdentifier(SectionName)) 883 return Error(Loc, "expected identifier after '.section' directive"); 884 885 // Verify there is a following comma. 886 if (!Lexer.is(AsmToken::Comma)) 887 return TokError("unexpected token in '.section' directive"); 888 889 std::string SectionSpec = SectionName; 890 SectionSpec += ","; 891 892 // Add all the tokens until the end of the line, ParseSectionSpecifier will 893 // handle this. 894 StringRef EOL = Lexer.LexUntilEndOfStatement(); 895 SectionSpec.append(EOL.begin(), EOL.end()); 896 897 Lex(); 898 if (Lexer.isNot(AsmToken::EndOfStatement)) 899 return TokError("unexpected token in '.section' directive"); 900 Lex(); 901 902 903 StringRef Segment, Section; 904 unsigned TAA, StubSize; 905 std::string ErrorStr = 906 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, 907 TAA, StubSize); 908 909 if (!ErrorStr.empty()) 910 return Error(Loc, ErrorStr.c_str()); 911 912 // FIXME: Arch specific. 913 bool isText = Segment == "__TEXT"; // FIXME: Hack. 914 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize, 915 isText ? SectionKind::getText() 916 : SectionKind::getDataRel())); 917 return false; 918} 919 920/// ParseDirectiveSectionSwitch - 921bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment, 922 const char *Section, 923 unsigned TAA, unsigned Align, 924 unsigned StubSize) { 925 if (Lexer.isNot(AsmToken::EndOfStatement)) 926 return TokError("unexpected token in section switching directive"); 927 Lex(); 928 929 // FIXME: Arch specific. 930 bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack. 931 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize, 932 isText ? SectionKind::getText() 933 : SectionKind::getDataRel())); 934 935 // Set the implicit alignment, if any. 936 // 937 // FIXME: This isn't really what 'as' does; I think it just uses the implicit 938 // alignment on the section (e.g., if one manually inserts bytes into the 939 // section, then just issueing the section switch directive will not realign 940 // the section. However, this is arguably more reasonable behavior, and there 941 // is no good reason for someone to intentionally emit incorrectly sized 942 // values into the implicitly aligned sections. 943 if (Align) 944 Out.EmitValueToAlignment(Align, 0, 1, 0); 945 946 return false; 947} 948 949bool AsmParser::ParseEscapedString(std::string &Data) { 950 assert(Lexer.is(AsmToken::String) && "Unexpected current token!"); 951 952 Data = ""; 953 StringRef Str = getTok().getStringContents(); 954 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 955 if (Str[i] != '\\') { 956 Data += Str[i]; 957 continue; 958 } 959 960 // Recognize escaped characters. Note that this escape semantics currently 961 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 962 ++i; 963 if (i == e) 964 return TokError("unexpected backslash at end of string"); 965 966 // Recognize octal sequences. 967 if ((unsigned) (Str[i] - '0') <= 7) { 968 // Consume up to three octal characters. 969 unsigned Value = Str[i] - '0'; 970 971 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 972 ++i; 973 Value = Value * 8 + (Str[i] - '0'); 974 975 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 976 ++i; 977 Value = Value * 8 + (Str[i] - '0'); 978 } 979 } 980 981 if (Value > 255) 982 return TokError("invalid octal escape sequence (out of range)"); 983 984 Data += (unsigned char) Value; 985 continue; 986 } 987 988 // Otherwise recognize individual escapes. 989 switch (Str[i]) { 990 default: 991 // Just reject invalid escape sequences for now. 992 return TokError("invalid escape sequence (unrecognized character)"); 993 994 case 'b': Data += '\b'; break; 995 case 'f': Data += '\f'; break; 996 case 'n': Data += '\n'; break; 997 case 'r': Data += '\r'; break; 998 case 't': Data += '\t'; break; 999 case '"': Data += '"'; break; 1000 case '\\': Data += '\\'; break; 1001 } 1002 } 1003 1004 return false; 1005} 1006 1007/// ParseDirectiveAscii: 1008/// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ] 1009bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) { 1010 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1011 for (;;) { 1012 if (Lexer.isNot(AsmToken::String)) 1013 return TokError("expected string in '.ascii' or '.asciz' directive"); 1014 1015 std::string Data; 1016 if (ParseEscapedString(Data)) 1017 return true; 1018 1019 Out.EmitBytes(Data, DEFAULT_ADDRSPACE); 1020 if (ZeroTerminated) 1021 Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE); 1022 1023 Lex(); 1024 1025 if (Lexer.is(AsmToken::EndOfStatement)) 1026 break; 1027 1028 if (Lexer.isNot(AsmToken::Comma)) 1029 return TokError("unexpected token in '.ascii' or '.asciz' directive"); 1030 Lex(); 1031 } 1032 } 1033 1034 Lex(); 1035 return false; 1036} 1037 1038/// ParseDirectiveValue 1039/// ::= (.byte | .short | ... ) [ expression (, expression)* ] 1040bool AsmParser::ParseDirectiveValue(unsigned Size) { 1041 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1042 for (;;) { 1043 const MCExpr *Value; 1044 SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc(); 1045 if (ParseExpression(Value)) 1046 return true; 1047 1048 Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE); 1049 1050 if (Lexer.is(AsmToken::EndOfStatement)) 1051 break; 1052 1053 // FIXME: Improve diagnostic. 1054 if (Lexer.isNot(AsmToken::Comma)) 1055 return TokError("unexpected token in directive"); 1056 Lex(); 1057 } 1058 } 1059 1060 Lex(); 1061 return false; 1062} 1063 1064/// ParseDirectiveSpace 1065/// ::= .space expression [ , expression ] 1066bool AsmParser::ParseDirectiveSpace() { 1067 int64_t NumBytes; 1068 if (ParseAbsoluteExpression(NumBytes)) 1069 return true; 1070 1071 int64_t FillExpr = 0; 1072 bool HasFillExpr = false; 1073 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1074 if (Lexer.isNot(AsmToken::Comma)) 1075 return TokError("unexpected token in '.space' directive"); 1076 Lex(); 1077 1078 if (ParseAbsoluteExpression(FillExpr)) 1079 return true; 1080 1081 HasFillExpr = true; 1082 1083 if (Lexer.isNot(AsmToken::EndOfStatement)) 1084 return TokError("unexpected token in '.space' directive"); 1085 } 1086 1087 Lex(); 1088 1089 if (NumBytes <= 0) 1090 return TokError("invalid number of bytes in '.space' directive"); 1091 1092 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 1093 Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE); 1094 1095 return false; 1096} 1097 1098/// ParseDirectiveFill 1099/// ::= .fill expression , expression , expression 1100bool AsmParser::ParseDirectiveFill() { 1101 int64_t NumValues; 1102 if (ParseAbsoluteExpression(NumValues)) 1103 return true; 1104 1105 if (Lexer.isNot(AsmToken::Comma)) 1106 return TokError("unexpected token in '.fill' directive"); 1107 Lex(); 1108 1109 int64_t FillSize; 1110 if (ParseAbsoluteExpression(FillSize)) 1111 return true; 1112 1113 if (Lexer.isNot(AsmToken::Comma)) 1114 return TokError("unexpected token in '.fill' directive"); 1115 Lex(); 1116 1117 int64_t FillExpr; 1118 if (ParseAbsoluteExpression(FillExpr)) 1119 return true; 1120 1121 if (Lexer.isNot(AsmToken::EndOfStatement)) 1122 return TokError("unexpected token in '.fill' directive"); 1123 1124 Lex(); 1125 1126 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) 1127 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); 1128 1129 for (uint64_t i = 0, e = NumValues; i != e; ++i) 1130 Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize, 1131 DEFAULT_ADDRSPACE); 1132 1133 return false; 1134} 1135 1136/// ParseDirectiveOrg 1137/// ::= .org expression [ , expression ] 1138bool AsmParser::ParseDirectiveOrg() { 1139 const MCExpr *Offset; 1140 SMLoc StartLoc = Lexer.getLoc(); 1141 if (ParseExpression(Offset)) 1142 return true; 1143 1144 // Parse optional fill expression. 1145 int64_t FillExpr = 0; 1146 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1147 if (Lexer.isNot(AsmToken::Comma)) 1148 return TokError("unexpected token in '.org' directive"); 1149 Lex(); 1150 1151 if (ParseAbsoluteExpression(FillExpr)) 1152 return true; 1153 1154 if (Lexer.isNot(AsmToken::EndOfStatement)) 1155 return TokError("unexpected token in '.org' directive"); 1156 } 1157 1158 Lex(); 1159 1160 // FIXME: Only limited forms of relocatable expressions are accepted here, it 1161 // has to be relative to the current section. 1162 Out.EmitValueToOffset(Offset, FillExpr); 1163 1164 return false; 1165} 1166 1167/// ParseDirectiveAlign 1168/// ::= {.align, ...} expression [ , expression [ , expression ]] 1169bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 1170 SMLoc AlignmentLoc = Lexer.getLoc(); 1171 int64_t Alignment; 1172 if (ParseAbsoluteExpression(Alignment)) 1173 return true; 1174 1175 SMLoc MaxBytesLoc; 1176 bool HasFillExpr = false; 1177 int64_t FillExpr = 0; 1178 int64_t MaxBytesToFill = 0; 1179 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1180 if (Lexer.isNot(AsmToken::Comma)) 1181 return TokError("unexpected token in directive"); 1182 Lex(); 1183 1184 // The fill expression can be omitted while specifying a maximum number of 1185 // alignment bytes, e.g: 1186 // .align 3,,4 1187 if (Lexer.isNot(AsmToken::Comma)) { 1188 HasFillExpr = true; 1189 if (ParseAbsoluteExpression(FillExpr)) 1190 return true; 1191 } 1192 1193 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1194 if (Lexer.isNot(AsmToken::Comma)) 1195 return TokError("unexpected token in directive"); 1196 Lex(); 1197 1198 MaxBytesLoc = Lexer.getLoc(); 1199 if (ParseAbsoluteExpression(MaxBytesToFill)) 1200 return true; 1201 1202 if (Lexer.isNot(AsmToken::EndOfStatement)) 1203 return TokError("unexpected token in directive"); 1204 } 1205 } 1206 1207 Lex(); 1208 1209 if (!HasFillExpr) { 1210 // FIXME: Sometimes fill with nop. 1211 FillExpr = 0; 1212 } 1213 1214 // Compute alignment in bytes. 1215 if (IsPow2) { 1216 // FIXME: Diagnose overflow. 1217 if (Alignment >= 32) { 1218 Error(AlignmentLoc, "invalid alignment value"); 1219 Alignment = 31; 1220 } 1221 1222 Alignment = 1ULL << Alignment; 1223 } 1224 1225 // Diagnose non-sensical max bytes to align. 1226 if (MaxBytesLoc.isValid()) { 1227 if (MaxBytesToFill < 1) { 1228 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 1229 "many bytes, ignoring maximum bytes expression"); 1230 MaxBytesToFill = 0; 1231 } 1232 1233 if (MaxBytesToFill >= Alignment) { 1234 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 1235 "has no effect"); 1236 MaxBytesToFill = 0; 1237 } 1238 } 1239 1240 // FIXME: hard code the parser to use EmitCodeAlignment for text when using 1241 // the TextAlignFillValue. 1242 if(Out.getCurrentSection()->getKind().isText() && 1243 Lexer.getMAI().getTextAlignFillValue() == FillExpr) 1244 Out.EmitCodeAlignment(Alignment, MaxBytesToFill); 1245 else 1246 // FIXME: Target specific behavior about how the "extra" bytes are filled. 1247 Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill); 1248 1249 return false; 1250} 1251 1252/// ParseDirectiveSymbolAttribute 1253/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 1254bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 1255 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1256 for (;;) { 1257 StringRef Name; 1258 1259 if (ParseIdentifier(Name)) 1260 return TokError("expected identifier in directive"); 1261 1262 MCSymbol *Sym = CreateSymbol(Name); 1263 1264 Out.EmitSymbolAttribute(Sym, Attr); 1265 1266 if (Lexer.is(AsmToken::EndOfStatement)) 1267 break; 1268 1269 if (Lexer.isNot(AsmToken::Comma)) 1270 return TokError("unexpected token in directive"); 1271 Lex(); 1272 } 1273 } 1274 1275 Lex(); 1276 return false; 1277} 1278 1279/// ParseDirectiveDarwinSymbolDesc 1280/// ::= .desc identifier , expression 1281bool AsmParser::ParseDirectiveDarwinSymbolDesc() { 1282 StringRef Name; 1283 if (ParseIdentifier(Name)) 1284 return TokError("expected identifier in directive"); 1285 1286 // Handle the identifier as the key symbol. 1287 MCSymbol *Sym = CreateSymbol(Name); 1288 1289 if (Lexer.isNot(AsmToken::Comma)) 1290 return TokError("unexpected token in '.desc' directive"); 1291 Lex(); 1292 1293 SMLoc DescLoc = Lexer.getLoc(); 1294 int64_t DescValue; 1295 if (ParseAbsoluteExpression(DescValue)) 1296 return true; 1297 1298 if (Lexer.isNot(AsmToken::EndOfStatement)) 1299 return TokError("unexpected token in '.desc' directive"); 1300 1301 Lex(); 1302 1303 // Set the n_desc field of this Symbol to this DescValue 1304 Out.EmitSymbolDesc(Sym, DescValue); 1305 1306 return false; 1307} 1308 1309/// ParseDirectiveComm 1310/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 1311bool AsmParser::ParseDirectiveComm(bool IsLocal) { 1312 SMLoc IDLoc = Lexer.getLoc(); 1313 StringRef Name; 1314 if (ParseIdentifier(Name)) 1315 return TokError("expected identifier in directive"); 1316 1317 // Handle the identifier as the key symbol. 1318 MCSymbol *Sym = CreateSymbol(Name); 1319 1320 if (Lexer.isNot(AsmToken::Comma)) 1321 return TokError("unexpected token in directive"); 1322 Lex(); 1323 1324 int64_t Size; 1325 SMLoc SizeLoc = Lexer.getLoc(); 1326 if (ParseAbsoluteExpression(Size)) 1327 return true; 1328 1329 int64_t Pow2Alignment = 0; 1330 SMLoc Pow2AlignmentLoc; 1331 if (Lexer.is(AsmToken::Comma)) { 1332 Lex(); 1333 Pow2AlignmentLoc = Lexer.getLoc(); 1334 if (ParseAbsoluteExpression(Pow2Alignment)) 1335 return true; 1336 1337 // If this target takes alignments in bytes (not log) validate and convert. 1338 if (Lexer.getMAI().getAlignmentIsInBytes()) { 1339 if (!isPowerOf2_64(Pow2Alignment)) 1340 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 1341 Pow2Alignment = Log2_64(Pow2Alignment); 1342 } 1343 } 1344 1345 if (Lexer.isNot(AsmToken::EndOfStatement)) 1346 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 1347 1348 Lex(); 1349 1350 // NOTE: a size of zero for a .comm should create a undefined symbol 1351 // but a size of .lcomm creates a bss symbol of size zero. 1352 if (Size < 0) 1353 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 1354 "be less than zero"); 1355 1356 // NOTE: The alignment in the directive is a power of 2 value, the assember 1357 // may internally end up wanting an alignment in bytes. 1358 // FIXME: Diagnose overflow. 1359 if (Pow2Alignment < 0) 1360 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 1361 "alignment, can't be less than zero"); 1362 1363 if (!Sym->isUndefined()) 1364 return Error(IDLoc, "invalid symbol redefinition"); 1365 1366 // '.lcomm' is equivalent to '.zerofill'. 1367 // Create the Symbol as a common or local common with Size and Pow2Alignment 1368 if (IsLocal) { 1369 Out.EmitZerofill(getMachOSection("__DATA", "__bss", 1370 MCSectionMachO::S_ZEROFILL, 0, 1371 SectionKind::getBSS()), 1372 Sym, Size, 1 << Pow2Alignment); 1373 return false; 1374 } 1375 1376 Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 1377 return false; 1378} 1379 1380/// ParseDirectiveDarwinZerofill 1381/// ::= .zerofill segname , sectname [, identifier , size_expression [ 1382/// , align_expression ]] 1383bool AsmParser::ParseDirectiveDarwinZerofill() { 1384 // FIXME: Handle quoted names here. 1385 1386 if (Lexer.isNot(AsmToken::Identifier)) 1387 return TokError("expected segment name after '.zerofill' directive"); 1388 StringRef Segment = getTok().getString(); 1389 Lex(); 1390 1391 if (Lexer.isNot(AsmToken::Comma)) 1392 return TokError("unexpected token in directive"); 1393 Lex(); 1394 1395 if (Lexer.isNot(AsmToken::Identifier)) 1396 return TokError("expected section name after comma in '.zerofill' " 1397 "directive"); 1398 StringRef Section = getTok().getString(); 1399 Lex(); 1400 1401 // If this is the end of the line all that was wanted was to create the 1402 // the section but with no symbol. 1403 if (Lexer.is(AsmToken::EndOfStatement)) { 1404 // Create the zerofill section but no symbol 1405 Out.EmitZerofill(getMachOSection(Segment, Section, 1406 MCSectionMachO::S_ZEROFILL, 0, 1407 SectionKind::getBSS())); 1408 return false; 1409 } 1410 1411 if (Lexer.isNot(AsmToken::Comma)) 1412 return TokError("unexpected token in directive"); 1413 Lex(); 1414 1415 if (Lexer.isNot(AsmToken::Identifier)) 1416 return TokError("expected identifier in directive"); 1417 1418 // handle the identifier as the key symbol. 1419 SMLoc IDLoc = Lexer.getLoc(); 1420 MCSymbol *Sym = CreateSymbol(getTok().getString()); 1421 Lex(); 1422 1423 if (Lexer.isNot(AsmToken::Comma)) 1424 return TokError("unexpected token in directive"); 1425 Lex(); 1426 1427 int64_t Size; 1428 SMLoc SizeLoc = Lexer.getLoc(); 1429 if (ParseAbsoluteExpression(Size)) 1430 return true; 1431 1432 int64_t Pow2Alignment = 0; 1433 SMLoc Pow2AlignmentLoc; 1434 if (Lexer.is(AsmToken::Comma)) { 1435 Lex(); 1436 Pow2AlignmentLoc = Lexer.getLoc(); 1437 if (ParseAbsoluteExpression(Pow2Alignment)) 1438 return true; 1439 } 1440 1441 if (Lexer.isNot(AsmToken::EndOfStatement)) 1442 return TokError("unexpected token in '.zerofill' directive"); 1443 1444 Lex(); 1445 1446 if (Size < 0) 1447 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 1448 "than zero"); 1449 1450 // NOTE: The alignment in the directive is a power of 2 value, the assember 1451 // may internally end up wanting an alignment in bytes. 1452 // FIXME: Diagnose overflow. 1453 if (Pow2Alignment < 0) 1454 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 1455 "can't be less than zero"); 1456 1457 if (!Sym->isUndefined()) 1458 return Error(IDLoc, "invalid symbol redefinition"); 1459 1460 // Create the zerofill Symbol with Size and Pow2Alignment 1461 // 1462 // FIXME: Arch specific. 1463 Out.EmitZerofill(getMachOSection(Segment, Section, 1464 MCSectionMachO::S_ZEROFILL, 0, 1465 SectionKind::getBSS()), 1466 Sym, Size, 1 << Pow2Alignment); 1467 1468 return false; 1469} 1470 1471/// ParseDirectiveDarwinSubsectionsViaSymbols 1472/// ::= .subsections_via_symbols 1473bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() { 1474 if (Lexer.isNot(AsmToken::EndOfStatement)) 1475 return TokError("unexpected token in '.subsections_via_symbols' directive"); 1476 1477 Lex(); 1478 1479 Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1480 1481 return false; 1482} 1483 1484/// ParseDirectiveAbort 1485/// ::= .abort [ "abort_string" ] 1486bool AsmParser::ParseDirectiveAbort() { 1487 // FIXME: Use loc from directive. 1488 SMLoc Loc = Lexer.getLoc(); 1489 1490 StringRef Str = ""; 1491 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1492 if (Lexer.isNot(AsmToken::String)) 1493 return TokError("expected string in '.abort' directive"); 1494 1495 Str = getTok().getString(); 1496 1497 Lex(); 1498 } 1499 1500 if (Lexer.isNot(AsmToken::EndOfStatement)) 1501 return TokError("unexpected token in '.abort' directive"); 1502 1503 Lex(); 1504 1505 // FIXME: Handle here. 1506 if (Str.empty()) 1507 Error(Loc, ".abort detected. Assembly stopping."); 1508 else 1509 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 1510 1511 return false; 1512} 1513 1514/// ParseDirectiveLsym 1515/// ::= .lsym identifier , expression 1516bool AsmParser::ParseDirectiveDarwinLsym() { 1517 StringRef Name; 1518 if (ParseIdentifier(Name)) 1519 return TokError("expected identifier in directive"); 1520 1521 // Handle the identifier as the key symbol. 1522 MCSymbol *Sym = CreateSymbol(Name); 1523 1524 if (Lexer.isNot(AsmToken::Comma)) 1525 return TokError("unexpected token in '.lsym' directive"); 1526 Lex(); 1527 1528 const MCExpr *Value; 1529 SMLoc StartLoc = Lexer.getLoc(); 1530 if (ParseExpression(Value)) 1531 return true; 1532 1533 if (Lexer.isNot(AsmToken::EndOfStatement)) 1534 return TokError("unexpected token in '.lsym' directive"); 1535 1536 Lex(); 1537 1538 // We don't currently support this directive. 1539 // 1540 // FIXME: Diagnostic location! 1541 (void) Sym; 1542 return TokError("directive '.lsym' is unsupported"); 1543} 1544 1545/// ParseDirectiveInclude 1546/// ::= .include "filename" 1547bool AsmParser::ParseDirectiveInclude() { 1548 if (Lexer.isNot(AsmToken::String)) 1549 return TokError("expected string in '.include' directive"); 1550 1551 std::string Filename = getTok().getString(); 1552 SMLoc IncludeLoc = Lexer.getLoc(); 1553 Lex(); 1554 1555 if (Lexer.isNot(AsmToken::EndOfStatement)) 1556 return TokError("unexpected token in '.include' directive"); 1557 1558 // Strip the quotes. 1559 Filename = Filename.substr(1, Filename.size()-2); 1560 1561 // Attempt to switch the lexer to the included file before consuming the end 1562 // of statement to avoid losing it when we switch. 1563 if (EnterIncludeFile(Filename)) { 1564 PrintMessage(IncludeLoc, 1565 "Could not find include file '" + Filename + "'", 1566 "error"); 1567 return true; 1568 } 1569 1570 return false; 1571} 1572 1573/// ParseDirectiveDarwinDumpOrLoad 1574/// ::= ( .dump | .load ) "filename" 1575bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) { 1576 if (Lexer.isNot(AsmToken::String)) 1577 return TokError("expected string in '.dump' or '.load' directive"); 1578 1579 Lex(); 1580 1581 if (Lexer.isNot(AsmToken::EndOfStatement)) 1582 return TokError("unexpected token in '.dump' or '.load' directive"); 1583 1584 Lex(); 1585 1586 // FIXME: If/when .dump and .load are implemented they will be done in the 1587 // the assembly parser and not have any need for an MCStreamer API. 1588 if (IsDump) 1589 Warning(IDLoc, "ignoring directive .dump for now"); 1590 else 1591 Warning(IDLoc, "ignoring directive .load for now"); 1592 1593 return false; 1594} 1595 1596/// ParseDirectiveIf 1597/// ::= .if expression 1598bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { 1599 // Consume the identifier that was the .if directive 1600 Lex(); 1601 1602 TheCondStack.push_back(TheCondState); 1603 TheCondState.TheCond = AsmCond::IfCond; 1604 if(TheCondState.Ignore) { 1605 EatToEndOfStatement(); 1606 } 1607 else { 1608 int64_t ExprValue; 1609 if (ParseAbsoluteExpression(ExprValue)) 1610 return true; 1611 1612 if (Lexer.isNot(AsmToken::EndOfStatement)) 1613 return TokError("unexpected token in '.if' directive"); 1614 1615 Lex(); 1616 1617 TheCondState.CondMet = ExprValue; 1618 TheCondState.Ignore = !TheCondState.CondMet; 1619 } 1620 1621 return false; 1622} 1623 1624/// ParseDirectiveElseIf 1625/// ::= .elseif expression 1626bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { 1627 if (TheCondState.TheCond != AsmCond::IfCond && 1628 TheCondState.TheCond != AsmCond::ElseIfCond) 1629 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 1630 " an .elseif"); 1631 TheCondState.TheCond = AsmCond::ElseIfCond; 1632 1633 // Consume the identifier that was the .elseif directive 1634 Lex(); 1635 1636 bool LastIgnoreState = false; 1637 if (!TheCondStack.empty()) 1638 LastIgnoreState = TheCondStack.back().Ignore; 1639 if (LastIgnoreState || TheCondState.CondMet) { 1640 TheCondState.Ignore = true; 1641 EatToEndOfStatement(); 1642 } 1643 else { 1644 int64_t ExprValue; 1645 if (ParseAbsoluteExpression(ExprValue)) 1646 return true; 1647 1648 if (Lexer.isNot(AsmToken::EndOfStatement)) 1649 return TokError("unexpected token in '.elseif' directive"); 1650 1651 Lex(); 1652 TheCondState.CondMet = ExprValue; 1653 TheCondState.Ignore = !TheCondState.CondMet; 1654 } 1655 1656 return false; 1657} 1658 1659/// ParseDirectiveElse 1660/// ::= .else 1661bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { 1662 // Consume the identifier that was the .else directive 1663 Lex(); 1664 1665 if (Lexer.isNot(AsmToken::EndOfStatement)) 1666 return TokError("unexpected token in '.else' directive"); 1667 1668 Lex(); 1669 1670 if (TheCondState.TheCond != AsmCond::IfCond && 1671 TheCondState.TheCond != AsmCond::ElseIfCond) 1672 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 1673 ".elseif"); 1674 TheCondState.TheCond = AsmCond::ElseCond; 1675 bool LastIgnoreState = false; 1676 if (!TheCondStack.empty()) 1677 LastIgnoreState = TheCondStack.back().Ignore; 1678 if (LastIgnoreState || TheCondState.CondMet) 1679 TheCondState.Ignore = true; 1680 else 1681 TheCondState.Ignore = false; 1682 1683 return false; 1684} 1685 1686/// ParseDirectiveEndIf 1687/// ::= .endif 1688bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { 1689 // Consume the identifier that was the .endif directive 1690 Lex(); 1691 1692 if (Lexer.isNot(AsmToken::EndOfStatement)) 1693 return TokError("unexpected token in '.endif' directive"); 1694 1695 Lex(); 1696 1697 if ((TheCondState.TheCond == AsmCond::NoCond) || 1698 TheCondStack.empty()) 1699 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 1700 ".else"); 1701 if (!TheCondStack.empty()) { 1702 TheCondState = TheCondStack.back(); 1703 TheCondStack.pop_back(); 1704 } 1705 1706 return false; 1707} 1708 1709/// ParseDirectiveFile 1710/// ::= .file [number] string 1711bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { 1712 // FIXME: I'm not sure what this is. 1713 int64_t FileNumber = -1; 1714 if (Lexer.is(AsmToken::Integer)) { 1715 FileNumber = getTok().getIntVal(); 1716 Lex(); 1717 1718 if (FileNumber < 1) 1719 return TokError("file number less than one"); 1720 } 1721 1722 if (Lexer.isNot(AsmToken::String)) 1723 return TokError("unexpected token in '.file' directive"); 1724 1725 StringRef Filename = getTok().getString(); 1726 Filename = Filename.substr(1, Filename.size()-2); 1727 Lex(); 1728 1729 if (Lexer.isNot(AsmToken::EndOfStatement)) 1730 return TokError("unexpected token in '.file' directive"); 1731 1732 if (FileNumber == -1) 1733 Out.EmitFileDirective(Filename); 1734 else 1735 Out.EmitDwarfFileDirective(FileNumber, Filename); 1736 1737 return false; 1738} 1739 1740/// ParseDirectiveLine 1741/// ::= .line [number] 1742bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { 1743 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1744 if (Lexer.isNot(AsmToken::Integer)) 1745 return TokError("unexpected token in '.line' directive"); 1746 1747 int64_t LineNumber = getTok().getIntVal(); 1748 (void) LineNumber; 1749 Lex(); 1750 1751 // FIXME: Do something with the .line. 1752 } 1753 1754 if (Lexer.isNot(AsmToken::EndOfStatement)) 1755 return TokError("unexpected token in '.file' directive"); 1756 1757 return false; 1758} 1759 1760 1761/// ParseDirectiveLoc 1762/// ::= .loc number [number [number]] 1763bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) { 1764 if (Lexer.isNot(AsmToken::Integer)) 1765 return TokError("unexpected token in '.loc' directive"); 1766 1767 // FIXME: What are these fields? 1768 int64_t FileNumber = getTok().getIntVal(); 1769 (void) FileNumber; 1770 // FIXME: Validate file. 1771 1772 Lex(); 1773 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1774 if (Lexer.isNot(AsmToken::Integer)) 1775 return TokError("unexpected token in '.loc' directive"); 1776 1777 int64_t Param2 = getTok().getIntVal(); 1778 (void) Param2; 1779 Lex(); 1780 1781 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1782 if (Lexer.isNot(AsmToken::Integer)) 1783 return TokError("unexpected token in '.loc' directive"); 1784 1785 int64_t Param3 = getTok().getIntVal(); 1786 (void) Param3; 1787 Lex(); 1788 1789 // FIXME: Do something with the .loc. 1790 } 1791 } 1792 1793 if (Lexer.isNot(AsmToken::EndOfStatement)) 1794 return TokError("unexpected token in '.file' directive"); 1795 1796 return false; 1797} 1798
| 288 return false; 289 } 290 case AsmToken::Integer: 291 Res = MCConstantExpr::Create(getTok().getIntVal(), getContext()); 292 EndLoc = Lexer.getLoc(); 293 Lex(); // Eat token. 294 return false; 295 case AsmToken::LParen: 296 Lex(); // Eat the '('. 297 return ParseParenExpr(Res, EndLoc); 298 case AsmToken::Minus: 299 Lex(); // Eat the operator. 300 if (ParsePrimaryExpr(Res, EndLoc)) 301 return true; 302 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 303 return false; 304 case AsmToken::Plus: 305 Lex(); // Eat the operator. 306 if (ParsePrimaryExpr(Res, EndLoc)) 307 return true; 308 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 309 return false; 310 case AsmToken::Tilde: 311 Lex(); // Eat the operator. 312 if (ParsePrimaryExpr(Res, EndLoc)) 313 return true; 314 Res = MCUnaryExpr::CreateNot(Res, getContext()); 315 return false; 316 } 317} 318 319bool AsmParser::ParseExpression(const MCExpr *&Res) { 320 SMLoc EndLoc; 321 return ParseExpression(Res, EndLoc); 322} 323 324/// ParseExpression - Parse an expression and return it. 325/// 326/// expr ::= expr +,- expr -> lowest. 327/// expr ::= expr |,^,&,! expr -> middle. 328/// expr ::= expr *,/,%,<<,>> expr -> highest. 329/// expr ::= primaryexpr 330/// 331bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 332 // Parse the expression. 333 Res = 0; 334 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc)) 335 return true; 336 337 // Try to constant fold it up front, if possible. 338 int64_t Value; 339 if (Res->EvaluateAsAbsolute(Value)) 340 Res = MCConstantExpr::Create(Value, getContext()); 341 342 return false; 343} 344 345bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 346 Res = 0; 347 return ParseParenExpr(Res, EndLoc) || 348 ParseBinOpRHS(1, Res, EndLoc); 349} 350 351bool AsmParser::ParseAbsoluteExpression(int64_t &Res) { 352 const MCExpr *Expr; 353 354 SMLoc StartLoc = Lexer.getLoc(); 355 if (ParseExpression(Expr)) 356 return true; 357 358 if (!Expr->EvaluateAsAbsolute(Res)) 359 return Error(StartLoc, "expected absolute expression"); 360 361 return false; 362} 363 364static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 365 MCBinaryExpr::Opcode &Kind) { 366 switch (K) { 367 default: 368 return 0; // not a binop. 369 370 // Lowest Precedence: &&, || 371 case AsmToken::AmpAmp: 372 Kind = MCBinaryExpr::LAnd; 373 return 1; 374 case AsmToken::PipePipe: 375 Kind = MCBinaryExpr::LOr; 376 return 1; 377 378 // Low Precedence: +, -, ==, !=, <>, <, <=, >, >= 379 case AsmToken::Plus: 380 Kind = MCBinaryExpr::Add; 381 return 2; 382 case AsmToken::Minus: 383 Kind = MCBinaryExpr::Sub; 384 return 2; 385 case AsmToken::EqualEqual: 386 Kind = MCBinaryExpr::EQ; 387 return 2; 388 case AsmToken::ExclaimEqual: 389 case AsmToken::LessGreater: 390 Kind = MCBinaryExpr::NE; 391 return 2; 392 case AsmToken::Less: 393 Kind = MCBinaryExpr::LT; 394 return 2; 395 case AsmToken::LessEqual: 396 Kind = MCBinaryExpr::LTE; 397 return 2; 398 case AsmToken::Greater: 399 Kind = MCBinaryExpr::GT; 400 return 2; 401 case AsmToken::GreaterEqual: 402 Kind = MCBinaryExpr::GTE; 403 return 2; 404 405 // Intermediate Precedence: |, &, ^ 406 // 407 // FIXME: gas seems to support '!' as an infix operator? 408 case AsmToken::Pipe: 409 Kind = MCBinaryExpr::Or; 410 return 3; 411 case AsmToken::Caret: 412 Kind = MCBinaryExpr::Xor; 413 return 3; 414 case AsmToken::Amp: 415 Kind = MCBinaryExpr::And; 416 return 3; 417 418 // Highest Precedence: *, /, %, <<, >> 419 case AsmToken::Star: 420 Kind = MCBinaryExpr::Mul; 421 return 4; 422 case AsmToken::Slash: 423 Kind = MCBinaryExpr::Div; 424 return 4; 425 case AsmToken::Percent: 426 Kind = MCBinaryExpr::Mod; 427 return 4; 428 case AsmToken::LessLess: 429 Kind = MCBinaryExpr::Shl; 430 return 4; 431 case AsmToken::GreaterGreater: 432 Kind = MCBinaryExpr::Shr; 433 return 4; 434 } 435} 436 437 438/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. 439/// Res contains the LHS of the expression on input. 440bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 441 SMLoc &EndLoc) { 442 while (1) { 443 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 444 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 445 446 // If the next token is lower precedence than we are allowed to eat, return 447 // successfully with what we ate already. 448 if (TokPrec < Precedence) 449 return false; 450 451 Lex(); 452 453 // Eat the next primary expression. 454 const MCExpr *RHS; 455 if (ParsePrimaryExpr(RHS, EndLoc)) return true; 456 457 // If BinOp binds less tightly with RHS than the operator after RHS, let 458 // the pending operator take RHS as its LHS. 459 MCBinaryExpr::Opcode Dummy; 460 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 461 if (TokPrec < NextTokPrec) { 462 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true; 463 } 464 465 // Merge LHS and RHS according to operator. 466 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 467 } 468} 469 470 471 472 473/// ParseStatement: 474/// ::= EndOfStatement 475/// ::= Label* Directive ...Operands... EndOfStatement 476/// ::= Label* Identifier OperandList* EndOfStatement 477bool AsmParser::ParseStatement() { 478 if (Lexer.is(AsmToken::EndOfStatement)) { 479 Lex(); 480 return false; 481 } 482 483 // Statements always start with an identifier. 484 AsmToken ID = getTok(); 485 SMLoc IDLoc = ID.getLoc(); 486 StringRef IDVal; 487 if (ParseIdentifier(IDVal)) 488 return TokError("unexpected token at start of statement"); 489 490 // FIXME: Recurse on local labels? 491 492 // See what kind of statement we have. 493 switch (Lexer.getKind()) { 494 case AsmToken::Colon: { 495 // identifier ':' -> Label. 496 Lex(); 497 498 // Diagnose attempt to use a variable as a label. 499 // 500 // FIXME: Diagnostics. Note the location of the definition as a label. 501 // FIXME: This doesn't diagnose assignment to a symbol which has been 502 // implicitly marked as external. 503 MCSymbol *Sym = CreateSymbol(IDVal); 504 if (!Sym->isUndefined()) 505 return Error(IDLoc, "invalid symbol redefinition"); 506 507 // Emit the label. 508 Out.EmitLabel(Sym); 509 510 return ParseStatement(); 511 } 512 513 case AsmToken::Equal: 514 // identifier '=' ... -> assignment statement 515 Lex(); 516 517 return ParseAssignment(IDVal); 518 519 default: // Normal instruction or directive. 520 break; 521 } 522 523 // Otherwise, we have a normal instruction or directive. 524 if (IDVal[0] == '.') { 525 // FIXME: This should be driven based on a hash lookup and callback. 526 if (IDVal == ".section") 527 return ParseDirectiveDarwinSection(); 528 if (IDVal == ".text") 529 // FIXME: This changes behavior based on the -static flag to the 530 // assembler. 531 return ParseDirectiveSectionSwitch("__TEXT", "__text", 532 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); 533 if (IDVal == ".const") 534 return ParseDirectiveSectionSwitch("__TEXT", "__const"); 535 if (IDVal == ".static_const") 536 return ParseDirectiveSectionSwitch("__TEXT", "__static_const"); 537 if (IDVal == ".cstring") 538 return ParseDirectiveSectionSwitch("__TEXT","__cstring", 539 MCSectionMachO::S_CSTRING_LITERALS); 540 if (IDVal == ".literal4") 541 return ParseDirectiveSectionSwitch("__TEXT", "__literal4", 542 MCSectionMachO::S_4BYTE_LITERALS, 543 4); 544 if (IDVal == ".literal8") 545 return ParseDirectiveSectionSwitch("__TEXT", "__literal8", 546 MCSectionMachO::S_8BYTE_LITERALS, 547 8); 548 if (IDVal == ".literal16") 549 return ParseDirectiveSectionSwitch("__TEXT","__literal16", 550 MCSectionMachO::S_16BYTE_LITERALS, 551 16); 552 if (IDVal == ".constructor") 553 return ParseDirectiveSectionSwitch("__TEXT","__constructor"); 554 if (IDVal == ".destructor") 555 return ParseDirectiveSectionSwitch("__TEXT","__destructor"); 556 if (IDVal == ".fvmlib_init0") 557 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0"); 558 if (IDVal == ".fvmlib_init1") 559 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1"); 560 561 // FIXME: The assembler manual claims that this has the self modify code 562 // flag, at least on x86-32, but that does not appear to be correct. 563 if (IDVal == ".symbol_stub") 564 return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub", 565 MCSectionMachO::S_SYMBOL_STUBS | 566 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 567 // FIXME: Different on PPC and ARM. 568 0, 16); 569 // FIXME: PowerPC only? 570 if (IDVal == ".picsymbol_stub") 571 return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub", 572 MCSectionMachO::S_SYMBOL_STUBS | 573 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 574 0, 26); 575 if (IDVal == ".data") 576 return ParseDirectiveSectionSwitch("__DATA", "__data"); 577 if (IDVal == ".static_data") 578 return ParseDirectiveSectionSwitch("__DATA", "__static_data"); 579 580 // FIXME: The section names of these two are misspelled in the assembler 581 // manual. 582 if (IDVal == ".non_lazy_symbol_pointer") 583 return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr", 584 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 585 4); 586 if (IDVal == ".lazy_symbol_pointer") 587 return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr", 588 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 589 4); 590 591 if (IDVal == ".dyld") 592 return ParseDirectiveSectionSwitch("__DATA", "__dyld"); 593 if (IDVal == ".mod_init_func") 594 return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func", 595 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 596 4); 597 if (IDVal == ".mod_term_func") 598 return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func", 599 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 600 4); 601 if (IDVal == ".const_data") 602 return ParseDirectiveSectionSwitch("__DATA", "__const"); 603 604 605 if (IDVal == ".objc_class") 606 return ParseDirectiveSectionSwitch("__OBJC", "__class", 607 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 608 if (IDVal == ".objc_meta_class") 609 return ParseDirectiveSectionSwitch("__OBJC", "__meta_class", 610 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 611 if (IDVal == ".objc_cat_cls_meth") 612 return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth", 613 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 614 if (IDVal == ".objc_cat_inst_meth") 615 return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth", 616 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 617 if (IDVal == ".objc_protocol") 618 return ParseDirectiveSectionSwitch("__OBJC", "__protocol", 619 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 620 if (IDVal == ".objc_string_object") 621 return ParseDirectiveSectionSwitch("__OBJC", "__string_object", 622 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 623 if (IDVal == ".objc_cls_meth") 624 return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth", 625 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 626 if (IDVal == ".objc_inst_meth") 627 return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth", 628 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 629 if (IDVal == ".objc_cls_refs") 630 return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs", 631 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 632 MCSectionMachO::S_LITERAL_POINTERS, 633 4); 634 if (IDVal == ".objc_message_refs") 635 return ParseDirectiveSectionSwitch("__OBJC", "__message_refs", 636 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 637 MCSectionMachO::S_LITERAL_POINTERS, 638 4); 639 if (IDVal == ".objc_symbols") 640 return ParseDirectiveSectionSwitch("__OBJC", "__symbols", 641 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 642 if (IDVal == ".objc_category") 643 return ParseDirectiveSectionSwitch("__OBJC", "__category", 644 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 645 if (IDVal == ".objc_class_vars") 646 return ParseDirectiveSectionSwitch("__OBJC", "__class_vars", 647 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 648 if (IDVal == ".objc_instance_vars") 649 return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars", 650 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 651 if (IDVal == ".objc_module_info") 652 return ParseDirectiveSectionSwitch("__OBJC", "__module_info", 653 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 654 if (IDVal == ".objc_class_names") 655 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 656 MCSectionMachO::S_CSTRING_LITERALS); 657 if (IDVal == ".objc_meth_var_types") 658 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 659 MCSectionMachO::S_CSTRING_LITERALS); 660 if (IDVal == ".objc_meth_var_names") 661 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 662 MCSectionMachO::S_CSTRING_LITERALS); 663 if (IDVal == ".objc_selector_strs") 664 return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs", 665 MCSectionMachO::S_CSTRING_LITERALS); 666 667 // Assembler features 668 if (IDVal == ".set") 669 return ParseDirectiveSet(); 670 671 // Data directives 672 673 if (IDVal == ".ascii") 674 return ParseDirectiveAscii(false); 675 if (IDVal == ".asciz") 676 return ParseDirectiveAscii(true); 677 678 if (IDVal == ".byte") 679 return ParseDirectiveValue(1); 680 if (IDVal == ".short") 681 return ParseDirectiveValue(2); 682 if (IDVal == ".long") 683 return ParseDirectiveValue(4); 684 if (IDVal == ".quad") 685 return ParseDirectiveValue(8); 686 687 // FIXME: Target hooks for IsPow2. 688 if (IDVal == ".align") 689 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 690 if (IDVal == ".align32") 691 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 692 if (IDVal == ".balign") 693 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 694 if (IDVal == ".balignw") 695 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 696 if (IDVal == ".balignl") 697 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 698 if (IDVal == ".p2align") 699 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 700 if (IDVal == ".p2alignw") 701 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 702 if (IDVal == ".p2alignl") 703 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 704 705 if (IDVal == ".org") 706 return ParseDirectiveOrg(); 707 708 if (IDVal == ".fill") 709 return ParseDirectiveFill(); 710 if (IDVal == ".space") 711 return ParseDirectiveSpace(); 712 713 // Symbol attribute directives 714 715 if (IDVal == ".globl" || IDVal == ".global") 716 return ParseDirectiveSymbolAttribute(MCSA_Global); 717 if (IDVal == ".hidden") 718 return ParseDirectiveSymbolAttribute(MCSA_Hidden); 719 if (IDVal == ".indirect_symbol") 720 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); 721 if (IDVal == ".internal") 722 return ParseDirectiveSymbolAttribute(MCSA_Internal); 723 if (IDVal == ".lazy_reference") 724 return ParseDirectiveSymbolAttribute(MCSA_LazyReference); 725 if (IDVal == ".no_dead_strip") 726 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 727 if (IDVal == ".private_extern") 728 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); 729 if (IDVal == ".protected") 730 return ParseDirectiveSymbolAttribute(MCSA_Protected); 731 if (IDVal == ".reference") 732 return ParseDirectiveSymbolAttribute(MCSA_Reference); 733 if (IDVal == ".weak") 734 return ParseDirectiveSymbolAttribute(MCSA_Weak); 735 if (IDVal == ".weak_definition") 736 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); 737 if (IDVal == ".weak_reference") 738 return ParseDirectiveSymbolAttribute(MCSA_WeakReference); 739 740 if (IDVal == ".comm") 741 return ParseDirectiveComm(/*IsLocal=*/false); 742 if (IDVal == ".lcomm") 743 return ParseDirectiveComm(/*IsLocal=*/true); 744 if (IDVal == ".zerofill") 745 return ParseDirectiveDarwinZerofill(); 746 if (IDVal == ".desc") 747 return ParseDirectiveDarwinSymbolDesc(); 748 if (IDVal == ".lsym") 749 return ParseDirectiveDarwinLsym(); 750 751 if (IDVal == ".subsections_via_symbols") 752 return ParseDirectiveDarwinSubsectionsViaSymbols(); 753 if (IDVal == ".abort") 754 return ParseDirectiveAbort(); 755 if (IDVal == ".include") 756 return ParseDirectiveInclude(); 757 if (IDVal == ".dump") 758 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true); 759 if (IDVal == ".load") 760 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false); 761 762 // Look up the handler in the handler table, 763 bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal]; 764 if (Handler) 765 return (this->*Handler)(IDVal, IDLoc); 766 767 // Target hook for parsing target specific directives. 768 if (!getTargetParser().ParseDirective(ID)) 769 return false; 770 771 Warning(IDLoc, "ignoring directive for now"); 772 EatToEndOfStatement(); 773 return false; 774 } 775 776 777 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; 778 if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands)) 779 // FIXME: Leaking ParsedOperands on failure. 780 return true; 781 782 if (Lexer.isNot(AsmToken::EndOfStatement)) 783 // FIXME: Leaking ParsedOperands on failure. 784 return TokError("unexpected token in argument list"); 785 786 // Eat the end of statement marker. 787 Lex(); 788 789 790 MCInst Inst; 791 792 bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst); 793 794 // Free any parsed operands. 795 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) 796 delete ParsedOperands[i]; 797 798 if (MatchFail) { 799 // FIXME: We should give nicer diagnostics about the exact failure. 800 Error(IDLoc, "unrecognized instruction"); 801 return true; 802 } 803 804 // Instruction is good, process it. 805 Out.EmitInstruction(Inst); 806 807 // Skip to end of line for now. 808 return false; 809} 810 811bool AsmParser::ParseAssignment(const StringRef &Name) { 812 // FIXME: Use better location, we should use proper tokens. 813 SMLoc EqualLoc = Lexer.getLoc(); 814 815 const MCExpr *Value; 816 SMLoc StartLoc = Lexer.getLoc(); 817 if (ParseExpression(Value)) 818 return true; 819 820 if (Lexer.isNot(AsmToken::EndOfStatement)) 821 return TokError("unexpected token in assignment"); 822 823 // Eat the end of statement marker. 824 Lex(); 825 826 // Validate that the LHS is allowed to be a variable (either it has not been 827 // used as a symbol, or it is an absolute symbol). 828 MCSymbol *Sym = getContext().LookupSymbol(Name); 829 if (Sym) { 830 // Diagnose assignment to a label. 831 // 832 // FIXME: Diagnostics. Note the location of the definition as a label. 833 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 834 if (!Sym->isUndefined() && !Sym->isAbsolute()) 835 return Error(EqualLoc, "redefinition of '" + Name + "'"); 836 else if (!Sym->isVariable()) 837 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 838 else if (!isa<MCConstantExpr>(Sym->getValue())) 839 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 840 Name + "'"); 841 } else 842 Sym = CreateSymbol(Name); 843 844 // FIXME: Handle '.'. 845 846 // Do the assignment. 847 Out.EmitAssignment(Sym, Value); 848 849 return false; 850} 851 852/// ParseIdentifier: 853/// ::= identifier 854/// ::= string 855bool AsmParser::ParseIdentifier(StringRef &Res) { 856 if (Lexer.isNot(AsmToken::Identifier) && 857 Lexer.isNot(AsmToken::String)) 858 return true; 859 860 Res = getTok().getIdentifier(); 861 862 Lex(); // Consume the identifier token. 863 864 return false; 865} 866 867/// ParseDirectiveSet: 868/// ::= .set identifier ',' expression 869bool AsmParser::ParseDirectiveSet() { 870 StringRef Name; 871 872 if (ParseIdentifier(Name)) 873 return TokError("expected identifier after '.set' directive"); 874 875 if (Lexer.isNot(AsmToken::Comma)) 876 return TokError("unexpected token in '.set'"); 877 Lex(); 878 879 return ParseAssignment(Name); 880} 881 882/// ParseDirectiveSection: 883/// ::= .section identifier (',' identifier)* 884/// FIXME: This should actually parse out the segment, section, attributes and 885/// sizeof_stub fields. 886bool AsmParser::ParseDirectiveDarwinSection() { 887 SMLoc Loc = Lexer.getLoc(); 888 889 StringRef SectionName; 890 if (ParseIdentifier(SectionName)) 891 return Error(Loc, "expected identifier after '.section' directive"); 892 893 // Verify there is a following comma. 894 if (!Lexer.is(AsmToken::Comma)) 895 return TokError("unexpected token in '.section' directive"); 896 897 std::string SectionSpec = SectionName; 898 SectionSpec += ","; 899 900 // Add all the tokens until the end of the line, ParseSectionSpecifier will 901 // handle this. 902 StringRef EOL = Lexer.LexUntilEndOfStatement(); 903 SectionSpec.append(EOL.begin(), EOL.end()); 904 905 Lex(); 906 if (Lexer.isNot(AsmToken::EndOfStatement)) 907 return TokError("unexpected token in '.section' directive"); 908 Lex(); 909 910 911 StringRef Segment, Section; 912 unsigned TAA, StubSize; 913 std::string ErrorStr = 914 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, 915 TAA, StubSize); 916 917 if (!ErrorStr.empty()) 918 return Error(Loc, ErrorStr.c_str()); 919 920 // FIXME: Arch specific. 921 bool isText = Segment == "__TEXT"; // FIXME: Hack. 922 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize, 923 isText ? SectionKind::getText() 924 : SectionKind::getDataRel())); 925 return false; 926} 927 928/// ParseDirectiveSectionSwitch - 929bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment, 930 const char *Section, 931 unsigned TAA, unsigned Align, 932 unsigned StubSize) { 933 if (Lexer.isNot(AsmToken::EndOfStatement)) 934 return TokError("unexpected token in section switching directive"); 935 Lex(); 936 937 // FIXME: Arch specific. 938 bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack. 939 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize, 940 isText ? SectionKind::getText() 941 : SectionKind::getDataRel())); 942 943 // Set the implicit alignment, if any. 944 // 945 // FIXME: This isn't really what 'as' does; I think it just uses the implicit 946 // alignment on the section (e.g., if one manually inserts bytes into the 947 // section, then just issueing the section switch directive will not realign 948 // the section. However, this is arguably more reasonable behavior, and there 949 // is no good reason for someone to intentionally emit incorrectly sized 950 // values into the implicitly aligned sections. 951 if (Align) 952 Out.EmitValueToAlignment(Align, 0, 1, 0); 953 954 return false; 955} 956 957bool AsmParser::ParseEscapedString(std::string &Data) { 958 assert(Lexer.is(AsmToken::String) && "Unexpected current token!"); 959 960 Data = ""; 961 StringRef Str = getTok().getStringContents(); 962 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 963 if (Str[i] != '\\') { 964 Data += Str[i]; 965 continue; 966 } 967 968 // Recognize escaped characters. Note that this escape semantics currently 969 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 970 ++i; 971 if (i == e) 972 return TokError("unexpected backslash at end of string"); 973 974 // Recognize octal sequences. 975 if ((unsigned) (Str[i] - '0') <= 7) { 976 // Consume up to three octal characters. 977 unsigned Value = Str[i] - '0'; 978 979 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 980 ++i; 981 Value = Value * 8 + (Str[i] - '0'); 982 983 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 984 ++i; 985 Value = Value * 8 + (Str[i] - '0'); 986 } 987 } 988 989 if (Value > 255) 990 return TokError("invalid octal escape sequence (out of range)"); 991 992 Data += (unsigned char) Value; 993 continue; 994 } 995 996 // Otherwise recognize individual escapes. 997 switch (Str[i]) { 998 default: 999 // Just reject invalid escape sequences for now. 1000 return TokError("invalid escape sequence (unrecognized character)"); 1001 1002 case 'b': Data += '\b'; break; 1003 case 'f': Data += '\f'; break; 1004 case 'n': Data += '\n'; break; 1005 case 'r': Data += '\r'; break; 1006 case 't': Data += '\t'; break; 1007 case '"': Data += '"'; break; 1008 case '\\': Data += '\\'; break; 1009 } 1010 } 1011 1012 return false; 1013} 1014 1015/// ParseDirectiveAscii: 1016/// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ] 1017bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) { 1018 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1019 for (;;) { 1020 if (Lexer.isNot(AsmToken::String)) 1021 return TokError("expected string in '.ascii' or '.asciz' directive"); 1022 1023 std::string Data; 1024 if (ParseEscapedString(Data)) 1025 return true; 1026 1027 Out.EmitBytes(Data, DEFAULT_ADDRSPACE); 1028 if (ZeroTerminated) 1029 Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE); 1030 1031 Lex(); 1032 1033 if (Lexer.is(AsmToken::EndOfStatement)) 1034 break; 1035 1036 if (Lexer.isNot(AsmToken::Comma)) 1037 return TokError("unexpected token in '.ascii' or '.asciz' directive"); 1038 Lex(); 1039 } 1040 } 1041 1042 Lex(); 1043 return false; 1044} 1045 1046/// ParseDirectiveValue 1047/// ::= (.byte | .short | ... ) [ expression (, expression)* ] 1048bool AsmParser::ParseDirectiveValue(unsigned Size) { 1049 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1050 for (;;) { 1051 const MCExpr *Value; 1052 SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc(); 1053 if (ParseExpression(Value)) 1054 return true; 1055 1056 Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE); 1057 1058 if (Lexer.is(AsmToken::EndOfStatement)) 1059 break; 1060 1061 // FIXME: Improve diagnostic. 1062 if (Lexer.isNot(AsmToken::Comma)) 1063 return TokError("unexpected token in directive"); 1064 Lex(); 1065 } 1066 } 1067 1068 Lex(); 1069 return false; 1070} 1071 1072/// ParseDirectiveSpace 1073/// ::= .space expression [ , expression ] 1074bool AsmParser::ParseDirectiveSpace() { 1075 int64_t NumBytes; 1076 if (ParseAbsoluteExpression(NumBytes)) 1077 return true; 1078 1079 int64_t FillExpr = 0; 1080 bool HasFillExpr = false; 1081 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1082 if (Lexer.isNot(AsmToken::Comma)) 1083 return TokError("unexpected token in '.space' directive"); 1084 Lex(); 1085 1086 if (ParseAbsoluteExpression(FillExpr)) 1087 return true; 1088 1089 HasFillExpr = true; 1090 1091 if (Lexer.isNot(AsmToken::EndOfStatement)) 1092 return TokError("unexpected token in '.space' directive"); 1093 } 1094 1095 Lex(); 1096 1097 if (NumBytes <= 0) 1098 return TokError("invalid number of bytes in '.space' directive"); 1099 1100 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 1101 Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE); 1102 1103 return false; 1104} 1105 1106/// ParseDirectiveFill 1107/// ::= .fill expression , expression , expression 1108bool AsmParser::ParseDirectiveFill() { 1109 int64_t NumValues; 1110 if (ParseAbsoluteExpression(NumValues)) 1111 return true; 1112 1113 if (Lexer.isNot(AsmToken::Comma)) 1114 return TokError("unexpected token in '.fill' directive"); 1115 Lex(); 1116 1117 int64_t FillSize; 1118 if (ParseAbsoluteExpression(FillSize)) 1119 return true; 1120 1121 if (Lexer.isNot(AsmToken::Comma)) 1122 return TokError("unexpected token in '.fill' directive"); 1123 Lex(); 1124 1125 int64_t FillExpr; 1126 if (ParseAbsoluteExpression(FillExpr)) 1127 return true; 1128 1129 if (Lexer.isNot(AsmToken::EndOfStatement)) 1130 return TokError("unexpected token in '.fill' directive"); 1131 1132 Lex(); 1133 1134 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) 1135 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); 1136 1137 for (uint64_t i = 0, e = NumValues; i != e; ++i) 1138 Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize, 1139 DEFAULT_ADDRSPACE); 1140 1141 return false; 1142} 1143 1144/// ParseDirectiveOrg 1145/// ::= .org expression [ , expression ] 1146bool AsmParser::ParseDirectiveOrg() { 1147 const MCExpr *Offset; 1148 SMLoc StartLoc = Lexer.getLoc(); 1149 if (ParseExpression(Offset)) 1150 return true; 1151 1152 // Parse optional fill expression. 1153 int64_t FillExpr = 0; 1154 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1155 if (Lexer.isNot(AsmToken::Comma)) 1156 return TokError("unexpected token in '.org' directive"); 1157 Lex(); 1158 1159 if (ParseAbsoluteExpression(FillExpr)) 1160 return true; 1161 1162 if (Lexer.isNot(AsmToken::EndOfStatement)) 1163 return TokError("unexpected token in '.org' directive"); 1164 } 1165 1166 Lex(); 1167 1168 // FIXME: Only limited forms of relocatable expressions are accepted here, it 1169 // has to be relative to the current section. 1170 Out.EmitValueToOffset(Offset, FillExpr); 1171 1172 return false; 1173} 1174 1175/// ParseDirectiveAlign 1176/// ::= {.align, ...} expression [ , expression [ , expression ]] 1177bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 1178 SMLoc AlignmentLoc = Lexer.getLoc(); 1179 int64_t Alignment; 1180 if (ParseAbsoluteExpression(Alignment)) 1181 return true; 1182 1183 SMLoc MaxBytesLoc; 1184 bool HasFillExpr = false; 1185 int64_t FillExpr = 0; 1186 int64_t MaxBytesToFill = 0; 1187 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1188 if (Lexer.isNot(AsmToken::Comma)) 1189 return TokError("unexpected token in directive"); 1190 Lex(); 1191 1192 // The fill expression can be omitted while specifying a maximum number of 1193 // alignment bytes, e.g: 1194 // .align 3,,4 1195 if (Lexer.isNot(AsmToken::Comma)) { 1196 HasFillExpr = true; 1197 if (ParseAbsoluteExpression(FillExpr)) 1198 return true; 1199 } 1200 1201 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1202 if (Lexer.isNot(AsmToken::Comma)) 1203 return TokError("unexpected token in directive"); 1204 Lex(); 1205 1206 MaxBytesLoc = Lexer.getLoc(); 1207 if (ParseAbsoluteExpression(MaxBytesToFill)) 1208 return true; 1209 1210 if (Lexer.isNot(AsmToken::EndOfStatement)) 1211 return TokError("unexpected token in directive"); 1212 } 1213 } 1214 1215 Lex(); 1216 1217 if (!HasFillExpr) { 1218 // FIXME: Sometimes fill with nop. 1219 FillExpr = 0; 1220 } 1221 1222 // Compute alignment in bytes. 1223 if (IsPow2) { 1224 // FIXME: Diagnose overflow. 1225 if (Alignment >= 32) { 1226 Error(AlignmentLoc, "invalid alignment value"); 1227 Alignment = 31; 1228 } 1229 1230 Alignment = 1ULL << Alignment; 1231 } 1232 1233 // Diagnose non-sensical max bytes to align. 1234 if (MaxBytesLoc.isValid()) { 1235 if (MaxBytesToFill < 1) { 1236 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 1237 "many bytes, ignoring maximum bytes expression"); 1238 MaxBytesToFill = 0; 1239 } 1240 1241 if (MaxBytesToFill >= Alignment) { 1242 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 1243 "has no effect"); 1244 MaxBytesToFill = 0; 1245 } 1246 } 1247 1248 // FIXME: hard code the parser to use EmitCodeAlignment for text when using 1249 // the TextAlignFillValue. 1250 if(Out.getCurrentSection()->getKind().isText() && 1251 Lexer.getMAI().getTextAlignFillValue() == FillExpr) 1252 Out.EmitCodeAlignment(Alignment, MaxBytesToFill); 1253 else 1254 // FIXME: Target specific behavior about how the "extra" bytes are filled. 1255 Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill); 1256 1257 return false; 1258} 1259 1260/// ParseDirectiveSymbolAttribute 1261/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 1262bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 1263 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1264 for (;;) { 1265 StringRef Name; 1266 1267 if (ParseIdentifier(Name)) 1268 return TokError("expected identifier in directive"); 1269 1270 MCSymbol *Sym = CreateSymbol(Name); 1271 1272 Out.EmitSymbolAttribute(Sym, Attr); 1273 1274 if (Lexer.is(AsmToken::EndOfStatement)) 1275 break; 1276 1277 if (Lexer.isNot(AsmToken::Comma)) 1278 return TokError("unexpected token in directive"); 1279 Lex(); 1280 } 1281 } 1282 1283 Lex(); 1284 return false; 1285} 1286 1287/// ParseDirectiveDarwinSymbolDesc 1288/// ::= .desc identifier , expression 1289bool AsmParser::ParseDirectiveDarwinSymbolDesc() { 1290 StringRef Name; 1291 if (ParseIdentifier(Name)) 1292 return TokError("expected identifier in directive"); 1293 1294 // Handle the identifier as the key symbol. 1295 MCSymbol *Sym = CreateSymbol(Name); 1296 1297 if (Lexer.isNot(AsmToken::Comma)) 1298 return TokError("unexpected token in '.desc' directive"); 1299 Lex(); 1300 1301 SMLoc DescLoc = Lexer.getLoc(); 1302 int64_t DescValue; 1303 if (ParseAbsoluteExpression(DescValue)) 1304 return true; 1305 1306 if (Lexer.isNot(AsmToken::EndOfStatement)) 1307 return TokError("unexpected token in '.desc' directive"); 1308 1309 Lex(); 1310 1311 // Set the n_desc field of this Symbol to this DescValue 1312 Out.EmitSymbolDesc(Sym, DescValue); 1313 1314 return false; 1315} 1316 1317/// ParseDirectiveComm 1318/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 1319bool AsmParser::ParseDirectiveComm(bool IsLocal) { 1320 SMLoc IDLoc = Lexer.getLoc(); 1321 StringRef Name; 1322 if (ParseIdentifier(Name)) 1323 return TokError("expected identifier in directive"); 1324 1325 // Handle the identifier as the key symbol. 1326 MCSymbol *Sym = CreateSymbol(Name); 1327 1328 if (Lexer.isNot(AsmToken::Comma)) 1329 return TokError("unexpected token in directive"); 1330 Lex(); 1331 1332 int64_t Size; 1333 SMLoc SizeLoc = Lexer.getLoc(); 1334 if (ParseAbsoluteExpression(Size)) 1335 return true; 1336 1337 int64_t Pow2Alignment = 0; 1338 SMLoc Pow2AlignmentLoc; 1339 if (Lexer.is(AsmToken::Comma)) { 1340 Lex(); 1341 Pow2AlignmentLoc = Lexer.getLoc(); 1342 if (ParseAbsoluteExpression(Pow2Alignment)) 1343 return true; 1344 1345 // If this target takes alignments in bytes (not log) validate and convert. 1346 if (Lexer.getMAI().getAlignmentIsInBytes()) { 1347 if (!isPowerOf2_64(Pow2Alignment)) 1348 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 1349 Pow2Alignment = Log2_64(Pow2Alignment); 1350 } 1351 } 1352 1353 if (Lexer.isNot(AsmToken::EndOfStatement)) 1354 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 1355 1356 Lex(); 1357 1358 // NOTE: a size of zero for a .comm should create a undefined symbol 1359 // but a size of .lcomm creates a bss symbol of size zero. 1360 if (Size < 0) 1361 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 1362 "be less than zero"); 1363 1364 // NOTE: The alignment in the directive is a power of 2 value, the assember 1365 // may internally end up wanting an alignment in bytes. 1366 // FIXME: Diagnose overflow. 1367 if (Pow2Alignment < 0) 1368 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 1369 "alignment, can't be less than zero"); 1370 1371 if (!Sym->isUndefined()) 1372 return Error(IDLoc, "invalid symbol redefinition"); 1373 1374 // '.lcomm' is equivalent to '.zerofill'. 1375 // Create the Symbol as a common or local common with Size and Pow2Alignment 1376 if (IsLocal) { 1377 Out.EmitZerofill(getMachOSection("__DATA", "__bss", 1378 MCSectionMachO::S_ZEROFILL, 0, 1379 SectionKind::getBSS()), 1380 Sym, Size, 1 << Pow2Alignment); 1381 return false; 1382 } 1383 1384 Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 1385 return false; 1386} 1387 1388/// ParseDirectiveDarwinZerofill 1389/// ::= .zerofill segname , sectname [, identifier , size_expression [ 1390/// , align_expression ]] 1391bool AsmParser::ParseDirectiveDarwinZerofill() { 1392 // FIXME: Handle quoted names here. 1393 1394 if (Lexer.isNot(AsmToken::Identifier)) 1395 return TokError("expected segment name after '.zerofill' directive"); 1396 StringRef Segment = getTok().getString(); 1397 Lex(); 1398 1399 if (Lexer.isNot(AsmToken::Comma)) 1400 return TokError("unexpected token in directive"); 1401 Lex(); 1402 1403 if (Lexer.isNot(AsmToken::Identifier)) 1404 return TokError("expected section name after comma in '.zerofill' " 1405 "directive"); 1406 StringRef Section = getTok().getString(); 1407 Lex(); 1408 1409 // If this is the end of the line all that was wanted was to create the 1410 // the section but with no symbol. 1411 if (Lexer.is(AsmToken::EndOfStatement)) { 1412 // Create the zerofill section but no symbol 1413 Out.EmitZerofill(getMachOSection(Segment, Section, 1414 MCSectionMachO::S_ZEROFILL, 0, 1415 SectionKind::getBSS())); 1416 return false; 1417 } 1418 1419 if (Lexer.isNot(AsmToken::Comma)) 1420 return TokError("unexpected token in directive"); 1421 Lex(); 1422 1423 if (Lexer.isNot(AsmToken::Identifier)) 1424 return TokError("expected identifier in directive"); 1425 1426 // handle the identifier as the key symbol. 1427 SMLoc IDLoc = Lexer.getLoc(); 1428 MCSymbol *Sym = CreateSymbol(getTok().getString()); 1429 Lex(); 1430 1431 if (Lexer.isNot(AsmToken::Comma)) 1432 return TokError("unexpected token in directive"); 1433 Lex(); 1434 1435 int64_t Size; 1436 SMLoc SizeLoc = Lexer.getLoc(); 1437 if (ParseAbsoluteExpression(Size)) 1438 return true; 1439 1440 int64_t Pow2Alignment = 0; 1441 SMLoc Pow2AlignmentLoc; 1442 if (Lexer.is(AsmToken::Comma)) { 1443 Lex(); 1444 Pow2AlignmentLoc = Lexer.getLoc(); 1445 if (ParseAbsoluteExpression(Pow2Alignment)) 1446 return true; 1447 } 1448 1449 if (Lexer.isNot(AsmToken::EndOfStatement)) 1450 return TokError("unexpected token in '.zerofill' directive"); 1451 1452 Lex(); 1453 1454 if (Size < 0) 1455 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 1456 "than zero"); 1457 1458 // NOTE: The alignment in the directive is a power of 2 value, the assember 1459 // may internally end up wanting an alignment in bytes. 1460 // FIXME: Diagnose overflow. 1461 if (Pow2Alignment < 0) 1462 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 1463 "can't be less than zero"); 1464 1465 if (!Sym->isUndefined()) 1466 return Error(IDLoc, "invalid symbol redefinition"); 1467 1468 // Create the zerofill Symbol with Size and Pow2Alignment 1469 // 1470 // FIXME: Arch specific. 1471 Out.EmitZerofill(getMachOSection(Segment, Section, 1472 MCSectionMachO::S_ZEROFILL, 0, 1473 SectionKind::getBSS()), 1474 Sym, Size, 1 << Pow2Alignment); 1475 1476 return false; 1477} 1478 1479/// ParseDirectiveDarwinSubsectionsViaSymbols 1480/// ::= .subsections_via_symbols 1481bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() { 1482 if (Lexer.isNot(AsmToken::EndOfStatement)) 1483 return TokError("unexpected token in '.subsections_via_symbols' directive"); 1484 1485 Lex(); 1486 1487 Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1488 1489 return false; 1490} 1491 1492/// ParseDirectiveAbort 1493/// ::= .abort [ "abort_string" ] 1494bool AsmParser::ParseDirectiveAbort() { 1495 // FIXME: Use loc from directive. 1496 SMLoc Loc = Lexer.getLoc(); 1497 1498 StringRef Str = ""; 1499 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1500 if (Lexer.isNot(AsmToken::String)) 1501 return TokError("expected string in '.abort' directive"); 1502 1503 Str = getTok().getString(); 1504 1505 Lex(); 1506 } 1507 1508 if (Lexer.isNot(AsmToken::EndOfStatement)) 1509 return TokError("unexpected token in '.abort' directive"); 1510 1511 Lex(); 1512 1513 // FIXME: Handle here. 1514 if (Str.empty()) 1515 Error(Loc, ".abort detected. Assembly stopping."); 1516 else 1517 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 1518 1519 return false; 1520} 1521 1522/// ParseDirectiveLsym 1523/// ::= .lsym identifier , expression 1524bool AsmParser::ParseDirectiveDarwinLsym() { 1525 StringRef Name; 1526 if (ParseIdentifier(Name)) 1527 return TokError("expected identifier in directive"); 1528 1529 // Handle the identifier as the key symbol. 1530 MCSymbol *Sym = CreateSymbol(Name); 1531 1532 if (Lexer.isNot(AsmToken::Comma)) 1533 return TokError("unexpected token in '.lsym' directive"); 1534 Lex(); 1535 1536 const MCExpr *Value; 1537 SMLoc StartLoc = Lexer.getLoc(); 1538 if (ParseExpression(Value)) 1539 return true; 1540 1541 if (Lexer.isNot(AsmToken::EndOfStatement)) 1542 return TokError("unexpected token in '.lsym' directive"); 1543 1544 Lex(); 1545 1546 // We don't currently support this directive. 1547 // 1548 // FIXME: Diagnostic location! 1549 (void) Sym; 1550 return TokError("directive '.lsym' is unsupported"); 1551} 1552 1553/// ParseDirectiveInclude 1554/// ::= .include "filename" 1555bool AsmParser::ParseDirectiveInclude() { 1556 if (Lexer.isNot(AsmToken::String)) 1557 return TokError("expected string in '.include' directive"); 1558 1559 std::string Filename = getTok().getString(); 1560 SMLoc IncludeLoc = Lexer.getLoc(); 1561 Lex(); 1562 1563 if (Lexer.isNot(AsmToken::EndOfStatement)) 1564 return TokError("unexpected token in '.include' directive"); 1565 1566 // Strip the quotes. 1567 Filename = Filename.substr(1, Filename.size()-2); 1568 1569 // Attempt to switch the lexer to the included file before consuming the end 1570 // of statement to avoid losing it when we switch. 1571 if (EnterIncludeFile(Filename)) { 1572 PrintMessage(IncludeLoc, 1573 "Could not find include file '" + Filename + "'", 1574 "error"); 1575 return true; 1576 } 1577 1578 return false; 1579} 1580 1581/// ParseDirectiveDarwinDumpOrLoad 1582/// ::= ( .dump | .load ) "filename" 1583bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) { 1584 if (Lexer.isNot(AsmToken::String)) 1585 return TokError("expected string in '.dump' or '.load' directive"); 1586 1587 Lex(); 1588 1589 if (Lexer.isNot(AsmToken::EndOfStatement)) 1590 return TokError("unexpected token in '.dump' or '.load' directive"); 1591 1592 Lex(); 1593 1594 // FIXME: If/when .dump and .load are implemented they will be done in the 1595 // the assembly parser and not have any need for an MCStreamer API. 1596 if (IsDump) 1597 Warning(IDLoc, "ignoring directive .dump for now"); 1598 else 1599 Warning(IDLoc, "ignoring directive .load for now"); 1600 1601 return false; 1602} 1603 1604/// ParseDirectiveIf 1605/// ::= .if expression 1606bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { 1607 // Consume the identifier that was the .if directive 1608 Lex(); 1609 1610 TheCondStack.push_back(TheCondState); 1611 TheCondState.TheCond = AsmCond::IfCond; 1612 if(TheCondState.Ignore) { 1613 EatToEndOfStatement(); 1614 } 1615 else { 1616 int64_t ExprValue; 1617 if (ParseAbsoluteExpression(ExprValue)) 1618 return true; 1619 1620 if (Lexer.isNot(AsmToken::EndOfStatement)) 1621 return TokError("unexpected token in '.if' directive"); 1622 1623 Lex(); 1624 1625 TheCondState.CondMet = ExprValue; 1626 TheCondState.Ignore = !TheCondState.CondMet; 1627 } 1628 1629 return false; 1630} 1631 1632/// ParseDirectiveElseIf 1633/// ::= .elseif expression 1634bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { 1635 if (TheCondState.TheCond != AsmCond::IfCond && 1636 TheCondState.TheCond != AsmCond::ElseIfCond) 1637 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 1638 " an .elseif"); 1639 TheCondState.TheCond = AsmCond::ElseIfCond; 1640 1641 // Consume the identifier that was the .elseif directive 1642 Lex(); 1643 1644 bool LastIgnoreState = false; 1645 if (!TheCondStack.empty()) 1646 LastIgnoreState = TheCondStack.back().Ignore; 1647 if (LastIgnoreState || TheCondState.CondMet) { 1648 TheCondState.Ignore = true; 1649 EatToEndOfStatement(); 1650 } 1651 else { 1652 int64_t ExprValue; 1653 if (ParseAbsoluteExpression(ExprValue)) 1654 return true; 1655 1656 if (Lexer.isNot(AsmToken::EndOfStatement)) 1657 return TokError("unexpected token in '.elseif' directive"); 1658 1659 Lex(); 1660 TheCondState.CondMet = ExprValue; 1661 TheCondState.Ignore = !TheCondState.CondMet; 1662 } 1663 1664 return false; 1665} 1666 1667/// ParseDirectiveElse 1668/// ::= .else 1669bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { 1670 // Consume the identifier that was the .else directive 1671 Lex(); 1672 1673 if (Lexer.isNot(AsmToken::EndOfStatement)) 1674 return TokError("unexpected token in '.else' directive"); 1675 1676 Lex(); 1677 1678 if (TheCondState.TheCond != AsmCond::IfCond && 1679 TheCondState.TheCond != AsmCond::ElseIfCond) 1680 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 1681 ".elseif"); 1682 TheCondState.TheCond = AsmCond::ElseCond; 1683 bool LastIgnoreState = false; 1684 if (!TheCondStack.empty()) 1685 LastIgnoreState = TheCondStack.back().Ignore; 1686 if (LastIgnoreState || TheCondState.CondMet) 1687 TheCondState.Ignore = true; 1688 else 1689 TheCondState.Ignore = false; 1690 1691 return false; 1692} 1693 1694/// ParseDirectiveEndIf 1695/// ::= .endif 1696bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { 1697 // Consume the identifier that was the .endif directive 1698 Lex(); 1699 1700 if (Lexer.isNot(AsmToken::EndOfStatement)) 1701 return TokError("unexpected token in '.endif' directive"); 1702 1703 Lex(); 1704 1705 if ((TheCondState.TheCond == AsmCond::NoCond) || 1706 TheCondStack.empty()) 1707 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 1708 ".else"); 1709 if (!TheCondStack.empty()) { 1710 TheCondState = TheCondStack.back(); 1711 TheCondStack.pop_back(); 1712 } 1713 1714 return false; 1715} 1716 1717/// ParseDirectiveFile 1718/// ::= .file [number] string 1719bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { 1720 // FIXME: I'm not sure what this is. 1721 int64_t FileNumber = -1; 1722 if (Lexer.is(AsmToken::Integer)) { 1723 FileNumber = getTok().getIntVal(); 1724 Lex(); 1725 1726 if (FileNumber < 1) 1727 return TokError("file number less than one"); 1728 } 1729 1730 if (Lexer.isNot(AsmToken::String)) 1731 return TokError("unexpected token in '.file' directive"); 1732 1733 StringRef Filename = getTok().getString(); 1734 Filename = Filename.substr(1, Filename.size()-2); 1735 Lex(); 1736 1737 if (Lexer.isNot(AsmToken::EndOfStatement)) 1738 return TokError("unexpected token in '.file' directive"); 1739 1740 if (FileNumber == -1) 1741 Out.EmitFileDirective(Filename); 1742 else 1743 Out.EmitDwarfFileDirective(FileNumber, Filename); 1744 1745 return false; 1746} 1747 1748/// ParseDirectiveLine 1749/// ::= .line [number] 1750bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { 1751 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1752 if (Lexer.isNot(AsmToken::Integer)) 1753 return TokError("unexpected token in '.line' directive"); 1754 1755 int64_t LineNumber = getTok().getIntVal(); 1756 (void) LineNumber; 1757 Lex(); 1758 1759 // FIXME: Do something with the .line. 1760 } 1761 1762 if (Lexer.isNot(AsmToken::EndOfStatement)) 1763 return TokError("unexpected token in '.file' directive"); 1764 1765 return false; 1766} 1767 1768 1769/// ParseDirectiveLoc 1770/// ::= .loc number [number [number]] 1771bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) { 1772 if (Lexer.isNot(AsmToken::Integer)) 1773 return TokError("unexpected token in '.loc' directive"); 1774 1775 // FIXME: What are these fields? 1776 int64_t FileNumber = getTok().getIntVal(); 1777 (void) FileNumber; 1778 // FIXME: Validate file. 1779 1780 Lex(); 1781 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1782 if (Lexer.isNot(AsmToken::Integer)) 1783 return TokError("unexpected token in '.loc' directive"); 1784 1785 int64_t Param2 = getTok().getIntVal(); 1786 (void) Param2; 1787 Lex(); 1788 1789 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1790 if (Lexer.isNot(AsmToken::Integer)) 1791 return TokError("unexpected token in '.loc' directive"); 1792 1793 int64_t Param3 = getTok().getIntVal(); 1794 (void) Param3; 1795 Lex(); 1796 1797 // FIXME: Do something with the .loc. 1798 } 1799 } 1800 1801 if (Lexer.isNot(AsmToken::EndOfStatement)) 1802 return TokError("unexpected token in '.file' directive"); 1803 1804 return false; 1805} 1806
|