Changeset 101247 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Sep 22, 2023 11:48:24 PM (18 months ago)
- svn:sync-xref-src-repo-rev:
- 159230
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r101203 r101247 59 59 #include <iprt/mem.h> 60 60 #include <iprt/string.h> 61 #if defined(RT_ARCH_AMD64) 62 # include <iprt/x86.h> 63 #elif defined(RT_ARCH_ARM64) 64 # include <iprt/armv8.h> 65 #endif 61 66 62 67 #ifdef RT_OS_WINDOWS … … 97 102 # error The setjmp approach must be enabled for the recompiler. 98 103 #endif 99 100 101 /*********************************************************************************************************************************102 * Defined Constants And Macros *103 *********************************************************************************************************************************/104 /** @name Stack Frame Layout105 *106 * @{ */107 /** The size of the area for stack variables and spills and stuff. */108 #define IEMNATIVE_FRAME_VAR_SIZE 0x40109 #ifdef RT_ARCH_AMD64110 /** Number of stack arguments slots for calls made from the frame. */111 # define IEMNATIVE_FRAME_STACK_ARG_COUNT 4112 /** An stack alignment adjustment (between non-volatile register pushes and113 * the stack variable area, so the latter better aligned). */114 # define IEMNATIVE_FRAME_ALIGN_SIZE 8115 /** Number of any shadow arguments (spill area) for calls we make. */116 # ifdef RT_OS_WINDOWS117 # define IEMNATIVE_FRAME_SHADOW_ARG_COUNT 4118 # else119 # define IEMNATIVE_FRAME_SHADOW_ARG_COUNT 0120 # endif121 122 /** Frame pointer (RBP) relative offset of the last push. */123 # ifdef RT_OS_WINDOWS124 # define IEMNATIVE_FP_OFF_LAST_PUSH (7 * -8)125 # else126 # define IEMNATIVE_FP_OFF_LAST_PUSH (5 * -8)127 # endif128 /** Frame pointer (RBP) relative offset of the stack variable area (the lowest129 * address for it). */130 # define IEMNATIVE_FP_OFF_STACK_VARS (IEMNATIVE_FP_OFF_LAST_PUSH - IEMNATIVE_FRAME_ALIGN_SIZE - IEMNATIVE_FRAME_VAR_SIZE)131 /** Frame pointer (RBP) relative offset of the first stack argument for calls. */132 # define IEMNATIVE_FP_OFF_STACK_ARG0 (IEMNATIVE_FP_OFF_STACK_VARS - IEMNATIVE_FRAME_STACK_ARG_COUNT * 8)133 /** Frame pointer (RBP) relative offset of the second stack argument for calls. */134 # define IEMNATIVE_FP_OFF_STACK_ARG1 (IEMNATIVE_FP_OFF_STACK_ARG0 + 8)135 /** Frame pointer (RBP) relative offset of the third stack argument for calls. */136 # define IEMNATIVE_FP_OFF_STACK_ARG2 (IEMNATIVE_FP_OFF_STACK_ARG0 + 16)137 /** Frame pointer (RBP) relative offset of the fourth stack argument for calls. */138 # define IEMNATIVE_FP_OFF_STACK_ARG3 (IEMNATIVE_FP_OFF_STACK_ARG0 + 24)139 140 # ifdef RT_OS_WINDOWS141 /** Frame pointer (RBP) relative offset of the first incoming shadow argument. */142 # define IEMNATIVE_FP_OFF_IN_SHADOW_ARG0 (16)143 /** Frame pointer (RBP) relative offset of the second incoming shadow argument. */144 # define IEMNATIVE_FP_OFF_IN_SHADOW_ARG1 (24)145 /** Frame pointer (RBP) relative offset of the third incoming shadow argument. */146 # define IEMNATIVE_FP_OFF_IN_SHADOW_ARG2 (32)147 /** Frame pointer (RBP) relative offset of the fourth incoming shadow argument. */148 # define IEMNATIVE_FP_OFF_IN_SHADOW_ARG3 (40)149 # endif150 151 #elif RT_ARCH_ARM64152 153 #else154 # error "port me"155 #endif156 /** @} */157 104 158 105 … … 475 422 Ptr = iemDwarfPutLeb128(Ptr, 1); /* Code alignment factor (LEB128 = 1). */ 476 423 Ptr = iemDwarfPutLeb128(Ptr, -8); /* Data alignment factor (LEB128 = -8). */ 424 # ifdef RT_ARCH_AMD64 477 425 Ptr = iemDwarfPutUleb128(Ptr, DWREG_AMD64_RA); /* Return address column (ULEB128) */ 426 # elif defined(RT_ARCH_ARM64) 427 Ptr = iemDwarfPutUleb128(Ptr, DWREG_ARM64_PC); /* Return address column (ULEB128) */ 428 # else 429 # error "port me" 430 # endif 478 431 /* Initial instructions: */ 432 # ifdef RT_ARCH_AMD64 479 433 Ptr = iemDwarfPutCfaDefCfa(Ptr, DWREG_AMD64_RBP, 16); /* CFA = RBP + 0x10 - first stack parameter */ 480 434 Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_AMD64_RA, 1); /* Ret RIP = [CFA + 1*-8] */ … … 485 439 Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_AMD64_R14, 6); /* R14 = [CFA + 6*-8] */ 486 440 Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_AMD64_R15, 7); /* R15 = [CFA + 7*-8] */ 441 # elif defined(RT_ARCH_ARM64) 442 Ptr = iemDwarfPutCfaDefCfa(Ptr, DWREG_ARM64_BP, 0); /* CFA = BP + 0x00 - first stack parameter */ 443 Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_ARM64_PC, 1); /* Ret PC = [CFA + 1*-8] */ 444 Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_ARM64_BP, 2); /* Ret BP = [CFA + 2*-8] */ 445 # endif 487 446 while ((Ptr.u - PtrCie.u) & 3) 488 447 *Ptr.pb++ = DW_CFA_nop; … … 1147 1106 # ifdef RT_OS_WINDOWS 1148 1107 # ifndef VBOXSTRICTRC_STRICT_ENABLED 1149 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xCX, X86_GREG_xBX);1108 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xCX, IEMNATIVE_REG_FIXED_PVMCPU); 1150 1109 AssertReturn(off != UINT32_MAX, UINT32_MAX); 1151 1110 if (cParams > 0) … … 1165 1124 } 1166 1125 # else /* VBOXSTRICTRC: Returned via hidden parameter. Sigh. */ 1167 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xDX, X86_GREG_xBX);1126 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xDX, IEMNATIVE_REG_FIXED_PVMCPU); 1168 1127 AssertReturn(off != UINT32_MAX, UINT32_MAX); 1169 1128 if (cParams > 0) … … 1188 1147 # endif /* VBOXSTRICTRC_STRICT_ENABLED */ 1189 1148 # else 1190 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xDI, X86_GREG_xBX);1149 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xDI, IEMNATIVE_REG_FIXED_PVMCPU); 1191 1150 AssertReturn(off != UINT32_MAX, UINT32_MAX); 1192 1151 if (cParams > 0) … … 1224 1183 1225 1184 #elif RT_ARCH_ARM64 1226 RT_NOREF(pReNative, pCallEntry );1185 RT_NOREF(pReNative, pCallEntry, cParams); 1227 1186 off = UINT32_MAX; 1228 1187 … … 1292 1251 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_x8, X86_GREG_xCX); /* cl = instruction number */ 1293 1252 AssertReturn(off != UINT32_MAX, UINT32_MAX); 1294 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xCX, X86_GREG_xBX);1253 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xCX, IEMNATIVE_REG_FIXED_PVMCPU); 1295 1254 AssertReturn(off != UINT32_MAX, UINT32_MAX); 1296 1255 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xDX, X86_GREG_xAX); 1297 1256 AssertReturn(off != UINT32_MAX, UINT32_MAX); 1298 1257 # else 1299 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xDI, X86_GREG_xBX);1258 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xDI, IEMNATIVE_REG_FIXED_PVMCPU); 1300 1259 AssertReturn(off != UINT32_MAX, UINT32_MAX); 1301 1260 off = iemNativeEmitLoadGprFromGpr(pReNative, off, X86_GREG_xSI, X86_GREG_xAX); … … 1343 1302 1344 1303 1304 typedef enum 1305 { 1306 kArm64InstrStLdPairType_kPostIndex = 1, 1307 kArm64InstrStLdPairType_kSigned = 2, 1308 kArm64InstrStLdPairType_kPreIndex = 3 1309 } ARM64INSTRSTLDPAIRTYPE; 1310 1311 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdPair(bool fLoad, uint32_t iOpc, ARM64INSTRSTLDPAIRTYPE enmType, 1312 uint32_t iReg1, uint32_t iReg2, uint32_t iBaseReg, int32_t iImm7 = 0) 1313 { 1314 Assert(iOpc < 3); Assert(iReg1 <= 31); Assert(iReg2 <= 31); Assert(iBaseReg <= 31); Assert(iImm7 < 64 && iImm7 >= -64); 1315 return (iOpc << 30) 1316 | UINT32_C(0x28000000) 1317 | ((uint32_t)enmType << 23) 1318 | ((uint32_t)fLoad << 22) 1319 | ((uint32_t)iImm7 << 15) 1320 | (iReg2 << 10) 1321 | (iBaseReg << 5) 1322 | iReg1; 1323 } 1324 1325 1326 1345 1327 /** 1346 1328 * Emits a standard prolog. … … 1364 1346 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xBP, X86_GREG_xSP); 1365 1347 pbCodeBuf[off++] = 0x50 + X86_GREG_xBX; /* push rbx */ 1348 AssertCompile(IEMNATIVE_REG_FIXED_PVMCPU == X86_GREG_xBX); 1366 1349 # ifdef RT_OS_WINDOWS 1367 1350 pbCodeBuf[off++] = X86_OP_REX_W; /* mov rbx, rcx ; RBX = pVCpu */ … … 1395 1378 1396 1379 #elif RT_ARCH_ARM64 1397 RT_NOREF(pReNative); 1398 off = UINT32_MAX; 1380 /* 1381 * We set up a stack frame exactly like on x86, only we have to push the 1382 * return address our selves here. We save all non-volatile registers. 1383 */ 1384 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 10); 1385 AssertReturn(pu32CodeBuf, UINT32_MAX); 1386 /* stp x19, x20, [sp, #-IEMNATIVE_FRAME_SAVE_REG_SIZE] ; Allocate space for saving registers and place x19+x20 at the bottom. */ 1387 AssertCompile(IEMNATIVE_FRAME_SAVE_REG_SIZE < 64*8); 1388 pu32CodeBuf[off++] = Armv8A64MkInstrStLdPair(false /*fLoad*/, 2 /*64-bit*/, kArm64InstrStLdPairType_kPreIndex, 1389 ARMV8_A64_REG_X19, ARMV8_A64_REG_X20, ARMV8_A64_REG_SP, 1390 -IEMNATIVE_FRAME_SAVE_REG_SIZE / 8); 1391 /* Save x21 thru x28 (SP remains unchanged in the kSigned variant). */ 1392 pu32CodeBuf[off++] = Armv8A64MkInstrStLdPair(false /*fLoad*/, 2 /*64-bit*/, kArm64InstrStLdPairType_kSigned, 1393 ARMV8_A64_REG_X21, ARMV8_A64_REG_X22, ARMV8_A64_REG_SP, 2); 1394 pu32CodeBuf[off++] = Armv8A64MkInstrStLdPair(false /*fLoad*/, 2 /*64-bit*/, kArm64InstrStLdPairType_kSigned, 1395 ARMV8_A64_REG_X23, ARMV8_A64_REG_X24, ARMV8_A64_REG_SP, 4); 1396 pu32CodeBuf[off++] = Armv8A64MkInstrStLdPair(false /*fLoad*/, 2 /*64-bit*/, kArm64InstrStLdPairType_kSigned, 1397 ARMV8_A64_REG_X25, ARMV8_A64_REG_X26, ARMV8_A64_REG_SP, 6); 1398 pu32CodeBuf[off++] = Armv8A64MkInstrStLdPair(false /*fLoad*/, 2 /*64-bit*/, kArm64InstrStLdPairType_kSigned, 1399 ARMV8_A64_REG_X27, ARMV8_A64_REG_X28, ARMV8_A64_REG_SP, 8); 1400 /* Save the BP and LR (ret address) registers at the top of the frame. */ 1401 pu32CodeBuf[off++] = Armv8A64MkInstrStLdPair(false /*fLoad*/, 2 /*64-bit*/, kArm64InstrStLdPairType_kSigned, 1402 ARMV8_A64_REG_BP, ARMV8_A64_REG_LR, ARMV8_A64_REG_SP, 10); 1403 AssertCompile(IEMNATIVE_FRAME_SAVE_REG_SIZE / 8 == 12); 1404 /* sub bp, sp, IEMNATIVE_FRAME_SAVE_REG_SIZE - 16 ; Set BP to point to the old BP stack address. */ 1405 AssertCompile(IEMNATIVE_FRAME_SAVE_REG_SIZE - 16 < 4096); 1406 pu32CodeBuf[off++] = UINT32_C(0xd1000000) | ((IEMNATIVE_FRAME_SAVE_REG_SIZE - 16) << 10) | ARMV8_A64_REG_SP | ARMV8_A64_REG_BP; 1407 1408 /* sub sp, sp, IEMNATIVE_FRAME_VAR_SIZE ; Allocate the variable area from SP. */ 1409 AssertCompile(IEMNATIVE_FRAME_VAR_SIZE < 4096); 1410 pu32CodeBuf[off++] = UINT32_C(0xd1000000) | (IEMNATIVE_FRAME_VAR_SIZE << 10) | ARMV8_A64_REG_SP | ARMV8_A64_REG_SP; 1399 1411 1400 1412 #else
Note:
See TracChangeset
for help on using the changeset viewer.