VirtualBox

Changeset 101505 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Oct 18, 2023 11:02:20 PM (18 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159577
Message:

VMM/IEM: Deal with the two other PC advancing MCs. Some fixes. bugref:10371

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py

    r101484 r101505  
    5151    'IEM_MC_DEFER_TO_CIMPL_3_RET_THREADED':                      (None, True,  True,  ),
    5252
    53     'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16':               (None, True,  False, ),
     53    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16':               (None, True,  True, ),
    5454    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32':               (None, True,  True,  ),
    55     'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64':               (None, True,  False, ),
     55    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64':               (None, True,  True, ),
    5656
    5757    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16_WITH_FLAGS':    (None, True,  False, ),
    58     'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32_WITH_FLAGS':    (None, True,  False,  ),
     58    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32_WITH_FLAGS':    (None, True,  False, ),
    5959    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64_WITH_FLAGS':    (None, True,  False, ),
    6060
     
    7676
    7777    'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16':                (None, True,  False, ),
    78     'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32':                (None, True,  False, ),
     78    'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32':                (None, True,  False,  ),
    7979    'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64':                (None, True,  False, ),
    8080    'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16':               (None, True,  False, ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r101490 r101505  
    173173    Elf64_Shdr          aShdrs[5];
    174174#  else
    175     Elf64_Shdr          aShdrs[6];
    176     Elf64_Phdr          aPhdrs[3];
     175    Elf64_Shdr          aShdrs[7];
     176    Elf64_Phdr          aPhdrs[2];
    177177#  endif
    178178    /** The dwarf ehframe data for the chunk. */
    179179    uint8_t             abEhFrame[512];
    180180    char                szzStrTab[128];
    181     Elf64_Sym           aSymbols[1];
     181    Elf64_Sym           aSymbols[3];
    182182#  ifdef IEMNATIVE_USE_GDB_JIT_ET_DYN
     183    Elf64_Sym           aDynSyms[2];
    183184    Elf64_Dyn           aDyn[6];
    184185#  endif
     
    353354
    354355
    355 static int iemExecMemAllocatorGrow(PIEMEXECMEMALLOCATOR pExecMemAllocator);
     356static int iemExecMemAllocatorGrow(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator);
    356357
    357358
     
    520521    if (pExecMemAllocator->cChunks < pExecMemAllocator->cMaxChunks)
    521522    {
    522         int rc = iemExecMemAllocatorGrow(pExecMemAllocator);
     523        int rc = iemExecMemAllocatorGrow(pVCpu, pExecMemAllocator);
    523524        AssertLogRelRCReturn(rc, NULL);
    524525
     
    641642 */
    642643static int
    643 iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PIEMEXECMEMALLOCATOR pExecMemAllocator, void *pvChunk, uint32_t idxChunk)
    644 {
     644iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator,
     645                                                     void *pvChunk, uint32_t idxChunk)
     646{
     647    RT_NOREF(pVCpu);
     648
    645649    /*
    646650     * The AMD64 unwind opcodes.
     
    821825 */
    822826static int
    823 iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PIEMEXECMEMALLOCATOR pExecMemAllocator, void *pvChunk, uint32_t idxChunk)
     827iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator,
     828                                                     void *pvChunk, uint32_t idxChunk)
    824829{
    825830    PIEMEXECMEMCHUNKEHFRAME const pEhFrame = &pExecMemAllocator->paEhFrames[idxChunk];
     
    951956
    952957    RT_ZERO(*pSymFile);
    953     /* The ELF header: */
     958
     959    /*
     960     * The ELF header:
     961     */
    954962    pSymFile->EHdr.e_ident[0]           = ELFMAG0;
    955963    pSymFile->EHdr.e_ident[1]           = ELFMAG1;
     
    9971005        memcpy(&pSymFile->szzStrTab[offStrTab], a_szStr, sizeof(a_szStr)); \
    9981006        offStrTab += sizeof(a_szStr); \
     1007        Assert(offStrTab < sizeof(pSymFile->szzStrTab)); \
    9991008    } while (0)
     1009#define APPEND_STR_FMT(a_szStr, ...) do { \
     1010        offStrTab += RTStrPrintf(&pSymFile->szzStrTab[offStrTab], sizeof(pSymFile->szzStrTab) - offStrTab, a_szStr, __VA_ARGS__); \
     1011        offStrTab++; \
     1012        Assert(offStrTab < sizeof(pSymFile->szzStrTab)); \
     1013    } while (0)
     1014
     1015    /*
     1016     * Section headers.
     1017     */
    10001018    /* Section header #0: NULL */
    10011019    unsigned i = 0;
     
    10481066    /* Section header: .symbols */
    10491067    pSymFile->aShdrs[i].sh_name         = offStrTab;
    1050 #   if defined(IEMNATIVE_USE_GDB_JIT_ET_DYN)
    1051     APPEND_STR(".dynsym");
    1052     pSymFile->aShdrs[i].sh_type         = SHT_DYNSYM;
    1053 #   else
    10541068    APPEND_STR(".symtab");
    10551069    pSymFile->aShdrs[i].sh_type         = SHT_SYMTAB;
    1056 #   endif
    10571070    pSymFile->aShdrs[i].sh_flags        = SHF_ALLOC;
    10581071    pSymFile->aShdrs[i].sh_offset
     
    10641077    pSymFile->aShdrs[i].sh_entsize      = sizeof(pSymFile->aSymbols[0]);
    10651078    i++;
     1079
     1080#   if defined(IEMNATIVE_USE_GDB_JIT_ET_DYN)
     1081    /* Section header: .symbols */
     1082    pSymFile->aShdrs[i].sh_name         = offStrTab;
     1083    APPEND_STR(".dynsym");
     1084    pSymFile->aShdrs[i].sh_type         = SHT_DYNSYM;
     1085    pSymFile->aShdrs[i].sh_flags        = SHF_ALLOC;
     1086    pSymFile->aShdrs[i].sh_offset
     1087        = pSymFile->aShdrs[i].sh_addr   = RT_UOFFSETOF(GDBJITSYMFILE, aDynSyms);
     1088    pSymFile->aShdrs[i].sh_size         = sizeof(pSymFile->aDynSyms);
     1089    pSymFile->aShdrs[i].sh_link         = iShStrTab;
     1090    pSymFile->aShdrs[i].sh_info         = RT_ELEMENTS(pSymFile->aDynSyms);
     1091    pSymFile->aShdrs[i].sh_addralign    = sizeof(pSymFile->aDynSyms[0].st_value);
     1092    pSymFile->aShdrs[i].sh_entsize      = sizeof(pSymFile->aDynSyms[0]);
     1093    i++;
     1094#   endif
    10661095
    10671096#   if defined(IEMNATIVE_USE_GDB_JIT_ET_DYN)
     
    10821111
    10831112    /* Section header: .text */
     1113    unsigned const iShText = i;
    10841114    pSymFile->aShdrs[i].sh_name         = offStrTab;
    10851115    APPEND_STR(".text");
     
    11061136     * The program headers:
    11071137     */
    1108     /* Headers and whatnot up to .dynamic: */
     1138    /* Everything in a single LOAD segment: */
    11091139    i = 0;
    11101140    pSymFile->aPhdrs[i].p_type          = PT_LOAD;
     
    11141144        = pSymFile->aPhdrs[i].p_paddr   = 0;
    11151145    pSymFile->aPhdrs[i].p_filesz         /* Size of segment in file. */
    1116         = pSymFile->aPhdrs[i].p_memsz   = RT_UOFFSETOF(GDBJITSYMFILE, aDyn);
     1146        = pSymFile->aPhdrs[i].p_memsz   = pExecMemAllocator->cbChunk - offSymFileInChunk;
    11171147    pSymFile->aPhdrs[i].p_align         = HOST_PAGE_SIZE;
    11181148    i++;
    1119     /* .dynamic */
     1149    /* The .dynamic segment. */
    11201150    pSymFile->aPhdrs[i].p_type          = PT_DYNAMIC;
    11211151    pSymFile->aPhdrs[i].p_flags         = PF_R;
     
    11271157    pSymFile->aPhdrs[i].p_align         = sizeof(pSymFile->aDyn[0].d_tag);
    11281158    i++;
    1129     /* The rest of the chunk. */
    1130     pSymFile->aPhdrs[i].p_type          = PT_LOAD;
    1131     pSymFile->aPhdrs[i].p_flags         = PF_X | PF_R;
    1132     pSymFile->aPhdrs[i].p_offset
    1133         = pSymFile->aPhdrs[i].p_vaddr
    1134         = pSymFile->aPhdrs[i].p_paddr   = sizeof(GDBJITSYMFILE);
    1135     pSymFile->aPhdrs[i].p_filesz         /* Size of segment in file. */
    1136         = pSymFile->aPhdrs[i].p_memsz   = pExecMemAllocator->cbChunk - offSymFileInChunk - sizeof(GDBJITSYMFILE);
    1137     pSymFile->aPhdrs[i].p_align         = 1;
    1138     i++;
    11391159
    11401160    Assert(i == RT_ELEMENTS(pSymFile->aPhdrs));
    11411161
    1142     /* The dynamic section: */
     1162    /*
     1163     * The dynamic section:
     1164     */
    11431165    i = 0;
    11441166    pSymFile->aDyn[i].d_tag             = DT_SONAME;
    11451167    pSymFile->aDyn[i].d_un.d_val        = offStrTab;
    1146     APPEND_STR("iem-native.so");
     1168    APPEND_STR_FMT("iem-exec-chunk-%u-%u", pVCpu->idCpu, idxChunk);
    11471169    i++;
    11481170    pSymFile->aDyn[i].d_tag             = DT_STRTAB;
     
    11531175    i++;
    11541176    pSymFile->aDyn[i].d_tag             = DT_SYMTAB;
    1155     pSymFile->aDyn[i].d_un.d_ptr        = RT_UOFFSETOF(GDBJITSYMFILE, aSymbols);
     1177    pSymFile->aDyn[i].d_un.d_ptr        = RT_UOFFSETOF(GDBJITSYMFILE, aDynSyms);
    11561178    i++;
    11571179    pSymFile->aDyn[i].d_tag             = DT_SYMENT;
    1158     pSymFile->aDyn[i].d_un.d_val        = sizeof(pSymFile->aSymbols[0]);
     1180    pSymFile->aDyn[i].d_un.d_val        = sizeof(pSymFile->aDynSyms[0]);
    11591181    i++;
    11601182    pSymFile->aDyn[i].d_tag             = DT_NULL;
    11611183    i++;
    11621184    Assert(i == RT_ELEMENTS(pSymFile->aDyn));
     1185#   endif /* IEMNATIVE_USE_GDB_JIT_ET_DYN */
     1186
     1187    /*
     1188     * Symbol tables:
     1189     */
     1190    /** @todo gdb doesn't seem to really like this ...   */
     1191    i = 0;
     1192    pSymFile->aSymbols[i].st_name       = 0;
     1193    pSymFile->aSymbols[i].st_shndx      = SHN_UNDEF;
     1194    pSymFile->aSymbols[i].st_value      = 0;
     1195    pSymFile->aSymbols[i].st_size       = 0;
     1196    pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_LOCAL, STT_NOTYPE);
     1197    pSymFile->aSymbols[i].st_other      = 0 /* STV_DEFAULT */;
     1198#   ifdef IEMNATIVE_USE_GDB_JIT_ET_DYN
     1199    pSymFile->aDynSyms[0] = pSymFile->aSymbols[i];
    11631200#   endif
    1164 
    1165     /* Symbol table: */
    1166     i = 0;
    1167     pSymFile->aSymbols[i].st_name       = offStrTab;
    1168     APPEND_STR("iem_exec_chunk");
     1201    i++;
     1202
     1203    pSymFile->aSymbols[i].st_name       = 0;
    11691204    pSymFile->aSymbols[i].st_shndx      = SHN_ABS;
    1170     pSymFile->aSymbols[i].st_value      = (uintptr_t)pvChunk;
    1171     pSymFile->aSymbols[i].st_size       = pExecMemAllocator->cbChunk;
    1172     pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_LOCAL, STT_FUNC);
     1205    pSymFile->aSymbols[i].st_value      = 0;
     1206    pSymFile->aSymbols[i].st_size       = 0;
     1207    pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_LOCAL, STT_FILE);
    11731208    pSymFile->aSymbols[i].st_other      = 0 /* STV_DEFAULT */;
    11741209    i++;
     1210
     1211    pSymFile->aSymbols[i].st_name       = offStrTab;
     1212    APPEND_STR_FMT("iem_exec_chunk_%u_%u", pVCpu->idCpu, idxChunk);
     1213#   if 0
     1214    pSymFile->aSymbols[i].st_shndx      = iShText;
     1215    pSymFile->aSymbols[i].st_value      = 0;
     1216#   else
     1217    pSymFile->aSymbols[i].st_shndx      = SHN_ABS;
     1218    pSymFile->aSymbols[i].st_value      = (uintptr_t)(pSymFile + 1);
     1219#   endif
     1220    pSymFile->aSymbols[i].st_size       = pSymFile->aShdrs[iShText].sh_size;
     1221    pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_GLOBAL, STT_FUNC);
     1222    pSymFile->aSymbols[i].st_other      = 0 /* STV_DEFAULT */;
     1223#   ifdef IEMNATIVE_USE_GDB_JIT_ET_DYN
     1224    pSymFile->aDynSyms[1] = pSymFile->aSymbols[i];
     1225    pSymFile->aDynSyms[1].st_value      = (uintptr_t)(pSymFile + 1);
     1226#   endif
     1227    i++;
     1228
    11751229    Assert(i == RT_ELEMENTS(pSymFile->aSymbols));
    11761230    Assert(offStrTab < sizeof(pSymFile->szzStrTab));
    11771231
    1178     /* The GDB JIT entry: */
     1232    /*
     1233     * The GDB JIT entry and informing GDB.
     1234     */
    11791235    pEhFrame->GdbJitEntry.pbSymFile = (uint8_t *)pSymFile;
    11801236#   if 1
     
    12011257    RTCritSectLeave(&g_IemNativeGdbJitLock);
    12021258
    1203 #  endif /* IEMNATIVE_USE_GDB_JIT */
     1259#  else  /* !IEMNATIVE_USE_GDB_JIT */
     1260    RT_NOREF(pVCpu);
     1261#  endif /* !IEMNATIVE_USE_GDB_JIT */
    12041262
    12051263    return VINF_SUCCESS;
     
    12161274 * regular allocator function when it's out of memory.
    12171275 */
    1218 static int iemExecMemAllocatorGrow(PIEMEXECMEMALLOCATOR pExecMemAllocator)
     1276static int iemExecMemAllocatorGrow(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator)
    12191277{
    12201278    /* Check that we've room for growth. */
     
    13221380             * (This sets pvUnwindInfo.)
    13231381             */
    1324             rc = iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(pExecMemAllocator, pvChunk, idxChunk);
     1382            rc = iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(pVCpu, pExecMemAllocator, pvChunk, idxChunk);
    13251383            if (RT_SUCCESS(rc))
    13261384#endif
     
    13441402#endif
    13451403    RTMemPageFree(pvChunk, pExecMemAllocator->cbChunk);
     1404    RT_NOREF(pVCpu);
    13461405    return rc;
    13471406}
     
    14591518    while (cbInitial < (uint64_t)pExecMemAllocator->cChunks * pExecMemAllocator->cbChunk)
    14601519    {
    1461         int rc = iemExecMemAllocatorGrow(pExecMemAllocator);
     1520        int rc = iemExecMemAllocatorGrow(pVCpu, pExecMemAllocator);
    14621521        AssertLogRelRCReturn(rc, rc);
    14631522    }
     
    28682927                                      uint64_t uParam0, uint64_t uParam1, uint64_t uParam2)
    28692928{
    2870 #ifdef VBOX_STRICT
    2871     off = iemNativeEmitMarker(pReNative, off);
    2872     AssertReturn(off != UINT32_MAX, UINT32_MAX);
    2873 #endif
     2929    iemNativeRegFlushGuestShadows(pReNative, UINT64_MAX); /** @todo optimize this */
     2930    off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 4, false /*fFreeArgVars*/);
    28742931
    28752932    /*
     
    29433000static int32_t iemNativeEmitThreadedCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry)
    29443001{
    2945 #ifdef VBOX_STRICT
    2946     off = iemNativeEmitMarker(pReNative, off);
    2947     AssertReturn(off != UINT32_MAX, UINT32_MAX);
    2948 #endif
    29493002    iemNativeRegFlushGuestShadows(pReNative, UINT64_MAX); /** @todo optimize this */
    29503003    off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 4, false /*fFreeArgVars*/);
     
    33593412
    33603413
     3414/** Same as iemRegAddToRip64AndFinishingNoFlags. */
     3415DECLINLINE(uint32_t) iemNativeEmitAddToRip64AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr)
     3416{
     3417    /* Allocate a temporary PC register. */
     3418    uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate);
     3419    AssertReturn(idxPcReg != UINT8_MAX, UINT32_MAX);
     3420
     3421    /* Perform the addition and store the result. */
     3422    off = iemNativeEmitAddGprImm8(pReNative, off, idxPcReg, cbInstr);
     3423    off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip));
     3424
     3425    /* Free but don't flush the PC register. */
     3426    iemNativeRegFreeTmp(pReNative, idxPcReg);
     3427
     3428    return off;
     3429}
     3430
    33613431/** Same as iemRegAddToEip32AndFinishingNoFlags. */
    33623432DECLINLINE(uint32_t) iemNativeEmitAddToEip32AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr)
    33633433{
    33643434    /* Allocate a temporary PC register. */
    3365     /** @todo this is not strictly required on AMD64, we could emit alternative
    3366      *        code here if we don't get a tmp register... */
    33673435    uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate);
    33683436    AssertReturn(idxPcReg != UINT8_MAX, UINT32_MAX);
     
    33773445    return off;
    33783446}
     3447
     3448
     3449/** Same as iemRegAddToIp16AndFinishingNoFlags. */
     3450DECLINLINE(uint32_t) iemNativeEmitAddToIp16AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr)
     3451{
     3452    /* Allocate a temporary PC register. */
     3453    uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate);
     3454    AssertReturn(idxPcReg != UINT8_MAX, UINT32_MAX);
     3455
     3456    /* Perform the addition and store the result. */
     3457    off = iemNativeEmitAddGpr32Imm8(pReNative, off, idxPcReg, cbInstr);
     3458    off = iemNativeEmitClear16UpGpr(pReNative, off, idxPcReg);
     3459    off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip));
     3460
     3461    /* Free but don't flush the PC register. */
     3462    iemNativeRegFreeTmp(pReNative, idxPcReg);
     3463
     3464    return off;
     3465}
     3466
    33793467
    33803468/*
     
    34743562    while (cCallsLeft-- > 0)
    34753563    {
     3564#ifdef VBOX_STRICT
     3565        off = iemNativeEmitMarker(pReNative, off, RT_MAKE_U32(pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->enmFunction));
     3566        AssertReturn(off != UINT32_MAX, pTb);
     3567#endif
    34763568        PFNIEMNATIVERECOMPFUNC const pfnRecom = g_apfnIemNativeRecompileFunctions[pCallEntry->enmFunction];
    34773569        if (pfnRecom) /** @todo stats on this.   */
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r101484 r101505  
    15901590
    15911591        if ThrdFnVar.ksVariation_16_Pre386 in dByVari:
     1592            if not fSimple:
     1593                aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 16', None)); # fall thru
    15921594            aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK', ThrdFnVar.ksVariation_16_Pre386));
    15931595        if ThrdFnVar.ksVariation_16f_Pre386 in dByVari:  # should be nested under previous if, but line too long.
     1596            if not fSimple:
     1597                aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 32 | 16', None)); # fall thru
    15941598            aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 32', ThrdFnVar.ksVariation_16f_Pre386));
    15951599
  • trunk/src/VBox/VMM/include/IEMN8veRecompiler.h

    r101488 r101505  
    596596 * in the disassembly.
    597597 */
    598 DECLINLINE(uint32_t) iemNativeEmitMarker(PIEMRECOMPILERSTATE pReNative, uint32_t off)
    599 {
    600 #ifdef RT_ARCH_AMD64
    601     uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
    602     AssertReturn(pbCodeBuf, UINT32_MAX);
    603     /* nop */
    604     pbCodeBuf[off++] = 0x90;
    605 
     598DECLINLINE(uint32_t) iemNativeEmitMarker(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t uInfo)
     599{
     600#ifdef RT_ARCH_AMD64
     601    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7);
     602    AssertReturn(pbCodeBuf, UINT32_MAX);
     603    if (uInfo == 0)
     604    {
     605        /* nop */
     606        pbCodeBuf[off++] = 0x90;
     607    }
     608    else
     609    {
     610        /* nop [disp32] */
     611        pbCodeBuf[off++] = 0x0f;
     612        pbCodeBuf[off++] = 0x1f;
     613        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM0, 0, 5);
     614        pbCodeBuf[off++] = RT_BYTE1(uInfo);
     615        pbCodeBuf[off++] = RT_BYTE2(uInfo);
     616        pbCodeBuf[off++] = RT_BYTE3(uInfo);
     617        pbCodeBuf[off++] = RT_BYTE4(uInfo);
     618    }
    606619#elif RT_ARCH_ARM64
    607620    uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     
    610623    pu32CodeBuf[off++] = 0xd503201f;
    611624
     625    RT_NOREF(uInfo);
    612626#else
    613627# error "port me"
     
    12431257
    12441258/**
     1259 * Emits a 64-bit GPR additions with a 8-bit signed immediate.
     1260 */
     1261DECLINLINE(uint32_t ) iemNativeEmitAddGprImm8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, int8_t iImm8)
     1262{
     1263#if defined(RT_ARCH_AMD64)
     1264    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
     1265    AssertReturn(pbCodeBuf, UINT32_MAX);
     1266    /* add or inc */
     1267    pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_B;
     1268    if (iImm8 != 1)
     1269    {
     1270        pbCodeBuf[off++] = 0x83;
     1271        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
     1272        pbCodeBuf[off++] = (uint8_t)iImm8;
     1273    }
     1274    else
     1275    {
     1276        pbCodeBuf[off++] = 0xff;
     1277        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
     1278    }
     1279
     1280#elif defined(RT_ARCH_ARM64)
     1281    uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1282    AssertReturn(pu32CodeBuf, UINT32_MAX);
     1283    if (iImm8 >= 0)
     1284        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iGprDst, iGprDst, (uint8_t)iImm8);
     1285    else
     1286        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, iGprDst, iGprDst, (uint8_t)-iImm8);
     1287
     1288#else
     1289# error "Port me"
     1290#endif
     1291    return off;
     1292}
     1293
     1294
     1295/**
    12451296 * Emits a 32-bit GPR additions with a 8-bit signed immediate.
    12461297 * @note Bits 32 thru 63 in the GPR will be zero after the operation.
     
    12511302    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
    12521303    AssertReturn(pbCodeBuf, UINT32_MAX);
     1304    /* add or inc */
    12531305    if (iGprDst >= 8)
    12541306        pbCodeBuf[off++] = X86_OP_REX_B;
    1255     pbCodeBuf[off++] = 0x83;
    1256     pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
    1257     pbCodeBuf[off++] = (uint8_t)iImm8;
     1307    if (iImm8 != 1)
     1308    {
     1309        pbCodeBuf[off++] = 0x83;
     1310        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
     1311        pbCodeBuf[off++] = (uint8_t)iImm8;
     1312    }
     1313    else
     1314    {
     1315        pbCodeBuf[off++] = 0xff;
     1316        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7);
     1317    }
    12581318
    12591319#elif defined(RT_ARCH_ARM64)
     
    12711331}
    12721332
     1333
     1334/**
     1335 * Emits code for clearing bits 16 thru 63 in the GPR.
     1336 */
     1337DECLINLINE(uint32_t ) iemNativeEmitClear16UpGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst)
     1338{
     1339#if defined(RT_ARCH_AMD64)
     1340    /* movzx reg32, reg16 */
     1341    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
     1342    AssertReturn(pbCodeBuf, UINT32_MAX);
     1343    if (iGprDst >= 8)
     1344        pbCodeBuf[off++] = X86_OP_REX_B | X86_OP_REX_R;
     1345    pbCodeBuf[off++] = 0x0f;
     1346    pbCodeBuf[off++] = 0xb7;
     1347    pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprDst & 7);
     1348
     1349#elif defined(RT_ARCH_ARM64)
     1350    uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1351    AssertReturn(pu32CodeBuf, UINT32_MAX);
     1352    /* This produces 0xffff; 0x4f: N=1 imms=001111 (immr=0) => size=64 length=15 */
     1353    pu32CodeBuf[off++] = Armv8A64MkInstrAndImm(iGrpDst, iGrpDst, 0x4f);
     1354#else
     1355# error "Port me"
     1356#endif
     1357    return off;
     1358}
     1359
    12731360/** @} */
    12741361
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette