llvm-mc: Parse .{,b,p2}align{,w,l} directives.
[oota-llvm.git] / tools / llvm-mc / AsmParser.cpp
1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This class implements the parser for assembly files.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "AsmParser.h"
15
16 #include "AsmExpr.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "llvm/Support/raw_ostream.h"
23 using namespace llvm;
24
25 bool AsmParser::Error(SMLoc L, const char *Msg) {
26   Lexer.PrintMessage(L, Msg);
27   return true;
28 }
29
30 bool AsmParser::TokError(const char *Msg) {
31   Lexer.PrintMessage(Lexer.getLoc(), Msg);
32   return true;
33 }
34
35 bool AsmParser::Run() {
36   // Prime the lexer.
37   Lexer.Lex();
38   
39   while (Lexer.isNot(asmtok::Eof))
40     if (ParseStatement())
41       return true;
42   
43   return false;
44 }
45
46 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
47 void AsmParser::EatToEndOfStatement() {
48   while (Lexer.isNot(asmtok::EndOfStatement) &&
49          Lexer.isNot(asmtok::Eof))
50     Lexer.Lex();
51   
52   // Eat EOL.
53   if (Lexer.is(asmtok::EndOfStatement))
54     Lexer.Lex();
55 }
56
57
58 /// ParseParenExpr - Parse a paren expression and return it.
59 /// NOTE: This assumes the leading '(' has already been consumed.
60 ///
61 /// parenexpr ::= expr)
62 ///
63 bool AsmParser::ParseParenExpr(AsmExpr *&Res) {
64   if (ParseExpression(Res)) return true;
65   if (Lexer.isNot(asmtok::RParen))
66     return TokError("expected ')' in parentheses expression");
67   Lexer.Lex();
68   return false;
69 }
70
71 /// ParsePrimaryExpr - Parse a primary expression and return it.
72 ///  primaryexpr ::= (parenexpr
73 ///  primaryexpr ::= symbol
74 ///  primaryexpr ::= number
75 ///  primaryexpr ::= ~,+,- primaryexpr
76 bool AsmParser::ParsePrimaryExpr(AsmExpr *&Res) {
77   switch (Lexer.getKind()) {
78   default:
79     return TokError("unknown token in expression");
80   case asmtok::Exclaim:
81     Lexer.Lex(); // Eat the operator.
82     if (ParsePrimaryExpr(Res))
83       return true;
84     Res = new AsmUnaryExpr(AsmUnaryExpr::LNot, Res);
85     return false;
86   case asmtok::Identifier: {
87     // This is a label, this should be parsed as part of an expression, to
88     // handle things like LFOO+4.
89     MCSymbol *Sym = Ctx.GetOrCreateSymbol(Lexer.getCurStrVal());
90
91     // If this is use of an undefined symbol then mark it external.
92     if (!Sym->getSection() && !Ctx.GetSymbolValue(Sym))
93       Sym->setExternal(true);
94     
95     Res = new AsmSymbolRefExpr(Sym);
96     Lexer.Lex(); // Eat identifier.
97     return false;
98   }
99   case asmtok::IntVal:
100     Res = new AsmConstantExpr(Lexer.getCurIntVal());
101     Lexer.Lex(); // Eat identifier.
102     return false;
103   case asmtok::LParen:
104     Lexer.Lex(); // Eat the '('.
105     return ParseParenExpr(Res);
106   case asmtok::Minus:
107     Lexer.Lex(); // Eat the operator.
108     if (ParsePrimaryExpr(Res))
109       return true;
110     Res = new AsmUnaryExpr(AsmUnaryExpr::Minus, Res);
111     return false;
112   case asmtok::Plus:
113     Lexer.Lex(); // Eat the operator.
114     if (ParsePrimaryExpr(Res))
115       return true;
116     Res = new AsmUnaryExpr(AsmUnaryExpr::Plus, Res);
117     return false;
118   case asmtok::Tilde:
119     Lexer.Lex(); // Eat the operator.
120     if (ParsePrimaryExpr(Res))
121       return true;
122     Res = new AsmUnaryExpr(AsmUnaryExpr::Not, Res);
123     return false;
124   }
125 }
126
127 /// ParseExpression - Parse an expression and return it.
128 /// 
129 ///  expr ::= expr +,- expr          -> lowest.
130 ///  expr ::= expr |,^,&,! expr      -> middle.
131 ///  expr ::= expr *,/,%,<<,>> expr  -> highest.
132 ///  expr ::= primaryexpr
133 ///
134 bool AsmParser::ParseExpression(AsmExpr *&Res) {
135   Res = 0;
136   return ParsePrimaryExpr(Res) ||
137          ParseBinOpRHS(1, Res);
138 }
139
140 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
141   AsmExpr *Expr;
142   
143   if (ParseExpression(Expr))
144     return true;
145
146   if (!Expr->EvaluateAsAbsolute(Ctx, Res))
147     return TokError("expected absolute expression");
148
149   return false;
150 }
151
152 static unsigned getBinOpPrecedence(asmtok::TokKind K, 
153                                    AsmBinaryExpr::Opcode &Kind) {
154   switch (K) {
155   default: return 0;    // not a binop.
156
157     // Lowest Precedence: &&, ||
158   case asmtok::AmpAmp:
159     Kind = AsmBinaryExpr::LAnd;
160     return 1;
161   case asmtok::PipePipe:
162     Kind = AsmBinaryExpr::LOr;
163     return 1;
164
165     // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
166   case asmtok::Plus:
167     Kind = AsmBinaryExpr::Add;
168     return 2;
169   case asmtok::Minus:
170     Kind = AsmBinaryExpr::Sub;
171     return 2;
172   case asmtok::EqualEqual:
173     Kind = AsmBinaryExpr::EQ;
174     return 2;
175   case asmtok::ExclaimEqual:
176   case asmtok::LessGreater:
177     Kind = AsmBinaryExpr::NE;
178     return 2;
179   case asmtok::Less:
180     Kind = AsmBinaryExpr::LT;
181     return 2;
182   case asmtok::LessEqual:
183     Kind = AsmBinaryExpr::LTE;
184     return 2;
185   case asmtok::Greater:
186     Kind = AsmBinaryExpr::GT;
187     return 2;
188   case asmtok::GreaterEqual:
189     Kind = AsmBinaryExpr::GTE;
190     return 2;
191
192     // Intermediate Precedence: |, &, ^
193     //
194     // FIXME: gas seems to support '!' as an infix operator?
195   case asmtok::Pipe:
196     Kind = AsmBinaryExpr::Or;
197     return 3;
198   case asmtok::Caret:
199     Kind = AsmBinaryExpr::Xor;
200     return 3;
201   case asmtok::Amp:
202     Kind = AsmBinaryExpr::And;
203     return 3;
204
205     // Highest Precedence: *, /, %, <<, >>
206   case asmtok::Star:
207     Kind = AsmBinaryExpr::Mul;
208     return 4;
209   case asmtok::Slash:
210     Kind = AsmBinaryExpr::Div;
211     return 4;
212   case asmtok::Percent:
213     Kind = AsmBinaryExpr::Mod;
214     return 4;
215   case asmtok::LessLess:
216     Kind = AsmBinaryExpr::Shl;
217     return 4;
218   case asmtok::GreaterGreater:
219     Kind = AsmBinaryExpr::Shr;
220     return 4;
221   }
222 }
223
224
225 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
226 /// Res contains the LHS of the expression on input.
227 bool AsmParser::ParseBinOpRHS(unsigned Precedence, AsmExpr *&Res) {
228   while (1) {
229     AsmBinaryExpr::Opcode Kind = AsmBinaryExpr::Add;
230     unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
231     
232     // If the next token is lower precedence than we are allowed to eat, return
233     // successfully with what we ate already.
234     if (TokPrec < Precedence)
235       return false;
236     
237     Lexer.Lex();
238     
239     // Eat the next primary expression.
240     AsmExpr *RHS;
241     if (ParsePrimaryExpr(RHS)) return true;
242     
243     // If BinOp binds less tightly with RHS than the operator after RHS, let
244     // the pending operator take RHS as its LHS.
245     AsmBinaryExpr::Opcode Dummy;
246     unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
247     if (TokPrec < NextTokPrec) {
248       if (ParseBinOpRHS(Precedence+1, RHS)) return true;
249     }
250
251     // Merge LHS and RHS according to operator.
252     Res = new AsmBinaryExpr(Kind, Res, RHS);
253   }
254 }
255
256   
257   
258   
259 /// ParseStatement:
260 ///   ::= EndOfStatement
261 ///   ::= Label* Directive ...Operands... EndOfStatement
262 ///   ::= Label* Identifier OperandList* EndOfStatement
263 bool AsmParser::ParseStatement() {
264   switch (Lexer.getKind()) {
265   default:
266     return TokError("unexpected token at start of statement");
267   case asmtok::EndOfStatement:
268     Lexer.Lex();
269     return false;
270   case asmtok::Identifier:
271     break;
272   // TODO: Recurse on local labels etc.
273   }
274   
275   // If we have an identifier, handle it as the key symbol.
276   SMLoc IDLoc = Lexer.getLoc();
277   const char *IDVal = Lexer.getCurStrVal();
278   
279   // Consume the identifier, see what is after it.
280   switch (Lexer.Lex()) {
281   case asmtok::Colon: {
282     // identifier ':'   -> Label.
283     Lexer.Lex();
284
285     // Diagnose attempt to use a variable as a label.
286     //
287     // FIXME: Diagnostics. Note the location of the definition as a label.
288     // FIXME: This doesn't diagnose assignment to a symbol which has been
289     // implicitly marked as external.
290     MCSymbol *Sym = Ctx.GetOrCreateSymbol(IDVal);
291     if (Sym->getSection())
292       return Error(IDLoc, "invalid symbol redefinition");
293     if (Ctx.GetSymbolValue(Sym))
294       return Error(IDLoc, "symbol already used as assembler variable");
295     
296     // Since we saw a label, create a symbol and emit it.
297     // FIXME: If the label starts with L it is an assembler temporary label.
298     // Why does the client of this api need to know this?
299     Out.EmitLabel(Sym);
300    
301     return ParseStatement();
302   }
303
304   case asmtok::Equal:
305     // identifier '=' ... -> assignment statement
306     Lexer.Lex();
307
308     return ParseAssignment(IDVal, false);
309
310   default: // Normal instruction or directive.
311     break;
312   }
313   
314   // Otherwise, we have a normal instruction or directive.  
315   if (IDVal[0] == '.') {
316     // FIXME: This should be driven based on a hash lookup and callback.
317     if (!strcmp(IDVal, ".section"))
318       return ParseDirectiveDarwinSection();
319     if (!strcmp(IDVal, ".text"))
320       // FIXME: This changes behavior based on the -static flag to the
321       // assembler.
322       return ParseDirectiveSectionSwitch("__TEXT,__text",
323                                          "regular,pure_instructions");
324     if (!strcmp(IDVal, ".const"))
325       return ParseDirectiveSectionSwitch("__TEXT,__const");
326     if (!strcmp(IDVal, ".static_const"))
327       return ParseDirectiveSectionSwitch("__TEXT,__static_const");
328     if (!strcmp(IDVal, ".cstring"))
329       return ParseDirectiveSectionSwitch("__TEXT,__cstring", 
330                                          "cstring_literals");
331     if (!strcmp(IDVal, ".literal4"))
332       return ParseDirectiveSectionSwitch("__TEXT,__literal4", "4byte_literals");
333     if (!strcmp(IDVal, ".literal8"))
334       return ParseDirectiveSectionSwitch("__TEXT,__literal8", "8byte_literals");
335     if (!strcmp(IDVal, ".literal16"))
336       return ParseDirectiveSectionSwitch("__TEXT,__literal16",
337                                          "16byte_literals");
338     if (!strcmp(IDVal, ".constructor"))
339       return ParseDirectiveSectionSwitch("__TEXT,__constructor");
340     if (!strcmp(IDVal, ".destructor"))
341       return ParseDirectiveSectionSwitch("__TEXT,__destructor");
342     if (!strcmp(IDVal, ".fvmlib_init0"))
343       return ParseDirectiveSectionSwitch("__TEXT,__fvmlib_init0");
344     if (!strcmp(IDVal, ".fvmlib_init1"))
345       return ParseDirectiveSectionSwitch("__TEXT,__fvmlib_init1");
346     if (!strcmp(IDVal, ".symbol_stub")) // FIXME: Different on PPC.
347       return ParseDirectiveSectionSwitch("__IMPORT,__jump_table,symbol_stubs",
348                                     "self_modifying_code+pure_instructions,5");
349     // FIXME: .picsymbol_stub on PPC.
350     if (!strcmp(IDVal, ".data"))
351       return ParseDirectiveSectionSwitch("__DATA,__data");
352     if (!strcmp(IDVal, ".static_data"))
353       return ParseDirectiveSectionSwitch("__DATA,__static_data");
354     if (!strcmp(IDVal, ".non_lazy_symbol_pointer"))
355       return ParseDirectiveSectionSwitch("__DATA,__nl_symbol_pointer",
356                                          "non_lazy_symbol_pointers");
357     if (!strcmp(IDVal, ".lazy_symbol_pointer"))
358       return ParseDirectiveSectionSwitch("__DATA,__la_symbol_pointer",
359                                          "lazy_symbol_pointers");
360     if (!strcmp(IDVal, ".dyld"))
361       return ParseDirectiveSectionSwitch("__DATA,__dyld");
362     if (!strcmp(IDVal, ".mod_init_func"))
363       return ParseDirectiveSectionSwitch("__DATA,__mod_init_func",
364                                          "mod_init_funcs");
365     if (!strcmp(IDVal, ".mod_term_func"))
366       return ParseDirectiveSectionSwitch("__DATA,__mod_term_func",
367                                          "mod_term_funcs");
368     if (!strcmp(IDVal, ".const_data"))
369       return ParseDirectiveSectionSwitch("__DATA,__const", "regular");
370     
371     
372     // FIXME: Verify attributes on sections.
373     if (!strcmp(IDVal, ".objc_class"))
374       return ParseDirectiveSectionSwitch("__OBJC,__class");
375     if (!strcmp(IDVal, ".objc_meta_class"))
376       return ParseDirectiveSectionSwitch("__OBJC,__meta_class");
377     if (!strcmp(IDVal, ".objc_cat_cls_meth"))
378       return ParseDirectiveSectionSwitch("__OBJC,__cat_cls_meth");
379     if (!strcmp(IDVal, ".objc_cat_inst_meth"))
380       return ParseDirectiveSectionSwitch("__OBJC,__cat_inst_meth");
381     if (!strcmp(IDVal, ".objc_protocol"))
382       return ParseDirectiveSectionSwitch("__OBJC,__protocol");
383     if (!strcmp(IDVal, ".objc_string_object"))
384       return ParseDirectiveSectionSwitch("__OBJC,__string_object");
385     if (!strcmp(IDVal, ".objc_cls_meth"))
386       return ParseDirectiveSectionSwitch("__OBJC,__cls_meth");
387     if (!strcmp(IDVal, ".objc_inst_meth"))
388       return ParseDirectiveSectionSwitch("__OBJC,__inst_meth");
389     if (!strcmp(IDVal, ".objc_cls_refs"))
390       return ParseDirectiveSectionSwitch("__OBJC,__cls_refs");
391     if (!strcmp(IDVal, ".objc_message_refs"))
392       return ParseDirectiveSectionSwitch("__OBJC,__message_refs");
393     if (!strcmp(IDVal, ".objc_symbols"))
394       return ParseDirectiveSectionSwitch("__OBJC,__symbols");
395     if (!strcmp(IDVal, ".objc_category"))
396       return ParseDirectiveSectionSwitch("__OBJC,__category");
397     if (!strcmp(IDVal, ".objc_class_vars"))
398       return ParseDirectiveSectionSwitch("__OBJC,__class_vars");
399     if (!strcmp(IDVal, ".objc_instance_vars"))
400       return ParseDirectiveSectionSwitch("__OBJC,__instance_vars");
401     if (!strcmp(IDVal, ".objc_module_info"))
402       return ParseDirectiveSectionSwitch("__OBJC,__module_info");
403     if (!strcmp(IDVal, ".objc_class_names"))
404       return ParseDirectiveSectionSwitch("__TEXT,__cstring","cstring_literals");
405     if (!strcmp(IDVal, ".objc_meth_var_types"))
406       return ParseDirectiveSectionSwitch("__TEXT,__cstring","cstring_literals");
407     if (!strcmp(IDVal, ".objc_meth_var_names"))
408       return ParseDirectiveSectionSwitch("__TEXT,__cstring","cstring_literals");
409     if (!strcmp(IDVal, ".objc_selector_strs"))
410       return ParseDirectiveSectionSwitch("__OBJC,__selector_strs");
411     
412     // Assembler features
413     if (!strcmp(IDVal, ".set"))
414       return ParseDirectiveSet();
415
416     // Data directives
417
418     if (!strcmp(IDVal, ".ascii"))
419       return ParseDirectiveAscii(false);
420     if (!strcmp(IDVal, ".asciz"))
421       return ParseDirectiveAscii(true);
422
423     // FIXME: Target hooks for size? Also for "word", "hword".
424     if (!strcmp(IDVal, ".byte"))
425       return ParseDirectiveValue(1);
426     if (!strcmp(IDVal, ".short"))
427       return ParseDirectiveValue(2);
428     if (!strcmp(IDVal, ".long"))
429       return ParseDirectiveValue(4);
430     if (!strcmp(IDVal, ".quad"))
431       return ParseDirectiveValue(8);
432
433     // FIXME: Target hooks for IsPow2.
434     if (!strcmp(IDVal, ".align"))
435       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
436     if (!strcmp(IDVal, ".align32"))
437       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
438     if (!strcmp(IDVal, ".balign"))
439       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
440     if (!strcmp(IDVal, ".balignw"))
441       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
442     if (!strcmp(IDVal, ".balignl"))
443       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
444     if (!strcmp(IDVal, ".p2align"))
445       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
446     if (!strcmp(IDVal, ".p2alignw"))
447       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
448     if (!strcmp(IDVal, ".p2alignl"))
449       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
450
451     if (!strcmp(IDVal, ".org"))
452       return ParseDirectiveOrg();
453
454     if (!strcmp(IDVal, ".fill"))
455       return ParseDirectiveFill();
456     if (!strcmp(IDVal, ".space"))
457       return ParseDirectiveSpace();
458
459     Lexer.PrintMessage(IDLoc, "warning: ignoring directive for now");
460     EatToEndOfStatement();
461     return false;
462   }
463
464   MCInst Inst;
465   if (ParseX86InstOperands(Inst))
466     return true;
467   
468   if (Lexer.isNot(asmtok::EndOfStatement))
469     return TokError("unexpected token in argument list");
470
471   // Eat the end of statement marker.
472   Lexer.Lex();
473   
474   // Instruction is good, process it.
475   outs() << "Found instruction: " << IDVal << " with " << Inst.getNumOperands()
476          << " operands.\n";
477   
478   // Skip to end of line for now.
479   return false;
480 }
481
482 bool AsmParser::ParseAssignment(const char *Name, bool IsDotSet) {
483   // FIXME: Use better location, we should use proper tokens.
484   SMLoc EqualLoc = Lexer.getLoc();
485
486   int64_t Value;
487   if (ParseAbsoluteExpression(Value))
488     return true;
489   
490   if (Lexer.isNot(asmtok::EndOfStatement))
491     return TokError("unexpected token in assignment");
492
493   // Eat the end of statement marker.
494   Lexer.Lex();
495
496   // Diagnose assignment to a label.
497   //
498   // FIXME: Diagnostics. Note the location of the definition as a label.
499   // FIXME: This doesn't diagnose assignment to a symbol which has been
500   // implicitly marked as external.
501   // FIXME: Handle '.'.
502   // FIXME: Diagnose assignment to protected identifier (e.g., register name).
503   MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name);
504   if (Sym->getSection())
505     return Error(EqualLoc, "invalid assignment to symbol emitted as a label");
506   if (Sym->isExternal())
507     return Error(EqualLoc, "invalid assignment to external symbol");
508
509   // Do the assignment.
510   Out.EmitAssignment(Sym, MCValue::get(Value), IsDotSet);
511
512   return false;
513 }
514
515 /// ParseDirectiveSet:
516 ///   ::= .set identifier ',' expression
517 bool AsmParser::ParseDirectiveSet() {
518   if (Lexer.isNot(asmtok::Identifier))
519     return TokError("expected identifier after '.set' directive");
520
521   const char *Name = Lexer.getCurStrVal();
522   
523   if (Lexer.Lex() != asmtok::Comma)
524     return TokError("unexpected token in '.set'");
525   Lexer.Lex();
526
527   return ParseAssignment(Name, true);
528 }
529
530 /// ParseDirectiveSection:
531 ///   ::= .section identifier (',' identifier)*
532 /// FIXME: This should actually parse out the segment, section, attributes and
533 /// sizeof_stub fields.
534 bool AsmParser::ParseDirectiveDarwinSection() {
535   if (Lexer.isNot(asmtok::Identifier))
536     return TokError("expected identifier after '.section' directive");
537   
538   std::string Section = Lexer.getCurStrVal();
539   Lexer.Lex();
540   
541   // Accept a comma separated list of modifiers.
542   while (Lexer.is(asmtok::Comma)) {
543     Lexer.Lex();
544     
545     if (Lexer.isNot(asmtok::Identifier))
546       return TokError("expected identifier in '.section' directive");
547     Section += ',';
548     Section += Lexer.getCurStrVal();
549     Lexer.Lex();
550   }
551   
552   if (Lexer.isNot(asmtok::EndOfStatement))
553     return TokError("unexpected token in '.section' directive");
554   Lexer.Lex();
555
556   Out.SwitchSection(Ctx.GetSection(Section.c_str()));
557   return false;
558 }
559
560 bool AsmParser::ParseDirectiveSectionSwitch(const char *Section,
561                                             const char *Directives) {
562   if (Lexer.isNot(asmtok::EndOfStatement))
563     return TokError("unexpected token in section switching directive");
564   Lexer.Lex();
565   
566   std::string SectionStr = Section;
567   if (Directives && Directives[0]) {
568     SectionStr += ","; 
569     SectionStr += Directives;
570   }
571   
572   Out.SwitchSection(Ctx.GetSection(Section));
573   return false;
574 }
575
576 /// ParseDirectiveAscii:
577 ///   ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
578 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
579   if (Lexer.isNot(asmtok::EndOfStatement)) {
580     for (;;) {
581       if (Lexer.isNot(asmtok::String))
582         return TokError("expected string in '.ascii' or '.asciz' directive");
583       
584       // FIXME: This shouldn't use a const char* + strlen, the string could have
585       // embedded nulls.
586       // FIXME: Should have accessor for getting string contents.
587       const char *Str = Lexer.getCurStrVal();
588       Out.EmitBytes(Str + 1, strlen(Str) - 2);
589       if (ZeroTerminated)
590         Out.EmitBytes("\0", 1);
591       
592       Lexer.Lex();
593       
594       if (Lexer.is(asmtok::EndOfStatement))
595         break;
596
597       if (Lexer.isNot(asmtok::Comma))
598         return TokError("unexpected token in '.ascii' or '.asciz' directive");
599       Lexer.Lex();
600     }
601   }
602
603   Lexer.Lex();
604   return false;
605 }
606
607 /// ParseDirectiveValue
608 ///  ::= (.byte | .short | ... ) [ expression (, expression)* ]
609 bool AsmParser::ParseDirectiveValue(unsigned Size) {
610   if (Lexer.isNot(asmtok::EndOfStatement)) {
611     for (;;) {
612       int64_t Expr;
613       if (ParseAbsoluteExpression(Expr))
614         return true;
615
616       Out.EmitValue(MCValue::get(Expr), Size);
617
618       if (Lexer.is(asmtok::EndOfStatement))
619         break;
620       
621       // FIXME: Improve diagnostic.
622       if (Lexer.isNot(asmtok::Comma))
623         return TokError("unexpected token in directive");
624       Lexer.Lex();
625     }
626   }
627
628   Lexer.Lex();
629   return false;
630 }
631
632 /// ParseDirectiveSpace
633 ///  ::= .space expression [ , expression ]
634 bool AsmParser::ParseDirectiveSpace() {
635   int64_t NumBytes;
636   if (ParseAbsoluteExpression(NumBytes))
637     return true;
638
639   int64_t FillExpr = 0;
640   bool HasFillExpr = false;
641   if (Lexer.isNot(asmtok::EndOfStatement)) {
642     if (Lexer.isNot(asmtok::Comma))
643       return TokError("unexpected token in '.space' directive");
644     Lexer.Lex();
645     
646     if (ParseAbsoluteExpression(FillExpr))
647       return true;
648
649     HasFillExpr = true;
650
651     if (Lexer.isNot(asmtok::EndOfStatement))
652       return TokError("unexpected token in '.space' directive");
653   }
654
655   Lexer.Lex();
656
657   if (NumBytes <= 0)
658     return TokError("invalid number of bytes in '.space' directive");
659
660   // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
661   for (uint64_t i = 0, e = NumBytes; i != e; ++i)
662     Out.EmitValue(MCValue::get(FillExpr), 1);
663
664   return false;
665 }
666
667 /// ParseDirectiveFill
668 ///  ::= .fill expression , expression , expression
669 bool AsmParser::ParseDirectiveFill() {
670   int64_t NumValues;
671   if (ParseAbsoluteExpression(NumValues))
672     return true;
673
674   if (Lexer.isNot(asmtok::Comma))
675     return TokError("unexpected token in '.fill' directive");
676   Lexer.Lex();
677   
678   int64_t FillSize;
679   if (ParseAbsoluteExpression(FillSize))
680     return true;
681
682   if (Lexer.isNot(asmtok::Comma))
683     return TokError("unexpected token in '.fill' directive");
684   Lexer.Lex();
685   
686   int64_t FillExpr;
687   if (ParseAbsoluteExpression(FillExpr))
688     return true;
689
690   if (Lexer.isNot(asmtok::EndOfStatement))
691     return TokError("unexpected token in '.fill' directive");
692   
693   Lexer.Lex();
694
695   if (FillSize != 1 && FillSize != 2 && FillSize != 4)
696     return TokError("invalid '.fill' size, expected 1, 2, or 4");
697
698   for (uint64_t i = 0, e = NumValues; i != e; ++i)
699     Out.EmitValue(MCValue::get(FillExpr), FillSize);
700
701   return false;
702 }
703
704 /// ParseDirectiveOrg
705 ///  ::= .org expression [ , expression ]
706 bool AsmParser::ParseDirectiveOrg() {
707   int64_t Offset;
708   if (ParseAbsoluteExpression(Offset))
709     return true;
710
711   // Parse optional fill expression.
712   int64_t FillExpr = 0;
713   if (Lexer.isNot(asmtok::EndOfStatement)) {
714     if (Lexer.isNot(asmtok::Comma))
715       return TokError("unexpected token in '.org' directive");
716     Lexer.Lex();
717     
718     if (ParseAbsoluteExpression(FillExpr))
719       return true;
720
721     if (Lexer.isNot(asmtok::EndOfStatement))
722       return TokError("unexpected token in '.org' directive");
723   }
724
725   Lexer.Lex();
726   
727   Out.EmitValueToOffset(MCValue::get(Offset), FillExpr);
728
729   return false;
730 }
731
732 /// ParseDirectiveAlign
733 ///  ::= {.align, ...} expression [ , expression [ , expression ]]
734 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
735   int64_t Alignment;
736   if (ParseAbsoluteExpression(Alignment))
737     return true;
738
739   SMLoc MaxBytesLoc;
740   bool HasFillExpr = false;
741   int64_t FillExpr = 0;
742   int64_t MaxBytesToFill = 0;
743   if (Lexer.isNot(asmtok::EndOfStatement)) {
744     if (Lexer.isNot(asmtok::Comma))
745       return TokError("unexpected token in directive");
746     Lexer.Lex();
747
748     // The fill expression can be omitted while specifying a maximum number of
749     // alignment bytes, e.g:
750     //  .align 3,,4
751     if (Lexer.isNot(asmtok::Comma)) {
752       HasFillExpr = true;
753       if (ParseAbsoluteExpression(FillExpr))
754         return true;
755     }
756
757     if (Lexer.isNot(asmtok::EndOfStatement)) {
758       if (Lexer.isNot(asmtok::Comma))
759         return TokError("unexpected token in directive");
760       Lexer.Lex();
761
762       MaxBytesLoc = Lexer.getLoc();
763       if (ParseAbsoluteExpression(MaxBytesToFill))
764         return true;
765       
766       if (Lexer.isNot(asmtok::EndOfStatement))
767         return TokError("unexpected token in directive");
768     }
769   }
770
771   Lexer.Lex();
772
773   if (!HasFillExpr) {
774     // FIXME: Sometimes fill with nop.
775     FillExpr = 0;
776   }
777
778   // Compute alignment in bytes.
779   if (IsPow2) {
780     // FIXME: Diagnose overflow.
781     Alignment = 1 << Alignment;
782   }
783
784   // Diagnose non-sensical max bytes to fill.
785   if (MaxBytesLoc.isValid()) {
786     if (MaxBytesToFill < 1) {
787       Lexer.PrintMessage(MaxBytesLoc, "warning: alignment directive can never "
788                          "be satisfied in this many bytes, ignoring");
789       return false;
790     }
791
792     if (MaxBytesToFill >= Alignment) {
793       Lexer.PrintMessage(MaxBytesLoc, "warning: maximum bytes expression "
794                          "exceeds alignment and has no effect");
795       MaxBytesToFill = 0;
796     }
797   }
798
799   // FIXME: Target specific behavior about how the "extra" bytes are filled.
800   Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
801
802   return false;
803 }
804