mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-27 21:30:51 +00:00
[ms] [llvm-ml] Add basic support for SEH, including PROC FRAME
Add basic support for SEH, including PROC FRAME Reviewed By: thakis Differential Revision: https://reviews.llvm.org/D86948
This commit is contained in:
parent
d82f49fb4b
commit
c1961f9100
@ -53,6 +53,9 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||
bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
|
||||
bool ParseDirectiveIncludelib(StringRef, SMLoc);
|
||||
|
||||
bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
|
||||
bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
|
||||
|
||||
bool IgnoreDirective(StringRef, SMLoc) {
|
||||
while (!getLexer().is(AsmToken::EndOfStatement)) {
|
||||
Lex();
|
||||
@ -65,13 +68,10 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||
MCAsmParserExtension::Initialize(Parser);
|
||||
|
||||
// x64 directives
|
||||
// .allocstack
|
||||
// .endprolog
|
||||
// .pushframe
|
||||
// .pushreg
|
||||
// .savereg
|
||||
// .savexmm128
|
||||
// .setframe
|
||||
addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
|
||||
".allocstack");
|
||||
addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
|
||||
".endprolog");
|
||||
|
||||
// Code label directives
|
||||
// label
|
||||
@ -92,16 +92,12 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||
|
||||
// Data allocation directives
|
||||
// align
|
||||
// byte/sbyte
|
||||
// dword/sdword
|
||||
// even
|
||||
// fword
|
||||
// qword
|
||||
// real4
|
||||
// real8
|
||||
// mmword
|
||||
// real10
|
||||
// tbyte
|
||||
// word/sword
|
||||
// xmmword
|
||||
// ymmword
|
||||
|
||||
// Listing control directives
|
||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".cref");
|
||||
@ -133,14 +129,11 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||
// .fpo
|
||||
addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
|
||||
"includelib");
|
||||
// mmword
|
||||
// option
|
||||
// popcontext
|
||||
// pushcontext
|
||||
// .radix
|
||||
// .safeseh
|
||||
// xmmword
|
||||
// ymmword
|
||||
|
||||
// Procedure directives
|
||||
addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>("endp");
|
||||
@ -148,7 +141,7 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||
addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>("proc");
|
||||
// proto
|
||||
|
||||
// Processor directives
|
||||
// Processor directives; all ignored
|
||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386");
|
||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386P");
|
||||
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".387");
|
||||
@ -202,11 +195,8 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||
// substr (equivalent to <name> TEXTEQU @SubStr(<params>))
|
||||
|
||||
// Structure and record directives
|
||||
// ends
|
||||
// record
|
||||
// struct
|
||||
// typedef
|
||||
// union
|
||||
}
|
||||
|
||||
bool ParseSectionDirectiveCode(StringRef, SMLoc) {
|
||||
@ -234,6 +224,7 @@ class COFFMasmParser : public MCAsmParserExtension {
|
||||
}
|
||||
|
||||
StringRef CurrentProcedure;
|
||||
bool CurrentProcedureFramed;
|
||||
|
||||
public:
|
||||
COFFMasmParser() = default;
|
||||
@ -361,8 +352,17 @@ bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
|
||||
getStreamer().EmitCOFFSymbolType(0x20);
|
||||
getStreamer().EndCOFFSymbolDef();
|
||||
|
||||
bool Framed = false;
|
||||
if (getLexer().is(AsmToken::Identifier) &&
|
||||
getTok().getString().equals_lower("frame")) {
|
||||
Lex();
|
||||
Framed = true;
|
||||
getStreamer().EmitWinCFIStartProc(Sym, Loc);
|
||||
}
|
||||
getStreamer().emitLabel(Sym, Loc);
|
||||
|
||||
CurrentProcedure = Label;
|
||||
CurrentProcedureFramed = Framed;
|
||||
return false;
|
||||
}
|
||||
bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
|
||||
@ -376,6 +376,30 @@ bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
|
||||
else if (CurrentProcedure != Label)
|
||||
return Error(LabelLoc, "endp does not match current procedure '" +
|
||||
CurrentProcedure + "'");
|
||||
|
||||
if (CurrentProcedureFramed) {
|
||||
getStreamer().EmitWinCFIEndProc(Loc);
|
||||
}
|
||||
CurrentProcedure = "";
|
||||
CurrentProcedureFramed = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
|
||||
SMLoc Loc) {
|
||||
int64_t Size;
|
||||
SMLoc SizeLoc = getTok().getLoc();
|
||||
if (getParser().parseAbsoluteExpression(Size))
|
||||
return Error(SizeLoc, "expected integer size");
|
||||
if (Size % 8 != 0)
|
||||
return Error(SizeLoc, "stack size must be a multiple of 8");
|
||||
getStreamer().EmitWinCFIAllocStack(static_cast<unsigned>(Size), Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFMasmParser::ParseSEHDirectiveEndProlog(StringRef Directive,
|
||||
SMLoc Loc) {
|
||||
getStreamer().EmitWinCFIEndProlog(Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -726,7 +726,12 @@ private:
|
||||
DK_STRUCT,
|
||||
DK_UNION,
|
||||
DK_ENDS,
|
||||
DK_END
|
||||
DK_END,
|
||||
DK_PUSHFRAME,
|
||||
DK_PUSHREG,
|
||||
DK_SAVEREG,
|
||||
DK_SAVEXMM128,
|
||||
DK_SETFRAME,
|
||||
};
|
||||
|
||||
/// Maps directive name --> DirectiveKind enum, for directives parsed by this
|
||||
@ -6333,6 +6338,11 @@ void MasmParser::initializeDirectiveKindMap() {
|
||||
DirectiveKindMap[".erridni"] = DK_ERRIDNI;
|
||||
DirectiveKindMap[".erre"] = DK_ERRE;
|
||||
DirectiveKindMap[".errnz"] = DK_ERRNZ;
|
||||
DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
|
||||
DirectiveKindMap[".pushreg"] = DK_PUSHREG;
|
||||
DirectiveKindMap[".savereg"] = DK_SAVEREG;
|
||||
DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
|
||||
DirectiveKindMap[".setframe"] = DK_SETFRAME;
|
||||
// DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
|
||||
// DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
|
||||
DirectiveKindMap["db"] = DK_DB;
|
||||
|
@ -4172,15 +4172,20 @@ bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||
return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
|
||||
else if (IDVal == ".cv_fpo_endproc")
|
||||
return parseDirectiveFPOEndProc(DirectiveID.getLoc());
|
||||
else if (IDVal == ".seh_pushreg")
|
||||
else if (IDVal == ".seh_pushreg" ||
|
||||
(Parser.isParsingMasm() && IDVal.equals_lower(".pushreg")))
|
||||
return parseDirectiveSEHPushReg(DirectiveID.getLoc());
|
||||
else if (IDVal == ".seh_setframe")
|
||||
else if (IDVal == ".seh_setframe" ||
|
||||
(Parser.isParsingMasm() && IDVal.equals_lower(".setframe")))
|
||||
return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
|
||||
else if (IDVal == ".seh_savereg")
|
||||
else if (IDVal == ".seh_savereg" ||
|
||||
(Parser.isParsingMasm() && IDVal.equals_lower(".savereg")))
|
||||
return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
|
||||
else if (IDVal == ".seh_savexmm")
|
||||
else if (IDVal == ".seh_savexmm" ||
|
||||
(Parser.isParsingMasm() && IDVal.equals_lower(".savexmm128")))
|
||||
return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());
|
||||
else if (IDVal == ".seh_pushframe")
|
||||
else if (IDVal == ".seh_pushframe" ||
|
||||
(Parser.isParsingMasm() && IDVal.equals_lower(".pushframe")))
|
||||
return parseDirectiveSEHPushFrame(DirectiveID.getLoc());
|
||||
|
||||
return true;
|
||||
|
18
test/tools/llvm-ml/proc.test
Normal file
18
test/tools/llvm-ml/proc.test
Normal file
@ -0,0 +1,18 @@
|
||||
# RUN: llvm-ml -m32 -filetype=asm %s | FileCheck %s
|
||||
# RUN: llvm-ml -m64 -filetype=asm %s | FileCheck %s
|
||||
|
||||
.code
|
||||
|
||||
t1 PROC
|
||||
ret
|
||||
t1 ENDP
|
||||
|
||||
; CHECK: .def t1
|
||||
; CHECK-NEXT: .scl 2
|
||||
; CHECK-NEXT: .type 32
|
||||
; CHECK-NEXT: .endef
|
||||
|
||||
; CHECK: t1:
|
||||
; CHECK: ret
|
||||
|
||||
END
|
34
test/tools/llvm-ml/proc_frame.test
Normal file
34
test/tools/llvm-ml/proc_frame.test
Normal file
@ -0,0 +1,34 @@
|
||||
# RUN: llvm-ml -m64 -filetype=asm %s | FileCheck %s
|
||||
|
||||
.code
|
||||
|
||||
t1 PROC FRAME
|
||||
push rbp
|
||||
.pushreg rbp
|
||||
mov rbp, rsp
|
||||
.setframe rbp, 0
|
||||
pushfq
|
||||
.allocstack 8
|
||||
.endprolog
|
||||
ret
|
||||
t1 ENDP
|
||||
|
||||
; CHECK: .def t1
|
||||
; CHECK-NEXT: .scl 2
|
||||
; CHECK-NEXT: .type 32
|
||||
; CHECK-NEXT: .endef
|
||||
|
||||
; CHECK: .seh_proc t1
|
||||
|
||||
; CHECK: t1:
|
||||
; CHECK: push rbp
|
||||
; CHECK: .seh_pushreg rbp
|
||||
; CHECK: mov rbp, rsp
|
||||
; CHECK: .seh_setframe rbp, 0
|
||||
; CHECK: pushfq
|
||||
; CHECK: .seh_stackalloc 8
|
||||
; CHECK: .seh_endprologue
|
||||
; CHECK: ret
|
||||
; CHECK: .seh_endproc
|
||||
|
||||
END
|
Loading…
Reference in New Issue
Block a user