VirtualBox

Changeset 106746 in vbox


Ignore:
Timestamp:
Oct 28, 2024 1:14:22 PM (4 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
165630
Message:

Disassembler: Decode SIMD ldr/str instructions, bugref:10394

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/dis-armv8.h

    r106744 r106746  
    112112    {
    113113        /** Offset from the base register. */
    114         int16_t                     offBase;
     114        int32_t                     offBase;
    115115        /** Amount of bits to extend. */
    116116        uint8_t                     cExtend;
  • trunk/src/VBox/Disassembler/DisasmCore-armv8.cpp

    r106744 r106746  
    106106static FNDISPARSEARMV8 disArmV8ParseFpScale;
    107107static FNDISPARSEARMV8 disArmV8ParseFpFixupFCvt;
     108static FNDISPARSEARMV8 disArmV8ParseSimdRegSize;
     109static FNDISPARSEARMV8 disArmV8ParseSimdRegSize64;
     110static FNDISPARSEARMV8 disArmV8ParseSimdRegSize128;
    108111static FNDISPARSEARMV8 disArmV8ParseSimdRegScalar;
    109112static FNDISPARSEARMV8 disArmV8ParseImmHImmB;
     
    161164    disArmV8ParseFpScale,
    162165    disArmV8ParseFpFixupFCvt,
     166    disArmV8ParseSimdRegSize,
     167    disArmV8ParseSimdRegSize64,
     168    disArmV8ParseSimdRegSize128,
    163169    disArmV8ParseSimdRegScalar,
    164170    disArmV8ParseImmHImmB,
     
    664670        case sizeof(uint32_t): pParam->armv8.u.offBase <<= 2; break;
    665671        case sizeof(uint64_t): pParam->armv8.u.offBase <<= 3; break;
     672        case 16:               pParam->armv8.u.offBase <<= 4; break;
    666673        default:
    667674            AssertReleaseFailed();
     
    874881
    875882
     883static int disArmV8ParseSimdRegSize(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     884{
     885    RT_NOREF(pOp, pInsnClass, pParam, pf64Bit);
     886
     887    Assert(pInsnParm->cBits == 2);
     888    uint32_t u32Size = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     889    switch (u32Size)
     890    {
     891        case 0: pDis->armv8.cbOperand = sizeof(uint8_t); break;
     892        case 1: pDis->armv8.cbOperand = sizeof(uint16_t); break;
     893        case 2: pDis->armv8.cbOperand = sizeof(uint32_t); break;
     894        case 3: pDis->armv8.cbOperand = sizeof(uint64_t); break;
     895        default:
     896            AssertReleaseFailed();
     897    }
     898
     899    return VINF_SUCCESS;
     900}
     901
     902
     903static int disArmV8ParseSimdRegSize64(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     904{
     905    RT_NOREF(u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
     906
     907    pDis->armv8.cbOperand = sizeof(uint64_t);
     908    return VINF_SUCCESS;
     909}
     910
     911
     912static int disArmV8ParseSimdRegSize128(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     913{
     914    RT_NOREF(u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
     915
     916    pDis->armv8.cbOperand = 16;
     917    return VINF_SUCCESS;
     918}
     919
     920
    876921static int disArmV8ParseSimdRegScalar(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    877922{
    878923    RT_NOREF(pDis, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
    879924
     925    Assert(pDis->armv8.cbOperand != 0);
    880926    Assert(pParam->armv8.enmType == kDisArmv8OpParmNone);
    881927
    882928    pParam->armv8.enmType = kDisArmv8OpParmReg;
    883929    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    884     pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Scalar_64Bit;
     930    switch (pDis->armv8.cbOperand)
     931    {
     932        case sizeof(uint8_t):  pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Scalar_8Bit;   break;
     933        case sizeof(uint16_t): pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Scalar_16Bit;  break;
     934        case sizeof(uint32_t): pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Scalar_32Bit;  break;
     935        case sizeof(uint64_t): pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Scalar_64Bit;  break;
     936        case 16:               pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Scalar_128Bit; break;
     937    }
    885938    return VINF_SUCCESS;
    886939}
  • trunk/src/VBox/Disassembler/DisasmFormatArmV8.cpp

    r106744 r106746  
    367367            return psz;
    368368        }
    369         case kDisOpParamArmV8RegType_Simd_Scalar_32Bit:
    370369        case kDisOpParamArmV8RegType_FpReg_Single:
    371370        {
     
    384383            return psz;
    385384        }
    386         case kDisOpParamArmV8RegType_Simd_Scalar_16Bit:
    387385        case kDisOpParamArmV8RegType_FpReg_Half:
    388386        {
     
    397395            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegSimdScalar8Bit));
    398396            const char *psz = g_aszArmV8RegSimdScalar8Bit[pReg->idReg];
     397            *pcchReg = 2 + !!psz[2];
     398            return psz;
     399        }
     400        case kDisOpParamArmV8RegType_Simd_Scalar_16Bit:
     401        {
     402            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegFpHalf));
     403            const char *psz = g_aszArmV8RegFpHalf[pReg->idReg];
     404            *pcchReg = 2 + !!psz[2];
     405            return psz;
     406        }
     407        case kDisOpParamArmV8RegType_Simd_Scalar_32Bit:
     408        {
     409            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegFpSingle));
     410            const char *psz = g_aszArmV8RegFpSingle[pReg->idReg];
    399411            *pcchReg = 2 + !!psz[2];
    400412            return psz;
     
    835847                        {
    836848                            PUT_SZ(", #");
    837                             PUT_NUM_S16(pParam->armv8.u.offBase);
     849                            if (   pParam->armv8.u.offBase >= INT16_MIN
     850                                && pParam->armv8.u.offBase <= INT16_MAX)
     851                                PUT_NUM_S16(pParam->armv8.u.offBase);
     852                            else
     853                                PUT_NUM_S32(pParam->armv8.u.offBase);
    838854                        }
    839855
  • trunk/src/VBox/Disassembler/DisasmInternal-armv8.h

    r106739 r106746  
    8484    kDisParmParseFpScale,
    8585    kDisParmParseFpFixupFCvt,
     86    kDisParmParseSimdRegSize,
     87    kDisParmParseSimdRegSize64,
     88    kDisParmParseSimdRegSize128,
    8689    kDisParmParseSimdRegScalar,
    8790    kDisParmParseImmHImmB,
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64-ld-st.cpp.h

    r106694 r106746  
    5858
    5959
     60/* SIMD STR/LDR */
     61DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegUImmSimd)
     62    DIS_ARMV8_INSN_DECODE(kDisParmParseSimdRegSize,   30,  2, DIS_ARMV8_INSN_PARAM_UNSET),
     63    DIS_ARMV8_INSN_DECODE(kDisParmParseSimdRegScalar,  0,  5, 0 /*idxParam*/),
     64    DIS_ARMV8_INSN_DECODE(kDisParmParseAddrGprSp,      5,  5, 1 /*idxParam*/),
     65    DIS_ARMV8_INSN_DECODE(kDisParmParseImmMemOff,     10, 12, 1 /*idxParam*/),
     66DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER_ALTERNATIVE(LdStRegUImmSimd128)
     67    DIS_ARMV8_INSN_DECODE(kDisParmParseSimdRegSize128, 0,  0, DIS_ARMV8_INSN_PARAM_UNSET),
     68    DIS_ARMV8_INSN_DECODE(kDisParmParseSimdRegScalar,  0,  5, 0 /*idxParam*/),
     69    DIS_ARMV8_INSN_DECODE(kDisParmParseAddrGprSp,      5,  5, 1 /*idxParam*/),
     70    DIS_ARMV8_INSN_DECODE(kDisParmParseImmMemOff,     10, 12, 1 /*idxParam*/),
     71DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegUImmSimd)
     72    DIS_ARMV8_OP(           0x3d000000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS),
     73    DIS_ARMV8_OP(           0x3d400000, "ldr",             OP_ARMV8_A64_LDR,       DISOPTYPE_HARMLESS),
     74    DIS_ARMV8_OP_ALT_DECODE(0x3d800000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS, LdStRegUImmSimd128), /** @todo size == 0. */
     75    DIS_ARMV8_OP_ALT_DECODE(0x3dc00000, "ldr",             OP_ARMV8_A64_LDR,       DISOPTYPE_HARMLESS, LdStRegUImmSimd128), /** @todo size == 0. */
     76DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END(LdStRegUImmSimd, 0x3fc00000 /*fFixedInsn*/,
     77                                       kDisArmV8OpcDecodeNop,
     78                                       RT_BIT_32(22) | RT_BIT_32(23), 22);
     79
     80
    6081/*
    6182 * C4.1.94 - Loads and Stores - Load/Store register variants
     
    7091DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegUImm)
    7192    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImmGpr),
    72     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     93    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImmSimd),
    7394DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegUImm, RT_BIT_32(26), 26);
    7495
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64-simd-fp.cpp.h

    r106649 r106746  
    472472 */
    473473DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(DataProcSimdScalarShiftByImm)
     474    DIS_ARMV8_INSN_DECODE(kDisParmParseSimdRegSize64,   0,  0, DIS_ARMV8_INSN_PARAM_UNSET),
    474475    DIS_ARMV8_INSN_DECODE(kDisParmParseSimdRegScalar,   0,  5, 0 /*idxParam*/),
    475476    DIS_ARMV8_INSN_DECODE(kDisParmParseSimdRegScalar,   5,  5, 1 /*idxParam*/),
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S

    r106739 r106746  
    13711371
    13721372
     1373        ; SIMD memory loads
     1374        ldr b0, [x0]
     1375        ldr b0, [x0, #4095]
     1376
     1377        ldr b31, [sp]
     1378        ldr b31, [sp, #4095]
     1379
     1380        ldr h0, [x0]
     1381        ldr h0, [x0, #8190]
     1382
     1383        ldr h31, [sp]
     1384        ldr h31, [sp, #8190]
     1385
     1386        ldr s0, [x0]
     1387        ldr s0, [x0, #16380]
     1388
     1389        ldr s31, [sp]
     1390        ldr s31, [sp, #16380]
     1391
     1392        ldr d0, [x0]
     1393        ldr d0, [x0, #32760]
     1394
     1395        ldr d31, [sp]
     1396        ldr d31, [sp, #32760]
     1397
     1398        ldr q0, [x0]
     1399        ldr q0, [x0, #65520]
     1400
     1401        ldr q31, [sp]
     1402        ldr q31, [sp, #65520]
     1403
     1404
     1405        ; SIMD memory stores
     1406        str b0, [x0]
     1407        str b0, [x0, #4095]
     1408
     1409        str b31, [sp]
     1410        str b31, [sp, #4095]
     1411
     1412        str h0, [x0]
     1413        str h0, [x0, #8190]
     1414
     1415        str h31, [sp]
     1416        str h31, [sp, #8190]
     1417
     1418        str s0, [x0]
     1419        str s0, [x0, #16380]
     1420
     1421        str s31, [sp]
     1422        str s31, [sp, #16380]
     1423
     1424        str d0, [x0]
     1425        str d0, [x0, #32760]
     1426
     1427        str d31, [sp]
     1428        str d31, [sp, #32760]
     1429
     1430        str q0, [x0]
     1431        str q0, [x0, #65520]
     1432
     1433        str q31, [sp]
     1434        str q31, [sp, #65520]
     1435
     1436
    13731437        ; Add/subtract with carry
    13741438
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