changeset 7696:fbbc2ea60c4d

fixed signal handler for long underflow on windows
author Christian Haeubl <haeubl@ssw.jku.at>
date Mon, 04 Feb 2013 17:29:13 +0100
parents 320d6fd3dbf3
children e7a85c94502e
files src/os/windows/vm/os_windows.cpp
diffstat 1 files changed, 26 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/os/windows/vm/os_windows.cpp	Mon Feb 04 15:49:59 2013 +0100
+++ b/src/os/windows/vm/os_windows.cpp	Mon Feb 04 17:29:13 2013 +0100
@@ -2103,18 +2103,32 @@
 #ifdef _M_IA64
   assert(0, "Fix Handle_IDiv_Exception");
 #elif _M_AMD64
-  PCONTEXT ctx = exceptionInfo->ContextRecord;
-  address pc = (address)ctx->Rip;
-#ifndef GRAAL
-  assert(pc[0] == 0xF7, "not an idiv opcode");
-  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
-  assert(ctx->Rax == min_jint, "unexpected idiv exception");
-#endif
-  // set correct result values and continue after idiv instruction
-  ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
-  ctx->Rax = (DWORD)min_jint;      // result
-  ctx->Rdx = (DWORD)0;             // remainder
-  // Continue the execution
+  #ifdef GRAAL
+    PCONTEXT ctx = exceptionInfo->ContextRecord;
+    address pc = (address)ctx->Rip;
+    assert(pc[0] == 0x48 && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
+    if (pc[0] == 0x48) {
+      // set correct result values and continue after idiv instruction
+      ctx->Rip = (DWORD64)pc + 3;        // REX idiv reg, reg  is 3 bytes
+      ctx->Rax = (DWORD64)min_jlong;     // result
+    } else {
+      ctx->Rip = (DWORD64)pc + 2;        // idiv reg, reg  is 2 bytes
+      ctx->Rax = (DWORD64)min_jint;      // result
+    }
+    ctx->Rdx = (DWORD64)0;             // remainder
+    // Continue the execution
+  #else
+    PCONTEXT ctx = exceptionInfo->ContextRecord;
+    address pc = (address)ctx->Rip;
+    assert(pc[0] == 0xF7, "not an idiv opcode");
+    assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
+    assert(ctx->Rax == min_jint, "unexpected idiv exception");
+    // set correct result values and continue after idiv instruction
+    ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
+    ctx->Rax = (DWORD)min_jint;      // result
+    ctx->Rdx = (DWORD)0;             // remainder
+    // Continue the execution
+  #endif // GRAAL
 #else
   PCONTEXT ctx = exceptionInfo->ContextRecord;
   address pc = (address)ctx->Eip;