Changeset 101682 in vbox for trunk/src/VBox/VMM/include
- Timestamp:
- Oct 31, 2023 12:18:44 PM (18 months ago)
- svn:sync-xref-src-repo-rev:
- 159774
- Location:
- trunk/src/VBox/VMM/include
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IEMInternal.h
r101640 r101682 1845 1845 # define IEM_TRY_SETJMP(a_pVCpu, a_rcTarget) \ 1846 1846 jmp_buf JmpBuf; \ 1847 jmp_buf * volatile pSavedJmpBuf = pVCpu->iem.s.CTX_SUFF(pJmpBuf); \1848 pVCpu->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf; \1847 jmp_buf * volatile pSavedJmpBuf = (a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf); \ 1848 (a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf; \ 1849 1849 if ((rcStrict = setjmp(JmpBuf)) == 0) 1850 1850 # define IEM_TRY_SETJMP_AGAIN(a_pVCpu, a_rcTarget) \ 1851 pSavedJmpBuf = pVCpu->iem.s.CTX_SUFF(pJmpBuf); \1852 pVCpu->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf; \1851 pSavedJmpBuf = (a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf); \ 1852 (a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf; \ 1853 1853 if ((rcStrict = setjmp(JmpBuf)) == 0) 1854 1854 # define IEM_CATCH_LONGJMP_BEGIN(a_pVCpu, a_rcTarget) \ … … 5590 5590 5591 5591 /* Native recompiler public bits: */ 5592 PIEMTB iemNativeRecompile(PVMCPUCC pVCpu, PIEMTB pTb);5593 int iemExecMemAllocatorInit(PVMCPU pVCpu, uint64_t cbMax, uint64_t cbInitial, uint32_t cbChunk);5594 void iemExecMemAllocatorFree(PVMCPU pVCpu, void *pv, size_t cb);5592 DECLHIDDEN(PIEMTB) iemNativeRecompile(PVMCPUCC pVCpu, PIEMTB pTb) RT_NOEXCEPT; 5593 int iemExecMemAllocatorInit(PVMCPU pVCpu, uint64_t cbMax, uint64_t cbInitial, uint32_t cbChunk); 5594 void iemExecMemAllocatorFree(PVMCPU pVCpu, void *pv, size_t cb); 5595 5595 5596 5596 -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r101661 r101682 621 621 /** The condition nesting stack. */ 622 622 IEMNATIVECOND aCondStack[2]; 623 624 #ifndef IEM_WITH_THROW_CATCH 625 /** Pointer to the setjmp/longjmp buffer if we're not using C++ exceptions 626 * for recompilation error handling. */ 627 jmp_buf JmpBuf; 628 #endif 623 629 } IEMRECOMPILERSTATE; 624 630 /** Pointer to a native recompiler state. */ … … 626 632 627 633 634 /** @def IEMNATIVE_TRY_SETJMP 635 * Wrapper around setjmp / try, hiding all the ugly differences. 636 * 637 * @note Use with extreme care as this is a fragile macro. 638 * @param a_pReNative The native recompile state. 639 * @param a_rcTarget The variable that should receive the status code in case 640 * of a longjmp/throw. 641 */ 642 /** @def IEMNATIVE_CATCH_LONGJMP_BEGIN 643 * Start wrapper for catch / setjmp-else. 644 * 645 * This will set up a scope. 646 * 647 * @note Use with extreme care as this is a fragile macro. 648 * @param a_pReNative The native recompile state. 649 * @param a_rcTarget The variable that should receive the status code in case 650 * of a longjmp/throw. 651 */ 652 /** @def IEMNATIVE_CATCH_LONGJMP_END 653 * End wrapper for catch / setjmp-else. 654 * 655 * This will close the scope set up by IEMNATIVE_CATCH_LONGJMP_BEGIN and clean 656 * up the state. 657 * 658 * @note Use with extreme care as this is a fragile macro. 659 * @param a_pReNative The native recompile state. 660 */ 661 /** @def IEMNATIVE_DO_LONGJMP 662 * 663 * Wrapper around longjmp / throw. 664 * 665 * @param a_pReNative The native recompile state. 666 * @param a_rc The status code jump back with / throw. 667 */ 668 #ifdef IEM_WITH_THROW_CATCH 669 # define IEMNATIVE_TRY_SETJMP(a_pReNative, a_rcTarget) \ 670 a_rcTarget = VINF_SUCCESS; \ 671 try 672 # define IEMNATIVE_CATCH_LONGJMP_BEGIN(a_pReNative, a_rcTarget) \ 673 catch (int rcThrown) \ 674 { \ 675 a_rcTarget = rcThrown 676 # define IEMNATIVE_CATCH_LONGJMP_END(a_pReNative) \ 677 } \ 678 ((void)0) 679 # define IEMNATIVE_DO_LONGJMP(a_pReNative, a_rc) throw int(a_rc) 680 #else /* !IEM_WITH_THROW_CATCH */ 681 # define IEMNATIVE_TRY_SETJMP(a_pReNative, a_rcTarget) \ 682 if ((a_rcTarget = setjmp((a_pReNative)->JmpBuf)) == 0) 683 # define IEMNATIVE_CATCH_LONGJMP_BEGIN(a_pReNative, a_rcTarget) \ 684 else \ 685 { \ 686 ((void)0) 687 # define IEMNATIVE_CATCH_LONGJMP_END(a_pReNative) \ 688 } 689 # define IEMNATIVE_DO_LONGJMP(a_pReNative, a_rc) longjmp((a_pReNative)->JmpBuf, (a_rc)) 690 #endif /* !IEM_WITH_THROW_CATCH */ 691 692 628 693 /** 629 694 * Native recompiler worker for a threaded function. 630 695 * 631 * @returns New code buffer offset , UINT32_MAX in case offailure.696 * @returns New code buffer offset; throws VBox status code in case of a failure. 632 697 * @param pReNative The native recompiler state. 633 698 * @param off The current code buffer offset. 634 699 * @param pCallEntry The threaded call entry. 635 700 * 636 * @note This is not allowed to throw anything atm. 637 */ 638 typedef DECLCALLBACKTYPE(uint32_t, FNIEMNATIVERECOMPFUNC,(PIEMRECOMPILERSTATE pReNative, uint32_t off, 639 PCIEMTHRDEDCALLENTRY pCallEntry)); 701 * @note This may throw/longjmp VBox status codes (int) to abort compilation, so no RT_NOEXCEPT! 702 */ 703 typedef uint32_t (VBOXCALL FNIEMNATIVERECOMPFUNC)(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry); 640 704 /** Pointer to a native recompiler worker for a threaded function. */ 641 705 typedef FNIEMNATIVERECOMPFUNC *PFNIEMNATIVERECOMPFUNC; 642 706 643 /** Defines a native recompiler worker for a threaded function. */ 707 /** Defines a native recompiler worker for a threaded function. 708 * @see FNIEMNATIVERECOMPFUNC */ 644 709 #define IEM_DECL_IEMNATIVERECOMPFUNC_DEF(a_Name) \ 645 DECLCALLBACK(uint32_t) a_Name(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry) 646 /** Prototypes a native recompiler function for a threaded function. */ 710 uint32_t VBOXCALL a_Name(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry) 711 712 /** Prototypes a native recompiler function for a threaded function. 713 * @see FNIEMNATIVERECOMPFUNC */ 647 714 #define IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(a_Name) FNIEMNATIVERECOMPFUNC a_Name 648 715 649 DECLHIDDEN(uint32_t) iemNativeLabelCreate(PIEMRECOMPILERSTATE pReNative, IEMNATIVELABELTYPE enmType, 650 uint32_t offWhere = UINT32_MAX, uint16_t uData = 0) RT_NOEXCEPT; 651 DECLHIDDEN(void) iemNativeLabelDefine(PIEMRECOMPILERSTATE pReNative, uint32_t idxLabel, uint32_t offWhere) RT_NOEXCEPT; 652 DECLHIDDEN(bool) iemNativeAddFixup(PIEMRECOMPILERSTATE pReNative, uint32_t offWhere, uint32_t idxLabel, 653 IEMNATIVEFIXUPTYPE enmType, int8_t offAddend = 0) RT_NOEXCEPT; 654 DECLHIDDEN(PIEMNATIVEINSTR) iemNativeInstrBufEnsureSlow(PIEMRECOMPILERSTATE pReNative, uint32_t off, 655 uint32_t cInstrReq) RT_NOEXCEPT; 656 657 DECLHIDDEN(uint8_t) iemNativeRegAllocTmp(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, 658 bool fPreferVolatile = true) RT_NOEXCEPT; 659 DECLHIDDEN(uint8_t) iemNativeRegAllocTmpImm(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint64_t uImm, 660 bool fPreferVolatile = true) RT_NOEXCEPT; 661 DECLHIDDEN(uint8_t) iemNativeRegAllocTmpForGuestReg(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, 662 IEMNATIVEGSTREG enmGstReg, 663 IEMNATIVEGSTREGUSE enmIntendedUse) RT_NOEXCEPT; 664 DECLHIDDEN(uint8_t) iemNativeRegAllocTmpForGuestRegIfAlreadyPresent(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, 665 IEMNATIVEGSTREG enmGstReg) RT_NOEXCEPT; 666 667 DECLHIDDEN(uint8_t) iemNativeRegAllocVar(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint8_t idxVar) RT_NOEXCEPT; 668 DECLHIDDEN(uint32_t) iemNativeRegAllocArgs(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cArgs) RT_NOEXCEPT; 669 DECLHIDDEN(uint8_t) iemNativeRegAssignRc(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg) RT_NOEXCEPT; 716 DECL_HIDDEN_THROW(uint32_t) iemNativeLabelCreate(PIEMRECOMPILERSTATE pReNative, IEMNATIVELABELTYPE enmType, 717 uint32_t offWhere = UINT32_MAX, uint16_t uData = 0); 718 DECL_HIDDEN_THROW(void) iemNativeLabelDefine(PIEMRECOMPILERSTATE pReNative, uint32_t idxLabel, uint32_t offWhere); 719 DECL_HIDDEN_THROW(void) iemNativeAddFixup(PIEMRECOMPILERSTATE pReNative, uint32_t offWhere, uint32_t idxLabel, 720 IEMNATIVEFIXUPTYPE enmType, int8_t offAddend = 0); 721 DECL_HIDDEN_THROW(PIEMNATIVEINSTR) iemNativeInstrBufEnsureSlow(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t cInstrReq); 722 723 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmp(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, bool fPreferVolatile = true); 724 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpImm(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint64_t uImm, 725 bool fPreferVolatile = true); 726 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpForGuestReg(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, 727 IEMNATIVEGSTREG enmGstReg, IEMNATIVEGSTREGUSE enmIntendedUse); 728 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpForGuestRegIfAlreadyPresent(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, 729 IEMNATIVEGSTREG enmGstReg); 730 731 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocVar(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint8_t idxVar); 732 DECL_HIDDEN_THROW(uint32_t) iemNativeRegAllocArgs(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cArgs); 733 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAssignRc(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg); 670 734 DECLHIDDEN(void) iemNativeRegFree(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg) RT_NOEXCEPT; 671 735 DECLHIDDEN(void) iemNativeRegFreeTmp(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg) RT_NOEXCEPT; 672 736 DECLHIDDEN(void) iemNativeRegFreeTmpImm(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg) RT_NOEXCEPT; 673 737 DECLHIDDEN(void) iemNativeRegFreeAndFlushMask(PIEMRECOMPILERSTATE pReNative, uint32_t fHstRegMask) RT_NOEXCEPT; 674 DECLHIDDEN(uint32_t) iemNativeRegFlushPendingWrites(PIEMRECOMPILERSTATE pReNative, uint32_t off) RT_NOEXCEPT; 675 676 DECLHIDDEN(uint32_t) iemNativeEmitLoadGprWithGstShadowReg(PIEMRECOMPILERSTATE pReNative, uint32_t off, 677 uint8_t idxHstReg, IEMNATIVEGSTREG enmGstReg) RT_NOEXCEPT; 678 DECLHIDDEN(uint32_t) iemNativeEmitCheckCallRetAndPassUp(PIEMRECOMPILERSTATE pReNative, uint32_t off, 679 uint8_t idxInstr) RT_NOEXCEPT; 738 DECL_HIDDEN_THROW(uint32_t) iemNativeRegFlushPendingWrites(PIEMRECOMPILERSTATE pReNative, uint32_t off); 739 740 DECL_HIDDEN_THROW(uint32_t) iemNativeEmitLoadGprWithGstShadowReg(PIEMRECOMPILERSTATE pReNative, uint32_t off, 741 uint8_t idxHstReg, IEMNATIVEGSTREG enmGstReg); 742 DECL_HIDDEN_THROW(uint32_t) iemNativeEmitCheckCallRetAndPassUp(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxInstr); 680 743 681 744 … … 688 751 * allocation size. 689 752 * 690 * @returns Pointer to the instruction output buffer on success , NULL on691 * failure.753 * @returns Pointer to the instruction output buffer on success; throws VBox 754 * status code on failure, so no need to check it. 692 755 * @param pReNative The native recompile state. 693 756 * @param off Current instruction offset. Works safely for UINT32_MAX … … 696 759 * overestimate this a bit. 697 760 */ 698 DECL_FORCE_INLINE(PIEMNATIVEINSTR) iemNativeInstrBufEnsure(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t cInstrReq) 699 { 700 uint64_t const offChecked = off + (uint64_t)cInstrReq; 761 DECL_FORCE_INLINE_THROW(PIEMNATIVEINSTR) 762 iemNativeInstrBufEnsure(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t cInstrReq) 763 { 764 uint64_t const offChecked = off + (uint64_t)cInstrReq; /** @todo may reconsider the need for UINT32_MAX safety... */ 701 765 if (RT_LIKELY(offChecked <= pReNative->cInstrBufAlloc)) 702 766 { … … 721 785 * in the disassembly. 722 786 */ 723 DECLINLINE(uint32_t) iemNativeEmitMarker(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t uInfo) 787 DECL_INLINE_THROW(uint32_t) 788 iemNativeEmitMarker(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t uInfo) 724 789 { 725 790 #ifdef RT_ARCH_AMD64 726 791 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 727 AssertReturn(pbCodeBuf, UINT32_MAX);728 792 if (uInfo == 0) 729 793 { … … 743 807 } 744 808 #elif RT_ARCH_ARM64 809 /* nop */ 745 810 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 746 AssertReturn(pu32CodeBuf, UINT32_MAX);747 /* nop */748 811 pu32CodeBuf[off++] = 0xd503201f; 749 812 … … 764 827 * Emits setting a GPR to zero. 765 828 */ 766 DECLINLINE(uint32_t) iemNativeEmitGprZero(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr) 767 { 768 #ifdef RT_ARCH_AMD64 829 DECL_INLINE_THROW(uint32_t) 830 iemNativeEmitGprZero(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr) 831 { 832 #ifdef RT_ARCH_AMD64 833 /* xor gpr32, gpr32 */ 769 834 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 770 AssertReturn(pbCodeBuf, UINT32_MAX);771 /* xor gpr32, gpr32 */772 835 if (iGpr >= 8) 773 836 pbCodeBuf[off++] = X86_OP_REX_R | X86_OP_REX_B; … … 776 839 777 840 #elif RT_ARCH_ARM64 841 /* mov gpr, #0x0 */ 778 842 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 779 AssertReturn(pu32CodeBuf, UINT32_MAX);780 /* mov gpr, #0x0 */781 843 pu32CodeBuf[off++] = UINT32_C(0xd2800000) | iGpr; 782 844 … … 792 854 * Emits loading a constant into a 64-bit GPR 793 855 */ 794 DECLINLINE(uint32_t) iemNativeEmitLoadGprImm64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint64_t uImm64) 856 DECL_INLINE_THROW(uint32_t) 857 iemNativeEmitLoadGprImm64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint64_t uImm64) 795 858 { 796 859 if (!uImm64) … … 802 865 /* mov gpr, imm32 */ 803 866 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6); 804 AssertReturn(pbCodeBuf, UINT32_MAX);805 867 if (iGpr >= 8) 806 868 pbCodeBuf[off++] = X86_OP_REX_B; … … 815 877 /* mov gpr, imm64 */ 816 878 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 10); 817 AssertReturn(pbCodeBuf, UINT32_MAX);818 879 if (iGpr < 8) 819 880 pbCodeBuf[off++] = X86_OP_REX_W; … … 833 894 #elif RT_ARCH_ARM64 834 895 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 835 AssertReturn(pu32CodeBuf, UINT32_MAX);836 896 837 897 /* … … 891 951 * only the ARM64 version does that. 892 952 */ 893 DECLINLINE(uint32_t) iemNativeEmitLoadGpr8Imm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint8_t uImm8) 953 DECL_INLINE_THROW(uint32_t) 954 iemNativeEmitLoadGpr8Imm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint8_t uImm8) 894 955 { 895 956 #ifdef RT_ARCH_AMD64 896 957 /* mov gpr, imm8 */ 897 958 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 898 AssertReturn(pbCodeBuf, UINT32_MAX);899 959 if (iGpr >= 8) 900 960 pbCodeBuf[off++] = X86_OP_REX_B; … … 907 967 /* movz gpr, imm16, lsl #0 */ 908 968 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 909 AssertReturn(pu32CodeBuf, UINT32_MAX);910 969 pu32CodeBuf[off++] = UINT32_C(0xd2800000) | (UINT32_C(0) << 21) | ((uint32_t)uImm8 << 5) | iGpr; 911 970 … … 922 981 * Common bit of iemNativeEmitLoadGprFromVCpuU64 and friends. 923 982 */ 924 DECL_FORCE_INLINE(uint32_t) iemNativeEmitGprByVCpuDisp(uint8_t *pbCodeBuf, uint32_t off, uint8_t iGprReg, uint32_t offVCpu) 983 DECL_FORCE_INLINE(uint32_t) 984 iemNativeEmitGprByVCpuDisp(uint8_t *pbCodeBuf, uint32_t off, uint8_t iGprReg, uint32_t offVCpu) 925 985 { 926 986 if (offVCpu < 128) … … 943 1003 * Common bit of iemNativeEmitLoadGprFromVCpuU64 and friends. 944 1004 */ 945 DECL_FORCE_INLINE(uint32_t) iemNativeEmitGprByVCpuLdSt(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprReg, 946 uint32_t offVCpu, ARMV8A64INSTRLDSTTYPE enmOperation, unsigned cbData) 1005 DECL_FORCE_INLINE_THROW(uint32_t) 1006 iemNativeEmitGprByVCpuLdSt(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprReg, 1007 uint32_t offVCpu, ARMV8A64INSTRLDSTTYPE enmOperation, unsigned cbData) 947 1008 { 948 1009 /* … … 955 1016 /* Use the unsigned variant of ldr Wt, [<Xn|SP>, #off]. */ 956 1017 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 957 AssertReturn(pu32CodeBuf, UINT32_MAX);958 1018 pu32CodeBuf[off++] = Armv8A64MkInstrStLdRUOff(enmOperation, iGpr, IEMNATIVE_REG_FIXED_PVMCPU, offVCpu / cbData); 959 1019 } … … 961 1021 { 962 1022 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 963 AssertReturn(pu32CodeBuf, UINT32_MAX);964 1023 pu32CodeBuf[off++] = Armv8A64MkInstrStLdRUOff(enmOperation, iGpr, IEMNATIVE_REG_FIXED_PCPUMCTX, 965 1024 (offVCpu - RT_UOFFSETOF(VMCPU, cpum.GstCtx)) / cbData); … … 973 1032 974 1033 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 975 AssertReturn(pu32CodeBuf, UINT32_MAX);976 1034 pu32CodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(enmOperation, iGpr, IEMNATIVE_REG_FIXED_PVMCPU, IEMNATIVE_REG_FIXED_TMP); 977 1035 } … … 985 1043 * Emits a 64-bit GPR load of a VCpu value. 986 1044 */ 987 DECLINLINE(uint32_t) iemNativeEmitLoadGprFromVCpuU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1045 DECL_INLINE_THROW(uint32_t) 1046 iemNativeEmitLoadGprFromVCpuU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 988 1047 { 989 1048 #ifdef RT_ARCH_AMD64 990 1049 /* mov reg64, mem64 */ 991 1050 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 992 AssertReturn(pbCodeBuf, UINT32_MAX);993 1051 if (iGpr < 8) 994 1052 pbCodeBuf[off++] = X86_OP_REX_W; … … 1013 1071 * @note Bits 32 thru 63 in the GPR will be zero after the operation. 1014 1072 */ 1015 DECLINLINE(uint32_t) iemNativeEmitLoadGprFromVCpuU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1073 DECL_INLINE_THROW(uint32_t) 1074 iemNativeEmitLoadGprFromVCpuU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1016 1075 { 1017 1076 #ifdef RT_ARCH_AMD64 1018 1077 /* mov reg32, mem32 */ 1019 1078 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1020 AssertReturn(pbCodeBuf, UINT32_MAX);1021 1079 if (iGpr >= 8) 1022 1080 pbCodeBuf[off++] = X86_OP_REX_R; … … 1039 1097 * @note Bits 16 thru 63 in the GPR will be zero after the operation. 1040 1098 */ 1041 DECLINLINE(uint32_t) iemNativeEmitLoadGprFromVCpuU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1099 DECL_INLINE_THROW(uint32_t) 1100 iemNativeEmitLoadGprFromVCpuU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1042 1101 { 1043 1102 #ifdef RT_ARCH_AMD64 1044 1103 /* movzx reg32, mem16 */ 1045 1104 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 1046 AssertReturn(pbCodeBuf, UINT32_MAX);1047 1105 if (iGpr >= 8) 1048 1106 pbCodeBuf[off++] = X86_OP_REX_R; … … 1066 1124 * @note Bits 8 thru 63 in the GPR will be zero after the operation. 1067 1125 */ 1068 DECLINLINE(uint32_t) iemNativeEmitLoadGprFromVCpuU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1126 DECL_INLINE_THROW(uint32_t) 1127 iemNativeEmitLoadGprFromVCpuU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1069 1128 { 1070 1129 #ifdef RT_ARCH_AMD64 1071 1130 /* movzx reg32, mem8 */ 1072 1131 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 1073 AssertReturn(pbCodeBuf, UINT32_MAX);1074 1132 if (iGpr >= 8) 1075 1133 pbCodeBuf[off++] = X86_OP_REX_R; … … 1092 1150 * Emits a store of a GPR value to a 64-bit VCpu field. 1093 1151 */ 1094 DECLINLINE(uint32_t) iemNativeEmitStoreGprToVCpuU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1152 DECL_INLINE_THROW(uint32_t) 1153 iemNativeEmitStoreGprToVCpuU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1095 1154 { 1096 1155 #ifdef RT_ARCH_AMD64 1097 1156 /* mov mem64, reg64 */ 1098 1157 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1099 AssertReturn(pbCodeBuf, UINT32_MAX);1100 1158 if (iGpr < 8) 1101 1159 pbCodeBuf[off++] = X86_OP_REX_W; … … 1119 1177 * Emits a store of a GPR value to a 32-bit VCpu field. 1120 1178 */ 1121 DECLINLINE(uint32_t) iemNativeEmitStoreGprFromVCpuU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1179 DECL_INLINE_THROW(uint32_t) 1180 iemNativeEmitStoreGprFromVCpuU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1122 1181 { 1123 1182 #ifdef RT_ARCH_AMD64 1124 1183 /* mov mem32, reg32 */ 1125 1184 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1126 AssertReturn(pbCodeBuf, UINT32_MAX);1127 1185 if (iGpr >= 8) 1128 1186 pbCodeBuf[off++] = X86_OP_REX_R; … … 1144 1202 * Emits a store of a GPR value to a 16-bit VCpu field. 1145 1203 */ 1146 DECLINLINE(uint32_t) iemNativeEmitStoreGprFromVCpuU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1204 DECL_INLINE_THROW(uint32_t) 1205 iemNativeEmitStoreGprFromVCpuU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1147 1206 { 1148 1207 #ifdef RT_ARCH_AMD64 1149 1208 /* mov mem16, reg16 */ 1150 1209 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 1151 AssertReturn(pbCodeBuf, UINT32_MAX);1152 1210 pbCodeBuf[off++] = X86_OP_PRF_SIZE_OP; 1153 1211 if (iGpr >= 8) … … 1170 1228 * Emits a store of a GPR value to a 8-bit VCpu field. 1171 1229 */ 1172 DECLINLINE(uint32_t) iemNativeEmitStoreGprFromVCpuU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1230 DECL_INLINE_THROW(uint32_t) 1231 iemNativeEmitStoreGprFromVCpuU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 1173 1232 { 1174 1233 #ifdef RT_ARCH_AMD64 1175 1234 /* mov mem8, reg8 */ 1176 1235 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1177 AssertReturn(pbCodeBuf, UINT32_MAX);1178 1236 if (iGpr >= 8) 1179 1237 pbCodeBuf[off++] = X86_OP_REX_R; … … 1195 1253 * Emits a gprdst = gprsrc load. 1196 1254 */ 1197 DECLINLINE(uint32_t) iemNativeEmitLoadGprFromGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1255 DECL_INLINE_THROW(uint32_t) 1256 iemNativeEmitLoadGprFromGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1198 1257 { 1199 1258 #ifdef RT_ARCH_AMD64 1200 1259 /* mov gprdst, gprsrc */ 1201 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1202 AssertReturn(pbCodeBuf, UINT32_MAX); 1260 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1203 1261 if ((iGprDst | iGprSrc) >= 8) 1204 1262 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W | X86_OP_REX_B … … 1211 1269 1212 1270 #elif RT_ARCH_ARM64 1271 /* mov dst, src; alias for: orr dst, xzr, src */ 1213 1272 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1214 AssertReturn(pu32CodeBuf, UINT32_MAX);1215 /* mov dst, src; alias for: orr dst, xzr, src */1216 1273 pu32CodeBuf[off++] = UINT32_C(0xaa000000) | ((uint32_t)iGprSrc << 16) | ((uint32_t)ARMV8_A64_REG_XZR << 5) | iGprDst; 1217 1274 … … 1253 1310 * Emits a 64-bit GRP load instruction with an BP relative source address. 1254 1311 */ 1255 DECLINLINE(uint32_t) iemNativeEmitLoadGprByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t offDisp) 1312 DECL_INLINE_THROW(uint32_t) 1313 iemNativeEmitLoadGprByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t offDisp) 1256 1314 { 1257 1315 /* mov gprdst, qword [rbp + offDisp] */ 1258 1316 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1259 AssertReturn(pbCodeBuf, UINT32_MAX);1260 1317 if (iGprDst < 8) 1261 1318 pbCodeBuf[off++] = X86_OP_REX_W; … … 1272 1329 * Emits a 32-bit GRP load instruction with an BP relative source address. 1273 1330 */ 1274 DECLINLINE(uint32_t) iemNativeEmitLoadGprByBpU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t offDisp) 1331 DECL_INLINE_THROW(uint32_t) 1332 iemNativeEmitLoadGprByBpU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t offDisp) 1275 1333 { 1276 1334 /* mov gprdst, dword [rbp + offDisp] */ 1277 1335 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1278 AssertReturn(pbCodeBuf, UINT32_MAX);1279 1336 if (iGprDst >= 8) 1280 1337 pbCodeBuf[off++] = X86_OP_REX_R; … … 1289 1346 * Emits a load effective address to a GRP with an BP relative source address. 1290 1347 */ 1291 DECLINLINE(uint32_t) iemNativeEmitLeaGprByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t offDisp) 1348 DECL_INLINE_THROW(uint32_t) 1349 iemNativeEmitLeaGprByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t offDisp) 1292 1350 { 1293 1351 /* lea gprdst, [rbp + offDisp] */ 1294 1352 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1295 AssertReturn(pbCodeBuf, UINT32_MAX);1296 1353 if (iGprDst < 8) 1297 1354 pbCodeBuf[off++] = X86_OP_REX_W; … … 1309 1366 * @note May trash IEMNATIVE_REG_FIXED_TMP0. 1310 1367 */ 1311 DECLINLINE(uint32_t) iemNativeEmitStoreGprByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offDisp, uint8_t iGprSrc) 1368 DECL_INLINE_THROW(uint32_t) 1369 iemNativeEmitStoreGprByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offDisp, uint8_t iGprSrc) 1312 1370 { 1313 1371 #ifdef RT_ARCH_AMD64 1314 1372 /* mov qword [rbp + offDisp], gprdst */ 1315 1373 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1316 AssertReturn(pbCodeBuf, UINT32_MAX);1317 1374 if (iGprSrc < 8) 1318 1375 pbCodeBuf[off++] = X86_OP_REX_W; … … 1327 1384 /* str w/ unsigned imm12 (scaled) */ 1328 1385 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1329 AssertReturn(pu32CodeBuf, UINT32_MAX);1330 1386 pu32CodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_St_Dword, iGprSrc, 1331 1387 ARMV8_A64_REG_BP, (uint32_t)offDisp / 8); … … 1335 1391 /* stur w/ signed imm9 (unscaled) */ 1336 1392 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1337 AssertReturn(pu32CodeBuf, UINT32_MAX);1338 1393 pu32CodeBuf[off++] = Armv8A64MkInstrSturLdur(kArmv8A64InstrLdStType_St_Dword, iGprSrc, ARMV8_A64_REG_BP, offDisp); 1339 1394 } … … 1343 1398 off = iemNativeEmitLoadGprImm64(pReNative, off, IEMNATIVE_REG_FIXED_TMP0, (uint32_t)offDisp); 1344 1399 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1345 AssertReturn(pu32CodeBuf, UINT32_MAX);1346 1400 pu32CodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(kArmv8A64InstrLdStType_St_Dword, iGprSrc, ARMV8_A64_REG_BP, 1347 1401 IEMNATIVE_REG_FIXED_TMP0, kArmv8A64InstrLdStExtend_Sxtw); … … 1361 1415 * @note May trash IEMNATIVE_REG_FIXED_TMP0. 1362 1416 */ 1363 DECLINLINE(uint32_t) iemNativeEmitStoreImm64ByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offDisp, uint64_t uImm64) 1417 DECL_INLINE_THROW(uint32_t) 1418 iemNativeEmitStoreImm64ByBp(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offDisp, uint64_t uImm64) 1364 1419 { 1365 1420 #ifdef RT_ARCH_AMD64 … … 1367 1422 { 1368 1423 /* mov qword [rbp + offDisp], imm32 - sign extended */ 1369 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 11); 1370 AssertReturn(pbCodeBuf, UINT32_MAX); 1371 1424 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 11); 1372 1425 pbCodeBuf[off++] = X86_OP_REX_W; 1373 1426 pbCodeBuf[off++] = 0xc7; … … 1404 1457 * Common bit of iemNativeEmitLoadGprByGpr and friends. 1405 1458 */ 1406 DECL_FORCE_INLINE(uint32_t) iemNativeEmitGprByGprDisp(uint8_t *pbCodeBuf, uint32_t off,1407 1459 DECL_FORCE_INLINE(uint32_t) 1460 iemNativeEmitGprByGprDisp(uint8_t *pbCodeBuf, uint32_t off, uint8_t iGprReg, uint8_t iGprBase, int32_t offDisp) 1408 1461 { 1409 1462 if (offDisp == 0 && (iGprBase & 7) != X86_GREG_xBP) /* Can use encoding w/o displacement field. */ … … 1436 1489 * Common bit of iemNativeEmitLoadGprFromVCpuU64 and friends. 1437 1490 */ 1438 DECL_FORCE_INLINE (uint32_t) iemNativeEmitGprByGprLdSt(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprReg,1439 uint8_t iGprBase, int32_t offDisp,1440 1491 DECL_FORCE_INLINE_THROW(uint32_t) 1492 iemNativeEmitGprByGprLdSt(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprReg, 1493 uint8_t iGprBase, int32_t offDisp, ARMV8A64INSTRLDSTTYPE enmOperation, unsigned cbData) 1441 1494 { 1442 1495 /* … … 1449 1502 /* Use the unsigned variant of ldr Wt, [<Xn|SP>, #off]. */ 1450 1503 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1451 AssertReturn(pu32CodeBuf, UINT32_MAX);1452 1504 pu32CodeBuf[off++] = Armv8A64MkInstrStLdRUOff(enmOperation, iGprReg, iGprBase, (uint32_t)offDisp / cbData); 1453 1505 } … … 1458 1510 /** @todo reduce by offVCpu by >> 3 or >> 2? if it saves instructions? */ 1459 1511 uint8_t const idxTmpReg = iemNativeRegAllocTmpImm(pReNative, off, (uint64)offDisp); 1460 AssertReturn(idxTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);1461 1512 1462 1513 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1463 AssertReturn(pu32CodeBuf, UINT32_MAX);1464 1514 pu32CodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(enmOperation, iGprReg, iGprBase, idxTmpReg); 1465 1515 … … 1475 1525 * Emits a 64-bit GPR load via a GPR base address with a displacement. 1476 1526 */ 1477 DECL INLINE(uint32_t) iemNativeEmitLoadGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off,1478 1527 DECL_INLINE_THROW(uint32_t) 1528 iemNativeEmitLoadGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprBase, int32_t offDisp) 1479 1529 { 1480 1530 #ifdef RT_ARCH_AMD64 1481 1531 /* mov reg64, mem64 */ 1482 1532 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 1483 AssertReturn(pbCodeBuf, UINT32_MAX);1484 1533 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprBase < 8 ? 0 : X86_OP_REX_B); 1485 1534 pbCodeBuf[off++] = 0x8b; … … 1501 1550 * @note Bits 63 thru 32 in @a iGprDst will be cleared. 1502 1551 */ 1503 DECL INLINE(uint32_t) iemNativeEmitLoadGpr32ByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off,1504 1552 DECL_INLINE_THROW(uint32_t) 1553 iemNativeEmitLoadGpr32ByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprBase, int32_t offDisp) 1505 1554 { 1506 1555 #ifdef RT_ARCH_AMD64 1507 1556 /* mov reg32, mem32 */ 1508 1557 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 1509 AssertReturn(pbCodeBuf, UINT32_MAX);1510 1558 if (iGprDst >= 8 || iGprBase >= 8) 1511 1559 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprBase < 8 ? 0 : X86_OP_REX_B); … … 1533 1581 * Emits a 64-bit GPR subtract with a signed immediate subtrahend. 1534 1582 */ 1535 DECLINLINE(uint32_t) iemNativeEmitSubGprImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t iSubtrahend) 1583 DECL_INLINE_THROW(uint32_t) 1584 iemNativeEmitSubGprImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t iSubtrahend) 1536 1585 { 1537 1586 /* sub gprdst, imm8/imm32 */ 1538 1587 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1539 AssertReturn(pbCodeBuf, UINT32_MAX);1540 1588 if (iGprDst < 8) 1541 1589 pbCodeBuf[off++] = X86_OP_REX_W; … … 1567 1615 * @note The AMD64 version sets flags. 1568 1616 */ 1569 DECLINLINE(uint32_t ) iemNativeEmitAddTwoGprs(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprAddend) 1617 DECL_INLINE_THROW(uint32_t) 1618 iemNativeEmitAddTwoGprs(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprAddend) 1570 1619 { 1571 1620 #if defined(RT_ARCH_AMD64) 1572 1621 /* add Gv,Ev */ 1573 1622 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1574 AssertReturn(pbCodeBuf, UINT32_MAX);1575 1623 pbCodeBuf[off++] = (iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_R) 1576 1624 | (iGprAddend < 8 ? 0 : X86_OP_REX_B); … … 1580 1628 #elif defined(RT_ARCH_ARM64) 1581 1629 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1582 AssertReturn(pu32CodeBuf, UINT32_MAX);1583 1630 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprDst, iGprAddend); 1584 1631 … … 1594 1641 * Emits a 64-bit GPR additions with a 8-bit signed immediate. 1595 1642 */ 1596 DECLINLINE(uint32_t ) iemNativeEmitAddGprImm8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int8_t iImm8) 1643 DECL_INLINE_THROW(uint32_t) 1644 iemNativeEmitAddGprImm8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int8_t iImm8) 1597 1645 { 1598 1646 #if defined(RT_ARCH_AMD64) 1647 /* add or inc */ 1599 1648 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 1600 AssertReturn(pbCodeBuf, UINT32_MAX);1601 /* add or inc */1602 1649 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_B; 1603 1650 if (iImm8 != 1) … … 1615 1662 #elif defined(RT_ARCH_ARM64) 1616 1663 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1617 AssertReturn(pu32CodeBuf, UINT32_MAX);1618 1664 if (iImm8 >= 0) 1619 1665 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iGprDst, iGprDst, (uint8_t)iImm8); … … 1633 1679 * @note Bits 32 thru 63 in the GPR will be zero after the operation. 1634 1680 */ 1635 DECLINLINE(uint32_t ) iemNativeEmitAddGpr32Imm8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int8_t iImm8) 1681 DECL_INLINE_THROW(uint32_t) 1682 iemNativeEmitAddGpr32Imm8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int8_t iImm8) 1636 1683 { 1637 1684 #if defined(RT_ARCH_AMD64) 1685 /* add or inc */ 1638 1686 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 1639 AssertReturn(pbCodeBuf, UINT32_MAX);1640 /* add or inc */1641 1687 if (iGprDst >= 8) 1642 1688 pbCodeBuf[off++] = X86_OP_REX_B; … … 1655 1701 #elif defined(RT_ARCH_ARM64) 1656 1702 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1657 AssertReturn(pu32CodeBuf, UINT32_MAX);1658 1703 if (iImm8 >= 0) 1659 1704 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iGprDst, iGprDst, (uint8_t)iImm8, false /*f64Bit*/); … … 1672 1717 * Emits a 64-bit GPR additions with a 64-bit signed addend. 1673 1718 */ 1674 DECLINLINE(uint32_t ) iemNativeEmitAddGprImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int64_t iAddend) 1719 DECL_INLINE_THROW(uint32_t) 1720 iemNativeEmitAddGprImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int64_t iAddend) 1675 1721 { 1676 1722 #if defined(RT_ARCH_AMD64) … … 1682 1728 /* add grp, imm32 */ 1683 1729 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1684 AssertReturn(pbCodeBuf, UINT32_MAX);1685 1730 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_B; 1686 1731 pbCodeBuf[off++] = 0x81; … … 1695 1740 /* Best to use a temporary register to deal with this in the simplest way: */ 1696 1741 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, (uint64_t)iAddend); 1697 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);1698 1742 1699 1743 /* add dst, tmpreg */ 1700 1744 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1701 AssertReturn(pbCodeBuf, UINT32_MAX);1702 1745 pbCodeBuf[off++] = (iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_R) 1703 1746 | (iTmpReg < 8 ? 0 : X86_OP_REX_B); … … 1712 1755 { 1713 1756 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1714 AssertReturn(pu32CodeBuf, UINT32_MAX);1715 1757 if (iAddend >= 0) 1716 1758 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iGprDst, iGprDst, (uint32_t)iAddend); … … 1722 1764 /* Use temporary register for the immediate. */ 1723 1765 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, (uint64_t)iAddend); 1724 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);1725 1766 1726 1767 /* add gprdst, gprdst, tmpreg */ 1727 1768 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1728 AssertReturn(pu32CodeBuf, UINT32_MAX);1729 1769 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprDst, iTmpReg); 1730 1770 … … 1744 1784 * @note Bits 32 thru 63 in the GPR will be zero after the operation. 1745 1785 */ 1746 DECLINLINE(uint32_t ) iemNativeEmitAddGpr32Imm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t iAddend) 1786 DECL_INLINE_THROW(uint32_t) 1787 iemNativeEmitAddGpr32Imm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int32_t iAddend) 1747 1788 { 1748 1789 #if defined(RT_ARCH_AMD64) … … 1752 1793 /* add grp, imm32 */ 1753 1794 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1754 AssertReturn(pbCodeBuf, UINT32_MAX);1755 1795 if (iGprDst >= 8) 1756 1796 pbCodeBuf[off++] = X86_OP_REX_B; … … 1766 1806 { 1767 1807 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1768 AssertReturn(pu32CodeBuf, UINT32_MAX);1769 1808 if (iAddend >= 0) 1770 1809 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iGprDst, iGprDst, (uint32_t)iAddend, false /*f64Bit*/); … … 1776 1815 /* Use temporary register for the immediate. */ 1777 1816 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, (uint32_t)iAddend); 1778 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);1779 1817 1780 1818 /* add gprdst, gprdst, tmpreg */ 1781 1819 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1782 AssertReturn(pu32CodeBuf, UINT32_MAX);1783 1820 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprDst, iTmpReg, false /*f64Bit*/); 1784 1821 … … 1802 1839 * Emits code for clearing bits 16 thru 63 in the GPR. 1803 1840 */ 1804 DECLINLINE(uint32_t ) iemNativeEmitClear16UpGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst) 1841 DECL_INLINE_THROW(uint32_t) 1842 iemNativeEmitClear16UpGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst) 1805 1843 { 1806 1844 #if defined(RT_ARCH_AMD64) 1807 1845 /* movzx reg32, reg16 */ 1808 1846 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 1809 AssertReturn(pbCodeBuf, UINT32_MAX);1810 1847 if (iGprDst >= 8) 1811 1848 pbCodeBuf[off++] = X86_OP_REX_B | X86_OP_REX_R; … … 1816 1853 #elif defined(RT_ARCH_ARM64) 1817 1854 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1818 AssertReturn(pu32CodeBuf, UINT32_MAX);1819 1855 # if 1 1820 1856 pu32CodeBuf[off++] = Armv8A64MkInstrUxth(iGprDst, iGprDst); … … 1837 1873 * and ARM64 hosts. 1838 1874 */ 1839 DECL INLINE(uint32_t ) iemNativeEmitAndGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc,1840 1875 DECL_INLINE_THROW(uint32_t) 1876 iemNativeEmitAndGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc, bool fSetFlags = false) 1841 1877 { 1842 1878 #if defined(RT_ARCH_AMD64) 1843 1879 /* and Gv, Ev */ 1844 1880 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1845 AssertReturn(pbCodeBuf, UINT32_MAX);1846 1881 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 1847 1882 pbCodeBuf[off++] = 0x23; … … 1851 1886 #elif defined(RT_ARCH_ARM64) 1852 1887 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1853 AssertReturn(pu32CodeBuf, UINT32_MAX);1854 1888 if (!fSetFlags) 1855 1889 pu32CodeBuf[off++] = Armv8A64MkInstrAnd(iGprDst, iGprDst, iGprSrc); … … 1868 1902 * Emits code for AND'ing two 32-bit GPRs. 1869 1903 */ 1870 DECLINLINE(uint32_t ) iemNativeEmitAndGpr32ByGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1904 DECL_INLINE_THROW(uint32_t) 1905 iemNativeEmitAndGpr32ByGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 1871 1906 { 1872 1907 #if defined(RT_ARCH_AMD64) 1873 1908 /* and Gv, Ev */ 1874 1909 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 1875 AssertReturn(pbCodeBuf, UINT32_MAX);1876 1910 if (iGprDst >= 8 || iGprSrc >= 8) 1877 1911 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); … … 1881 1915 #elif defined(RT_ARCH_ARM64) 1882 1916 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1883 AssertReturn(pu32CodeBuf, UINT32_MAX);1884 1917 pu32CodeBuf[off++] = Armv8A64MkInstrAnd(iGprDst, iGprDst, iGprSrc, false /*f64Bit*/); 1885 1918 … … 1898 1931 * and ARM64 hosts. 1899 1932 */ 1900 DECL INLINE(uint32_t ) iemNativeEmitAndGprByImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint64_t uImm,1901 1933 DECL_INLINE_THROW(uint32_t) 1934 iemNativeEmitAndGprByImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint64_t uImm, bool fSetFlags = false) 1902 1935 { 1903 1936 #if defined(RT_ARCH_AMD64) … … 1906 1939 /* and Ev, imm8 */ 1907 1940 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 1908 AssertReturn(pbCodeBuf, UINT32_MAX);1909 1941 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R); 1910 1942 pbCodeBuf[off++] = 0x83; … … 1916 1948 /* and Ev, imm32 */ 1917 1949 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1918 AssertReturn(pbCodeBuf, UINT32_MAX);1919 1950 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R); 1920 1951 pbCodeBuf[off++] = 0x81; … … 1929 1960 /* Use temporary register for the 64-bit immediate. */ 1930 1961 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 1931 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);1932 1962 off = iemNativeEmitAndGprByGpr(pReNative, off, iGprDst, iTmpReg); 1933 1963 iemNativeRegFreeTmpImm(pReNative, iTmpReg); … … 1941 1971 { 1942 1972 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1943 AssertReturn(pu32CodeBuf, UINT32_MAX);1944 1973 if (!fSetFlags) 1945 1974 pu32CodeBuf[off++] = Armv8A64MkInstrAndImm(iGprDst, iGprDst, uImmNandS, uImmR); … … 1951 1980 /* Use temporary register for the 64-bit immediate. */ 1952 1981 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 1953 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);1954 1982 off = iemNativeEmitAndGprByGpr(pReNative, off, iGprDst, iTmpReg, fSetFlags); 1955 1983 iemNativeRegFreeTmpImm(pReNative, iTmpReg); … … 1967 1995 * Emits code for AND'ing an 32-bit GPRs with a constant. 1968 1996 */ 1969 DECL INLINE(uint32_t ) iemNativeEmitAndGpr32ByImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint32_t uImm,1970 1997 DECL_INLINE_THROW(uint32_t) 1998 iemNativeEmitAndGpr32ByImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint32_t uImm, bool fSetFlags = false) 1971 1999 { 1972 2000 #if defined(RT_ARCH_AMD64) 1973 2001 /* and Ev, imm */ 1974 2002 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1975 AssertReturn(pbCodeBuf, UINT32_MAX);1976 2003 if (iGprDst >= 8) 1977 2004 pbCodeBuf[off++] = X86_OP_REX_R; … … 1999 2026 { 2000 2027 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2001 AssertReturn(pu32CodeBuf, UINT32_MAX);2002 2028 if (!fSetFlags) 2003 2029 pu32CodeBuf[off++] = Armv8A64MkInstrAndImm(iGprDst, iGprDst, uImmNandS, uImmR, false /*f64Bit*/); … … 2009 2035 /* Use temporary register for the 64-bit immediate. */ 2010 2036 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2011 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);2012 2037 if (!fSetFlags) 2013 2038 off = iemNativeEmitAndGpr32ByGpr32(pReNative, off, iGprDst, iTmpReg); … … 2028 2053 * Emits code for XOR'ing two 64-bit GPRs. 2029 2054 */ 2030 DECLINLINE(uint32_t ) iemNativeEmitXorGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 2055 DECL_INLINE_THROW(uint32_t) 2056 iemNativeEmitXorGprByGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 2031 2057 { 2032 2058 #if defined(RT_ARCH_AMD64) 2033 2059 /* and Gv, Ev */ 2034 2060 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 2035 AssertReturn(pbCodeBuf, UINT32_MAX);2036 2061 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 2037 2062 pbCodeBuf[off++] = 0x33; … … 2040 2065 #elif defined(RT_ARCH_ARM64) 2041 2066 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2042 AssertReturn(pu32CodeBuf, UINT32_MAX);2043 2067 pu32CodeBuf[off++] = Armv8A64MkInstrEor(iGprDst, iGprDst, iGprSrc); 2044 2068 … … 2054 2078 * Emits code for XOR'ing two 32-bit GPRs. 2055 2079 */ 2056 DECLINLINE(uint32_t ) iemNativeEmitXorGpr32ByGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 2080 DECL_INLINE_THROW(uint32_t) 2081 iemNativeEmitXorGpr32ByGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 2057 2082 { 2058 2083 #if defined(RT_ARCH_AMD64) 2059 2084 /* and Gv, Ev */ 2060 2085 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 2061 AssertReturn(pbCodeBuf, UINT32_MAX);2062 2086 if (iGprDst >= 8 || iGprSrc >= 8) 2063 2087 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); … … 2067 2091 #elif defined(RT_ARCH_ARM64) 2068 2092 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2069 AssertReturn(pu32CodeBuf, UINT32_MAX);2070 2093 pu32CodeBuf[off++] = Armv8A64MkInstrEor(iGprDst, iGprDst, iGprSrc, false /*f64Bit*/); 2071 2094 … … 2085 2108 * Emits code for shifting a GPR a fixed number of bits to the left. 2086 2109 */ 2087 DECLINLINE(uint32_t ) iemNativeEmitShiftGprLeft(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2110 DECL_INLINE_THROW(uint32_t) 2111 iemNativeEmitShiftGprLeft(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2088 2112 { 2089 2113 Assert(cShift > 0 && cShift < 64); … … 2092 2116 /* shl dst, cShift */ 2093 2117 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 2094 AssertReturn(pbCodeBuf, UINT32_MAX);2095 2118 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_B; 2096 2119 if (cShift != 1) … … 2108 2131 #elif defined(RT_ARCH_ARM64) 2109 2132 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2110 AssertReturn(pu32CodeBuf, UINT32_MAX);2111 2133 pu32CodeBuf[off++] = Armv8A64MkInstrLslImm(iGprDst, iGprDst, cShift); 2112 2134 … … 2122 2144 * Emits code for shifting a 32-bit GPR a fixed number of bits to the left. 2123 2145 */ 2124 DECLINLINE(uint32_t ) iemNativeEmitShiftGpr32Left(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2146 DECL_INLINE_THROW(uint32_t) 2147 iemNativeEmitShiftGpr32Left(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2125 2148 { 2126 2149 Assert(cShift > 0 && cShift < 32); … … 2129 2152 /* shl dst, cShift */ 2130 2153 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 2131 AssertReturn(pbCodeBuf, UINT32_MAX);2132 2154 if (iGprDst >= 8) 2133 2155 pbCodeBuf[off++] = X86_OP_REX_B; … … 2146 2168 #elif defined(RT_ARCH_ARM64) 2147 2169 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2148 AssertReturn(pu32CodeBuf, UINT32_MAX);2149 2170 pu32CodeBuf[off++] = Armv8A64MkInstrLslImm(iGprDst, iGprDst, cShift, false /*64Bit*/); 2150 2171 … … 2160 2181 * Emits code for (unsigned) shifting a GPR a fixed number of bits to the right. 2161 2182 */ 2162 DECLINLINE(uint32_t ) iemNativeEmitShiftGprRight(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2183 DECL_INLINE_THROW(uint32_t) 2184 iemNativeEmitShiftGprRight(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2163 2185 { 2164 2186 Assert(cShift > 0 && cShift < 64); … … 2167 2189 /* shr dst, cShift */ 2168 2190 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 2169 AssertReturn(pbCodeBuf, UINT32_MAX);2170 2191 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_B; 2171 2192 if (cShift != 1) … … 2183 2204 #elif defined(RT_ARCH_ARM64) 2184 2205 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2185 AssertReturn(pu32CodeBuf, UINT32_MAX);2186 2206 pu32CodeBuf[off++] = Armv8A64MkInstrLsrImm(iGprDst, iGprDst, cShift); 2187 2207 … … 2198 2218 * right. 2199 2219 */ 2200 DECLINLINE(uint32_t ) iemNativeEmitShiftGpr32Right(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2220 DECL_INLINE_THROW(uint32_t) 2221 iemNativeEmitShiftGpr32Right(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t cShift) 2201 2222 { 2202 2223 Assert(cShift > 0 && cShift < 32); … … 2205 2226 /* shr dst, cShift */ 2206 2227 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 2207 AssertReturn(pbCodeBuf, UINT32_MAX);2208 2228 if (iGprDst >= 8) 2209 2229 pbCodeBuf[off++] = X86_OP_REX_B; … … 2222 2242 #elif defined(RT_ARCH_ARM64) 2223 2243 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2224 AssertReturn(pu32CodeBuf, UINT32_MAX);2225 2244 pu32CodeBuf[off++] = Armv8A64MkInstrLsrImm(iGprDst, iGprDst, cShift, false /*64Bit*/); 2226 2245 … … 2243 2262 * Emits an ARM64 compare instruction. 2244 2263 */ 2245 DECL INLINE(uint32_t) iemNativeEmitCmpArm64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint8_t iGprRight,2246 bool f64Bit = true, uint32_t cShift = 0,2247 2264 DECL_INLINE_THROW(uint32_t) 2265 iemNativeEmitCmpArm64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint8_t iGprRight, 2266 bool f64Bit = true, uint32_t cShift = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_Lsr) 2248 2267 { 2249 2268 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2250 AssertReturn(pu32CodeBuf, UINT32_MAX);2251 2269 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(true /*fSub*/, ARMV8_A64_REG_XZR /*iRegResult*/, iGprLeft, iGprRight, 2252 2270 f64Bit, true /*fSetFlags*/, cShift, enmShift); … … 2261 2279 * with conditional instruction. 2262 2280 */ 2263 DECLINLINE(uint32_t) iemNativeEmitCmpGprWithGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint8_t iGprRight) 2281 DECL_INLINE_THROW(uint32_t) 2282 iemNativeEmitCmpGprWithGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint8_t iGprRight) 2264 2283 { 2265 2284 #ifdef RT_ARCH_AMD64 2266 2285 /* cmp Gv, Ev */ 2267 2286 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 2268 AssertReturn(pbCodeBuf, UINT32_MAX);2269 2287 pbCodeBuf[off++] = X86_OP_REX_W | (iGprLeft >= 8 ? X86_OP_REX_R : 0) | (iGprRight >= 8 ? X86_OP_REX_B : 0); 2270 2288 pbCodeBuf[off++] = 0x3b; … … 2286 2304 * with conditional instruction. 2287 2305 */ 2288 DECL INLINE(uint32_t) iemNativeEmitCmpGpr32WithGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off,2289 2306 DECL_INLINE_THROW(uint32_t) 2307 iemNativeEmitCmpGpr32WithGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint8_t iGprRight) 2290 2308 { 2291 2309 #ifdef RT_ARCH_AMD64 2292 2310 /* cmp Gv, Ev */ 2293 2311 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 2294 AssertReturn(pbCodeBuf, UINT32_MAX);2295 2312 if (iGprLeft >= 8 || iGprRight >= 8) 2296 2313 pbCodeBuf[off++] = (iGprLeft >= 8 ? X86_OP_REX_R : 0) | (iGprRight >= 8 ? X86_OP_REX_B : 0); … … 2313 2330 * flags/whatever for use with conditional instruction. 2314 2331 */ 2315 DECLINLINE(uint32_t) iemNativeEmitCmpGprWithImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint64_t uImm) 2332 DECL_INLINE_THROW(uint32_t) 2333 iemNativeEmitCmpGprWithImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint64_t uImm) 2316 2334 { 2317 2335 #ifdef RT_ARCH_AMD64 … … 2320 2338 /* cmp Ev, Ib */ 2321 2339 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 2322 AssertReturn(pbCodeBuf, UINT32_MAX);2323 2340 pbCodeBuf[off++] = X86_OP_REX_W | (iGprLeft >= 8 ? X86_OP_REX_B : 0); 2324 2341 pbCodeBuf[off++] = 0x83; … … 2330 2347 /* cmp Ev, imm */ 2331 2348 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 2332 AssertReturn(pbCodeBuf, UINT32_MAX);2333 2349 pbCodeBuf[off++] = X86_OP_REX_W | (iGprLeft >= 8 ? X86_OP_REX_B : 0); 2334 2350 pbCodeBuf[off++] = 0x81; … … 2343 2359 { 2344 2360 /* Use temporary register for the immediate. */ 2345 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2346 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 2347 2361 uint8_t const iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2348 2362 off = iemNativeEmitCmpGprWithGpr(pReNative, off, iGprLeft, iTmpReg); 2349 2350 2363 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 2351 2364 } … … 2356 2369 { 2357 2370 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2358 AssertReturn(pu32CodeBuf, UINT32_MAX);2359 2371 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2360 2372 true /*64Bit*/, true /*fSetFlags*/); … … 2363 2375 { 2364 2376 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2365 AssertReturn(pu32CodeBuf, UINT32_MAX);2366 2377 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2367 2378 true /*64Bit*/, true /*fSetFlags*/, true /*fShift12*/); … … 2371 2382 /* Use temporary register for the immediate. */ 2372 2383 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2373 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);2374 2375 2384 off = iemNativeEmitCmpGprWithGpr(pReNative, off, iGprLeft, iTmpReg); 2376 2377 2385 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 2378 2386 } … … 2391 2399 * flags/whatever for use with conditional instruction. 2392 2400 */ 2393 DECLINLINE(uint32_t) iemNativeEmitCmpGpr32WithImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint32_t uImm) 2401 DECL_INLINE_THROW(uint32_t) 2402 iemNativeEmitCmpGpr32WithImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint32_t uImm) 2394 2403 { 2395 2404 #ifdef RT_ARCH_AMD64 2396 2405 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 2397 AssertReturn(pbCodeBuf, UINT32_MAX);2398 2406 if (iGprLeft >= 8) 2399 2407 pbCodeBuf[off++] = X86_OP_REX_B; … … 2422 2430 { 2423 2431 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2424 AssertReturn(pu32CodeBuf, UINT32_MAX);2425 2432 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2426 2433 false /*64Bit*/, true /*fSetFlags*/); … … 2429 2436 { 2430 2437 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2431 AssertReturn(pu32CodeBuf, UINT32_MAX);2432 2438 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2433 2439 false /*64Bit*/, true /*fSetFlags*/, true /*fShift12*/); … … 2437 2443 /* Use temporary register for the immediate. */ 2438 2444 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2439 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);2440 2441 2445 off = iemNativeEmitCmpGpr32WithGpr(pReNative, off, iGprLeft, iTmpReg); 2442 2443 2446 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 2444 2447 } … … 2461 2464 * Emits a JMP rel32 / B imm19 to the given label. 2462 2465 */ 2463 DECLINLINE(uint32_t) iemNativeEmitJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 2466 DECL_INLINE_THROW(uint32_t) 2467 iemNativeEmitJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 2464 2468 { 2465 2469 Assert(idxLabel < pReNative->cLabels); … … 2467 2471 #ifdef RT_ARCH_AMD64 2468 2472 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6); 2469 AssertReturn(pbCodeBuf, UINT32_MAX);2470 2473 if (pReNative->paLabels[idxLabel].off != UINT32_MAX) 2471 2474 { … … 2489 2492 { 2490 2493 pbCodeBuf[off++] = 0xe9; /* jmp rel32 */ 2491 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_Rel32, -4), UINT32_MAX);2494 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_Rel32, -4); 2492 2495 pbCodeBuf[off++] = 0xfe; 2493 2496 pbCodeBuf[off++] = 0xff; … … 2499 2502 #elif defined(RT_ARCH_ARM64) 2500 2503 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2501 AssertReturn(pu32CodeBuf, UINT32_MAX);2502 2504 if (pReNative->paLabels[idxLabel].off != UINT32_MAX) 2503 2505 pu32CodeBuf[off++] = Armv8A64MkInstrB(pReNative->paLabels[idxReturnLabel].off - off); 2504 2506 else 2505 2507 { 2506 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5), UINT32_MAX);2508 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5); 2507 2509 pu32CodeBuf[off++] = Armv8A64MkInstrB(-1); 2508 2510 } … … 2519 2521 * Emits a JMP rel32 / B imm19 to a new undefined label. 2520 2522 */ 2521 DECL INLINE(uint32_t) iemNativeEmitJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,2522 2523 DECL_INLINE_THROW(uint32_t) 2524 iemNativeEmitJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2523 2525 { 2524 2526 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 2525 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX);2526 2527 return iemNativeEmitJmpToLabel(pReNative, off, idxLabel); 2527 2528 } … … 2558 2559 * Emits a Jcc rel32 / B.cc imm19 to the given label (ASSUMED requiring fixup). 2559 2560 */ 2560 DECL INLINE(uint32_t) iemNativeEmitJccToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,2561 2561 DECL_INLINE_THROW(uint32_t) 2562 iemNativeEmitJccToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel, IEMNATIVEINSTRCOND enmCond) 2562 2563 { 2563 2564 Assert(idxLabel < pReNative->cLabels); … … 2566 2567 /* jcc rel32 */ 2567 2568 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6); 2568 AssertReturn(pbCodeBuf, UINT32_MAX);2569 2569 pbCodeBuf[off++] = 0x0f; 2570 2570 pbCodeBuf[off++] = (uint8_t)enmCond | 0x80; 2571 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_Rel32, -4), UINT32_MAX);2571 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_Rel32, -4); 2572 2572 pbCodeBuf[off++] = 0x00; 2573 2573 pbCodeBuf[off++] = 0x00; … … 2577 2577 #elif defined(RT_ARCH_ARM64) 2578 2578 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2579 AssertReturn(pu32CodeBuf, UINT32_MAX); 2580 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5), UINT32_MAX); 2579 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5); 2581 2580 pu32CodeBuf[off++] = Armv8A64MkInstrBCond(enmCond, -1); 2582 2581 … … 2592 2591 * Emits a Jcc rel32 / B.cc imm19 to a new label. 2593 2592 */ 2594 DECLINLINE(uint32_t) iemNativeEmitJccToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2595 IEMNATIVELABELTYPE enmLabelType, uint16_t uData, IEMNATIVEINSTRCOND enmCond) 2593 DECL_INLINE_THROW(uint32_t) 2594 iemNativeEmitJccToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2595 IEMNATIVELABELTYPE enmLabelType, uint16_t uData, IEMNATIVEINSTRCOND enmCond) 2596 2596 { 2597 2597 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 2598 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX);2599 2598 return iemNativeEmitJccToLabel(pReNative, off, idxLabel, enmCond); 2600 2599 } … … 2604 2603 * Emits a JZ/JE rel32 / B.EQ imm19 to the given label. 2605 2604 */ 2606 DECL INLINE(uint32_t) iemNativeEmitJzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)2605 DECL_INLINE_THROW(uint32_t) iemNativeEmitJzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 2607 2606 { 2608 2607 #ifdef RT_ARCH_AMD64 … … 2618 2617 * Emits a JZ/JE rel32 / B.EQ imm19 to a new label. 2619 2618 */ 2620 DECL INLINE(uint32_t) iemNativeEmitJzToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,2621 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0)2619 DECL_INLINE_THROW(uint32_t) iemNativeEmitJzToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2620 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2622 2621 { 2623 2622 #ifdef RT_ARCH_AMD64 … … 2634 2633 * Emits a JNZ/JNE rel32 / B.NE imm19 to the given label. 2635 2634 */ 2636 DECL INLINE(uint32_t) iemNativeEmitJnzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)2635 DECL_INLINE_THROW(uint32_t) iemNativeEmitJnzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 2637 2636 { 2638 2637 #ifdef RT_ARCH_AMD64 … … 2648 2647 * Emits a JNZ/JNE rel32 / B.NE imm19 to a new label. 2649 2648 */ 2650 DECL INLINE(uint32_t) iemNativeEmitJnzToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,2651 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0)2649 DECL_INLINE_THROW(uint32_t) iemNativeEmitJnzToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2650 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2652 2651 { 2653 2652 #ifdef RT_ARCH_AMD64 … … 2664 2663 * Emits a JBE/JNA rel32 / B.LS imm19 to the given label. 2665 2664 */ 2666 DECL INLINE(uint32_t) iemNativeEmitJbeToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)2665 DECL_INLINE_THROW(uint32_t) iemNativeEmitJbeToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 2667 2666 { 2668 2667 #ifdef RT_ARCH_AMD64 … … 2678 2677 * Emits a JBE/JNA rel32 / B.LS imm19 to a new label. 2679 2678 */ 2680 DECL INLINE(uint32_t) iemNativeEmitJbeToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,2681 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0)2679 DECL_INLINE_THROW(uint32_t) iemNativeEmitJbeToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2680 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2682 2681 { 2683 2682 #ifdef RT_ARCH_AMD64 … … 2694 2693 * Emits a JA/JNBE rel32 / B.HI imm19 to the given label. 2695 2694 */ 2696 DECL INLINE(uint32_t) iemNativeEmitJaToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)2695 DECL_INLINE_THROW(uint32_t) iemNativeEmitJaToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel) 2697 2696 { 2698 2697 #ifdef RT_ARCH_AMD64 … … 2708 2707 * Emits a JA/JNBE rel32 / B.HI imm19 to a new label. 2709 2708 */ 2710 DECL INLINE(uint32_t) iemNativeEmitJaToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,2711 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0)2709 DECL_INLINE_THROW(uint32_t) iemNativeEmitJaToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2710 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2712 2711 { 2713 2712 #ifdef RT_ARCH_AMD64 … … 2725 2724 * How @a offJmp is applied is are target specific. 2726 2725 */ 2727 DECL INLINE(uint32_t) iemNativeEmitJccToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off,2728 2726 DECL_INLINE_THROW(uint32_t) 2727 iemNativeEmitJccToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget, IEMNATIVEINSTRCOND enmCond) 2729 2728 { 2730 2729 #ifdef RT_ARCH_AMD64 2731 2730 /* jcc rel32 */ 2732 2731 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6); 2733 AssertReturn(pbCodeBuf, UINT32_MAX);2734 2732 if (offTarget < 128 && offTarget >= -128) 2735 2733 { … … 2749 2747 #elif defined(RT_ARCH_ARM64) 2750 2748 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2751 AssertReturn(pu32CodeBuf, UINT32_MAX);2752 2749 pu32CodeBuf[off++] = Armv8A64MkInstrBCond(enmCond, offTarget); 2753 2750 … … 2764 2761 * How @a offJmp is applied is are target specific. 2765 2762 */ 2766 DECL INLINE(uint32_t) iemNativeEmitJzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget)2763 DECL_INLINE_THROW(uint32_t) iemNativeEmitJzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 2767 2764 { 2768 2765 #ifdef RT_ARCH_AMD64 … … 2780 2777 * How @a offJmp is applied is are target specific. 2781 2778 */ 2782 DECL INLINE(uint32_t) iemNativeEmitJnzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget)2779 DECL_INLINE_THROW(uint32_t) iemNativeEmitJnzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 2783 2780 { 2784 2781 #ifdef RT_ARCH_AMD64 … … 2796 2793 * How @a offJmp is applied is are target specific. 2797 2794 */ 2798 DECL INLINE(uint32_t) iemNativeEmitJbeToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget)2795 DECL_INLINE_THROW(uint32_t) iemNativeEmitJbeToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 2799 2796 { 2800 2797 #ifdef RT_ARCH_AMD64 … … 2812 2809 * How @a offJmp is applied is are target specific. 2813 2810 */ 2814 DECL INLINE(uint32_t) iemNativeEmitJaToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget)2811 DECL_INLINE_THROW(uint32_t) iemNativeEmitJaToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 2815 2812 { 2816 2813 #ifdef RT_ARCH_AMD64 … … 2861 2858 * Internal helper, don't call directly. 2862 2859 */ 2863 DECL INLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfCc(PIEMRECOMPILERSTATE pReNative, uint32_t off,2864 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel,2865 2860 DECL_INLINE_THROW(uint32_t) 2861 iemNativeEmitTestBitInGprAndJmpToLabelIfCc(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc, 2862 uint8_t iBitNo, uint32_t idxLabel, bool fJmpIfSet) 2866 2863 { 2867 2864 Assert(iBitNo < 64); 2868 2865 #ifdef RT_ARCH_AMD64 2869 2866 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); 2870 AssertReturn(pbCodeBuf, UINT32_MAX);2871 2867 if (iBitNo < 8) 2872 2868 { … … 2896 2892 /* Use the TBNZ instruction here. */ 2897 2893 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2898 AssertReturn(pu32CodeBuf, UINT32_MAX); 2899 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm14At5), UINT32_MAX); 2894 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm14At5); 2900 2895 pu32CodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, 0, iGprSrc, iBitNo); 2901 2896 … … 2914 2909 * @note On ARM64 the range is only +/-8191 instructions. 2915 2910 */ 2916 DECL INLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfSet(PIEMRECOMPILERSTATE pReNative, uint32_t off,2917 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel)2911 DECL_INLINE_THROW(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2912 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel) 2918 2913 { 2919 2914 return iemNativeEmitTestBitInGprAndJmpToLabelIfCc(pReNative, off, iGprSrc, iBitNo, idxLabel, true /*fJmpIfSet*/); … … 2927 2922 * @note On ARM64 the range is only +/-8191 instructions. 2928 2923 */ 2929 DECL INLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(PIEMRECOMPILERSTATE pReNative, uint32_t off,2930 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel)2924 DECL_INLINE_THROW(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2925 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel) 2931 2926 { 2932 2927 return iemNativeEmitTestBitInGprAndJmpToLabelIfCc(pReNative, off, iGprSrc, iBitNo, idxLabel, false /*fJmpIfSet*/); … … 2938 2933 * flags accordingly. 2939 2934 */ 2940 DECLINLINE(uint32_t) iemNativeEmitTestAnyBitsInGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc, uint64_t fBits) 2935 DECL_INLINE_THROW(uint32_t) 2936 iemNativeEmitTestAnyBitsInGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc, uint64_t fBits) 2941 2937 { 2942 2938 Assert(fBits != 0); … … 2946 2942 { 2947 2943 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, fBits); 2948 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);2949 2944 2950 2945 /* test Ev,Gv */ 2951 2946 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); 2952 AssertReturn(pbCodeBuf, UINT32_MAX);2953 2947 pbCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_R) | (iTmpReg < 8 ? 0 : X86_OP_REX_B); 2954 2948 pbCodeBuf[off++] = 0x85; … … 2961 2955 /* test Eb, imm8 or test Ev, imm32 */ 2962 2956 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 2963 AssertReturn(pbCodeBuf, UINT32_MAX);2964 2957 if (fBits <= UINT8_MAX) 2965 2958 { … … 2984 2977 /** @todo implement me. */ 2985 2978 else 2986 AssertFailed Return(UINT32_MAX);2979 AssertFailedStmt(IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_EMIT_CASE_NOT_IMPLEMENTED_1)); 2987 2980 2988 2981 #elif defined(RT_ARCH_ARM64) … … 2994 2987 else 2995 2988 { 2996 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, fBits);2997 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX);2998 2999 2989 /* ands Zr, iGprSrc, iTmpReg */ 2990 uint8_t const iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, fBits); 3000 2991 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 3001 AssertReturn(pu32CodeBuf, UINT32_MAX);3002 2992 pu32CodeBuf[off++] = Armv8A64MkInstrAnds(ARMV8_A64_REG_XZR, iGprSrc, iTmpReg); 3003 3004 2993 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 3005 2994 } … … 3017 3006 * are set in @a iGprSrc. 3018 3007 */ 3019 DECLINLINE(uint32_t) iemNativeEmitTestAnyBitsInGprAndJmpToLabelIfAnySet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3020 uint8_t iGprSrc, uint64_t fBits, uint32_t idxLabel) 3008 DECL_INLINE_THROW(uint32_t) 3009 iemNativeEmitTestAnyBitsInGprAndJmpToLabelIfAnySet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3010 uint8_t iGprSrc, uint64_t fBits, uint32_t idxLabel) 3021 3011 { 3022 3012 Assert(fBits); Assert(!RT_IS_POWER_OF_TWO(fBits)); … … 3033 3023 * are set in @a iGprSrc. 3034 3024 */ 3035 DECLINLINE(uint32_t) iemNativeEmitTestAnyBitsInGprAndJmpToLabelIfNoneSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3036 uint8_t iGprSrc, uint64_t fBits, uint32_t idxLabel) 3025 DECL_INLINE_THROW(uint32_t) 3026 iemNativeEmitTestAnyBitsInGprAndJmpToLabelIfNoneSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3027 uint8_t iGprSrc, uint64_t fBits, uint32_t idxLabel) 3037 3028 { 3038 3029 Assert(fBits); Assert(!RT_IS_POWER_OF_TWO(fBits)); … … 3050 3041 * The operand size is given by @a f64Bit. 3051 3042 */ 3052 DECL INLINE(uint32_t) iemNativeEmitTestIfGprIsZeroAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,3053 uint8_t iGprSrc, bool f64Bit, uint32_t idxLabel)3043 DECL_INLINE_THROW(uint32_t) iemNativeEmitTestIfGprIsZeroAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3044 uint8_t iGprSrc, bool f64Bit, uint32_t idxLabel) 3054 3045 { 3055 3046 Assert(idxLabel < pReNative->cLabels); … … 3058 3049 /* test reg32,reg32 / test reg64,reg64 */ 3059 3050 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 3060 AssertReturn(pbCodeBuf, UINT32_MAX);3061 3051 if (f64Bit) 3062 3052 pbCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_R | X86_OP_REX_B); … … 3072 3062 #elif defined(RT_ARCH_ARM64) 3073 3063 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 3074 AssertReturn(pu32CodeBuf, UINT32_MAX); 3075 AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5), UINT32_MAX); 3064 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5); 3076 3065 pu32CodeBuf[off++] = Armv8A64MkInstrCbzCbnz(false /*fJmpIfNotZero*/, 0, f64Bit); 3077 3066 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); … … 3089 3078 * The operand size is given by @a f64Bit. 3090 3079 */ 3091 DECL INLINE(uint32_t) iemNativeEmitTestIfGprIsZeroAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc,3092 bool f64Bit, IEMNATIVELABELTYPE enmLabelType,3093 3080 DECL_INLINE_THROW(uint32_t) 3081 iemNativeEmitTestIfGprIsZeroAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc, bool f64Bit, 3082 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3094 3083 { 3095 3084 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 3096 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX);3097 3085 return iemNativeEmitTestIfGprIsZeroAndJmpToLabel(pReNative, off, iGprSrc, f64Bit, idxLabel); 3098 3086 } … … 3103 3091 * differs. 3104 3092 */ 3105 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualGprAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3106 uint8_t iGprLeft, uint8_t iGprRight, uint32_t idxLabel) 3093 DECL_INLINE_THROW(uint32_t) 3094 iemNativeEmitTestIfGprNotEqualGprAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3095 uint8_t iGprLeft, uint8_t iGprRight, uint32_t idxLabel) 3107 3096 { 3108 3097 off = iemNativeEmitCmpGprWithGpr(pReNative, off, iGprLeft, iGprRight); … … 3115 3104 * Emits code that jumps to a new label if @a iGprLeft and @a iGprRight differs. 3116 3105 */ 3117 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualGprAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3118 uint8_t iGprLeft, uint8_t iGprRight, 3119 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3106 DECL_INLINE_THROW(uint32_t) 3107 iemNativeEmitTestIfGprNotEqualGprAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3108 uint8_t iGprLeft, uint8_t iGprRight, 3109 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3120 3110 { 3121 3111 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 3122 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX);3123 3112 return iemNativeEmitTestIfGprNotEqualGprAndJmpToLabel(pReNative, off, iGprLeft, iGprRight, idxLabel); 3124 3113 } … … 3128 3117 * Emits code that jumps to the given label if @a iGprSrc differs from @a uImm. 3129 3118 */ 3130 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualImmAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3131 uint8_t iGprSrc, uint64_t uImm, uint32_t idxLabel) 3119 DECL_INLINE_THROW(uint32_t) 3120 iemNativeEmitTestIfGprNotEqualImmAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3121 uint8_t iGprSrc, uint64_t uImm, uint32_t idxLabel) 3132 3122 { 3133 3123 off = iemNativeEmitCmpGprWithImm(pReNative, off, iGprSrc, uImm); … … 3140 3130 * Emits code that jumps to a new label if @a iGprSrc differs from @a uImm. 3141 3131 */ 3142 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualImmAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3143 uint8_t iGprSrc, uint64_t uImm, 3144 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3132 DECL_INLINE_THROW(uint32_t) 3133 iemNativeEmitTestIfGprNotEqualImmAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3134 uint8_t iGprSrc, uint64_t uImm, 3135 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3145 3136 { 3146 3137 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 3147 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX);3148 3138 return iemNativeEmitTestIfGprNotEqualImmAndJmpToLabel(pReNative, off, iGprSrc, uImm, idxLabel); 3149 3139 } … … 3154 3144 * @a uImm. 3155 3145 */ 3156 DECL INLINE(uint32_t) iemNativeEmitTestIfGpr32NotEqualImmAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off,3157 uint8_t iGprSrc, uint32_t uImm, uint32_t idxLabel)3146 DECL_INLINE_THROW(uint32_t) iemNativeEmitTestIfGpr32NotEqualImmAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3147 uint8_t iGprSrc, uint32_t uImm, uint32_t idxLabel) 3158 3148 { 3159 3149 off = iemNativeEmitCmpGpr32WithImm(pReNative, off, iGprSrc, uImm); … … 3167 3157 * @a uImm. 3168 3158 */ 3169 DECLINLINE(uint32_t) iemNativeEmitTestIfGpr32NotEqualImmAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3170 uint8_t iGprSrc, uint32_t uImm, 3171 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3159 DECL_INLINE_THROW(uint32_t) 3160 iemNativeEmitTestIfGpr32NotEqualImmAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3161 uint8_t iGprSrc, uint32_t uImm, 3162 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3172 3163 { 3173 3164 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 3174 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX);3175 3165 return iemNativeEmitTestIfGpr32NotEqualImmAndJmpToLabel(pReNative, off, iGprSrc, uImm, idxLabel); 3176 3166 } … … 3181 3171 * Emits a call to a 64-bit address. 3182 3172 */ 3183 DECL INLINE(uint32_t) iemNativeEmitCallImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uintptr_t uPfn)3173 DECL_INLINE_THROW(uint32_t) iemNativeEmitCallImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uintptr_t uPfn) 3184 3174 { 3185 3175 #ifdef RT_ARCH_AMD64 … … 3188 3178 /* call rax */ 3189 3179 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2); 3190 AssertReturn(pbCodeBuf, UINT32_MAX);3191 3180 pbCodeBuf[off++] = 0xff; 3192 3181 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 2, X86_GREG_xAX); … … 3196 3185 3197 3186 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 3198 AssertReturn(pu32CodeBuf, UINT32_MAX);3199 3187 pu32CodeBuf[off++] = Armv8A64MkInstrBlr(IEMNATIVE_REG_FIXED_TMP0); 3188 3200 3189 #else 3201 3190 # error "port me"
Note:
See TracChangeset
for help on using the changeset viewer.