Changeset 101304 in vbox for trunk/include
- Timestamp:
- Sep 29, 2023 1:02:02 AM (17 months ago)
- svn:sync-xref-src-repo-rev:
- 159300
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/armv8.h
r101260 r101304 2243 2243 * @returns The encoded instruction. 2244 2244 * @param fLoad true for ldp, false of stp. 2245 * @param iOpcWhen @a fSimdFp is @c false:2245 * @param u2Opc When @a fSimdFp is @c false: 2246 2246 * - 0 for 32-bit GPRs (Wt). 2247 2247 * - 1 for encoding stgp or ldpsw. … … 2262 2262 * stgp/ldpsw instructions. 2263 2263 */ 2264 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdPair(bool fLoad, uint32_t iOpc, ARM64INSTRSTLDPAIRTYPE enmType,2264 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdPair(bool fLoad, uint32_t u2Opc, ARM64INSTRSTLDPAIRTYPE enmType, 2265 2265 uint32_t iReg1, uint32_t iReg2, uint32_t iBaseReg, int32_t iImm7 = 0, 2266 2266 bool fSimdFp = false) 2267 2267 { 2268 Assert( iOpc < 3); Assert(iReg1 <= 31); Assert(iReg2 <= 31); Assert(iBaseReg <= 31); Assert(iImm7 < 64 && iImm7 >= -64);2269 return ( iOpc<< 30)2270 | UINT32_C(0x28000000) 2268 Assert(u2Opc < 3); Assert(iReg1 <= 31); Assert(iReg2 <= 31); Assert(iBaseReg <= 31); Assert(iImm7 < 64 && iImm7 >= -64); 2269 return (u2Opc << 30) 2270 | UINT32_C(0x28000000) /* 0b101000000000000000000000000000 */ 2271 2271 | ((uint32_t)fSimdFp << 26) /* VR bit, see "Top-level encodings for A64" */ 2272 2272 | ((uint32_t)enmType << 23) … … 2276 2276 | (iBaseReg << 5) 2277 2277 | iReg1; 2278 } 2279 2280 typedef enum /* Size VR Opc */ 2281 { /* \ | / */ 2282 kArmv8A64InstrLdStType_Mask_Size = 0x300, 2283 kArmv8A64InstrLdStType_Mask_VR = 0x010, 2284 kArmv8A64InstrLdStType_Mask_Opc = 0x003, 2285 kArmv8A64InstrLdStType_Shift_Size = 8, 2286 kArmv8A64InstrLdStType_Shift_VR = 4, 2287 kArmv8A64InstrLdStType_Shift_Opc = 0, 2288 2289 kArmv8A64InstrLdStType_St_Byte = 0x000, 2290 kArmv8A64InstrLdStType_Ld_Byte = 0x001, 2291 kArmv8A64InstrLdStType_Ld_SignByte64 = 0x002, 2292 kArmv8A64InstrLdStType_Ld_SignByte32 = 0x003, 2293 2294 kArmv8A64InstrLdStType_St_Half = 0x100, /**< Half = 16-bit */ 2295 kArmv8A64InstrLdStType_Ld_Half = 0x101, /**< Half = 16-bit */ 2296 kArmv8A64InstrLdStType_Ld_SignHalf64 = 0x102, /**< Half = 16-bit */ 2297 kArmv8A64InstrLdStType_Ld_SignHalf32 = 0x103, /**< Half = 16-bit */ 2298 2299 kArmv8A64InstrLdStType_St_Word = 0x200, /**< Word = 32-bit */ 2300 kArmv8A64InstrLdStType_Ld_Word = 0x201, /**< Word = 32-bit */ 2301 kArmv8A64InstrLdStType_Ld_SignWord64 = 0x202, /**< Word = 32-bit */ 2302 2303 kArmv8A64InstrLdStType_St_Dword = 0x300, /**< Dword = 64-bit */ 2304 kArmv8A64InstrLdStType_Ld_Dword = 0x301, /**< Dword = 64-bit */ 2305 2306 kArmv8A64InstrLdStType_Prefetch = 0x302, /**< Not valid in all variations, check docs. */ 2307 2308 kArmv8A64InstrLdStType_St_Vr_Byte = 0x010, 2309 kArmv8A64InstrLdStType_Ld_Vr_Byte = 0x011, 2310 kArmv8A64InstrLdStType_St_Vr_128 = 0x012, 2311 kArmv8A64InstrLdStType_Ld_Vr_128 = 0x013, 2312 2313 kArmv8A64InstrLdStType_St_Vr_Half = 0x110, /**< Half = 16-bit */ 2314 kArmv8A64InstrLdStType_Ld_Vr_Half = 0x111, /**< Half = 16-bit */ 2315 2316 kArmv8A64InstrLdStType_St_Vr_Word = 0x210, /**< Word = 32-bit */ 2317 kArmv8A64InstrLdStType_Ld_Vr_Word = 0x211, /**< Word = 32-bit */ 2318 2319 kArmv8A64InstrLdStType_St_Vr_Dword = 0x310, /**< Dword = 64-bit */ 2320 kArmv8A64InstrLdStType_Ld_Vr_Dword = 0x311 /**< Dword = 64-bit */ 2321 2322 } ARMV8A64INSTRLDSTTYPE; 2323 2324 /** 2325 * A64: Encodes load/store with unscaled 9-bit signed immediate. 2326 * 2327 * @returns The encoded instruction. 2328 * @param u32Opcode The base opcode value. 2329 * @param enmType The load/store instruction type. Prefech valid (PRFUM) 2330 * @param iReg The register to load into / store. 2331 * @param iBaseReg The base register to use when addressing. SP is allowed. 2332 * @param i9ImmDisp The 9-bit signed addressing displacement. Unscaled. 2333 */ 2334 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdImm9Ex(uint32_t u32Opcode, ARMV8A64INSTRLDSTTYPE enmType, 2335 uint32_t iReg, uint32_t iRegBase, int32_t i9ImmDisp = 0) 2336 { 2337 Assert(i9ImmDisp >= -256 && i9ImmDisp < 256); Assert(iReg < 32); Assert(iRegBase < 32); 2338 return u32Opcode 2339 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_Size) << (30 - kArmv8A64InstrLdStType_Shift_Size)) 2340 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_VR) << (26 - kArmv8A64InstrLdStType_Shift_VR)) 2341 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_Opc) << (22 - kArmv8A64InstrLdStType_Shift_Opc)) 2342 | (((uint32_t)i9ImmDisp & UINT32_C(0x1ff)) << 12) 2343 | (iRegBase << 5) 2344 | iReg; 2345 } 2346 2347 2348 /** 2349 * A64: Encodes load/store with unscaled 9-bit signed immediate. 2350 * 2351 * @returns The encoded instruction. 2352 * @param enmType The load/store instruction type. Prefech valid (PRFUM) 2353 * @param iReg The register to load into / store. 2354 * @param iBaseReg The base register to use when addressing. SP is allowed. 2355 * @param i9ImmDisp The 9-bit signed addressing displacement. Unscaled. 2356 */ 2357 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrSturLdur(ARMV8A64INSTRLDSTTYPE enmType, 2358 uint32_t iReg, uint32_t iRegBase, int32_t i9ImmDisp = 0) 2359 { 2360 /* 3 2 1 0 */ 2361 /* 10987654321098765432109876543210 */ 2362 return Armv8A64MkInstrStLdImm9Ex(UINT32_C(0x38000000) /* 0b00111000000000000000000000000000 */, 2363 enmType, iReg, iRegBase, i9ImmDisp); 2364 } 2365 2366 /** 2367 * A64: Encodes load/store with unscaled 9-bit signed immediate, post-indexed. 2368 * 2369 * @returns The encoded instruction. 2370 * @param enmType The load/store instruction type. Prefech not valid. 2371 * @param iReg The register to load into / store. 2372 * @param iBaseReg The base register to use when addressing. SP is allowed. 2373 * Written back. 2374 * @param i9ImmDisp The 9-bit signed addressing displacement. Unscaled. 2375 */ 2376 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStrLdrPostIndex9(ARMV8A64INSTRLDSTTYPE enmType, 2377 uint32_t iReg, uint32_t iRegBase, int32_t i9ImmDisp = 0) 2378 { 2379 Assert(enmType != kArmv8A64InstrLdStType_Prefetch); /* 3 2 1 0 */ 2380 /* 10987654321098765432109876543210 */ 2381 return Armv8A64MkInstrStLdImm9Ex(UINT32_C(0x38000400) /* 0b00111000000000000000010000000000 */, 2382 enmType, iReg, iRegBase, i9ImmDisp); 2383 } 2384 2385 /** 2386 * A64: Encodes load/store with unscaled 9-bit signed immediate, pre-indexed 2387 * 2388 * @returns The encoded instruction. 2389 * @param enmType The load/store instruction type. Prefech valid (PRFUM) 2390 * @param iReg The register to load into / store. 2391 * @param iBaseReg The base register to use when addressing. SP is allowed. 2392 * Written back. 2393 * @param i9ImmDisp The 9-bit signed addressing displacement. Unscaled. 2394 */ 2395 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStrLdrPreIndex9(ARMV8A64INSTRLDSTTYPE enmType, 2396 uint32_t iReg, uint32_t iRegBase, int32_t i9ImmDisp = 0) 2397 { 2398 Assert(enmType != kArmv8A64InstrLdStType_Prefetch); /* 3 2 1 0 */ 2399 /* 10987654321098765432109876543210 */ 2400 return Armv8A64MkInstrStLdImm9Ex(UINT32_C(0x38000c00) /* 0b00111000000000000000110000000000 */, 2401 enmType, iReg, iRegBase, i9ImmDisp); 2402 } 2403 2404 /** 2405 * A64: Encodes unprivileged load/store with unscaled 9-bit signed immediate. 2406 * 2407 * @returns The encoded instruction. 2408 * @param enmType The load/store instruction type. Prefech not valid, 2409 * nor any SIMD&FP variants. 2410 * @param iReg The register to load into / store. 2411 * @param iBaseReg The base register to use when addressing. SP is allowed. 2412 * @param i9ImmDisp The 9-bit signed addressing displacement. Unscaled. 2413 */ 2414 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrSttrLdtr(ARMV8A64INSTRLDSTTYPE enmType, 2415 uint32_t iReg, uint32_t iRegBase, int32_t i9ImmDisp = 0) 2416 { 2417 Assert(enmType != kArmv8A64InstrLdStType_Prefetch); 2418 Assert(!((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_VR)); 2419 /* 3 2 1 0 */ 2420 /* 10987654321098765432109876543210 */ 2421 return Armv8A64MkInstrStLdImm9Ex(UINT32_C(0x38000800) /* 0b00111000000000000000100000000000 */, 2422 enmType, iReg, iRegBase, i9ImmDisp); 2423 } 2424 2425 2426 /** 2427 * A64: Encodes load/store w/ scaled 12-bit unsigned address displacement. 2428 * 2429 * @returns The encoded instruction. 2430 * @param enmType The load/store instruction type. Prefech not valid, 2431 * nor any SIMD&FP variants. 2432 * @param iReg The register to load into / store. 2433 * @param iBaseReg The base register to use when addressing. SP is allowed. 2434 * @param u12ImmDisp Addressing displacement, scaled by size. 2435 */ 2436 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdRUOff(ARMV8A64INSTRLDSTTYPE enmType, 2437 uint32_t iReg, uint32_t iRegBase, uint32_t u12ImmDisp) 2438 { 2439 Assert(u12ImmDisp < 4096U); 2440 Assert(iReg < 32); /* 3 2 1 0 */ 2441 Assert(iRegBase < 32); /* 10987654321098765432109876543210 */ 2442 return UINT32_C(0x39000000) /* 0b00111001000000000000000000000000 */ 2443 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_Size) << (30 - kArmv8A64InstrLdStType_Shift_Size)) 2444 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_VR) << (26 - kArmv8A64InstrLdStType_Shift_VR)) 2445 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_Opc) << (22 - kArmv8A64InstrLdStType_Shift_Opc)) 2446 | (u12ImmDisp << 10) 2447 | (iRegBase << 5) 2448 | iReg; 2449 } 2450 2451 typedef enum 2452 { 2453 kArmv8A64InstrLdStExtend_Uxtw = 2, /**< Zero-extend (32-bit) word. */ 2454 kArmv8A64InstrLdStExtend_Lsl = 3, /**< Not valid for bytes. */ 2455 kArmv8A64InstrLdStExtend_Sxtw = 6, /**< Sign-extend (32-bit) word. */ 2456 kArmv8A64InstrLdStExtend_Sxtx = 7 /**< Sign-extend (64-bit) dword (to 128-bit SIMD&FP reg, presumably). */ 2457 } ARMV8A64INSTRLDSTEXTEND; 2458 2459 /** 2460 * A64: Encodes load/store w/ scaled 12-bit unsigned address displacement. 2461 * 2462 * @returns The encoded instruction. 2463 * @param enmType The load/store instruction type. 2464 * @param iReg The register to load into / store. 2465 * @param iBaseReg The base register to use when addressing. SP is allowed. 2466 * @param iRegIndex The index register. 2467 * @param enmExtend The extending to apply to @a iRegIndex. 2468 * @param fShifted Whether to shift the index. The shift amount corresponds 2469 * to the access size (thus irrelevant for byte accesses). 2470 */ 2471 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdRegIdx(ARMV8A64INSTRLDSTTYPE enmType, 2472 uint32_t iReg, uint32_t iRegBase, uint32_t iRegIndex, 2473 ARMV8A64INSTRLDSTEXTEND enmExtend = kArmv8A64InstrLdStExtend_Lsl, 2474 bool fShifted = false) 2475 { 2476 Assert(iRegIndex < 32); 2477 Assert(iReg < 32); /* 3 2 1 0 */ 2478 Assert(iRegBase < 32); /* 10987654321098765432109876543210 */ 2479 return UINT32_C(0x38200800) /* 0b00111000001000000000100000000000 */ 2480 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_Size) << (30 - kArmv8A64InstrLdStType_Shift_Size)) 2481 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_VR) << (26 - kArmv8A64InstrLdStType_Shift_VR)) 2482 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdStType_Mask_Opc) << (22 - kArmv8A64InstrLdStType_Shift_Opc)) 2483 | (iRegIndex << 16) 2484 | ((uint32_t)enmExtend << 13) 2485 | ((uint32_t)fShifted << 12) 2486 | (iRegBase << 5) 2487 | iReg; 2488 } 2489 2490 typedef enum /* VR Opc */ 2491 { /* \ | */ 2492 kArmv8A64InstrLdrLitteral_Mask_Vr = 0x10, 2493 kArmv8A64InstrLdrLitteral_Mask_Opc = 0x03, 2494 kArmv8A64InstrLdrLitteral_Shift_Vr = 4, 2495 kArmv8A64InstrLdrLitteral_Shift_Opc = 0, 2496 2497 kArmv8A64InstrLdrLitteral_Word = 0x00, /**< word = 32-bit */ 2498 kArmv8A64InstrLdrLitteral_Dword = 0x01, /**< dword = 64-bit */ 2499 kArmv8A64InstrLdrLitteral_SignWord64 = 0x02, /**< Loads word, signextending it to 64-bit */ 2500 kArmv8A64InstrLdrLitteral_Prefetch = 0x03, /**< prfm */ 2501 2502 kArmv8A64InstrLdrLitteral_Vr_Word = 0x10, /**< word = 32-bit */ 2503 kArmv8A64InstrLdrLitteral_Vr_Dword = 0x11, /**< dword = 64-bit */ 2504 kArmv8A64InstrLdrLitteral_Vr_128 = 0x12 2505 } ARMV8A64INSTRLDRLITTERAL; 2506 2507 2508 /** 2509 * A64: Encodes load w/ a PC relative 19-bit signed immediate. 2510 * 2511 * @returns The encoded instruction. 2512 * @param enmType The load instruction type. 2513 * @param iReg The register to load into. 2514 * @param i19Imm The signed immediate value, multiplied by 4 regardless 2515 * of access size. 2516 */ 2517 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrLdrLitteral(ARMV8A64INSTRLDRLITTERAL enmType, uint32_t iReg, int32_t i19Imm) 2518 { 2519 Assert(i19Imm >= -262144 && i19Imm < 262144); 2520 Assert(iReg < 32); /* 3 2 1 0 */ 2521 /* 10987654321098765432109876543210 */ 2522 return UINT32_C(0x30000000) /* 0b00110000000000000000000000000000 */ 2523 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdrLitteral_Mask_Vr) << (26 - kArmv8A64InstrLdrLitteral_Shift_Vr)) 2524 | (((uint32_t)enmType & (uint32_t)kArmv8A64InstrLdrLitteral_Mask_Opc) << (30 - kArmv8A64InstrLdrLitteral_Shift_Opc)) 2525 | (((uint32_t)i19Imm & UINT32_C(0x00ffffe0)) << 5) 2526 | iReg; 2278 2527 } 2279 2528
Note:
See TracChangeset
for help on using the changeset viewer.