2270 assert(0, "Fix Handle_IDiv_Exception"); |
2270 assert(0, "Fix Handle_IDiv_Exception"); |
2271 #else |
2271 #else |
2272 #ifdef _M_AMD64 |
2272 #ifdef _M_AMD64 |
2273 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2273 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2274 address pc = (address)ctx->Rip; |
2274 address pc = (address)ctx->Rip; |
2275 assert(pc[0] == 0xF7, "not an idiv opcode"); |
2275 assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode"); |
2276 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2276 assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); |
2277 assert(ctx->Rax == min_jint, "unexpected idiv exception"); |
2277 if (pc[0] == 0xF7) { |
2278 // set correct result values and continue after idiv instruction |
2278 // set correct result values and continue after idiv instruction |
2279 ctx->Rip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes |
2279 ctx->Rip = (DWORD64)pc + 2; // idiv reg, reg is 2 bytes |
2280 ctx->Rax = (DWORD)min_jint; // result |
2280 } else { |
|
2281 ctx->Rip = (DWORD64)pc + 3; // REX idiv reg, reg is 3 bytes |
|
2282 } |
|
2283 // Do not set ctx->Rax as it already contains the correct value (either 32 or 64 bit, depending on the operation) |
|
2284 // this is the case because the exception only happens for -MinValue/-1 and -MinValue is always in rax because of the |
|
2285 // idiv opcode (0xF7). |
2281 ctx->Rdx = (DWORD)0; // remainder |
2286 ctx->Rdx = (DWORD)0; // remainder |
2282 // Continue the execution |
2287 // Continue the execution |
2283 #else |
2288 #else |
2284 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2289 PCONTEXT ctx = exceptionInfo->ContextRecord; |
2285 address pc = (address)ctx->Eip; |
2290 address pc = (address)ctx->Eip; |