VirtualBox

Changeset 106805 in vbox for trunk/src/VBox/Disassembler


Ignore:
Timestamp:
Oct 31, 2024 10:54:16 AM (6 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
165704
Message:

Disassembler: Decode RCW compare and swap and RCW compare and swap pair instructions, bugref:10394

Location:
trunk/src/VBox/Disassembler
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Disassembler/DisasmCore-armv8.cpp

    r106791 r106805  
    8787static FNDISPARSEARMV8 disArmV8ParseAddrGprSp;
    8888static FNDISPARSEARMV8 disArmV8ParseRegFixed31;
     89static FNDISPARSEARMV8 disArmV8ParseGprCount;
    8990static FNDISPARSEARMV8 disArmV8ParseImmsImmrN;
    9091static FNDISPARSEARMV8 disArmV8ParseHw;
     
    152153    disArmV8ParseAddrGprSp,
    153154    disArmV8ParseRegFixed31,
     155    disArmV8ParseGprCount,
    154156    disArmV8ParseImmsImmrN,
    155157    disArmV8ParseHw,
     
    341343    pParam->armv8.enmType = kDisArmv8OpParmReg;
    342344
     345    pParam->armv8.Op.Reg.cRegs = 1;
    343346    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    344347    if (*pf64Bit || (pParam->armv8.enmType == kDisArmv8OpParmAddrInGpr))
     
    356359
    357360    pParam->armv8.enmType = kDisArmv8OpParmReg;
     361    pParam->armv8.Op.Reg.cRegs = 1;
    358362    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    359363    pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Gpr_32Bit;
     
    368372
    369373    pParam->armv8.enmType = kDisArmv8OpParmReg;
     374    pParam->armv8.Op.Reg.cRegs = 1;
    370375    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    371376    pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Gpr_64Bit;
     
    380385
    381386    pParam->armv8.enmType = kDisArmv8OpParmReg;
     387    pParam->armv8.Op.Reg.cRegs = 1;
    382388    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    383389    if (pParam->armv8.Op.Reg.idReg == 31)
     
    396402    Assert(pParam->armv8.enmType != kDisArmv8OpParmNone);
    397403
     404    pParam->armv8.GprIndex.cRegs      = 1;
    398405    pParam->armv8.GprIndex.idReg      = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    399406    pParam->armv8.GprIndex.enmRegType = kDisOpParamArmV8RegType_Gpr_64Bit; /* Might get overwritten later on. */
     
    409416
    410417    pParam->armv8.enmType           = kDisArmv8OpParmReg;
     418    pParam->armv8.Op.Reg.cRegs      = 1;
    411419    pParam->armv8.Op.Reg.idReg      = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    412420    pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Vector;
     
    422430
    423431    pParam->armv8.enmType = kDisArmv8OpParmAddrInGpr;
     432    pParam->armv8.Op.Reg.cRegs = 1;
    424433    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    425434    if (pParam->armv8.Op.Reg.idReg == 31)
     
    438447    if (disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits) != 31)
    439448        return VERR_DIS_INVALID_OPCODE;
     449    return VINF_SUCCESS;
     450}
     451
     452
     453static int disArmV8ParseGprCount(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     454{
     455    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
     456
     457    /* This is special as it doesn't really parse the instruction but sets the register count of the given parameter based on the number if bits. */
     458    Assert(pInsnParm->cBits <= 2);
     459    Assert(pInsnParm->idxBitStart == 0);
     460    Assert(pParam->armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_64Bit);
     461    pParam->armv8.Op.Reg.cRegs      = pInsnParm->cBits;
    440462    return VINF_SUCCESS;
    441463}
     
    869891
    870892    pParam->armv8.enmType = kDisArmv8OpParmReg;
     893    pParam->armv8.Op.Reg.cRegs = 1;
    871894    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    872895    switch (pDis->armv8.enmFpType)
     
    9881011
    9891012    pParam->armv8.enmType = kDisArmv8OpParmReg;
     1013    pParam->armv8.Op.Reg.cRegs = 1;
    9901014    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    9911015    switch (pDis->armv8.cbOperand)
  • trunk/src/VBox/Disassembler/DisasmFormatArmV8.cpp

    r106791 r106805  
    870870                    else
    871871                    {
    872                         size_t cchTmp;
    873                         const char *pszTmp = disasmFormatArmV8Reg(pDis, pParam->armv8.Op.Reg.enmRegType,
    874                                                                   pParam->armv8.Op.Reg.idReg, &cchTmp);
    875                         PUT_STR(pszTmp, cchTmp);
    876 
    877                         if (   pParam->armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Simd_Vector
    878                             && pParam->armv8.Op.Reg.enmVecType != kDisOpParamArmV8VecRegType_None)
     872                        if (pParam->armv8.Op.Reg.cRegs > 1)
    879873                        {
    880                             PUT_C('.');
    881                             pszTmp = disasmFormatArmV8VecRegType(pParam->armv8.Op.Reg.enmVecType, &cchTmp);
     874                            for (uint8_t idReg = pParam->armv8.Op.Reg.idReg; idReg < (pParam->armv8.Op.Reg.idReg + pParam->armv8.Op.Reg.cRegs); idReg++)
     875                            {
     876                                if (idReg > pParam->armv8.Op.Reg.idReg)
     877                                    PUT_C(',');
     878                                PUT_C(' '); /** @todo Make the indenting configurable. */
     879
     880                                size_t cchTmp;
     881                                const char *pszTmp = disasmFormatArmV8Reg(pDis, pParam->armv8.Op.Reg.enmRegType,
     882                                                                          idReg, &cchTmp);
     883                                PUT_STR(pszTmp, cchTmp);
     884
     885                                if (   pParam->armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Simd_Vector
     886                                    && pParam->armv8.Op.Reg.enmVecType != kDisOpParamArmV8VecRegType_None)
     887                                {
     888                                    PUT_C('.');
     889                                    pszTmp = disasmFormatArmV8VecRegType(pParam->armv8.Op.Reg.enmVecType, &cchTmp);
     890                                    PUT_STR(pszTmp, cchTmp);
     891                                }
     892                            }
     893                        }
     894                        else
     895                        {
     896                            size_t cchTmp;
     897                            const char *pszTmp = disasmFormatArmV8Reg(pDis, pParam->armv8.Op.Reg.enmRegType,
     898                                                                      pParam->armv8.Op.Reg.idReg, &cchTmp);
    882899                            PUT_STR(pszTmp, cchTmp);
     900
     901                            if (   pParam->armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Simd_Vector
     902                                && pParam->armv8.Op.Reg.enmVecType != kDisOpParamArmV8VecRegType_None)
     903                            {
     904                                PUT_C('.');
     905                                pszTmp = disasmFormatArmV8VecRegType(pParam->armv8.Op.Reg.enmVecType, &cchTmp);
     906                                PUT_STR(pszTmp, cchTmp);
     907                            }
    883908                        }
    884909                    }
  • trunk/src/VBox/Disassembler/DisasmInternal-armv8.h

    r106791 r106805  
    6464    kDisParmParseAddrGprSp,
    6565    kDisParmParseRegFixed31,
     66    kDisParmParseGprCount,
    6667    kDisParmParseImmsImmrN,
    6768    kDisParmParseHw,
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64-ld-st.cpp.h

    r106791 r106805  
    10931093
    10941094
     1095/* C4.1.94.6 - RCW compare and swap. */
     1096DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRcwCmpSwp)
     1097    DIS_ARMV8_INSN_DECODE(kDisParmParseGprZr64,        16,  5, 0 /*idxParam*/),
     1098    DIS_ARMV8_INSN_DECODE(kDisParmParseGprZr64,         0,  5, 1 /*idxParam*/),
     1099    DIS_ARMV8_INSN_DECODE(kDisParmParseAddrGprSp,       5,  5, 2 /*idxParam*/),
     1100DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRcwCmpSwp)
     1101    DIS_ARMV8_OP(0x19200800, "rcwcas",          OP_ARMV8_A64_RCWCAS,    DISOPTYPE_HARMLESS), /* FEAT_THE */
     1102    DIS_ARMV8_OP(0x19600800, "rcwcasl",         OP_ARMV8_A64_RCWCASL,   DISOPTYPE_HARMLESS), /* FEAT_THE */
     1103    DIS_ARMV8_OP(0x19a00800, "rcwcasa",         OP_ARMV8_A64_RCWCASA,   DISOPTYPE_HARMLESS), /* FEAT_THE */
     1104    DIS_ARMV8_OP(0x19e00800, "rcwcasal",        OP_ARMV8_A64_RCWCASAL,  DISOPTYPE_HARMLESS), /* FEAT_THE */
     1105    DIS_ARMV8_OP(0x59200800, "rcwscas",         OP_ARMV8_A64_RCWSCAS,   DISOPTYPE_HARMLESS), /* FEAT_THE */
     1106    DIS_ARMV8_OP(0x59600800, "rcwscasl",        OP_ARMV8_A64_RCWSCASL,  DISOPTYPE_HARMLESS), /* FEAT_THE */
     1107    DIS_ARMV8_OP(0x59a00800, "rcwscasa",        OP_ARMV8_A64_RCWSCASA,  DISOPTYPE_HARMLESS), /* FEAT_THE */
     1108    DIS_ARMV8_OP(0x59e00800, "rcwscasal",       OP_ARMV8_A64_RCWSCASAL, DISOPTYPE_HARMLESS), /* FEAT_THE */
     1109DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END(LdStRcwCmpSwp, 0xffe0fc00 /*fFixedInsn*/,
     1110                                       kDisArmV8OpcDecodeCollate,
     1111                                       RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30), 22);
     1112
     1113
     1114/* C4.1.94.6 - RCW compare and swap pair. */
     1115DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRcwCmpSwpPair)
     1116    DIS_ARMV8_INSN_DECODE(kDisParmParseGprZr64,        16,  5, 0 /*idxParam*/),
     1117    DIS_ARMV8_INSN_DECODE(kDisParmParseGprCount,        0,  2, 0 /*idxParam*/),
     1118    DIS_ARMV8_INSN_DECODE(kDisParmParseGprZr64,         0,  5, 1 /*idxParam*/),
     1119    DIS_ARMV8_INSN_DECODE(kDisParmParseGprCount,        0,  2, 1 /*idxParam*/),
     1120    DIS_ARMV8_INSN_DECODE(kDisParmParseAddrGprSp,       5,  5, 2 /*idxParam*/),
     1121DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRcwCmpSwpPair)
     1122    DIS_ARMV8_OP(0x19200c00, "rcwcasp",         OP_ARMV8_A64_RCWCASP,    DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1123    DIS_ARMV8_OP(0x19600c00, "rcwcaspl",        OP_ARMV8_A64_RCWCASPL,   DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1124    DIS_ARMV8_OP(0x19a00c00, "rcwcaspa",        OP_ARMV8_A64_RCWCASPA,   DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1125    DIS_ARMV8_OP(0x19e00c00, "rcwcaspal",       OP_ARMV8_A64_RCWCASPAL,  DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1126    DIS_ARMV8_OP(0x59200c00, "rcwscasp",        OP_ARMV8_A64_RCWSCASP,   DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1127    DIS_ARMV8_OP(0x59600c00, "rcwscaspl",       OP_ARMV8_A64_RCWSCASPL,  DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1128    DIS_ARMV8_OP(0x59a00c00, "rcwscaspa",       OP_ARMV8_A64_RCWSCASPA,  DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1129    DIS_ARMV8_OP(0x59e00c00, "rcwscaspal",      OP_ARMV8_A64_RCWSCASPAL, DISOPTYPE_HARMLESS), /* FEAT_D128 && FEAT_THE */
     1130DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END(LdStRcwCmpSwpPair, 0xffe0fc00 /*fFixedInsn*/,
     1131                                       kDisArmV8OpcDecodeCollate,
     1132                                       RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30), 22);
     1133
     1134
    10951135/**
    10961136 * C4.1.94 - Loads and Stores
    10971137 *
     1138 * Differentiate between the RCW compare and swap (pair) and 128-bit atomic instructions.
     1139 */
     1140DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRcwCmpSwp128BitAtomic)
     1141    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo 128-bit atomic instructions */
     1142    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
     1143    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRcwCmpSwp),
     1144    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRcwCmpSwpPair),
     1145DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRcwCmpSwp128BitAtomic, RT_BIT_32(10) | RT_BIT_32(11), 10);
     1146
     1147
     1148/**
     1149 * C4.1.94 - Loads and Stores
     1150 *
    10981151 * Differentiate between further based on op0<3> (bit 31).
    10991152 */
    11001153DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStBit28_1_Bit29_0_Bit24_1_Bit21_1)
    1101     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo RCW compare and swap (pair) / 128-bit atomic memory operations */
     1154    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRcwCmpSwp128BitAtomic),
    11021155    DIS_ARMV8_DECODE_MAP_ENTRY(LdStMemTags),
    11031156DIS_ARMV8_DECODE_MAP_DEFINE_END_SINGLE_BIT(LdStBit28_1_Bit29_0_Bit24_1_Bit21_1, 31);
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S

    r106791 r106805  
    41514151
    41524152        ;
     4153        ; RCW compare and swap
     4154        ;
     4155        ;.cpu generic+the+d128
     4156
     4157        ;rcwcas x0,   x1, [x3] - Requires FEAT_THE
     4158        ;rcwcas xzr, xzr, [sp] - Requires FEAT_THE
     4159
     4160        ;rcwcasl x0,   x1, [x3] - Requires FEAT_THE
     4161        ;rcwcasl xzr, xzr, [sp] - Requires FEAT_THE
     4162
     4163        ;rcwcasa x0,   x1, [x3] - Requires FEAT_THE
     4164        ;rcwcasa xzr, xzr, [sp] - Requires FEAT_THE
     4165
     4166        ;rcwcasal x0,   x1, [x3] - Requires FEAT_THE
     4167        ;rcwcasal xzr, xzr, [sp] - Requires FEAT_THE
     4168
     4169        ;rcwscas x0,   x1, [x3] - Requires FEAT_THE
     4170        ;rcwscas xzr, xzr, [sp] - Requires FEAT_THE
     4171
     4172        ;rcwscasl x0,   x1, [x3] - Requires FEAT_THE
     4173        ;rcwscasl xzr, xzr, [sp] - Requires FEAT_THE
     4174
     4175        ;rcwscasa x0,   x1, [x3] - Requires FEAT_THE
     4176        ;rcwscasa xzr, xzr, [sp] - Requires FEAT_THE
     4177
     4178        ;rcwscasal x0,   x1, [x3] - Requires FEAT_THE
     4179        ;rcwscasal xzr, xzr, [sp] - Requires FEAT_THE
     4180
     4181        ;
     4182        ; RCW compare and swap pair
     4183        ;
     4184
     4185        ;rcwcasp x0, x1, x2, x3, [x4] - Requires FEAT_THE && FEAT_D128
     4186        ;rcwcasp x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4187
     4188        ;rcwcaspl x0, x1, x2, x3, [x4] - Requires FEAT_THE && FEAT_D128
     4189        ;rcwcaspl x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4190
     4191        ;rcwcaspa x0, x1, x2, x3, [x3] - Requires FEAT_THE && FEAT_D128
     4192        ;rcwcaspa x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4193
     4194        ;rcwcaspal x0, x1, x2, x3, [x3] - Requires FEAT_THE && FEAT_D128
     4195        ;rcwcaspal x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4196
     4197        ;rcwscasp x0, x1, x2, x3, [x3] - Requires FEAT_THE && FEAT_D128
     4198        ;rcwscasp x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4199
     4200        ;rcwscaspl x0, x1, x2, x3, [x3] - Requires FEAT_THE && FEAT_D128
     4201        ;rcwscaspl x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4202
     4203        ;rcwscaspa x0, x1, x2, x3, [x3] - Requires FEAT_THE && FEAT_D128
     4204        ;rcwscaspa x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4205
     4206        ;rcwscaspal x0, x1, x2, x3, [x3] - Requires FEAT_THE && FEAT_D128
     4207        ;rcwscaspal x0, x1, x2, x3, [sp] - Requires FEAT_THE && FEAT_D128
     4208
     4209        ;
    41534210        ; Keep last so the testcase can catch errors in
    41544211        ; the disassembly of the last instruction.
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1.cpp

    r106791 r106805  
    9292    { RT_STR_TUPLE(".cpu"),                     RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  0 },
    9393    { RT_STR_TUPLE("generic+mte"),              RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  0 },
     94    { RT_STR_TUPLE("generic+the+d128"),         RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  0 },
    9495    { RT_STR_TUPLE("_testproca64"),             RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  0 },
    9596    { RT_STR_TUPLE("_testproca64_endproc"),     RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  0 },
Note: See TracChangeset for help on using the changeset viewer.

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