Turns out GAS does have Win64 EH directives. (It also supports WinCE EH.) Make
authorCharles Davis <cdavis@mines.edu>
Thu, 19 May 2011 17:46:39 +0000 (17:46 +0000)
committerCharles Davis <cdavis@mines.edu>
Thu, 19 May 2011 17:46:39 +0000 (17:46 +0000)
ours compatible with GAS.

In retrospect, I should have emailed binutils about this earlier. Thanks to
Kai Tietz for pointing out that GAS already had SEH directives.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131652 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCStreamer.h
include/llvm/MC/MCWin64EH.h
lib/MC/MCAsmStreamer.cpp
lib/MC/MCStreamer.cpp

index 83bcb15ae9ae2b2ad8d0d84fcdb14cb7b0fe3362..b5e99305e025e80ac80a1acc2cbb050fa71413cf 100644 (file)
@@ -463,16 +463,18 @@ namespace llvm {
     virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
     virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
 
-    virtual void EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler = 0);
+    virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
     virtual void EmitWin64EHEndProc();
     virtual void EmitWin64EHStartChained();
     virtual void EmitWin64EHEndChained();
-    virtual void EmitWin64EHUnwindOnly();
-    virtual void EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size);
+    virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
+                                    bool Except);
+    virtual void EmitWin64EHHandlerData();
     virtual void EmitWin64EHPushReg(int64_t Register);
     virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset);
     virtual void EmitWin64EHAllocStack(int64_t Size);
     virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset);
+    virtual void EmitWin64EHSaveXMM(int64_t Register, int64_t Offset);
     virtual void EmitWin64EHPushFrame(bool Code);
     virtual void EmitWin64EHEndProlog();
 
index c772cdef2a5a488ad1683826be8e9a2047e7b6e4..4c6d91972ed14b62282fb75affa6f7c886f8e115 100644 (file)
@@ -62,17 +62,15 @@ namespace llvm {
   };
 
   struct MCWin64EHUnwindInfo {
-    MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), Lsda(0),
-                            Function(0), UnwindOnly(false), LsdaSize(0),
+    MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0),
+                            Function(0), UnwindOnly(false),
                             PrologSize(0), LastFrameInst(-1), ChainedParent(0),
                             Instructions() {}
     MCSymbol *Begin;
     MCSymbol *End;
     const MCSymbol *ExceptionHandler;
-    const MCSymbol *Lsda;
     const MCSymbol *Function;
     bool UnwindOnly;
-    unsigned LsdaSize;
     unsigned PrologSize;
     int LastFrameInst;
     MCWin64EHUnwindInfo *ChainedParent;
index 36fa393c56402eee3e93de6ec2e0e0ea0bba4e45..6be029887776bd53a55a37ddc1e82853e9c51c6a 100644 (file)
@@ -208,16 +208,18 @@ public:
   virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
   virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
 
-  virtual void EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler = 0);
+  virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
   virtual void EmitWin64EHEndProc();
   virtual void EmitWin64EHStartChained();
   virtual void EmitWin64EHEndChained();
-  virtual void EmitWin64EHUnwindOnly();
-  virtual void EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size);
+  virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
+                                  bool Except);
+  virtual void EmitWin64EHHandlerData();
   virtual void EmitWin64EHPushReg(int64_t Register);
   virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset);
   virtual void EmitWin64EHAllocStack(int64_t Size);
   virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset);
+  virtual void EmitWin64EHSaveXMM(int64_t Register, int64_t Offset);
   virtual void EmitWin64EHPushFrame(bool Code);
   virtual void EmitWin64EHEndProlog();
 
@@ -928,67 +930,75 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) {
-  OS << ".w64_startproc " << *Symbol;
-  if (EHandler)
-    OS << ", " << *EHandler;
+void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
+  OS << ".seh_proc " << *Symbol;
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHEndProc() {
-  OS << "\t.w64_endproc";
+  OS << "\t.seh_endproc";
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHStartChained() {
-  OS << "\t.w64_startchained";
+  OS << "\t.seh_startchained";
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHEndChained() {
-  OS << "\t.w64_endchained";
+  OS << "\t.seh_endchained";
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWin64EHUnwindOnly() {
-  OS << "\t.w64_unwind_only";
+void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
+                                       bool Except) {
+  OS << "\t.seh_handler " << *Sym;
+  if (Unwind)
+    OS << ", @unwind";
+  if (Except)
+    OS << ", @except";
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size) {
-  OS << "\t.w64_lsda " << *Sym << ", " << Size;
+void MCAsmStreamer::EmitWin64EHHandlerData() {
+  OS << "\t.seh_handlerdata";
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHPushReg(int64_t Register) {
-  OS << "\t.w64_pushreg " << Register;
+  OS << "\t.seh_pushreg " << Register;
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) {
-  OS << "\t.w64_setframe " << Register << ", " << Offset;
+  OS << "\t.seh_setframe " << Register << ", " << Offset;
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHAllocStack(int64_t Size) {
-  OS << "\t.w64_allocstack " << Size;
+  OS << "\t.seh_stackalloc " << Size;
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) {
-  OS << "\t.w64_savereg " << Register << ", " << Offset;
+  OS << "\t.seh_savereg " << Register << ", " << Offset;
+  EmitEOL();
+}
+
+void MCAsmStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) {
+  OS << "\t.seh_savexmm " << Register << ", " << Offset;
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
-  OS << "\t.w64_pushframe";
+  OS << "\t.seh_pushframe";
   if (Code)
-    OS << " " << "code";
+    OS << " @code";
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
-  OS << "\t.w64_endprolog";
+  OS << "\t.seh_endprologue";
   EmitEOL();
 }
 
index 4163198e3945d87443d48ea3a535d26868950a12..fc09369ae2b293a45b095ab1cd92dec5bbc62014 100644 (file)
@@ -321,14 +321,13 @@ void MCStreamer::EnsureValidW64UnwindInfo() {
     report_fatal_error("No open Win64 EH frame function!");
 }
 
-void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) {
+void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
   MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
   if (CurFrame && !CurFrame->End)
     report_fatal_error("Starting a function before ending the previous one!");
   MCWin64EHUnwindInfo Frame;
   Frame.Begin = getContext().CreateTempSymbol();
   Frame.Function = Symbol;
-  Frame.ExceptionHandler = EHandler;
   EmitLabel(Frame.Begin);
   setCurrentW64UnwindInfo(&Frame);
 }
@@ -342,8 +341,7 @@ void MCStreamer::EmitWin64EHEndProc() {
   EmitLabel(CurFrame->End);
 }
 
-void MCStreamer::EmitWin64EHStartChained()
-{
+void MCStreamer::EmitWin64EHStartChained() {
   EnsureValidW64UnwindInfo();
   MCWin64EHUnwindInfo Frame;
   MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
@@ -354,8 +352,7 @@ void MCStreamer::EmitWin64EHStartChained()
   setCurrentW64UnwindInfo(&Frame);
 }
 
-void MCStreamer::EmitWin64EHEndChained()
-{
+void MCStreamer::EmitWin64EHEndChained() {
   EnsureValidW64UnwindInfo();
   MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
   if (!CurFrame->ChainedParent)
@@ -365,50 +362,53 @@ void MCStreamer::EmitWin64EHEndChained()
   CurrentW64UnwindInfo = CurFrame->ChainedParent;
 }
 
-void MCStreamer::EmitWin64EHUnwindOnly()
-{
+void MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
+                                    bool Except) {
+  EnsureValidW64UnwindInfo();
+  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+  CurFrame->ExceptionHandler = Sym;
+  if (Unwind)
+    CurFrame->UnwindOnly = true;
+  else if (!Except)
+    report_fatal_error("Don't know what kind of handler this is!");
+}
+
+void MCStreamer::EmitWin64EHHandlerData() {
   errs() << "Not implemented yet\n";
   abort();
 }
 
-void MCStreamer::EmitWin64EHLsda(const MCSymbol *Sym, int64_t Size)
-{
+void MCStreamer::EmitWin64EHPushReg(int64_t Register) {
   errs() << "Not implemented yet\n";
   abort();
 }
 
-void MCStreamer::EmitWin64EHPushReg(int64_t Register)
-{
+void MCStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) {
   errs() << "Not implemented yet\n";
   abort();
 }
 
-void MCStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset)
-{
+void MCStreamer::EmitWin64EHAllocStack(int64_t Size) {
   errs() << "Not implemented yet\n";
   abort();
 }
 
-void MCStreamer::EmitWin64EHAllocStack(int64_t Size)
-{
+void MCStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) {
   errs() << "Not implemented yet\n";
   abort();
 }
 
-void MCStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset)
-{
+void MCStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) {
   errs() << "Not implemented yet\n";
   abort();
 }
 
-void MCStreamer::EmitWin64EHPushFrame(bool Code)
-{
+void MCStreamer::EmitWin64EHPushFrame(bool Code) {
   errs() << "Not implemented yet\n";
   abort();
 }
 
-void MCStreamer::EmitWin64EHEndProlog()
-{
+void MCStreamer::EmitWin64EHEndProlog() {
   errs() << "Not implemented yet\n";
   abort();
 }