VirtualBox

Changeset 101304 in vbox for trunk/include


Ignore:
Timestamp:
Sep 29, 2023 1:02:02 AM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159300
Message:

VMM/IEM: Emit native code for pure defer-CImpl instructions. Tested on linux.amd64 only and this doesn't cover cases with zero parameters. bugref:10371

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/armv8.h

    r101260 r101304  
    22432243 * @returns The encoded instruction.
    22442244 * @param   fLoad       true for ldp, false of stp.
    2245  * @param   iOpc        When @a fSimdFp is @c false:
     2245 * @param   u2Opc       When @a fSimdFp is @c false:
    22462246 *                          - 0 for 32-bit GPRs (Wt).
    22472247 *                          - 1 for encoding stgp or ldpsw.
     
    22622262 *                      stgp/ldpsw instructions.
    22632263 */
    2264 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdPair(bool fLoad, uint32_t iOpc, ARM64INSTRSTLDPAIRTYPE enmType,
     2264DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdPair(bool fLoad, uint32_t u2Opc, ARM64INSTRSTLDPAIRTYPE enmType,
    22652265                                                    uint32_t iReg1, uint32_t iReg2, uint32_t iBaseReg, int32_t iImm7 = 0,
    22662266                                                    bool fSimdFp = false)
    22672267{
    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 */
    22712271         | ((uint32_t)fSimdFp                  << 26) /* VR bit, see "Top-level encodings for A64" */
    22722272         | ((uint32_t)enmType                  << 23)
     
    22762276         | (iBaseReg                           <<  5)
    22772277         | iReg1;
     2278}
     2279
     2280typedef 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 */
     2334DECL_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 */
     2357DECL_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 */
     2376DECL_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 */
     2395DECL_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 */
     2414DECL_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 */
     2436DECL_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
     2451typedef 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 */
     2471DECL_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
     2490typedef 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 */
     2517DECL_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;
    22782527}
    22792528
Note: See TracChangeset for help on using the changeset viewer.

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