[PATCH][MC/X86_64] Implement Win64 exception handling

Nico Rieck nico.rieck at gmail.com
Thu Jan 9 06:04:14 PST 2014


Hello Kai!

On 09.01.2014 08:04, Kai Nacke wrote:
> the latest commits broke the patch. This version applies cleanly to trunk.
 

+      llvm_unreachable("X86::X86::SUB64ri8/32 not allowed with these operands");

Any reason why "X86::" is used twice here and in other places?


+  case X86::MOV64mr:
+  case X86::MOVAPSmr:
+    DReg = MI->getOperand(0).getReg();
+    SReg = MI->getOperand(1).getReg();
+    Offset = MI->getOperand(4).getImm();

The ModRM byte comes before SReg, which makes Offset operand 3,
and SReg 5. While you're at it, check that Scale/Index/Segment
are 1/0/0 respectively.


+  case X86::LEA64r:
+    DReg = MI->getOperand(0).getReg();
+    SReg = MI->getOperand(1).getReg();
+    Offset = MI->getOperand(4).getImm();
+    if (SReg == RI->getStackRegister()) {
+      assert(Offset < 0 && "Offset must be negativ");

IMO just put this Offset check into the SReg if.


+      if (DReg == RI->getStackRegister()) {
+        OutStreamer.EmitWin64EHAllocStack(-Offset);
+      } else if (DReg == RI->getFrameRegister(*MF)) {
+        OutStreamer.EmitWin64EHSetFrame(RI->getSEHRegNum(DReg), -Offset);
+      } else
+        llvm_unreachable("X86::X86::LEA64r not allowed with these operands");

I noticed that the order here is very important because getFrameRegister
can also return SP. There should be a comment stating this, maybe
"Check stack register first in case there is no frame register."?


diff --git a/test/CodeGen/X86/win64_eh.ll b/test/CodeGen/X86/win64_eh.ll
new file mode 100644
index 0000000..1e662bd
--- /dev/null
+++ b/test/CodeGen/X86/win64_eh.ll
@@ -0,0 +1,180 @@
+; RUN: llc < %s -O0 -mcpu=corei7 -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=WIN64
+; RUN: llc < %s -O0 -mcpu=corei7 -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=MINGW64
+; RUN: llc < %s -O0 -mcpu=atom -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=MINGW64-ATOM
+
+; Check function with nor prolog

Typo, and "without" sounds better anyway. ;)


; Checks a stack allocation requiring call to __chkstk/___chkstk_ms
define void @foo2() uwtable {
entry:
  %baz = alloca [4000 x i16], align 2
  ret void
}
; WIN64: .seh_proc foo2
; WIN64: movabsq $8000, %rax
; WIN64: callq __chkstk
; WIN64: subq %rax, %rsp

No check for ".seh_stackalloc 8000"?

; WIN64: .seh_endprologue
; WIN64: ret
; WIN64: .seh_endproc


Since WIN64 and MINGW64 are mostly equivalent you could use a common
FileCheck prefix for both.

The rest LGTM. Let's hope someone else can greenlight it.

-Nico



More information about the llvm-commits mailing list