12
12
#include " llvm/MC/MCAsmMacro.h"
13
13
#include " llvm/MC/MCContext.h"
14
14
#include " llvm/MC/MCParser/MCAsmLexer.h"
15
+ #include " llvm/MC/MCParser/MCAsmParser.h"
15
16
#include " llvm/MC/MCParser/MCAsmParserExtension.h"
17
+ #include " llvm/MC/MCParser/MCMasmParser.h"
16
18
#include " llvm/MC/MCParser/MCTargetAsmParser.h"
17
19
#include " llvm/MC/MCSectionCOFF.h"
18
20
#include " llvm/MC/MCStreamer.h"
@@ -41,6 +43,7 @@ class COFFMasmParser : public MCAsmParserExtension {
41
43
StringRef COMDATSymName, COFF::COMDATType Type,
42
44
Align Alignment);
43
45
46
+ bool parseDirectiveModel (StringRef, SMLoc);
44
47
bool parseDirectiveProc (StringRef, SMLoc);
45
48
bool parseDirectiveEndProc (StringRef, SMLoc);
46
49
bool parseDirectiveSegment (StringRef, SMLoc);
@@ -167,7 +170,7 @@ class COFFMasmParser : public MCAsmParserExtension {
167
170
// .exit
168
171
// .fardata
169
172
// .fardata?
170
- addDirectiveHandler<&COFFMasmParser::IgnoreDirective >(" .model" );
173
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveModel >(" .model" );
171
174
// .stack
172
175
// .startup
173
176
@@ -201,8 +204,13 @@ class COFFMasmParser : public MCAsmParserExtension {
201
204
}
202
205
203
206
// / Stack of active procedure definitions.
204
- SmallVector<StringRef, 1 > CurrentProcedures;
205
- SmallVector<bool , 1 > CurrentProceduresFramed;
207
+ enum ProcDistance { PROC_DISTANCE_NEAR = 0 , PROC_DISTANCE_FAR = 1 };
208
+ struct ProcInfo {
209
+ StringRef Name;
210
+ ProcDistance Distance = PROC_DISTANCE_NEAR;
211
+ bool IsFramed = false ;
212
+ };
213
+ SmallVector<ProcInfo, 1 > CurrentProcedures;
206
214
207
215
public:
208
216
COFFMasmParser () = default ;
@@ -435,48 +443,75 @@ bool COFFMasmParser::parseDirectiveOption(StringRef Directive, SMLoc Loc) {
435
443
return false ;
436
444
}
437
445
446
+ // / parseDirectiveModel
447
+ // / ::= ".model" "flat"
448
+ bool COFFMasmParser::parseDirectiveModel (StringRef Directive, SMLoc Loc) {
449
+ if (!getLexer ().is (AsmToken::Identifier))
450
+ return TokError (" expected identifier in directive" );
451
+
452
+ StringRef ModelType = getTok ().getIdentifier ();
453
+ if (!ModelType.equals_insensitive (" flat" )) {
454
+ return TokError (
455
+ " expected 'flat' for memory model; no other models supported" );
456
+ }
457
+
458
+ // Ignore; no action necessary.
459
+ Lex ();
460
+ return false ;
461
+ }
462
+
438
463
// / parseDirectiveProc
439
464
// / TODO(epastor): Implement parameters and other attributes.
440
- // / ::= label "proc" [[distance]]
465
+ // / ::= label "proc" [[distance]] [[frame]]
441
466
// / statements
442
467
// / label "endproc"
443
468
bool COFFMasmParser::parseDirectiveProc (StringRef Directive, SMLoc Loc) {
444
469
if (!getStreamer ().getCurrentFragment ())
445
470
return Error (getTok ().getLoc (), " expected section directive" );
446
471
447
- StringRef Label ;
448
- if (getParser ().parseIdentifier (Label ))
472
+ ProcInfo Proc ;
473
+ if (getParser ().parseIdentifier (Proc. Name ))
449
474
return Error (Loc, " expected identifier for procedure" );
450
- if (getLexer ().is (AsmToken::Identifier)) {
475
+ while (getLexer ().is (AsmToken::Identifier)) {
451
476
StringRef nextVal = getTok ().getString ();
452
477
SMLoc nextLoc = getTok ().getLoc ();
453
478
if (nextVal.equals_insensitive (" far" )) {
454
- // TODO(epastor): Handle far procedure definitions.
455
479
Lex ();
456
- return Error (nextLoc, " far procedure definitions not yet supported" );
480
+ Proc.Distance = PROC_DISTANCE_FAR;
481
+ nextVal = getTok ().getString ();
482
+ nextLoc = getTok ().getLoc ();
457
483
} else if (nextVal.equals_insensitive (" near" )) {
458
484
Lex ();
485
+ Proc.Distance = PROC_DISTANCE_NEAR;
486
+ nextVal = getTok ().getString ();
487
+ nextLoc = getTok ().getLoc ();
488
+ } else if (nextVal.equals_insensitive (" frame" )) {
489
+ Lex ();
490
+ Proc.IsFramed = true ;
459
491
nextVal = getTok ().getString ();
460
492
nextLoc = getTok ().getLoc ();
493
+ } else {
494
+ break ;
461
495
}
462
496
}
463
- MCSymbolCOFF *Sym = cast<MCSymbolCOFF>(getContext ().getOrCreateSymbol (Label));
497
+ MCSymbolCOFF *Sym =
498
+ cast<MCSymbolCOFF>(getContext ().getOrCreateSymbol (Proc.Name ));
464
499
465
500
// Define symbol as simple external function
466
501
Sym->setExternal (true );
467
502
Sym->setType (COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT);
503
+ if (Proc.Distance == PROC_DISTANCE_FAR)
504
+ Sym->setIsFarProc ();
505
+
506
+ cast<MCMasmParser>(getParser ())
507
+ .setDefaultRetIsFar (Proc.Distance == PROC_DISTANCE_FAR);
468
508
469
- bool Framed = false ;
470
- if (getLexer ().is (AsmToken::Identifier) &&
471
- getTok ().getString ().equals_insensitive (" frame" )) {
472
- Lex ();
473
- Framed = true ;
509
+ if (Proc.IsFramed ) {
474
510
getStreamer ().emitWinCFIStartProc (Sym, Loc);
475
511
}
476
512
getStreamer ().emitLabel (Sym, Loc);
477
513
478
- CurrentProcedures.push_back (Label);
479
- CurrentProceduresFramed.push_back (Framed);
514
+ CurrentProcedures.push_back (std::move (Proc));
480
515
return false ;
481
516
}
482
517
bool COFFMasmParser::parseDirectiveEndProc (StringRef Directive, SMLoc Loc) {
@@ -487,15 +522,18 @@ bool COFFMasmParser::parseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
487
522
488
523
if (CurrentProcedures.empty ())
489
524
return Error (Loc, " endp outside of procedure block" );
490
- else if (!CurrentProcedures.back ().equals_insensitive (Label))
525
+ else if (!CurrentProcedures.back ().Name . equals_insensitive (Label))
491
526
return Error (LabelLoc, " endp does not match current procedure '" +
492
- CurrentProcedures.back () + " '" );
527
+ CurrentProcedures.back (). Name + " '" );
493
528
494
- if (CurrentProceduresFramed .back ()) {
529
+ if (CurrentProcedures .back (). IsFramed ) {
495
530
getStreamer ().emitWinCFIEndProc (Loc);
496
531
}
497
532
CurrentProcedures.pop_back ();
498
- CurrentProceduresFramed.pop_back ();
533
+ cast<MCMasmParser>(getParser ())
534
+ .setDefaultRetIsFar (!CurrentProcedures.empty () &&
535
+ CurrentProcedures.back ().Distance ==
536
+ PROC_DISTANCE_FAR);
499
537
return false ;
500
538
}
501
539
0 commit comments