Changeset 47173 in vbox
- Timestamp:
- Jul 15, 2013 11:26:39 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 87276
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r47138 r47173 2408 2408 uint64_t uCr2) 2409 2409 { 2410 NOREF(cbInstr); 2411 #if 0 2412 /* 2413 * Read the IDT entry. 2414 */ 2415 uint16_t offIdt = (uint16_t)u8Vector << 4; 2416 if (pCtx->idtr.cbIdt < offIdt + 7) 2417 { 2418 Log(("iemRaiseXcptOrIntInLongMode: %#x is out of bounds (%#x)\n", u8Vector, pCtx->idtr.cbIdt)); 2419 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT)); 2420 } 2421 X86DESC64 Idte; 2422 VBOXSTRICTRC rcStrict = iemMemFetchSysU64(pIemCpu, &Idte.au64[0], UINT8_MAX, pCtx->idtr.pIdt + offIdt); 2423 if (RT_LIKELY(rcStrict != VINF_SUCCESS)) 2424 rcStrict = iemMemFetchSysU64(pIemCpu, &Idte.au64[1], UINT8_MAX, pCtx->idtr.pIdt + offIdt + 8); 2425 if (RT_UNLIKELY(rcStrict != VINF_SUCCESS)) 2426 return rcStrict; 2427 Log(("iemiemRaiseXcptOrIntInLongMode: vec=%#x P=%u DPL=%u DT=%u:%u IST=%u %04x:%08x%04x%04x\n", 2428 u8Vector, Idte.Gate.u1Present, Idte.Gate.u2Dpl, Idte.Gate.u1DescType, Idte.Gate.u4Type, 2429 Idte.Gate.u3IST, Idte.Gate.u16Sel, Idte.Gate.u32OffsetTop, Idte.Gate.u16OffsetHigh, Idte.Gate.u16OffsetLow)); 2430 2431 /* 2432 * Check the descriptor type, DPL and such. 2433 * ASSUMES this is done in the same order as described for call-gate calls. 2434 */ 2435 if (Idte.Gate.u1DescType) 2436 { 2437 Log(("iemRaiseXcptOrIntInLongMode %#x - not system selector (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type)); 2438 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT)); 2439 } 2440 uint32_t fEflToClear = X86_EFL_TF | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM; 2441 switch (Idte.Gate.u4Type) 2442 { 2443 case AMD64_SEL_TYPE_SYS_INT_GATE: 2444 fEflToClear |= X86_EFL_IF; 2445 break; 2446 case AMD64_SEL_TYPE_SYS_TRAP_GATE: 2447 break; 2448 2449 default: 2450 Log(("iemRaiseXcptOrIntInLongMode %#x - invalid type (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type)); 2451 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT)); 2452 2453 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 2454 } 2455 2456 /* Check DPL against CPL if applicable. */ 2457 if (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT) 2458 { 2459 if (pIemCpu->uCpl > Idte.Gate.u2Dpl) 2460 { 2461 Log(("iemRaiseXcptOrIntInLongMode %#x - CPL (%d) > DPL (%d) -> #GP\n", u8Vector, pIemCpu->uCpl, Idte.Gate.u2Dpl)); 2462 return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT)); 2463 } 2464 } 2465 2466 /* Is it there? */ 2467 if (!Idte.Gate.u1Present) 2468 { 2469 Log(("iemRaiseXcptOrIntInLongMode %#x - not present -> #NP\n", u8Vector)); 2470 return iemRaiseSelectorNotPresentWithErr(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT)); 2471 } 2472 2473 /* A null CS is bad. */ 2474 RTSEL NewCS = Idte.Gate.u16Sel; 2475 if (!(NewCS & X86_SEL_MASK_OFF_RPL)) 2476 { 2477 Log(("iemRaiseXcptOrIntInLongMode %#x - CS=%#x -> #GP\n", u8Vector, NewCS)); 2478 return iemRaiseGeneralProtectionFault0(pIemCpu); 2479 } 2480 2481 /* Fetch the descriptor for the new CS. */ 2482 IEMSELDESC DescCS; 2483 rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS); 2484 if (rcStrict != VINF_SUCCESS) 2485 { 2486 Log(("iemRaiseXcptOrIntInLongMode %#x - CS=%#x - rc=%Rrc\n", u8Vector, NewCS, VBOXSTRICTRC_VAL(rcStrict))); 2487 return rcStrict; 2488 } 2489 2490 /* Must be a 64-bit code segment. */ 2491 if (!DescCS.Long.Gen.u1DescType) 2492 { 2493 Log(("iemRaiseXcptOrIntInLongMode %#x - CS=%#x - system selector (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type)); 2494 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL); 2495 } 2496 /** @todo what do we check here? */ 2497 if (!DescCS.Long.Gen.u1Long || DescCS.Long.Gen.u1DefBig) 2498 { 2499 Log(("iemRaiseXcptOrIntInLongMode %#x - CS=%#x - (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type)); 2500 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL); 2501 } 2502 2503 /* Don't allow lowering the privilege level. */ 2504 /** @todo Does the lowering of privileges apply to software interrupts 2505 * only? This has bearings on the more-privileged or 2506 * same-privilege stack behavior further down. A testcase would 2507 * be nice. */ 2508 if (DescCS.Legacy.Gen.u2Dpl > pIemCpu->uCpl) 2509 { 2510 Log(("iemRaiseXcptOrIntInLongMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n", 2511 u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl)); 2512 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL); 2513 } 2514 /** @todo is the RPL of the interrupt/trap gate descriptor checked? */ 2515 2516 /* Check the new EIP against the new CS limit. */ 2517 uint32_t const uNewEip = Idte.Gate.u4Type == X86_SEL_TYPE_SYS_286_INT_GATE 2518 || Idte.Gate.u4Type == X86_SEL_TYPE_SYS_286_TRAP_GATE 2519 ? Idte.Gate.u16OffsetLow 2520 : Idte.Gate.u16OffsetLow | ((uint32_t)Idte.Gate.u16OffsetHigh << 16); 2521 uint32_t cbLimitCS = X86DESC_LIMIT_G(&DescCS.Legacy); 2522 if (uNewEip > cbLimitCS) 2523 { 2524 Log(("iemRaiseXcptOrIntInLongMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n", 2525 u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl)); 2526 return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & X86_SEL_MASK_OFF_RPL); 2527 } 2528 2529 /* Make sure the selector is present. */ 2530 if (!DescCS.Legacy.Gen.u1Present) 2531 { 2532 Log(("iemRaiseXcptOrIntInLongMode %#x - CS=%#x - segment not present -> #NP\n", u8Vector, NewCS)); 2533 return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewCS); 2534 } 2535 2536 /* 2537 * If the privilege level changes, we need to get a new stack from the TSS. 2538 * This in turns means validating the new SS and ESP... 2539 */ 2540 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx); 2541 uint8_t const uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF 2542 ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl; 2543 if (uNewCpl != pIemCpu->uCpl) 2544 { 2545 RTSEL NewSS; 2546 uint32_t uNewEsp; 2547 rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &NewSS, &uNewEsp); 2548 if (rcStrict != VINF_SUCCESS) 2549 return rcStrict; 2550 2551 IEMSELDESC DescSS; 2552 rcStrict = iemMiscValidateNewSS(pIemCpu, pCtx, NewSS, uNewCpl, &DescSS); 2553 if (rcStrict != VINF_SUCCESS) 2554 return rcStrict; 2555 2556 /* Check that there is sufficient space for the stack frame. */ 2557 uint32_t cbLimitSS = X86DESC_LIMIT_G(&DescSS.Legacy); 2558 if (DescSS.Legacy.Gen.u4Type & X86_SEL_TYPE_DOWN) 2559 { 2560 IEM_RETURN_ASPECT_NOT_IMPLEMENTED_LOG(("Expand down segments\n")); /** @todo Implement expand down segment support. */ 2561 } 2562 2563 uint8_t const cbStackFrame = fFlags & IEM_XCPT_FLAGS_ERR ? 24 : 20; 2564 if ( uNewEsp - 1 > cbLimitSS 2565 || uNewEsp < cbStackFrame) 2566 { 2567 Log(("iemRaiseXcptOrIntInLongMode: %#x - SS=%#x ESP=%#x cbStackFrame=%#x is out of bounds -> #GP\n", 2568 u8Vector, NewSS, uNewEsp, cbStackFrame)); 2569 return iemRaiseSelectorBoundsBySelector(pIemCpu, NewSS); 2570 } 2571 2572 /* 2573 * Start making changes. 2574 */ 2575 2576 /* Create the stack frame. */ 2577 RTPTRUNION uStackFrame; 2578 rcStrict = iemMemMap(pIemCpu, &uStackFrame.pv, cbStackFrame, UINT8_MAX, 2579 uNewEsp - cbStackFrame + X86DESC_BASE(&DescSS.Legacy), IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS); /* _SYS is a hack ... */ 2580 if (rcStrict != VINF_SUCCESS) 2581 return rcStrict; 2582 void * const pvStackFrame = uStackFrame.pv; 2583 2584 if (fFlags & IEM_XCPT_FLAGS_ERR) 2585 *uStackFrame.pu32++ = uErr; 2586 uStackFrame.pu32[0] = (fFlags & (IEM_XCPT_FLAGS_T_SOFT_INT | IEM_XCPT_FLAGS_BP_INSTR)) == IEM_XCPT_FLAGS_T_SOFT_INT 2587 ? pCtx->eip + cbInstr : pCtx->eip; 2588 uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl; 2589 uStackFrame.pu32[2] = fEfl; 2590 uStackFrame.pu32[3] = pCtx->esp; 2591 uStackFrame.pu32[4] = pCtx->ss.Sel; 2592 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS); 2593 if (rcStrict != VINF_SUCCESS) 2594 return rcStrict; 2595 2596 /* Mark the selectors 'accessed' (hope this is the correct time). */ 2597 /** @todo testcase: excatly _when_ are the accessed bits set - before or 2598 * after pushing the stack frame? (Write protect the gdt + stack to 2599 * find out.) */ 2600 if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED)) 2601 { 2602 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewCS); 2603 if (rcStrict != VINF_SUCCESS) 2604 return rcStrict; 2605 DescCS.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED; 2606 } 2607 2608 if (!(DescSS.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED)) 2609 { 2610 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewSS); 2611 if (rcStrict != VINF_SUCCESS) 2612 return rcStrict; 2613 DescSS.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED; 2614 } 2615 2616 /* 2617 * Start comitting the register changes (joins with the DPL=CPL branch). 2618 */ 2619 pCtx->ss.Sel = NewSS; 2620 pCtx->ss.ValidSel = NewSS; 2621 pCtx->ss.fFlags = CPUMSELREG_FLAGS_VALID; 2622 pCtx->ss.u32Limit = cbLimitSS; 2623 pCtx->ss.u64Base = X86DESC_BASE(&DescSS.Legacy); 2624 pCtx->ss.Attr.u = X86DESC_GET_HID_ATTR(&DescSS.Legacy); 2625 pCtx->rsp = uNewEsp - cbStackFrame; /** @todo Is the high word cleared for 16-bit stacks and/or interrupt handlers? */ 2626 pIemCpu->uCpl = uNewCpl; 2627 } 2628 /* 2629 * Same privilege, no stack change and smaller stack frame. 2630 */ 2631 else 2632 { 2633 uint64_t uNewRsp; 2634 RTPTRUNION uStackFrame; 2635 uint8_t const cbStackFrame = fFlags & IEM_XCPT_FLAGS_ERR ? 16 : 12; 2636 rcStrict = iemMemStackPushBeginSpecial(pIemCpu, cbStackFrame, &uStackFrame.pv, &uNewRsp); 2637 if (rcStrict != VINF_SUCCESS) 2638 return rcStrict; 2639 void * const pvStackFrame = uStackFrame.pv; 2640 2641 if (fFlags & IEM_XCPT_FLAGS_ERR) 2642 *uStackFrame.pu32++ = uErr; 2643 uStackFrame.pu32[0] = (fFlags & (IEM_XCPT_FLAGS_T_SOFT_INT | IEM_XCPT_FLAGS_BP_INSTR)) == IEM_XCPT_FLAGS_T_SOFT_INT 2644 ? pCtx->eip + cbInstr : pCtx->eip; 2645 uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl; 2646 uStackFrame.pu32[2] = fEfl; 2647 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W); /* don't use the commit here */ 2648 if (rcStrict != VINF_SUCCESS) 2649 return rcStrict; 2650 2651 /* Mark the CS selector as 'accessed'. */ 2652 if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_ACCESSED)) 2653 { 2654 rcStrict = iemMemMarkSelDescAccessed(pIemCpu, NewCS); 2655 if (rcStrict != VINF_SUCCESS) 2656 return rcStrict; 2657 DescCS.Legacy.Gen.u4Type |= X86_SEL_TYPE_ACCESSED; 2658 } 2659 2660 /* 2661 * Start committing the register changes (joins with the other branch). 2662 */ 2663 pCtx->rsp = uNewRsp; 2664 } 2665 2666 /* ... register committing continues. */ 2667 pCtx->cs.Sel = (NewCS & ~X86_SEL_RPL) | uNewCpl; 2668 pCtx->cs.ValidSel = (NewCS & ~X86_SEL_RPL) | uNewCpl; 2669 pCtx->cs.fFlags = CPUMSELREG_FLAGS_VALID; 2670 pCtx->cs.u32Limit = cbLimitCS; 2671 pCtx->cs.u64Base = X86DESC_BASE(&DescCS.Legacy); 2672 pCtx->cs.Attr.u = X86DESC_GET_HID_ATTR(&DescCS.Legacy); 2673 2674 pCtx->rip = uNewEip; 2675 fEfl &= ~fEflToClear; 2676 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl); 2677 2678 if (fFlags & IEM_XCPT_FLAGS_CR2) 2679 pCtx->cr2 = uCr2; 2680 2681 if (fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT) 2682 iemRaiseXcptAdjustState(pCtx, u8Vector); 2683 2684 return fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT ? VINF_IEM_RAISED_XCPT : VINF_SUCCESS; 2685 #else 2410 2686 NOREF(pIemCpu); NOREF(pCtx); NOREF(cbInstr); NOREF(u8Vector); NOREF(fFlags); NOREF(uErr); NOREF(uCr2); 2411 2687 /** @todo implement me. */ 2412 2688 IEM_RETURN_ASPECT_NOT_IMPLEMENTED_LOG(("long mode exception / interrupt dispatching\n")); 2689 #endif 2413 2690 } 2414 2691 -
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r47138 r47173 1274 1274 ENDPROC iemAImpl_ %+ %1 %+ _u32 1275 1275 1276 %ifdef RT_ARCH_AMD64 1276 %ifdef RT_ARCH_AMD64 ; The 32-bit host version lives in IEMAllAImplC.cpp. 1277 1277 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20 1278 1278 PROLOGUE_4_ARGS 1279 1279 IEM_MAYBE_LOAD_FLAGS A3, %2, %3 1280 1280 mov rax, [A0] 1281 %ifdef ASM_CALL64_GCC1281 %ifdef ASM_CALL64_GCC 1282 1282 %1 A2 1283 1283 mov [A0], rax 1284 1284 mov [A1], rdx 1285 %else1285 %else 1286 1286 mov T1, A1 1287 1287 %1 A2 1288 1288 mov [A0], rax 1289 1289 mov [T1], rdx 1290 %endif1290 %endif 1291 1291 IEM_SAVE_FLAGS A3, %2, %3 1292 1292 xor eax, eax 1293 1293 EPILOGUE_4_ARGS_EX 12 1294 1294 ENDPROC iemAImpl_ %+ %1 %+ _u64 1295 %else ; stub it for now - later, replace with hand coded stuff. 1296 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20 1297 int3 1298 ret 12 1299 ENDPROC iemAImpl_ %+ %1 %+ _u64 1300 %endif ; !RT_ARCH_AMD64 1295 %endif ; !RT_ARCH_AMD64 1301 1296 1302 1297 %endmacro … … 1304 1299 IEMIMPL_MUL_OP mul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF) 1305 1300 IEMIMPL_MUL_OP imul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF) 1301 1302 1303 BEGINCODE 1304 ;; 1305 ; Worker function for negating a 32-bit number in T1:T0 1306 ; @uses None (T0,T1) 1307 iemAImpl_negate_T0_T1_u32: 1308 push 0 1309 push 0 1310 xchg T0_32, [xSP] 1311 xchg T1_32, [xSP + xCB] 1312 sub T0_32, [xSP] 1313 sbb T1_32, [xSP + xCB] 1314 add xSP, xCB*2 1315 ret 1316 1317 %ifdef RT_ARCH_AMD64 1318 ;; 1319 ; Worker function for negating a 64-bit number in T1:T0 1320 ; @uses None (T0,T1) 1321 iemAImpl_negate_T0_T1_u64: 1322 push 0 1323 push 0 1324 xchg T0, [xSP] 1325 xchg T1, [xSP + xCB] 1326 sub T0, [xSP] 1327 sbb T1, [xSP + xCB] 1328 add xSP, xCB*2 1329 ret 1330 %endif 1306 1331 1307 1332 … … 1483 1508 test T1_32, T1_32 1484 1509 jns .both_positive 1485 neg T0_32 1486 neg T1_32 1510 call iemAImpl_negate_T0_T1_u32 1487 1511 .one_of_each: ; OK range is 2^(result-with - 1) + (divisor - 1). 1488 1512 push T0 ; Start off like unsigned below. … … 1503 1527 test T1_32, T1_32 1504 1528 jns .one_of_each 1505 neg T0_32 1506 neg T1_32 1529 call iemAImpl_negate_T0_T1_u32 1507 1530 .both_positive: ; Same as unsigned shifted by sign indicator bit. 1508 1531 shl T1_32, 1 … … 1547 1570 ENDPROC iemAImpl_ %+ %1 %+ _u32 1548 1571 1549 %ifdef RT_ARCH_AMD64 1572 %ifdef RT_ARCH_AMD64 ; The 32-bit host version lives in IEMAllAImplC.cpp. 1550 1573 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20 1551 1574 PROLOGUE_4_ARGS … … 1553 1576 test A2, A2 1554 1577 jz .div_zero 1555 %if %4 == 01578 %if %4 == 0 1556 1579 cmp [A1], A2 1557 1580 jae .div_overflow 1558 %else1581 %else 1559 1582 push A2 ; save A2 so we modify it (we out of regs on x86). 1560 1583 mov T0, [A0] ; T0 = dividend low … … 1564 1587 test T1, T1 1565 1588 jns .both_positive 1566 neg T0 1567 neg T1 1589 call iemAImpl_negate_T0_T1_u64 1568 1590 .one_of_each: ; OK range is 2^(result-with - 1) + (divisor - 1). 1569 1591 push T0 ; Start off like unsigned below. … … 1585 1607 test T1, T1 1586 1608 jns .one_of_each 1587 neg T0 1588 neg T1 1609 call iemAImpl_negate_T0_T1_u64 1589 1610 .both_positive: ; Same as unsigned shifted by sign indicator bit. 1590 1611 shl T1, 1 … … 1595 1616 .div_no_overflow: 1596 1617 pop A2 1597 %endif1618 %endif 1598 1619 1599 1620 IEM_MAYBE_LOAD_FLAGS A3, %2, %3 1600 1621 mov rax, [A0] 1601 %ifdef ASM_CALL64_GCC1622 %ifdef ASM_CALL64_GCC 1602 1623 mov T1, A2 1603 1624 mov rax, [A0] … … 1606 1627 mov [A0], rax 1607 1628 mov [A1], rdx 1608 %else1629 %else 1609 1630 mov T1, A1 1610 1631 mov rax, [A0] … … 1613 1634 mov [A0], rax 1614 1635 mov [T1], rdx 1615 %endif1636 %endif 1616 1637 IEM_SAVE_FLAGS A3, %2, %3 1617 1638 xor eax, eax … … 1621 1642 1622 1643 .div_overflow: 1623 %if %4 != 01644 %if %4 != 0 1624 1645 pop A2 1625 %endif1646 %endif 1626 1647 .div_zero: 1627 1648 mov eax, -1 1628 1649 jmp .return 1629 1650 ENDPROC iemAImpl_ %+ %1 %+ _u64 1630 %else ; stub it for now - later, replace with hand coded stuff. 1631 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20 1632 int3 1633 ret 1634 ENDPROC iemAImpl_ %+ %1 %+ _u64 1635 %endif ; !RT_ARCH_AMD64 1651 %endif ; !RT_ARCH_AMD64 1636 1652 1637 1653 %endmacro -
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r37955 r47173 5 5 6 6 /* 7 * Copyright (C) 2011 Oracle Corporation7 * Copyright (C) 2011-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 23 23 #include <iprt/x86.h> 24 24 25 #if 0 25 26 #ifdef RT_ARCH_X86 27 /* 28 * There are a few 64-bit on 32-bit things we'd rather do in C. 29 */ 26 30 27 31 28 IEM_DECL_IMPL_DEF( void, iemImpl_add_u8,(uint8_t *pu8Dst, uint8_t u8Src,uint32_t *pEFlags))32 IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Factor, uint32_t *pEFlags)) 29 33 { 30 /* incorrect sketch (testing fastcall + gcc) */ 31 uint8_t u8Dst = *pu8Dst; 32 uint8_t u8Res = u8Dst + u8Src; 33 *pu8Dst = u8Res; 34 35 if (u8Res) 36 *pEFlags &= X86_EFL_ZF; 37 else 38 *pEFlags |= X86_EFL_ZF; 39 } 40 41 IEM_DECL_IMPL_DEF(void, iemImpl_add_u8_locked,(uint8_t *pu8Dst, uint8_t u8Src, uint32_t *pEFlags)) 42 { 43 iemImpl_add_u8(pu8Dst, u8Src, pEFlags); 34 AssertFailed(); 35 return -1; 44 36 } 45 37 46 38 47 #endif 39 IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Factor, uint32_t *pEFlags)) 40 { 41 AssertFailed(); 42 return -1; 43 } 48 44 45 46 IEM_DECL_IMPL_DEF(int, iemAImpl_div_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Divisor, uint32_t *pEFlags)) 47 { 48 AssertFailed(); 49 return -1; 50 } 51 52 53 IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Divisor, uint32_t *pEFlags)) 54 { 55 AssertFailed(); 56 return -1; 57 } 58 59 #endif /* RT_ARCH_X86 */ 60
Note:
See TracChangeset
for help on using the changeset viewer.