VirtualBox

Changeset 101248 in vbox for trunk/include


Ignore:
Timestamp:
Sep 24, 2023 2:48:56 AM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159231
Message:

VMM/IEM: Ran first native arm TB. Executable memory fun prevents easily running any further blocks. bugref:10370

File:
1 edited

Legend:

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

    r101246 r101248  
    22022202/** @} */
    22032203
     2204
     2205#if (!defined(VBOX_FOR_DTRACE_LIB) && defined(__cplusplus) && !defined(ARMV8_WITHOUT_MK_INSTR)) || defined(DOXYGEN_RUNNING)
     2206/** @def grp_rt_armv8_mkinstr   Instruction Encoding Helpers
     2207 *
     2208 * A few inlined functions and macros for assiting in encoding common ARMv8
     2209 * instructions.
     2210 *
     2211 * @{ */
     2212
     2213/** A64: Return instruction. */
     2214#define ARMV8_A64_INSTR_RET         UINT32_C(0xd65f03c0)
     2215
     2216
     2217typedef enum
     2218{
     2219    /** Add @a iImm7*sizeof(reg) to @a iBaseReg after the store/load,
     2220     * and update the register. */
     2221    kArm64InstrStLdPairType_kPostIndex = 1,
     2222    /** Add @a iImm7*sizeof(reg) to @a iBaseReg before the store/load,
     2223     * but don't update the register. */
     2224    kArm64InstrStLdPairType_kSigned    = 2,
     2225    /** Add @a iImm7*sizeof(reg) to @a iBaseReg before the store/load,
     2226     * and update the register. */
     2227    kArm64InstrStLdPairType_kPreIndex  = 3
     2228} ARM64INSTRSTLDPAIRTYPE;
     2229
     2230/**
     2231 * A64: Encodes either stp (store register pair) or ldp (load register pair).
     2232 *
     2233 * @returns The encoded instruction.
     2234 * @param   fLoad       true for ldp, false of stp.
     2235 * @param   iOpc        When @a fSimdFp is @c false:
     2236 *                          - 0 for 32-bit GPRs (Wt).
     2237 *                          - 1 for encoding stgp or ldpsw.
     2238 *                          - 2 for 64-bit GRPs (Xt).
     2239 *                          - 3 illegal.
     2240 *                      When @a fSimdFp is @c true:
     2241 *                          - 0 for 32-bit SIMD&FP registers (St).
     2242 *                          - 1 for 64-bit SIMD&FP registers (Dt).
     2243 *                          - 2 for 128-bit SIMD&FP regsiters (Qt).
     2244 * @param   enmType     The instruction variant wrt addressing and updating of the
     2245 *                      addressing register.
     2246 * @param   iReg1       The first register to store/load.
     2247 * @param   iReg2       The second register to store/load.
     2248 * @param   iBaseReg    The base register to use when addressing. SP is allowed.
     2249 * @param   iImm7       Signed addressing immediate value scaled, range -64..63,
     2250 *                      will be multiplied by the register size.
     2251 * @param   fSimdFp     true for SIMD&FP registers, false for GPRs and
     2252 *                      stgp/ldpsw instructions.
     2253 */
     2254DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrStLdPair(bool fLoad, uint32_t iOpc, ARM64INSTRSTLDPAIRTYPE enmType,
     2255                                                    uint32_t iReg1, uint32_t iReg2, uint32_t iBaseReg, int32_t iImm7 = 0,
     2256                                                    bool fSimdFp = false)
     2257{
     2258    Assert(iOpc < 3); Assert(iReg1 <= 31); Assert(iReg2 <= 31); Assert(iBaseReg <= 31); Assert(iImm7 < 64 && iImm7 >= -64);
     2259    return (iOpc                               << 30)
     2260         | UINT32_C(0x28000000)
     2261         | ((uint32_t)fSimdFp                  << 26) /* VR bit, see "Top-level encodings for A64" */
     2262         | ((uint32_t)enmType                  << 23)
     2263         | ((uint32_t)fLoad                    << 22)
     2264         | (((uint32_t)iImm7 & UINT32_C(0x7f)) << 15)
     2265         | (iReg2                              << 10)
     2266         | (iBaseReg                           <<  5)
     2267         | iReg1;
     2268}
     2269
     2270
     2271typedef enum
     2272{
     2273    kArmv8A64InstrShift_kLsl = 0,
     2274    kArmv8A64InstrShift_kLsr,
     2275    kArmv8A64InstrShift_kAsr,
     2276    kArmv8A64InstrShift_kRor
     2277} ARMV8A64INSTRSHIFT;
     2278
     2279
     2280/**
     2281 * A64: Encodes a logical instruction with a shifted 2nd register operand.
     2282 *
     2283 * @returns The encoded instruction.
     2284 * @param   u2Opc           The logical operation to perform.
     2285 * @param   fNot            Whether to complement the 2nd operand.
     2286 * @param   iRegResult      The output register.
     2287 * @param   iReg1           The 1st register operand.
     2288 * @param   iReg2Shifted    The 2nd register operand, to which the optional
     2289 *                          shifting is applied.
     2290 * @param   f64Bit          true for 64-bit GPRs (default), @c false for 32-bit
     2291 *                          GPRs.
     2292 * @param   offShift6       The shift amount (default: none).
     2293 * @param   enmShift        The shift operation (default: LSL).
     2294 */
     2295DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrLogicalShiftedReg(uint32_t u2Opc, bool fNot,
     2296                                                             uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted,
     2297                                                             bool f64Bit, uint32_t offShift6, ARMV8A64INSTRSHIFT enmShift)
     2298{
     2299    Assert(u2Opc < 4); Assert(offShift6 < (f64Bit ? 64 : 32));
     2300    Assert(iRegResult < 32); Assert(iReg1 < 32); Assert(iReg2Shifted < 32);
     2301    return ((uint32_t)f64Bit << 31)
     2302         | (u2Opc << 29)
     2303         | UINT32_C(0x0a000000)
     2304         | ((uint32_t)enmShift << 22)
     2305         | ((uint32_t)fNot     << 21)
     2306         | (iReg2Shifted       << 16)
     2307         | (offShift6          << 10)
     2308         | (iReg1              <<  5)
     2309         | iRegResult;
     2310}
     2311
     2312
     2313/** A64: Encodes an AND instruction.
     2314 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2315DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrAnd(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2316                                               uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2317{
     2318    return Armv8A64MkInstrLogicalShiftedReg(0, false /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2319}
     2320
     2321
     2322/** A64: Encodes an BIC instruction.
     2323 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2324DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrBic(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2325                                               uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2326{
     2327    return Armv8A64MkInstrLogicalShiftedReg(0, true /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2328}
     2329
     2330
     2331/** A64: Encodes an ORR instruction.
     2332 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2333DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrOrr(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2334                                               uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2335{
     2336    return Armv8A64MkInstrLogicalShiftedReg(1, false /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2337}
     2338
     2339
     2340/** A64: Encodes an ORN instruction.
     2341 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2342DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrOrn(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2343                                               uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2344{
     2345    return Armv8A64MkInstrLogicalShiftedReg(1, true /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2346}
     2347
     2348
     2349/** A64: Encodes an EOR instruction.
     2350 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2351DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrEor(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2352                                               uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2353{
     2354    return Armv8A64MkInstrLogicalShiftedReg(2, false /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2355}
     2356
     2357
     2358/** A64: Encodes an EON instruction.
     2359 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2360DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrEon(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2361                                               uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2362{
     2363    return Armv8A64MkInstrLogicalShiftedReg(2, true /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2364}
     2365
     2366
     2367/** A64: Encodes an ANDS instruction.
     2368 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2369DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrAnds(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2370                                                uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2371{
     2372    return Armv8A64MkInstrLogicalShiftedReg(3, false /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2373}
     2374
     2375
     2376/** A64: Encodes an BICS instruction.
     2377 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details.  */
     2378DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrBics(uint32_t iRegResult, uint32_t iReg1, uint32_t iReg2Shifted, bool f64Bit = true,
     2379                                                uint32_t offShift6 = 0, ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_kLsl)
     2380{
     2381    return Armv8A64MkInstrLogicalShiftedReg(3, true /*fNot*/, iRegResult, iReg1, iReg2Shifted, f64Bit, offShift6, enmShift);
     2382}
     2383
     2384
     2385/**
     2386 * A64: Encodes either add, adds, sub or subs.
     2387 *
     2388 * @returns The encoded instruction.
     2389 * @param   fSub                    true for sub and subs, false for add and
     2390 *                                  adds.
     2391 * @param   iRegResult              The register to store the result in.
     2392 *                                  SP is valid when @a fSetFlags = false,
     2393 *                                  and ZR is valid otherwise.
     2394 * @param   iRegSrc                 The register containing the augend (@a fSub
     2395 *                                  = false) or minuend (@a fSub = true).  SP is
     2396 *                                  a valid registers for all variations.
     2397 * @param   uImm12AddendSubtrahend  The addended (@a fSub = false) or subtrahend
     2398 *                                  (@a fSub = true).
     2399 * @param   f64Bit                  true for 64-bit GRPs (default), false for
     2400 *                                  32-bit GPRs.
     2401 * @param   fSetFlags               Whether to set flags (adds / subs) or not
     2402 *                                  (add / sub - default).
     2403 * @param   fShift12                Whether to shift uImm12AddendSubtrahend 12
     2404 *                                  bits to the left, or not (default).
     2405 */
     2406DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrAddSub(bool fSub, uint32_t iRegResult, uint32_t iRegSrc,
     2407                                                  uint32_t uImm12AddendSubtrahend, bool f64Bit = true, bool fSetFlags = false,
     2408                                                  bool fShift12 = false)
     2409{
     2410    Assert(uImm12AddendSubtrahend < 4096); Assert(iRegSrc < 32); Assert(iRegResult < 32);
     2411    return ((uint32_t)f64Bit       << 31)
     2412         | ((uint32_t)fSub         << 30)
     2413         | ((uint32_t)fSetFlags    << 29)
     2414         | UINT32_C(0x11000000)
     2415         | ((uint32_t)fShift12     << 22)
     2416         | (uImm12AddendSubtrahend << 10)
     2417         | (iRegSrc                <<  5)
     2418         | iRegResult;
     2419}
     2420
     2421
     2422/**
     2423 * A64: Encodes a B (unconditional branch w/ imm) instruction.
     2424 *
     2425 * @returns The encoded instruction.
     2426 * @param   iImm26      Signed number of instruction to jump (i.e. *4).
     2427 */
     2428DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrB(int32_t iImm26)
     2429{
     2430    Assert(iImm26 >= -67108864 && iImm26 < 67108864);
     2431    return UINT32_C(0x14000000) | ((uint32_t)iImm26 & UINT32_C(0x3ffffff));
     2432}
     2433
     2434
     2435/**
     2436 * A64: Encodes a BL (unconditional call w/ imm) instruction.
     2437 *
     2438 * @returns The encoded instruction.
     2439 * @param   iImm26      Signed number of instruction to jump (i.e. *4).
     2440 */
     2441DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrBl(int32_t iImm26)
     2442{
     2443    return Armv8A64MkInstrB(iImm26) | RT_BIT_32(31);
     2444}
     2445
     2446
     2447/**
     2448 * A64: Encodes a BR (unconditional branch w/ register) instruction.
     2449 *
     2450 * @returns The encoded instruction.
     2451 * @param   iReg                    The register containing the target address.
     2452 */
     2453DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrBr(uint32_t iReg)
     2454{
     2455    Assert(iReg < 32);
     2456    return UINT32_C(0xd61f0000) | (iReg <<  5);
     2457}
     2458
     2459
     2460/**
     2461 * A64: Encodes a BLR instruction.
     2462 *
     2463 * @returns The encoded instruction.
     2464 * @param   iReg                    The register containing the target address.
     2465 */
     2466DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrBlr(uint32_t iReg)
     2467{
     2468    return Armv8A64MkInstrBr(iReg) | RT_BIT_32(21);
     2469}
     2470
     2471
     2472/**
     2473 * A64: Encodes CBZ and CBNZ (conditional branch w/ immediate) instructions.
     2474 *
     2475 * @returns The encoded instruction.
     2476 * @param   fJmpIfNotZero   false to jump if register is zero, true to jump if
     2477 *                          its not zero.
     2478 * @param   iImm19          Signed number of instruction to jump (i.e. *4).
     2479 * @param   iReg            The GPR to check for zero / non-zero value.
     2480 * @param   f64Bit          true for 64-bit register, false for 32-bit.
     2481 */
     2482DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCbzCbnz(bool fJmpIfNotZero, int32_t iImm19, uint32_t iReg, bool f64Bit = true)
     2483{
     2484    Assert(iReg < 32); Assert(iImm19 >= -262144 && iImm19 < 262144);
     2485    return ((uint32_t)f64Bit             << 31)
     2486         | UINT32_C(0x34000000)
     2487         | ((uint32_t)fJmpIfNotZero      << 24)
     2488         | (((uint32_t)iImm19 & 0x7ffff) <<  5)
     2489         | iReg;
     2490}
     2491
     2492
     2493/** @} */
     2494
     2495#endif /* !dtrace && __cplusplus */
     2496
    22042497/** @} */
    22052498
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