VirtualBox

Changeset 104173 in vbox for trunk


Ignore:
Timestamp:
Apr 5, 2024 9:38:49 AM (6 months ago)
Author:
vboxsync
Message:

VMM/IEM: ARM64 assembly renditions of shl, shr and sar assembly helpers. bugref:10376

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl-arm64.S

    r103003 r104173  
    4444#endif
    4545
     46.macro BEGINPROC, a_Name
     47        .private_extern NAME(\a_Name)
     48        .globl          NAME(\a_Name)
     49NAME(\a_Name):
     50.endm
     51
     52
     53.macro CALC_EFLAGS_PARITY, regEfl, regResult, regTmp
     54        /*
     55         * Parity calculation for low byte of the result (sucks that there is no popcount for gprs).
     56         */
     57        eor     \regTmp, \regResult, \regResult, LSR #4
     58        eor     \regTmp, \regTmp, \regTmp, LSR #2
     59        eor     \regTmp, \regTmp, \regTmp, LSR #1
     60        eor     \regTmp, \regTmp, #1
     61        bfi     \regEfl, \regTmp, #X86_EFL_PF_BIT, #1   /* PF(2) = popcount(w9 & 0xff) & 1 ^ 1 */
     62.endm
     63
     64
     65.macro CALC_EFLAGS_AUX_CARRY, regEfl, regResult, regLeft, regRight, regTmp
     66        /*
     67         * Auxilary carry / borrow flag.  This is related to 8-bit BCD.
     68         */
     69        eor     \regTmp, \regLeft, \regRight
     70        eor     \regTmp, \regTmp, \regResult
     71        lsr     \regTmp, \regTmp, #X86_EFL_AF_BIT
     72        bfi     \regEfl, \regTmp, #X86_EFL_AF_BIT, #1   /* AF(4) = (w8 ^ w1 ^ w9 & X86_EFL_AF) >> X86_EFL_AF_BIT */
     73.endm
    4674
    4775.macro CALC_EFLAGS, regEfl, regResult, regLeft, regRight, regTmp, fSkipFlags=0
     
    311339        ret
    312340        .cfi_endproc
     341
     342
     343
     344/*
     345 * Shift Left.
     346 */
     347
     348/* void iemAImpl_shl_u8(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags); */
     349/* void iemAImpl_shl_u16(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags); */
     350/* void iemAImpl_shl_u32(uint16_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags); */
     351.macro SHL_8_16_32, a_Name, a_cBits, a_fIntelFlags, a_LdStSuff
     352        .p2align        2
     353BEGINPROC \a_Name
     354        .cfi_startproc
     355
     356        /* Do we need to shift anything at all? */
     357        and     w1, w1, #0x1f
     358        cbz     w1, 99f
     359
     360        /*
     361         * Do the shifting
     362         */
     363        ldr\a_LdStSuff  w8, [x0]
     364.ifne \a_cBits < 32
     365        lslv    w9, w8, w1
     366.else
     367        lslv    x9, x8, x1                      /* use 64-bit registers here so we get CF for free. We know x1 != 0. */
     368.endif
     369        str\a_LdStSuff  w9, [x0]
     370
     371        /*
     372         * Calculate EFLAGS.
     373         */
     374        ldr     w10, [x2]                       /* w10 = eflags; CF=0 PF=2 AF=4 ZF=6 SF=7 OF=11 */
     375
     376        CALC_EFLAGS_PARITY w10, w9, w12
     377
     378.ifne \a_cBits < 32
     379        setf\a_cBits w9                         /* Sets NZ */
     380.else
     381        ands    wzr, w9, w9                     /* Sets NZ */
     382.endif
     383#if 1
     384        mrs     x11, NZCV
     385        lsr     w11, w11, #30                   /* N=1; Z=0 */
     386        bfi     w10, w11, X86_EFL_ZF_BIT, 2     /* EFLAGS.ZF and EFLAGS.SF */
     387#else
     388        cset    x11, eq
     389        bfi     w10, w11, X86_EFL_ZF_BIT, 1
     390        cset    x12, pl
     391        bfi     w10, w12, X86_EFL_SF_BIT, 1
     392#endif
     393
     394.ifne \a_cBits < 32
     395        bfxil   w10, w9, #\a_cBits, #1          /* w9 bit 8/16 contains carry. (X86_EFL_CF_BIT == 0) */
     396.else
     397        bfxil   x10, x9, #\a_cBits, #1          /* x9 bit 32 contains carry. (X86_EFL_CF_BIT == 0) */
     398.endif
     399
     400.ifne \a_fIntelFlags
     401        /* Intel: OF = first bit shifted: fEfl |= X86_EFL_GET_OF_ ## cOpBits(uDst ^ (uDst << 1)); */
     402        eor     w11, w8, w8, LSL #1
     403        lsr     w11, w11, #(\a_cBits - 1)
     404        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     405
     406        and     w10, w10, ~X86_EFL_AF           /* AF is cleared */
     407.else
     408        /* AMD: OF = last bit shifted: fEfl |= ((uResult >> (cOpBits - 1)) ^ fCarry) << X86_EFL_OF_BIT;  */
     409 .ifne \a_cBits < 32
     410        eor     w11, w9, w9, LSR #1
     411        lsr     w11, w11, #(\a_cBits - 1)
     412 .else
     413        eor     x11, x9, x9, LSR #1
     414        lsr     x11, x11, #(\a_cBits - 1)
     415 .endif
     416        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     417
     418        orr     w10, w10, X86_EFL_AF           /* AF is set  */
     419.endif
     420
     421        str     w10, [x2]
     42299:
     423        ret
     424        .cfi_endproc
     425.endm
     426
     427SHL_8_16_32 iemAImpl_shl_u8,         8, 1, b
     428SHL_8_16_32 iemAImpl_shl_u8_intel,   8, 1, b
     429SHL_8_16_32 iemAImpl_shl_u8_amd,     8, 0, b
     430
     431SHL_8_16_32 iemAImpl_shl_u16,       16, 1, h
     432SHL_8_16_32 iemAImpl_shl_u16_intel, 16, 1, h
     433SHL_8_16_32 iemAImpl_shl_u16_amd,   16, 0, h
     434
     435SHL_8_16_32 iemAImpl_shl_u32,       32, 1,
     436SHL_8_16_32 iemAImpl_shl_u32_intel, 32, 1,
     437SHL_8_16_32 iemAImpl_shl_u32_amd,   32, 0,
     438
     439;; @todo this is slightly slower than the C version (release) on an M2. Investigate why.
     440/* void iemAImpl_shl_u64(uint16_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags); */
     441.macro SHL_64, a_Name, a_fIntelFlags
     442        .p2align        2
     443BEGINPROC \a_Name
     444        .cfi_startproc
     445
     446        /* Do we need to shift anything at all? */
     447        and     w1, w1, #0x3f
     448        cbz     w1, 99f
     449
     450        /*
     451         * Do the shifting
     452         */
     453        ldr     x8, [x0]
     454        lslv    x9, x8, x1
     455        str     x9, [x0]
     456
     457        /*
     458         * Calculate EFLAGS.
     459         */
     460        ldr     w10, [x2]                       /* w10 = eflags; CF=0 PF=2 AF=4 ZF=6 SF=7 OF=11 */
     461
     462        CALC_EFLAGS_PARITY w10, w9, w11
     463
     464        ands    xzr, x9, x9                     /* Sets NZ */
     465        mrs     x11, NZCV
     466        lsr     w11, w11, #30                   /* N=1; Z=0 */
     467        bfi     w10, w11, X86_EFL_ZF_BIT, 2     /* EFLAGS.ZF and EFLAGS.SF */
     468
     469        neg     w11, w1                         /* the shift count is MODed by the data size, so this is safe. */
     470        lsrv    x11, x8, x11
     471        bfi     w10, w11, X86_EFL_CF_BIT, 1
     472
     473.ifne \a_fIntelFlags
     474        /* Intel: OF = first bit shifted: fEfl |= X86_EFL_GET_OF_ ## cOpBits(uDst ^ (uDst << 1)); */
     475        eor     x11, x8, x8, LSL #1
     476        lsr     x11, x11, #63
     477        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     478
     479        and     w10, w10, ~X86_EFL_AF           /* AF is cleared */
     480.else
     481        /* AMD: OF = last bit shifted: fEfl |= ((uResult >> (cOpBits - 1)) ^ fCarry) << X86_EFL_OF_BIT;  */
     482        eor     x11, x11, x9, LSR #63           /* w11[0]=CF from above */
     483        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     484
     485        orr     w10, w10, X86_EFL_AF           /* AF is set  */
     486.endif
     487        str     w10, [x2]
     48899:
     489        ret
     490        .cfi_endproc
     491.endm
     492
     493SHL_64 iemAImpl_shl_u64,       1
     494SHL_64 iemAImpl_shl_u64_intel, 1
     495SHL_64 iemAImpl_shl_u64_amd,   0
     496
     497
     498/*
     499 * Shift Right, Unsigned.
     500 */
     501
     502/* void iemAImpl_shr_u8(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags); */
     503/* void iemAImpl_shr_u16(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags); */
     504/* void iemAImpl_shr_u32(uint16_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags); */
     505.macro shr_8_16_32, a_Name, a_cBits, a_fIntelFlags, a_LdStSuff
     506        .p2align        2
     507BEGINPROC \a_Name
     508        .cfi_startproc
     509
     510        /* Do we need to shift anything at all? */
     511        and     w1, w1, #0x1f
     512        cbz     w1, 99f
     513
     514        /* Load EFLAGS before we start the calculation. */
     515        ldr     w10, [x2]                       /* w10 = eflags; CF=0 PF=2 AF=4 ZF=6 SF=7 OF=11 */
     516
     517        /*
     518         * Do the shifting.
     519         */
     520        ldr\a_LdStSuff  w8, [x0]
     521        lsrv    w9, w8, w1
     522        str\a_LdStSuff  w9, [x0]
     523
     524        /*
     525         * Calculate EFLAGS.
     526         */
     527        sub     w11, w1, #1
     528        lsrv    w11, w8, w11
     529        bfxil   w10, w11, #X86_EFL_CF_BIT, #1
     530
     531.ifne \a_fIntelFlags
     532        and     w10, w10, ~X86_EFL_AF           /* AF is cleared */
     533        /* Intel: OF = one bit shift: fEfl |= X86_EFL_GET_OF_ ## cOpBits(uDstIn); */
     534        lsr     w11, w8, #(\a_cBits - 1)
     535        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     536.else
     537        orr     w10, w10, X86_EFL_AF            /* AF is set  */
     538        /* AMD: OF = last bits shifted: fEfl |= (uResult >> (cOpBits - 2)) << X86_EFL_OF_BIT;  */
     539        lsr     w11, w9, #(\a_cBits - 2)
     540        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     541.endif
     542
     543        CALC_EFLAGS_PARITY w10, w9, w11
     544
     545.ifne \a_cBits < 32
     546        setf\a_cBits w9                         /* Sets NZ */
     547.else
     548        ands    wzr, w9, w9                     /* Sets NZ */
     549.endif
     550        mrs     x11, NZCV
     551        lsr     w11, w11, #30                   /* N=1; Z=0 */
     552        bfi     w10, w11, X86_EFL_ZF_BIT, 2     /* EFLAGS.ZF and EFLAGS.SF */
     553
     554        str     w10, [x2]
     55599:
     556        ret
     557        .cfi_endproc
     558.endm
     559
     560shr_8_16_32 iemAImpl_shr_u8,         8, 1, b
     561shr_8_16_32 iemAImpl_shr_u8_intel,   8, 1, b
     562shr_8_16_32 iemAImpl_shr_u8_amd,     8, 0, b
     563
     564shr_8_16_32 iemAImpl_shr_u16,       16, 1, h
     565shr_8_16_32 iemAImpl_shr_u16_intel, 16, 1, h
     566shr_8_16_32 iemAImpl_shr_u16_amd,   16, 0, h
     567
     568shr_8_16_32 iemAImpl_shr_u32,       32, 1,
     569shr_8_16_32 iemAImpl_shr_u32_intel, 32, 1,
     570shr_8_16_32 iemAImpl_shr_u32_amd,   32, 0,
     571
     572;; @todo this is slightly slower than the C version (release) on an M2. Investigate why.
     573/* void iemAImpl_shr_u64(uint16_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags); */
     574.macro shr_64, a_Name, a_fIntelFlags
     575        .p2align        2
     576BEGINPROC \a_Name
     577        .cfi_startproc
     578
     579        /* Do we need to shift anything at all? */
     580        ands    w1, w1, #0x3f
     581        b.eq    99f
     582
     583        /* Load EFLAGS before we start the calculation. */
     584        ldr     w10, [x2]                       /* w10 = eflags; CF=0 PF=2 AF=4 ZF=6 SF=7 OF=11 */
     585
     586        /*
     587         * Do the shifting
     588         */
     589        ldr     x8, [x0]
     590        lsrv    x9, x8, x1
     591        str     x9, [x0]
     592
     593        /*
     594         * Calculate EFLAGS.
     595         */
     596        sub     w11, w1, #1
     597        lsrv    x11, x8, x11
     598        bfxil   w10, w11, #X86_EFL_CF_BIT, #1
     599
     600.ifne \a_fIntelFlags
     601        and     w10, w10, ~X86_EFL_AF           /* AF is cleared */
     602        /* Intel: OF = one bit shift: fEfl |= X86_EFL_GET_OF_ ## cOpBits(uDstIn); */
     603        lsr     x11, x8, #63
     604        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     605.else
     606        orr     w10, w10, X86_EFL_AF            /* AF is set  */
     607        /* AMD: OF = last bits shifted: fEfl |= (uResult >> (cOpBits - 2)) << X86_EFL_OF_BIT;  */
     608        lsr     x11, x9, #62
     609        bfi     w10, w11, #X86_EFL_OF_BIT, #1
     610.endif
     611
     612        CALC_EFLAGS_PARITY w10, w9, w11
     613
     614        ands    xzr, x9, x9                     /* Sets NZ */
     615        mrs     x11, NZCV
     616        lsr     w11, w11, #30                   /* N=1; Z=0 */
     617        bfi     w10, w11, X86_EFL_ZF_BIT, 2     /* EFLAGS.ZF and EFLAGS.SF */
     618
     619        str     w10, [x2]
     62099:
     621        ret
     622        .cfi_endproc
     623.endm
     624
     625shr_64 iemAImpl_shr_u64,       1
     626shr_64 iemAImpl_shr_u64_intel, 1
     627shr_64 iemAImpl_shr_u64_amd,   0
     628
     629
     630/*
     631 * Shift Right, Signed
     632 */
     633
     634/* void iemAImpl_sar_u8(uint8_t *pu8Dst, uint8_t cShift, uint32_t *pEFlags); */
     635/* void iemAImpl_sar_u16(uint16_t *pu16Dst, uint8_t cShift, uint32_t *pEFlags); */
     636/* void iemAImpl_sar_u32(uint16_t *pu32Dst, uint8_t cShift, uint32_t *pEFlags); */
     637.macro sar_8_16_32, a_Name, a_cBits, a_fIntelFlags, a_LdSuff, a_StSuff
     638        .p2align        2
     639BEGINPROC \a_Name
     640        .cfi_startproc
     641
     642        /* Do we need to shift anything at all? */
     643        and     w1, w1, #0x1f
     644        cbz     w1, 99f
     645
     646        /* Load EFLAGS before we start the calculation. */
     647        ldr     w10, [x2]                       /* w10 = eflags; CF=0 PF=2 AF=4 ZF=6 SF=7 OF=11 */
     648
     649        /*
     650         * Do the shifting.
     651         */
     652        ldr\a_LdSuff  w8, [x0]                  /* Sign-extending for 8 and 16 bits! */
     653        asrv    w9, w8, w1
     654        str\a_StSuff  w9, [x0]
     655
     656        /*
     657         * Calculate EFLAGS.
     658         */
     659        sub     w11, w1, #1
     660        lsrv    w11, w8, w11
     661        bfxil   w10, w11, #X86_EFL_CF_BIT, #1
     662
     663.ifne \a_fIntelFlags
     664        mov     w11, ~(X86_EFL_AF | X86_EFL_OF)
     665        and     w10, w10, w11                   /* AF and OF are cleared */
     666.else
     667        orr     w10, w10, X86_EFL_AF            /* AF is set  */
     668        and     w10, w10, ~X86_EFL_OF           /* OF is cleared */
     669.endif
     670
     671        CALC_EFLAGS_PARITY w10, w9, w11
     672
     673.ifne \a_cBits < 32
     674        setf\a_cBits w9                         /* Sets NZ */
     675.else
     676        ands    wzr, w9, w9                     /* Sets NZ */
     677.endif
     678        mrs     x11, NZCV
     679        lsr     w11, w11, #30                   /* N=1; Z=0 */
     680        bfi     w10, w11, X86_EFL_ZF_BIT, 2     /* EFLAGS.ZF and EFLAGS.SF */
     681
     682        str     w10, [x2]
     68399:
     684        ret
     685        .cfi_endproc
     686.endm
     687
     688sar_8_16_32 iemAImpl_sar_u8,         8, 1, sb, b
     689sar_8_16_32 iemAImpl_sar_u8_intel,   8, 1, sb, b
     690sar_8_16_32 iemAImpl_sar_u8_amd,     8, 0, sb, b
     691
     692sar_8_16_32 iemAImpl_sar_u16,       16, 1, sh, h
     693sar_8_16_32 iemAImpl_sar_u16_intel, 16, 1, sh, h
     694sar_8_16_32 iemAImpl_sar_u16_amd,   16, 0, sh, h
     695
     696sar_8_16_32 iemAImpl_sar_u32,       32, 1, ,
     697sar_8_16_32 iemAImpl_sar_u32_intel, 32, 1, ,
     698sar_8_16_32 iemAImpl_sar_u32_amd,   32, 0, ,
     699
     700;; @todo this is slightly slower than the C version (release) on an M2. Investigate why.
     701/* void iemAImpl_sar_u64(uint16_t *pu64Dst, uint8_t cShift, uint32_t *pEFlags); */
     702.macro sar_64, a_Name, a_fIntelFlags
     703        .p2align        2
     704BEGINPROC \a_Name
     705        .cfi_startproc
     706
     707        /* Do we need to shift anything at all? */
     708        ands    w1, w1, #0x3f
     709        b.eq    99f
     710
     711        /* Load EFLAGS before we start the calculation. */
     712        ldr     w10, [x2]                       /* w10 = eflags; CF=0 PF=2 AF=4 ZF=6 SF=7 OF=11 */
     713
     714        /*
     715         * Do the shifting
     716         */
     717        ldr     x8, [x0]
     718        asrv    x9, x8, x1
     719        str     x9, [x0]
     720
     721        /*
     722         * Calculate EFLAGS.
     723         */
     724        sub     w11, w1, #1
     725        lsrv    x11, x8, x11
     726        bfxil   w10, w11, #X86_EFL_CF_BIT, #1
     727
     728.ifne \a_fIntelFlags
     729        mov     w11, ~(X86_EFL_AF | X86_EFL_OF)
     730        and     w10, w10, w11                   /* AF and OF are cleared */
     731.else
     732        orr     w10, w10, X86_EFL_AF            /* AF is set  */
     733        and     w10, w10, ~X86_EFL_OF           /* OF is cleared */
     734.endif
     735
     736        CALC_EFLAGS_PARITY w10, w9, w11
     737
     738        ands    xzr, x9, x9                     /* Sets NZ */
     739        mrs     x11, NZCV
     740        lsr     w11, w11, #30                   /* N=1; Z=0 */
     741        bfi     w10, w11, X86_EFL_ZF_BIT, 2     /* EFLAGS.ZF and EFLAGS.SF */
     742
     743        str     w10, [x2]
     74499:
     745        ret
     746        .cfi_endproc
     747.endm
     748
     749sar_64 iemAImpl_sar_u64,       1
     750sar_64 iemAImpl_sar_u64_intel, 1
     751sar_64 iemAImpl_sar_u64_amd,   0
     752
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r104156 r104173  
    8484
    8585/**
     86 * Calculates the parity flag.
     87 *
     88 * @returns X86_EFL_PF or 0.
     89 * @param   a_uResult       Unsigned result value.
     90 */
     91#if !defined(RT_ARCH_ARM64) || 1 /** @todo profile this... micro benching in tstIEMAImpl indicates no gain, but it may be skewed. */
     92# define IEM_EFL_CALC_PARITY(a_uResult) (g_afParity[(a_uResult) & 0xff])
     93#else
     94# define IEM_EFL_CALC_PARITY(a_uResult) iemAImplCalcParity(a_uResult)
     95DECL_FORCE_INLINE(uint32_t) iemAImplCalcParity(uint32_t uResult)
     96{
     97    /* Emulate 8-bit pop count.  This translates to 4 EOR instructions on
     98       ARM64 as they can shift the 2nd source operand. */
     99    uint8_t bPf = uResult ^ (uResult >> 4);
     100    bPf ^= bPf >> 2;
     101    bPf ^= bPf >> 1;
     102    bPf ^= 1;
     103    return (bPf & 1) << X86_EFL_PF_BIT;
     104}
     105#endif
     106
     107/**
    86108 * Extracts the OF flag from a OF calculation result.
    87109 *
     
    111133        fEflTmp &= ~X86_EFL_STATUS_BITS; \
    112134        fEflTmp |= (a_CfExpr) << X86_EFL_CF_BIT; \
    113         fEflTmp |= g_afParity[(a_uResult) & 0xff]; \
     135        fEflTmp |= IEM_EFL_CALC_PARITY(a_uResult); \
    114136        fEflTmp |= ((uint32_t)(a_uResult) ^ (uint32_t)(a_uSrc) ^ (uint32_t)(a_uDst)) & X86_EFL_AF; \
    115137        fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \
     
    148170        uint32_t fEflTmp = *(a_pfEFlags); \
    149171        fEflTmp &= ~X86_EFL_STATUS_BITS; \
    150         fEflTmp |= g_afParity[(a_uResult) & 0xff]; \
     172        fEflTmp |= IEM_EFL_CALC_PARITY(a_uResult); \
    151173        fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \
    152174        fEflTmp |= X86_EFL_CALC_SF(a_uResult, a_cBitsWidth); \
     
    14141436        { \
    14151437            *puDst    = --iBit; \
    1416             fEfl     |= g_afParity[iBit]; \
     1438            fEfl     |= IEM_EFL_CALC_PARITY(iBit); \
    14171439        } \
    14181440        else \
     
    15531575        uint32_t fEfl = *(a_pfEFlags) & ~(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF); \
    15541576        if (uResult) \
    1555             fEfl |= g_afParity[uResult]; \
     1577            fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    15561578        else \
    15571579            fEfl |= X86_EFL_ZF | X86_EFL_PF; \
     
    24022424        if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \
    24032425            fEfl |= X86_EFL_SF; \
    2404         fEfl |= g_afParity[Result.s.Lo & 0xff]; \
     2426        fEfl |= IEM_EFL_CALC_PARITY(Result.s.Lo); \
    24052427        if (Result.s.Hi != 0) \
    24062428            fEfl |= X86_EFL_CF | X86_EFL_OF; \
     
    25162538        if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \
    25172539            fEfl |= X86_EFL_SF;  \
    2518         fEfl |= g_afParity[Result.s.Lo & 0xff]; \
     2540        fEfl |= IEM_EFL_CALC_PARITY(Result.s.Lo & 0xff); \
    25192541    } \
    25202542    *pfEFlags = fEfl; \
     
    27472769        uint32_t fEflTmp = *(a_pfEFlags); \
    27482770        fEflTmp &= ~X86_EFL_STATUS_BITS | X86_EFL_CF; \
    2749         fEflTmp |= g_afParity[(a_uResult) & 0xff]; \
     2771        fEflTmp |= IEM_EFL_CALC_PARITY(a_uResult); \
    27502772        fEflTmp |= ((uint32_t)(a_uResult) ^ (uint32_t)(a_uDst)) & X86_EFL_AF; \
    27512773        fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \
     
    29042926        fEflTmp &= ~X86_EFL_STATUS_BITS & ~X86_EFL_CF; \
    29052927        fEflTmp |= ((a_uDst) != 0) << X86_EFL_CF_BIT; \
    2906         fEflTmp |= g_afParity[(a_uResult) & 0xff]; \
     2928        fEflTmp |= IEM_EFL_CALC_PARITY(a_uResult); \
    29072929        fEflTmp |= ((uint32_t)(a_uResult) ^ (uint32_t)(a_uDst)) & X86_EFL_AF; \
    29082930        fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \
     
    32743296        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
    32753297        fEfl |= X86_EFL_CALC_ZF(uResult); \
    3276         fEfl |= g_afParity[uResult & 0xff]; \
     3298        fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    32773299        if (!a_fIntelFlags) \
    32783300            fEfl |= X86_EFL_AF; /* AMD 3990x sets it unconditionally, Intel 10980XE does the oposite */ \
     
    32813303}
    32823304
    3283 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     3305#if !defined(RT_ARCH_ARM64)
     3306
     3307# if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    32843308EMIT_SHL(64, uint64_t, RT_NOTHING, 1)
    3285 #endif
     3309# endif
    32863310EMIT_SHL(64, uint64_t, _intel,     1)
    32873311EMIT_SHL(64, uint64_t, _amd,       0)
    32883312
    3289 #if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     3313# if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
    32903314EMIT_SHL(32, uint32_t, RT_NOTHING, 1)
    3291 #endif
     3315# endif
    32923316EMIT_SHL(32, uint32_t, _intel,     1)
    32933317EMIT_SHL(32, uint32_t, _amd,       0)
    32943318
    3295 #if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     3319# if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
    32963320EMIT_SHL(16, uint16_t, RT_NOTHING, 1)
    3297 #endif
     3321# endif
    32983322EMIT_SHL(16, uint16_t, _intel,     1)
    32993323EMIT_SHL(16, uint16_t, _amd,       0)
    33003324
    3301 #if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     3325# if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
    33023326EMIT_SHL(8,  uint8_t,  RT_NOTHING, 1)
    3303 #endif
     3327# endif
    33043328EMIT_SHL(8,  uint8_t,  _intel,     1)
    33053329EMIT_SHL(8,  uint8_t,  _amd,       0)
     3330
     3331#endif /* !RT_ARCH_ARM64 */
    33063332
    33073333
     
    33273353        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
    33283354        fEfl |= X86_EFL_CALC_ZF(uResult); \
    3329         fEfl |= g_afParity[uResult & 0xff]; \
     3355        fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    33303356        if (!a_fIntelFlags) \
    33313357            fEfl |= X86_EFL_AF; /* AMD 3990x sets it unconditionally, Intel 10980XE does the oposite */ \
     
    33343360}
    33353361
    3336 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     3362#if !defined(RT_ARCH_ARM64)
     3363
     3364# if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    33373365EMIT_SHR(64, uint64_t, RT_NOTHING, 1)
    3338 #endif
     3366# endif
    33393367EMIT_SHR(64, uint64_t, _intel,     1)
    33403368EMIT_SHR(64, uint64_t, _amd,       0)
    33413369
    3342 #if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     3370# if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
    33433371EMIT_SHR(32, uint32_t, RT_NOTHING, 1)
    3344 #endif
     3372# endif
    33453373EMIT_SHR(32, uint32_t, _intel,     1)
    33463374EMIT_SHR(32, uint32_t, _amd,       0)
    33473375
    3348 #if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     3376# if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
    33493377EMIT_SHR(16, uint16_t, RT_NOTHING, 1)
    3350 #endif
     3378# endif
    33513379EMIT_SHR(16, uint16_t, _intel,     1)
    33523380EMIT_SHR(16, uint16_t, _amd,       0)
    33533381
    3354 #if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     3382# if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
    33553383EMIT_SHR(8,  uint8_t,  RT_NOTHING, 1)
    3356 #endif
     3384# endif
    33573385EMIT_SHR(8,  uint8_t,  _intel,     1)
    33583386EMIT_SHR(8,  uint8_t,  _amd,       0)
     3387
     3388#endif /* !RT_ARCH_ARM64 */
    33593389
    33603390
     
    33793409        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
    33803410        fEfl |= X86_EFL_CALC_ZF(uResult); \
    3381         fEfl |= g_afParity[uResult & 0xff]; \
     3411        fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    33823412        if (!a_fIntelFlags) \
    33833413            fEfl |= X86_EFL_AF; /* AMD 3990x sets it unconditionally, Intel 10980XE does the oposite */ \
     
    33863416}
    33873417
    3388 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     3418#if !defined(RT_ARCH_ARM64)
     3419
     3420# if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    33893421EMIT_SAR(64, uint64_t, int64_t, RT_NOTHING, 1)
    3390 #endif
     3422# endif
    33913423EMIT_SAR(64, uint64_t, int64_t, _intel,     1)
    33923424EMIT_SAR(64, uint64_t, int64_t, _amd,       0)
    33933425
    3394 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     3426# if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    33953427EMIT_SAR(32, uint32_t, int32_t, RT_NOTHING, 1)
    3396 #endif
     3428# endif
    33973429EMIT_SAR(32, uint32_t, int32_t, _intel,     1)
    33983430EMIT_SAR(32, uint32_t, int32_t, _amd,       0)
    33993431
    3400 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     3432# if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    34013433EMIT_SAR(16, uint16_t, int16_t, RT_NOTHING, 1)
    3402 #endif
     3434# endif
    34033435EMIT_SAR(16, uint16_t, int16_t, _intel,     1)
    34043436EMIT_SAR(16, uint16_t, int16_t, _amd,       0)
    34053437
    3406 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     3438# if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    34073439EMIT_SAR(8,  uint8_t,  int8_t,  RT_NOTHING, 1)
    3408 #endif
     3440# endif
    34093441EMIT_SAR(8,  uint8_t,  int8_t,  _intel,     1)
    34103442EMIT_SAR(8,  uint8_t,  int8_t,  _amd,       0)
     3443
     3444#endif /* !RT_ARCH_ARM64 */
    34113445
    34123446
     
    34513485        AssertCompile(X86_EFL_CF_BIT == 0); \
    34523486        fEfl |= (uDst >> (a_cBitsWidth - cShift)) & X86_EFL_CF; /* CF = last bit shifted out */ \
    3453         fEfl |= g_afParity[uResult & 0xff]; \
     3487        fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    34543488        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
    34553489        fEfl |= X86_EFL_CALC_ZF(uResult); \
     
    35083542            fEfl |= X86_EFL_AF; \
    35093543        } \
    3510         fEfl |= g_afParity[uResult & 0xff]; \
     3544        fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    35113545        fEfl |= X86_EFL_CALC_SF(uResult, 16); \
    35123546        fEfl |= X86_EFL_CALC_ZF(uResult); \
     
    35663600        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
    35673601        fEfl |= X86_EFL_CALC_ZF(uResult); \
    3568         fEfl |= g_afParity[uResult & 0xff]; \
     3602        fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    35693603        *pfEFlags = fEfl; \
    35703604    } \
     
    36183652        fEfl |= X86_EFL_CALC_SF(uResult, 16); \
    36193653        fEfl |= X86_EFL_CALC_ZF(uResult); \
    3620         fEfl |= g_afParity[uResult & 0xff]; \
     3654        fEfl |= IEM_EFL_CALC_PARITY(uResult); \
    36213655        *pfEFlags = fEfl; \
    36223656    } \
  • trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp

    r104156 r104173  
    256256
    257257static unsigned     g_cVerbosity = 0;
     258static bool         g_fVerboseSkipping = true;
    258259
    259260
     
    12461247static bool SubTestAndCheckIfEnabled(const char *pszName)
    12471248{
    1248     RTTestSub(g_hTest, pszName);
    1249     if (IsTestEnabled(pszName))
    1250         return true;
    1251     RTTestSkipped(g_hTest, g_cVerbosity > 0 ? "excluded" : NULL);
     1249    bool const fEnabled = IsTestEnabled(pszName);
     1250    if (g_fVerboseSkipping || fEnabled)
     1251    {
     1252        RTTestSub(g_hTest, pszName);
     1253        if (fEnabled)
     1254            return true;
     1255        RTTestSkipped(g_hTest, g_cVerbosity > 0 ? "excluded" : NULL);
     1256    }
    12521257    return false;
    12531258}
     
    1000910014    uint32_t const      cDefaultTests = 96;
    1001010015    uint32_t            cTests        = cDefaultTests;
     10016
    1001110017    RTGETOPTDEF const   s_aOptions[]  =
    1001210018    {
     
    1003710043        { "--verbose",              'v', RTGETOPT_REQ_NOTHING },
    1003810044        { "--quiet",                'q', RTGETOPT_REQ_NOTHING },
     10045        { "--quiet-skipping",       'Q', RTGETOPT_REQ_NOTHING },
    1003910046    };
    1004010047
     
    1013010137                g_cVerbosity++;
    1013110138                break;
     10139            case 'Q':
     10140                g_fVerboseSkipping = false;
     10141                break;
    1013210142
    1013310143            case 'h':
    10134                 RTPrintf("usage: %s <-g|-t> [options]\n"
     10144                RTPrintf("usage: %Rbn <-g|-t> [options]\n"
    1013510145                         "\n"
    1013610146                         "Mode:\n"
     
    1018110191                         "  -q, --quiet\n"
    1018210192                         "    Noise level.  Default: --quiet\n"
    10183                          , argv[0], cDefaultTests);
     10193                         "  -Q, --quiet-skipping\n"
     10194                         "    Don't display skipped tests.\n"
     10195                         "\n"
     10196                         "Tip! When working on a single instruction, use the the -I and -Q options to\n"
     10197                         "     restrict the testing: %Rbn -tiQI \"shr_*\"\n"
     10198                         , argv[0], cDefaultTests, argv[0]);
    1018410199                return RTEXITCODE_SUCCESS;
    1018510200            default:
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