VirtualBox

Changeset 105815 in vbox


Ignore:
Timestamp:
Aug 22, 2024 12:25:28 PM (6 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164528
Message:

Disassembler/ARMv8: Started decoding more ldr/str instruction variants, bugref:10394

Location:
trunk
Files:
5 edited

Legend:

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

    r105810 r105815  
    9999    /** Condition flag for the instruction - kArmv8InstrCond_Al if not conditional instruction. */
    100100    DISARMV8INSTRCOND   enmCond;
     101    /** Operand size (for loads/stores primarily). */
     102    uint8_t             cbOperand;
    101103} DIS_STATE_ARMV8_T;
    102104AssertCompile(sizeof(DIS_STATE_ARMV8_T) <= 32);
  • trunk/src/VBox/Disassembler/DisasmCore-armv8.cpp

    r105810 r105815  
    5050 * @remark no DECLCALLBACK() here because it's considered to be internal and
    5151 *         there is no point in enforcing CDECL. */
    52 typedef int FNDISPARSEARMV8(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit);
     52typedef int FNDISPARSEARMV8(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit);
    5353/** Pointer to a disassembler parser function. */
    5454typedef FNDISPARSEARMV8 *PFNDISPARSEARMV8;
     
    7474 * @{ */
    7575static FNDISPARSEARMV8 disArmV8ParseIllegal;
    76 static FNDISPARSEARMV8 disArmV8ParseIs32Bit;
     76static FNDISPARSEARMV8 disArmV8ParseSize;
    7777static FNDISPARSEARMV8 disArmV8ParseImm;
    7878static FNDISPARSEARMV8 disArmV8ParseImmRel;
     
    9696static FNDISDECODEARMV8 disArmV8DecodeIllegal;
    9797static FNDISDECODEARMV8 disArmV8DecodeLookup;
     98static FNDISDECODEARMV8 disArmV8DecodeCollate;
    9899/** @} */
    99100
     
    106107{
    107108    disArmV8ParseIllegal,
    108     disArmV8ParseIs32Bit,
     109    disArmV8ParseSize,
    109110    disArmV8ParseImm,
    110111    disArmV8ParseImmRel,
     
    130131    disArmV8DecodeIllegal,
    131132    disArmV8DecodeLookup,
     133    disArmV8DecodeCollate
    132134};
    133135
     
    135137DECLINLINE(uint32_t) disArmV8ExtractBitVecFromInsn(uint32_t u32Insn, uint8_t idxBitStart, uint8_t cBits)
    136138{
    137     uint32_t fMask = RT_BIT_32(idxBitStart + cBits) - 1;
     139    uint32_t fMask = (uint32_t)(RT_BIT_64(idxBitStart + cBits) - 1);
    138140    return (u32Insn & fMask) >> idxBitStart;
    139141}
     
    152154
    153155
    154 static int disArmV8ParseIllegal(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    155 {
    156     RT_NOREF(pDis, u32Insn, pInsnClass, pParam, pInsnParm, pf64Bit);
     156static int disArmV8ParseIllegal(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     157{
     158    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
    157159    AssertFailed();
    158160    return VERR_INTERNAL_ERROR;
     
    160162
    161163
    162 static int disArmV8ParseIs32Bit(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    163 {
    164     RT_NOREF(pDis, pInsnClass, pParam);
    165 
    166     AssertReturn(pInsnParm->idxBitStart < 32 && pInsnParm->cBits == 1, VERR_INTERNAL_ERROR_2);
    167     *pf64Bit = RT_BOOL(u32Insn & RT_BIT_32(pInsnParm->idxBitStart));
    168     return VINF_SUCCESS;
    169 }
    170 
    171 
    172 static int disArmV8ParseImm(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    173 {
    174     RT_NOREF(pDis, pInsnClass, pf64Bit);
     164static int disArmV8ParseSize(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     165{
     166    RT_NOREF(pInsnClass, pParam);
     167
     168    Assert(pInsnParm->cBits == 2);
     169    uint32_t u32Size = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     170    switch (u32Size)
     171    {
     172        case 0: pDis->armv8.cbOperand = sizeof(uint8_t); break;
     173        case 1: pDis->armv8.cbOperand = sizeof(uint16_t); break;
     174        case 2: pDis->armv8.cbOperand = sizeof(uint32_t); break;
     175        case 3: pDis->armv8.cbOperand = sizeof(uint64_t); break;
     176        default:
     177            AssertReleaseFailed();
     178    }
     179    *pf64Bit =    pDis->armv8.cbOperand == sizeof(uint64_t)
     180               || (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_64BIT);
     181    return VINF_SUCCESS;
     182}
     183
     184
     185static int disArmV8ParseImm(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     186{
     187    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    175188
    176189    AssertReturn(pInsnParm->idxBitStart + pInsnParm->cBits < 32, VERR_INTERNAL_ERROR_2);
     
    199212
    200213
    201 static int disArmV8ParseImmRel(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    202 {
    203     RT_NOREF(pDis, pInsnClass, pf64Bit);
     214static int disArmV8ParseImmRel(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     215{
     216    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    204217
    205218    AssertReturn(pInsnParm->idxBitStart + pInsnParm->cBits < 32, VERR_INTERNAL_ERROR_2);
     
    228241
    229242
    230 static int disArmV8ParseImmAdr(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    231 {
    232     RT_NOREF(pDis, pInsnClass, pf64Bit, pInsnParm);
     243static int disArmV8ParseImmAdr(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     244{
     245    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit, pInsnParm);
    233246
    234247    pParam->uValue  = disArmV8ExtractBitVecFromInsn(u32Insn, 5, 19);
     
    239252
    240253
    241 static int disArmV8ParseReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    242 {
    243     RT_NOREF(pDis, pInsnClass);
     254static int disArmV8ParseReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     255{
     256    RT_NOREF(pDis, pOp, pInsnClass);
    244257    pParam->armv8.Reg.idxGenReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    245258    pParam->armv8.cb            = *pf64Bit ? sizeof(uint64_t) : sizeof(uint32_t);
     
    251264
    252265
    253 static int disArmV8ParseImmsImmrN(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    254 {
    255     RT_NOREF(pDis);
     266static int disArmV8ParseImmsImmrN(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     267{
     268    RT_NOREF(pDis, pOp);
    256269    AssertReturn(pInsnParm->cBits == 13, VERR_INTERNAL_ERROR_2);
    257270
     
    276289
    277290
    278 static int disArmV8ParseHw(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    279 {
    280     RT_NOREF(pDis, pInsnClass, pParam);
     291static int disArmV8ParseHw(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     292{
     293    RT_NOREF(pDis, pOp, pInsnClass, pParam);
    281294    Assert(pInsnParm->cBits == 2);
    282295
     
    298311
    299312
    300 static int disArmV8ParseCond(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    301 {
    302     RT_NOREF(pInsnClass, pParam, pf64Bit);
     313static int disArmV8ParseCond(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     314{
     315    RT_NOREF(pInsnClass, pOp, pParam, pf64Bit);
    303316    Assert(pInsnParm->cBits <= 4);
    304317    if (pParam)
     
    314327
    315328
    316 static int disArmV8ParsePState(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    317 {
    318     RT_NOREF(pDis, u32Insn, pInsnClass, pParam, pInsnParm, pf64Bit);
     329static int disArmV8ParsePState(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     330{
     331    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
    319332    //AssertFailed();
    320333    /** @todo */
     
    323336
    324337
    325 static int disArmV8ParseSysReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    326 {
    327     RT_NOREF(pDis, pInsnClass, pf64Bit);
     338static int disArmV8ParseSysReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     339{
     340    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    328341    AssertReturn(pInsnParm->cBits == 15, VERR_INTERNAL_ERROR_2);
    329342
     
    341354
    342355
    343 static int disArmV8ParseSh12(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    344 {
    345     RT_NOREF(pDis, pInsnClass, pf64Bit);
     356static int disArmV8ParseSh12(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     357{
     358    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    346359    Assert(pInsnParm->cBits == 1);
    347360    if (u32Insn & RT_BIT_32(pInsnParm->idxBitStart))
     
    375388
    376389
    377 static int disArmV8ParseImmTbz(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    378 {
    379     RT_NOREF(pDis, pInsnClass, pf64Bit);
     390static int disArmV8ParseImmTbz(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     391{
     392    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    380393
    381394    AssertReturn(!pInsnParm->idxBitStart && !pInsnParm->cBits, VERR_INTERNAL_ERROR_2);
     
    390403
    391404
    392 static int disArmV8ParseShift(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    393 {
    394     RT_NOREF(pDis, pInsnClass, pf64Bit);
     405static int disArmV8ParseShift(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     406{
     407    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    395408
    396409    AssertReturn(pInsnParm->cBits == 2, VERR_INTERNAL_ERROR_2);
     
    410423
    411424
    412 static int disArmV8ParseShiftAmount(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    413 {
    414     RT_NOREF(pDis, pInsnClass, pf64Bit);
     425static int disArmV8ParseShiftAmount(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     426{
     427    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    415428
    416429    uint32_t u32Amount = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     
    430443
    431444
    432 static int disArmV8ParseImmMemOff(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    433 {
    434     RT_NOREF(pDis, pInsnClass, pf64Bit);
     445static int disArmV8ParseImmMemOff(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     446{
     447    RT_NOREF(pInsnClass, pOp, pf64Bit);
    435448
    436449    AssertReturn(pInsnParm->cBits <= 12, VERR_INTERNAL_ERROR_2);
    437 
    438     uint8_t const uScale = *pf64Bit ? 8 : 4;
    439     pParam->armv8.u.offBase = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits) * uScale;
     450    AssertReturn(pDis->armv8.cbOperand != 0, VERR_INTERNAL_ERROR_2);
     451
     452    pParam->armv8.u.offBase = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     453    switch (pDis->armv8.cbOperand)
     454    {
     455        case sizeof(uint8_t): break;
     456        case sizeof(uint16_t): pParam->armv8.u.offBase <<= 1; break;
     457        case sizeof(uint32_t): pParam->armv8.u.offBase <<= 2; break;
     458        case sizeof(uint64_t): pParam->armv8.u.offBase <<= 3; break;
     459        default:
     460            AssertReleaseFailed();
     461    }
    440462    pParam->armv8.cb = sizeof(uint16_t);
    441463    return VINF_SUCCESS;
     
    461483            return i;
    462484    }
     485
     486    return UINT32_MAX;
     487}
     488
     489
     490static uint32_t disArmV8DecodeCollate(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass)
     491{
     492    RT_NOREF(pDis);
     493
     494    /* Need to build a compact representation of the relevant bits from the mask to create an index. */
     495    uint32_t fMask = pInsnClass->fMask >> pInsnClass->cShift;
     496
     497    /** @todo Optimize. */
     498    uint32_t idx = 0;
     499    uint32_t cShift = 0;
     500    while (fMask)
     501    {
     502        if (fMask & 0x1)
     503        {
     504            idx |= (u32Insn & 1) << cShift;
     505            cShift++;
     506        }
     507
     508        u32Insn >>= 1;
     509        fMask   >>= 1;
     510    }
     511
     512    if (RT_LIKELY(idx < pInsnClass->Hdr.cDecode))
     513        return idx;
    463514
    464515    return UINT32_MAX;
     
    533584    pDis->aParams[3].armv8.enmShift = kDisArmv8OpParmShiftNone;
    534585    pDis->armv8.enmCond             = kDisArmv8InstrCond_Al;
     586    pDis->armv8.cbOperand           = 0;
    535587
    536588    pDis->pCurInstr = &pOp->Opc;
     
    549601           && RT_SUCCESS(rc))
    550602    {
    551         rc = g_apfnDisasm[pDecode->idxParse](pDis, u32Insn, pInsnClass,
     603        rc = g_apfnDisasm[pDecode->idxParse](pDis, u32Insn, pOp, pInsnClass,
    552604                                               pDecode->idxParam != DIS_ARMV8_INSN_PARAM_UNSET
    553605                                             ? &pDis->aParams[pDecode->idxParam]
  • trunk/src/VBox/Disassembler/DisasmInternal-armv8.h

    r105808 r105815  
    5151{
    5252    kDisParmParseNop = 0,
    53     kDisParmParseIs32Bit,
     53    kDisParmParseSize,
    5454    kDisParmParseImm,
    5555    kDisParmParseImmRel,
     
    7777typedef struct DISARMV8OPCODE
    7878{
    79     /** The value of masked bits of the isntruction. */
     79    /** The value of the fixed bits of the instruction. */
    8080    uint32_t            fValue;
     81    /** Special flags for the opcode. */
     82    uint32_t            fFlags;
    8183    /** The generic opcode structure. */
    8284    DISOPCODE           Opc;
     
    113115    kDisArmV8OpcDecodeNop = 0,
    114116    kDisArmV8OpcDecodeLookup,
     117    kDisArmV8OpcDecodeCollate,
    115118    kDisArmV8OpcDecodeMax
    116119} DISARMV8OPCDECODE;
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp

    r105810 r105815  
    4040
    4141#define DIS_ARMV8_OP(a_fValue, a_szOpcode, a_uOpcode, a_fOpType) \
    42     { a_fValue, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
     42    { a_fValue, 0, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
     43#define DIS_ARMV8_OP_EX(a_fValue, a_szOpcode, a_uOpcode, a_fOpType, a_fFlags) \
     44    { a_fValue, a_fFlags, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
    4345
    4446#ifndef DIS_CORE_ONLY
     
    544546
    545547
    546 DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdSt)
     548/* STRB/LDRB/LDRSB/STR/LDR/STRH/LDRH/LDRSH/LDRSW/PRFM
     549 *
     550 * Note: The size,opc bitfields are concatenated to form an index.
     551 */
     552DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegUImmGpr)
     553    DIS_ARMV8_OP(0x39000000, "strb",            OP_ARMV8_A64_STRB,      DISOPTYPE_HARMLESS),
     554    DIS_ARMV8_OP(0x39400000, "ldrb",            OP_ARMV8_A64_LDRB,      DISOPTYPE_HARMLESS),
     555 DIS_ARMV8_OP_EX(0x39800000, "ldrsb",           OP_ARMV8_A64_LDRSB,     DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     556    DIS_ARMV8_OP(0x39c00000, "ldrsb",           OP_ARMV8_A64_LDRSB,     DISOPTYPE_HARMLESS),
     557    DIS_ARMV8_OP(0x79000000, "strh",            OP_ARMV8_A64_STRH,      DISOPTYPE_HARMLESS),
     558    DIS_ARMV8_OP(0x79400000, "ldrh",            OP_ARMV8_A64_LDRH,      DISOPTYPE_HARMLESS),
     559 DIS_ARMV8_OP_EX(0x79800000, "ldrsh",           OP_ARMV8_A64_LDRSH,     DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     560    DIS_ARMV8_OP(0x79c00000, "ldrsh",           OP_ARMV8_A64_LDRSH,     DISOPTYPE_HARMLESS),
     561    DIS_ARMV8_OP(0xb9000000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS),
    547562    DIS_ARMV8_OP(0xb9400000, "ldr",             OP_ARMV8_A64_LDR,       DISOPTYPE_HARMLESS),
    548     DIS_ARMV8_OP(0xb9000000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS),
    549 DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdSt)
    550     DIS_ARMV8_INSN_DECODE(kDisParmParseIs32Bit,       30,  1, DIS_ARMV8_INSN_PARAM_UNSET),
     563 DIS_ARMV8_OP_EX(0xb9800000, "ldrsw",           OP_ARMV8_A64_LDRSW,     DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     564    INVALID_OPCODE,
     565    DIS_ARMV8_OP(0xf9000000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS),
     566    DIS_ARMV8_OP(0xf9400000, "ldr",             OP_ARMV8_A64_LDR,       DISOPTYPE_HARMLESS),
     567    INVALID_OPCODE, /** @todo PRFM */
     568    INVALID_OPCODE,
     569DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegUImmGpr)
     570    DIS_ARMV8_INSN_DECODE(kDisParmParseSize,          30,  2, DIS_ARMV8_INSN_PARAM_UNSET),
    551571    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            0,  5, 0 /*idxParam*/),
    552572    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            5,  5, 1 /*idxParam*/),
    553573    DIS_ARMV8_INSN_DECODE(kDisParmParseImmMemOff,     10, 12, 1 /*idxParam*/),
    554 DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdSt, 0xbfc00000 /*fFixedInsn*/, 0 /*fClass*/,
    555                                                 kDisArmV8OpcDecodeLookup, 0xbfc00000, 0,
     574DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdStRegUImmGpr, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
     575                                                kDisArmV8OpcDecodeCollate,
     576                                                RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
    556577                                                kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     578
     579
     580/*
     581 * C4.1.94 - Loads and Stores - Load/Store register variants
     582 *
     583 * Differentiate further based on the VR field.
     584 *
     585 *     Bit  26
     586 *     +-------------------------------------------
     587 *           0 GPR variants.
     588 *           1 SIMD/FP variants
     589 */
     590DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegUImm)
     591    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImmGpr),
     592    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     593DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegUImm, RT_BIT_32(26), 26);
     594
     595
     596/*
     597 * C4.1.94 - Loads and Stores - Load/Store register variants
     598 *
     599 * Differentiate further based on the op2<14> field.
     600 *
     601 *     Bit  14
     602 *     +-------------------------------------------
     603 *           0 All the other Load/store register variants and Atomic memory operations.
     604 *           1 Load/store register (unsigned immediate).
     605 */
     606DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStReg)
     607    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     608    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImm),
     609DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStReg, RT_BIT_32(24), 24);
     610
     611
     612/*
     613 * C4.1.94 - Loads and Stores
     614 *
     615 * Differentiate further based on the op0<1:0> field.
     616 * Splitting this up because the decoding would get insane otherwise with tables doing cross referencing...
     617 *
     618 *     Bit  29 28
     619 *     +-------------------------------------------
     620 *           0  0 Compare and swap pair / Advanced SIMD loads/stores / Load/store exclusive pair / Load/store exclusive register
     621 *                Load/store ordered / Compare and swap
     622 *           0  1 RCW compare and swap / 128-bit atomic memory instructions / GCS load/store / Load/store memory tags /
     623 *                LDIAPP/STILP / LDAPR/STLR / Load register (literal) / Memory Copy and Set
     624 *           1  0 Load/store no-allocate pair / Load/store register pair /
     625 *           1  1 Load/store register / Atomic memory operations
     626 */
     627DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStOp0Lo)
     628    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     629    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     630    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     631    DIS_ARMV8_DECODE_MAP_ENTRY(LdStReg),
     632DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStOp0Lo, RT_BIT_32(28) | RT_BIT_32(29), 28);
     633
    557634
    558635/*
     
    599676    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /** @todo SVE */
    600677    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Unallocated */
    601     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Load/Stores */
     678    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
    602679    DIS_ARMV8_DECODE_MAP_ENTRY(LogicalAddSubReg),                   /* Data processing (register) (see op1 in C4.1.68). */
    603     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Load/Stores */
     680    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
    604681    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Data processing (SIMD & FP) */
    605682    DIS_ARMV8_DECODE_MAP_ENTRY(DataProcessingImm),                  /* Data processing (immediate). */
     
    607684    DIS_ARMV8_DECODE_MAP_ENTRY(BrExcpSys),                          /* Branches / Exception generation and system instructions. */
    608685    DIS_ARMV8_DECODE_MAP_ENTRY(BrExcpSys),                          /* Branches / Exception generation and system instructions. */
    609     DIS_ARMV8_DECODE_MAP_ENTRY(LdSt),                               /* Load/Stores. */
     686    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
    610687    DIS_ARMV8_DECODE_MAP_ENTRY(DataProcReg),                        /* Data processing (register) (see op1 in C4.1.68). */
    611     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Load/Stores. */
     688    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
    612689    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY                              /* Data processing (SIMD & FP). */
    613690DIS_ARMV8_DECODE_MAP_DEFINE_END_NON_STATIC(DecodeL0, RT_BIT_32(25) | RT_BIT_32(26) | RT_BIT_32(27) | RT_BIT_32(28), 25);
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S

    r105810 r105815  
    373373
    374374        ; Memory loads
     375        ldrb w0, [x28]
     376        ldrb w0, [x28, #1]
     377        ldrb w0, [x28, #4095]
     378
     379        ldrsb w0, [x28]
     380        ldrsb w0, [x28, #1]
     381        ldrsb w0, [x28, #4095]
     382
     383        ldrsb x0, [x28]
     384        ldrsb x0, [x28, #1]
     385        ldrsb x0, [x28, #4095]
     386
     387        ldrh w0, [x28]
     388        ldrh w0, [x28, #2]
     389        ldrh w0, [x28, #1024]
     390
     391        ldrsh w0, [x28]
     392        ldrsh w0, [x28, #2]
     393        ldrsh w0, [x28, #1024]
     394
     395        ldrsh x0, [x28]
     396        ldrsh x0, [x28, #2]
     397        ldrsh x0, [x28, #1024]
     398
    375399        ldr x0, [x28]
    376400        ldr x0, [x28, #8]
     
    381405        ldr w0, [x28, #16380]
    382406
     407        ldrsw x0, [x28]
     408        ldrsw x0, [x28, #4]
     409        ldrsw x0, [x28, #16380]
     410
    383411        ; Memory stores
     412        strb w0, [x28]
     413        strb w0, [x28, #1]
     414        strb w0, [x28, #4095]
     415
     416        strh w0, [x28]
     417        strh w0, [x28, #2]
     418        strh w0, [x28, #1024]
     419
    384420        str x0, [x28]
    385421        str x0, [x28, #8]
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