blob: c4cdc3c9f96fb61512c84e7d75b4e2338017f551 [file] [log] [blame]
Michael J. Spencer7d490042010-10-09 11:01:07 +00001//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
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#include "llvm/MC/MCParser/MCAsmParserExtension.h"
Jim Grosbachf2a35fb2011-07-25 17:55:35 +000011#include "llvm/ADT/StringSwitch.h"
Michael J. Spencer7d490042010-10-09 11:01:07 +000012#include "llvm/ADT/Twine.h"
13#include "llvm/MC/MCAsmInfo.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCParser/MCAsmLexer.h"
Evan Cheng0e6a0522011-07-18 20:57:22 +000016#include "llvm/MC/MCRegisterInfo.h"
Michael J. Spencer7d490042010-10-09 11:01:07 +000017#include "llvm/MC/MCSectionCOFF.h"
18#include "llvm/MC/MCStreamer.h"
Charles Davisfbc539f2011-05-22 21:12:15 +000019#include "llvm/MC/MCExpr.h"
Evan Cheng94b95502011-07-26 00:24:13 +000020#include "llvm/MC/MCTargetAsmParser.h"
Michael J. Spencer7d490042010-10-09 11:01:07 +000021#include "llvm/Support/COFF.h"
22using namespace llvm;
23
24namespace {
25
26class COFFAsmParser : public MCAsmParserExtension {
27 template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
28 void AddDirectiveHandler(StringRef Directive) {
29 getParser().AddDirectiveHandler(this, Directive,
30 HandleDirective<COFFAsmParser, Handler>);
31 }
32
33 bool ParseSectionSwitch(StringRef Section,
34 unsigned Characteristics,
35 SectionKind Kind);
36
37 virtual void Initialize(MCAsmParser &Parser) {
38 // Call the base implementation.
39 MCAsmParserExtension::Initialize(Parser);
40
41 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
42 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
43 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
44 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
45 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
46 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
47 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
Rafael Espindola8f7d12c2011-12-17 01:14:52 +000048 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
Charles Davisfbc539f2011-05-22 21:12:15 +000049
50 // Win64 EH directives.
51 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
52 ".seh_proc");
53 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
54 ".seh_endproc");
55 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
56 ".seh_startchained");
57 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
58 ".seh_endchained");
59 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
60 ".seh_handler");
61 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
62 ".seh_handlerdata");
63 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
64 ".seh_pushreg");
65 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
66 ".seh_setframe");
67 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
68 ".seh_stackalloc");
69 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
70 ".seh_savereg");
71 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
72 ".seh_savexmm");
73 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
74 ".seh_pushframe");
75 AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
76 ".seh_endprologue");
Jim Grosbachf2a35fb2011-07-25 17:55:35 +000077 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
Michael J. Spencer7d490042010-10-09 11:01:07 +000078 }
79
80 bool ParseSectionDirectiveText(StringRef, SMLoc) {
81 return ParseSectionSwitch(".text",
82 COFF::IMAGE_SCN_CNT_CODE
83 | COFF::IMAGE_SCN_MEM_EXECUTE
84 | COFF::IMAGE_SCN_MEM_READ,
85 SectionKind::getText());
86 }
87 bool ParseSectionDirectiveData(StringRef, SMLoc) {
88 return ParseSectionSwitch(".data",
89 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
90 | COFF::IMAGE_SCN_MEM_READ
91 | COFF::IMAGE_SCN_MEM_WRITE,
92 SectionKind::getDataRel());
93 }
94 bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
95 return ParseSectionSwitch(".bss",
96 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
97 | COFF::IMAGE_SCN_MEM_READ
98 | COFF::IMAGE_SCN_MEM_WRITE,
99 SectionKind::getBSS());
100 }
101
102 bool ParseDirectiveDef(StringRef, SMLoc);
103 bool ParseDirectiveScl(StringRef, SMLoc);
104 bool ParseDirectiveType(StringRef, SMLoc);
105 bool ParseDirectiveEndef(StringRef, SMLoc);
Rafael Espindola8f7d12c2011-12-17 01:14:52 +0000106 bool ParseDirectiveSecRel32(StringRef, SMLoc);
Michael J. Spencer7d490042010-10-09 11:01:07 +0000107
Charles Davisfbc539f2011-05-22 21:12:15 +0000108 // Win64 EH directives.
109 bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
110 bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
111 bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
112 bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
113 bool ParseSEHDirectiveHandler(StringRef, SMLoc);
114 bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
Charles Davis3b32d022011-05-24 20:06:30 +0000115 bool ParseSEHDirectivePushReg(StringRef, SMLoc);
116 bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
117 bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
118 bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
119 bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
120 bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
Charles Davisfbc539f2011-05-22 21:12:15 +0000121 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
122
123 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
Charles Davis3b32d022011-05-24 20:06:30 +0000124 bool ParseSEHRegisterNumber(unsigned &RegNo);
Jim Grosbachf2a35fb2011-07-25 17:55:35 +0000125 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
Michael J. Spencer7d490042010-10-09 11:01:07 +0000126public:
127 COFFAsmParser() {}
128};
129
130} // end annonomous namespace.
131
Jim Grosbachf2a35fb2011-07-25 17:55:35 +0000132/// ParseDirectiveSymbolAttribute
133/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
134bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
135 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
136 .Case(".weak", MCSA_Weak)
137 .Default(MCSA_Invalid);
138 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
140 for (;;) {
141 StringRef Name;
142
143 if (getParser().ParseIdentifier(Name))
144 return TokError("expected identifier in directive");
145
146 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
147
148 getStreamer().EmitSymbolAttribute(Sym, Attr);
149
150 if (getLexer().is(AsmToken::EndOfStatement))
151 break;
152
153 if (getLexer().isNot(AsmToken::Comma))
154 return TokError("unexpected token in directive");
155 Lex();
156 }
157 }
158
159 Lex();
160 return false;
161}
162
Michael J. Spencer7d490042010-10-09 11:01:07 +0000163bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
164 unsigned Characteristics,
165 SectionKind Kind) {
166 if (getLexer().isNot(AsmToken::EndOfStatement))
167 return TokError("unexpected token in section switching directive");
168 Lex();
169
170 getStreamer().SwitchSection(getContext().getCOFFSection(
171 Section, Characteristics, Kind));
172
173 return false;
174}
175
176bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
177 StringRef SymbolName;
178
179 if (getParser().ParseIdentifier(SymbolName))
180 return TokError("expected identifier in directive");
181
182 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
183
184 getStreamer().BeginCOFFSymbolDef(Sym);
185
186 Lex();
187 return false;
188}
189
190bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
191 int64_t SymbolStorageClass;
192 if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
193 return true;
194
195 if (getLexer().isNot(AsmToken::EndOfStatement))
196 return TokError("unexpected token in directive");
197
198 Lex();
199 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
200 return false;
201}
202
203bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
204 int64_t Type;
205 if (getParser().ParseAbsoluteExpression(Type))
206 return true;
207
208 if (getLexer().isNot(AsmToken::EndOfStatement))
209 return TokError("unexpected token in directive");
210
211 Lex();
212 getStreamer().EmitCOFFSymbolType(Type);
213 return false;
214}
215
216bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
217 Lex();
218 getStreamer().EndCOFFSymbolDef();
219 return false;
220}
221
Rafael Espindola8f7d12c2011-12-17 01:14:52 +0000222bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
223 StringRef SymbolID;
224 if (getParser().ParseIdentifier(SymbolID))
225 return true;
226
227 if (getLexer().isNot(AsmToken::EndOfStatement))
228 return TokError("unexpected token in directive");
229
230 MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
231
232 Lex();
233 getStreamer().EmitCOFFSecRel32(Symbol);
234 return false;
235}
236
Charles Davisfbc539f2011-05-22 21:12:15 +0000237bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
Charles Davis30921322011-05-25 01:33:42 +0000238 StringRef SymbolID;
239 if (getParser().ParseIdentifier(SymbolID))
Charles Davisfbc539f2011-05-22 21:12:15 +0000240 return true;
241
Charles Davisfbc539f2011-05-22 21:12:15 +0000242 if (getLexer().isNot(AsmToken::EndOfStatement))
243 return TokError("unexpected token in directive");
244
Charles Davis30921322011-05-25 01:33:42 +0000245 MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
246
Charles Davisfbc539f2011-05-22 21:12:15 +0000247 Lex();
Charles Davis30921322011-05-25 01:33:42 +0000248 getStreamer().EmitWin64EHStartProc(Symbol);
Charles Davisfbc539f2011-05-22 21:12:15 +0000249 return false;
250}
251
252bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
253 Lex();
254 getStreamer().EmitWin64EHEndProc();
255 return false;
256}
257
258bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
259 Lex();
260 getStreamer().EmitWin64EHStartChained();
261 return false;
262}
263
264bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
265 Lex();
266 getStreamer().EmitWin64EHEndChained();
267 return false;
268}
269
270bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
Charles Davis30921322011-05-25 01:33:42 +0000271 StringRef SymbolID;
272 if (getParser().ParseIdentifier(SymbolID))
Charles Davisfbc539f2011-05-22 21:12:15 +0000273 return true;
274
Charles Davis30921322011-05-25 01:33:42 +0000275 if (getLexer().isNot(AsmToken::Comma))
276 return TokError("you must specify one or both of @unwind or @except");
277 Lex();
Charles Davisfbc539f2011-05-22 21:12:15 +0000278 bool unwind = false, except = false;
Charles Davis30921322011-05-25 01:33:42 +0000279 if (ParseAtUnwindOrAtExcept(unwind, except))
280 return true;
Charles Davisfbc539f2011-05-22 21:12:15 +0000281 if (getLexer().is(AsmToken::Comma)) {
282 Lex();
Charles Davis30921322011-05-25 01:33:42 +0000283 if (ParseAtUnwindOrAtExcept(unwind, except))
Charles Davisfbc539f2011-05-22 21:12:15 +0000284 return true;
285 }
286 if (getLexer().isNot(AsmToken::EndOfStatement))
287 return TokError("unexpected token in directive");
288
Charles Davis30921322011-05-25 01:33:42 +0000289 MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID);
290
Charles Davisfbc539f2011-05-22 21:12:15 +0000291 Lex();
Charles Davis30921322011-05-25 01:33:42 +0000292 getStreamer().EmitWin64EHHandler(handler, unwind, except);
Charles Davisfbc539f2011-05-22 21:12:15 +0000293 return false;
294}
295
296bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
297 Lex();
298 getStreamer().EmitWin64EHHandlerData();
299 return false;
300}
301
302bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000303 unsigned Reg;
304 if (ParseSEHRegisterNumber(Reg))
305 return true;
306
307 if (getLexer().isNot(AsmToken::EndOfStatement))
308 return TokError("unexpected token in directive");
309
310 Lex();
311 getStreamer().EmitWin64EHPushReg(Reg);
312 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000313}
314
315bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000316 unsigned Reg;
317 int64_t Off;
318 if (ParseSEHRegisterNumber(Reg))
319 return true;
Charles Davis410ef2b2011-05-25 21:43:45 +0000320 if (getLexer().isNot(AsmToken::Comma))
321 return TokError("you must specify a stack pointer offset");
322
323 Lex();
Charles Davis3b32d022011-05-24 20:06:30 +0000324 SMLoc startLoc = getLexer().getLoc();
325 if (getParser().ParseAbsoluteExpression(Off))
326 return true;
327
328 if (Off & 0x0F)
329 return Error(startLoc, "offset is not a multiple of 16");
330
331 if (getLexer().isNot(AsmToken::EndOfStatement))
332 return TokError("unexpected token in directive");
333
334 Lex();
335 getStreamer().EmitWin64EHSetFrame(Reg, Off);
336 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000337}
338
Charles Davis16e1b3f2011-05-23 16:43:09 +0000339bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
340 int64_t Size;
Charles Davis3b32d022011-05-24 20:06:30 +0000341 SMLoc startLoc = getLexer().getLoc();
Charles Davis16e1b3f2011-05-23 16:43:09 +0000342 if (getParser().ParseAbsoluteExpression(Size))
343 return true;
344
Charles Davis3b32d022011-05-24 20:06:30 +0000345 if (Size & 7)
346 return Error(startLoc, "size is not a multiple of 8");
347
Charles Davis16e1b3f2011-05-23 16:43:09 +0000348 if (getLexer().isNot(AsmToken::EndOfStatement))
349 return TokError("unexpected token in directive");
350
351 Lex();
352 getStreamer().EmitWin64EHAllocStack(Size);
353 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000354}
355
356bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000357 unsigned Reg;
358 int64_t Off;
359 if (ParseSEHRegisterNumber(Reg))
360 return true;
Charles Davis575630c2011-05-25 04:51:25 +0000361 if (getLexer().isNot(AsmToken::Comma))
Charles Davis410ef2b2011-05-25 21:43:45 +0000362 return TokError("you must specify an offset on the stack");
Charles Davis575630c2011-05-25 04:51:25 +0000363
364 Lex();
Charles Davis3b32d022011-05-24 20:06:30 +0000365 SMLoc startLoc = getLexer().getLoc();
366 if (getParser().ParseAbsoluteExpression(Off))
367 return true;
368
369 if (Off & 7)
370 return Error(startLoc, "size is not a multiple of 8");
371
372 if (getLexer().isNot(AsmToken::EndOfStatement))
373 return TokError("unexpected token in directive");
374
375 Lex();
376 // FIXME: Err on %xmm* registers
377 getStreamer().EmitWin64EHSaveReg(Reg, Off);
378 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000379}
380
Charles Davis3b32d022011-05-24 20:06:30 +0000381// FIXME: This method is inherently x86-specific. It should really be in the
382// x86 backend.
Charles Davisfbc539f2011-05-22 21:12:15 +0000383bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
Charles Davis3b32d022011-05-24 20:06:30 +0000384 unsigned Reg;
385 int64_t Off;
386 if (ParseSEHRegisterNumber(Reg))
387 return true;
Charles Davis575630c2011-05-25 04:51:25 +0000388 if (getLexer().isNot(AsmToken::Comma))
Charles Davis410ef2b2011-05-25 21:43:45 +0000389 return TokError("you must specify an offset on the stack");
Charles Davis575630c2011-05-25 04:51:25 +0000390
391 Lex();
Charles Davis3b32d022011-05-24 20:06:30 +0000392 SMLoc startLoc = getLexer().getLoc();
393 if (getParser().ParseAbsoluteExpression(Off))
394 return true;
395
396 if (getLexer().isNot(AsmToken::EndOfStatement))
397 return TokError("unexpected token in directive");
398
399 if (Off & 0x0F)
400 return Error(startLoc, "offset is not a multiple of 16");
401
402 Lex();
403 // FIXME: Err on non-%xmm* registers
404 getStreamer().EmitWin64EHSaveXMM(Reg, Off);
405 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000406}
407
Charles Davis16e1b3f2011-05-23 16:43:09 +0000408bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
Charles Davis47268162011-05-25 04:08:15 +0000409 bool Code = false;
Charles Davis16e1b3f2011-05-23 16:43:09 +0000410 StringRef CodeID;
Charles Davis47268162011-05-25 04:08:15 +0000411 if (getLexer().is(AsmToken::At)) {
412 SMLoc startLoc = getLexer().getLoc();
413 Lex();
414 if (!getParser().ParseIdentifier(CodeID)) {
415 if (CodeID != "code")
416 return Error(startLoc, "expected @code");
417 Code = true;
418 }
Charles Davis16e1b3f2011-05-23 16:43:09 +0000419 }
420
421 if (getLexer().isNot(AsmToken::EndOfStatement))
422 return TokError("unexpected token in directive");
423
424 Lex();
425 getStreamer().EmitWin64EHPushFrame(Code);
426 return false;
Charles Davisfbc539f2011-05-22 21:12:15 +0000427}
428
429bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
430 Lex();
431 getStreamer().EmitWin64EHEndProlog();
432 return false;
433}
434
435bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
436 StringRef identifier;
Charles Davis30921322011-05-25 01:33:42 +0000437 if (getLexer().isNot(AsmToken::At))
438 return TokError("a handler attribute must begin with '@'");
Charles Davisfbc539f2011-05-22 21:12:15 +0000439 SMLoc startLoc = getLexer().getLoc();
Charles Davis30921322011-05-25 01:33:42 +0000440 Lex();
441 if (getParser().ParseIdentifier(identifier))
Charles Davisfbc539f2011-05-22 21:12:15 +0000442 return Error(startLoc, "expected @unwind or @except");
Charles Davis30921322011-05-25 01:33:42 +0000443 if (identifier == "unwind")
Charles Davisfbc539f2011-05-22 21:12:15 +0000444 unwind = true;
Charles Davis30921322011-05-25 01:33:42 +0000445 else if (identifier == "except")
Charles Davisfbc539f2011-05-22 21:12:15 +0000446 except = true;
447 else
448 return Error(startLoc, "expected @unwind or @except");
449 return false;
450}
451
Charles Davis3b32d022011-05-24 20:06:30 +0000452bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
Charles Davis3b32d022011-05-24 20:06:30 +0000453 SMLoc startLoc = getLexer().getLoc();
Charles Davis575630c2011-05-25 04:51:25 +0000454 if (getLexer().is(AsmToken::Percent)) {
Evan Cheng0e6a0522011-07-18 20:57:22 +0000455 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
Charles Davis3b32d022011-05-24 20:06:30 +0000456 SMLoc endLoc;
457 unsigned LLVMRegNo;
458 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
Charles Davis575630c2011-05-25 04:51:25 +0000459 return true;
Charles Davis3b32d022011-05-24 20:06:30 +0000460
Evan Cheng0e6a0522011-07-18 20:57:22 +0000461#if 0
462 // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
463 // violation so this validation code is disabled.
464
Charles Davis3b32d022011-05-24 20:06:30 +0000465 // Check that this is a non-volatile register.
Evan Cheng1be0e272011-07-15 02:09:41 +0000466 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
Charles Davis3b32d022011-05-24 20:06:30 +0000467 unsigned i;
468 for (i = 0; NVRegs[i] != 0; ++i)
469 if (NVRegs[i] == LLVMRegNo)
470 break;
471 if (NVRegs[i] == 0)
472 return Error(startLoc, "expected non-volatile register");
Evan Cheng0e6a0522011-07-18 20:57:22 +0000473#endif
Charles Davis3b32d022011-05-24 20:06:30 +0000474
Evan Cheng0e6a0522011-07-18 20:57:22 +0000475 int SEHRegNo = MRI.getSEHRegNum(LLVMRegNo);
Charles Davis3b32d022011-05-24 20:06:30 +0000476 if (SEHRegNo < 0)
477 return Error(startLoc,"register can't be represented in SEH unwind info");
478 RegNo = SEHRegNo;
479 }
Charles Davis575630c2011-05-25 04:51:25 +0000480 else {
481 int64_t n;
482 if (getParser().ParseAbsoluteExpression(n))
483 return true;
484 if (n > 15)
485 return Error(startLoc, "register number is too high");
Charles Davis3b32d022011-05-24 20:06:30 +0000486 RegNo = n;
Charles Davis575630c2011-05-25 04:51:25 +0000487 }
Charles Davis3b32d022011-05-24 20:06:30 +0000488
Charles Davis3b32d022011-05-24 20:06:30 +0000489 return false;
490}
491
Michael J. Spencer7d490042010-10-09 11:01:07 +0000492namespace llvm {
493
494MCAsmParserExtension *createCOFFAsmParser() {
495 return new COFFAsmParser;
496}
497
498}