VirtualBox

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


Ignore:
Timestamp:
Aug 25, 2024 1:39:38 PM (6 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164577
Message:

Disassembler/ARMv8: Implement decoding of the ldr/str (pre-/post-indexed) variant instructions and add testcases, bugref:10394

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

Legend:

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

    r105857 r105858  
    9494static FNDISPARSEARMV8 disArmV8ParseOption;
    9595static FNDISPARSEARMV8 disArmV8ParseS;
     96static FNDISPARSEARMV8 disArmV8ParseSetPreIndexed;
     97static FNDISPARSEARMV8 disArmV8ParseSetPostIndexed;
    9698/** @}  */
    9799
     
    132134    disArmV8ParseSImmMemOffUnscaled,
    133135    disArmV8ParseOption,
    134     disArmV8ParseS
     136    disArmV8ParseS,
     137    disArmV8ParseSetPreIndexed,
     138    disArmV8ParseSetPostIndexed
    135139};
    136140
     
    568572    }
    569573
     574    return VINF_SUCCESS;
     575}
     576
     577
     578static int disArmV8ParseSetPreIndexed(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     579{
     580    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pInsnParm, pf64Bit);
     581
     582    pParam->fUse |= DISUSE_PRE_INDEXED;
     583    return VINF_SUCCESS;
     584}
     585
     586
     587static int disArmV8ParseSetPostIndexed(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     588{
     589    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pInsnParm, pf64Bit);
     590
     591    pParam->fUse |= DISUSE_POST_INDEXED;
    570592    return VINF_SUCCESS;
    571593}
  • trunk/src/VBox/Disassembler/DisasmFormatArmV8.cpp

    r105848 r105858  
    701701                case kDisArmv8OpParmAddrInGpr:
    702702                {
     703                    Assert(   (pParam->fUse & (DISUSE_PRE_INDEXED | DISUSE_POST_INDEXED))
     704                           != (DISUSE_PRE_INDEXED | DISUSE_POST_INDEXED));
     705                    Assert(   (   RT_BOOL(pParam->fUse & (DISUSE_PRE_INDEXED | DISUSE_POST_INDEXED))
     706                               != RT_BOOL(pParam->fUse & DISUSE_INDEX))
     707                           || !(pParam->fUse & (DISUSE_PRE_INDEXED | DISUSE_POST_INDEXED | DISUSE_INDEX)));
     708
    703709                    PUT_C('[');
    704710
     
    707713                    PUT_STR(pszReg, cchReg);
    708714
    709                     if (pParam->fUse & DISUSE_INDEX)
     715                    if (pParam->fUse & DISUSE_POST_INDEXED)
    710716                    {
    711                         PUT_SZ(", ");
    712 
    713                         pszReg = disasmFormatArmV8Reg(pDis, &pParam->armv8.GprIndex, &cchReg);
    714                         PUT_STR(pszReg, cchReg);
    715                     }
    716                     else if (pParam->armv8.u.offBase)
    717                     {
    718                         PUT_SZ(", #");
     717                        Assert(pParam->armv8.enmExtend == kDisArmv8OpParmExtendNone);
     718                        PUT_SZ("], #");
    719719                        PUT_NUM_S16(pParam->armv8.u.offBase);
    720720                    }
    721 
    722                     if (pParam->armv8.enmExtend != kDisArmv8OpParmExtendNone)
     721                    else
    723722                    {
    724                         PUT_SZ(", ");
    725                         switch (pParam->armv8.enmExtend)
     723                        if (pParam->fUse & DISUSE_INDEX)
    726724                        {
    727                             case kDisArmv8OpParmExtendUxtX: /* UXTX is same as LSL which is preferred by most disassemblers/assemblers. */
    728                             case kDisArmv8OpParmExtendLsl:
    729                                 PUT_SZ("LSL #");
    730                                 break;
    731                             case kDisArmv8OpParmExtendUxtB: PUT_SZ("UXTB #"); break;
    732                             case kDisArmv8OpParmExtendUxtH: PUT_SZ("UXTH #"); break;
    733                             case kDisArmv8OpParmExtendUxtW: PUT_SZ("UXTW #"); break;
    734                             case kDisArmv8OpParmExtendSxtB: PUT_SZ("SXTB #"); break;
    735                             case kDisArmv8OpParmExtendSxtH: PUT_SZ("SXTH #"); break;
    736                             case kDisArmv8OpParmExtendSxtW: PUT_SZ("SXTW #"); break;
    737                             case kDisArmv8OpParmExtendSxtX: PUT_SZ("SXTX #"); break;
    738                             default:
    739                                 AssertFailed();
     725                            PUT_SZ(", ");
     726
     727                            pszReg = disasmFormatArmV8Reg(pDis, &pParam->armv8.GprIndex, &cchReg);
     728                            PUT_STR(pszReg, cchReg);
    740729                        }
    741                         PUT_NUM_8(pParam->armv8.u.cExtend);
     730                        else if (pParam->armv8.u.offBase)
     731                        {
     732                            PUT_SZ(", #");
     733                            PUT_NUM_S16(pParam->armv8.u.offBase);
     734                        }
     735
     736                        if (pParam->armv8.enmExtend != kDisArmv8OpParmExtendNone)
     737                        {
     738                            PUT_SZ(", ");
     739                            switch (pParam->armv8.enmExtend)
     740                            {
     741                                case kDisArmv8OpParmExtendUxtX: /* UXTX is same as LSL which is preferred by most disassemblers/assemblers. */
     742                                case kDisArmv8OpParmExtendLsl:
     743                                    PUT_SZ("LSL #");
     744                                    break;
     745                                case kDisArmv8OpParmExtendUxtB: PUT_SZ("UXTB #"); break;
     746                                case kDisArmv8OpParmExtendUxtH: PUT_SZ("UXTH #"); break;
     747                                case kDisArmv8OpParmExtendUxtW: PUT_SZ("UXTW #"); break;
     748                                case kDisArmv8OpParmExtendSxtB: PUT_SZ("SXTB #"); break;
     749                                case kDisArmv8OpParmExtendSxtH: PUT_SZ("SXTH #"); break;
     750                                case kDisArmv8OpParmExtendSxtW: PUT_SZ("SXTW #"); break;
     751                                case kDisArmv8OpParmExtendSxtX: PUT_SZ("SXTX #"); break;
     752                                default:
     753                                    AssertFailed();
     754                            }
     755                            PUT_NUM_8(pParam->armv8.u.cExtend);
     756                        }
     757
     758                        PUT_C(']');
     759
     760                        if (pParam->fUse & DISUSE_PRE_INDEXED)
     761                            PUT_C('!');
    742762                    }
    743763
    744                     PUT_C(']');
    745764                    break;
    746765                }
  • trunk/src/VBox/Disassembler/DisasmInternal-armv8.h

    r105857 r105858  
    7272    kDisParmParseOption,
    7373    kDisParmParseS,
     74    kDisParmParseSetPreIndexed,
     75    kDisParmParseSetPostIndexed,
    7476    kDisParmParseMax
    7577} DISPARMPARSEIDX;
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp

    r105857 r105858  
    792792
    793793/*
     794 * STP/LDP/STGP/LDPSW - pre-indexed variant.
     795 *
     796 * Note: The opc,L bitfields are concatenated to form an index.
     797 */
     798DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegPairPreIndex)
     799 DIS_ARMV8_OP_EX(0x29800000, "stp",             OP_ARMV8_A64_STP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
     800 DIS_ARMV8_OP_EX(0x29c00000, "ldp",             OP_ARMV8_A64_LDP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
     801    INVALID_OPCODE,
     802    INVALID_OPCODE,
     803 DIS_ARMV8_OP_EX(0xa9800000, "stp",             OP_ARMV8_A64_STP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     804 DIS_ARMV8_OP_EX(0xa9c00000, "ldp",             OP_ARMV8_A64_LDP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     805    INVALID_OPCODE,
     806    INVALID_OPCODE,
     807DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegPairPreIndex)
     808    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            0,  5, 0 /*idxParam*/),
     809    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,           10,  5, 1 /*idxParam*/),
     810    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            5,  5, 2 /*idxParam*/),
     811    DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOff,    15,  7, 2 /*idxParam*/),
     812    DIS_ARMV8_INSN_DECODE(kDisParmParseSetPreIndexed,  0,  0, 2 /*idxParam*/),
     813DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LdStRegPairPreIndex, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
     814                                                kDisArmV8OpcDecodeCollate,
     815                                                RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
     816                                                kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     817
     818
     819/*
     820 * STP/LDP/STGP/LDPSW - post-indexed variant.
     821 *
     822 * Note: The opc,L bitfields are concatenated to form an index.
     823 */
     824DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegPairPostIndex)
     825 DIS_ARMV8_OP_EX(0x28800000, "stp",             OP_ARMV8_A64_STP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
     826 DIS_ARMV8_OP_EX(0x28c00000, "ldp",             OP_ARMV8_A64_LDP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
     827    INVALID_OPCODE,
     828    INVALID_OPCODE,
     829 DIS_ARMV8_OP_EX(0xa8800000, "stp",             OP_ARMV8_A64_STP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     830 DIS_ARMV8_OP_EX(0xa8c00000, "ldp",             OP_ARMV8_A64_LDP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     831    INVALID_OPCODE,
     832    INVALID_OPCODE,
     833DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegPairPostIndex)
     834    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,             0,  5, 0 /*idxParam*/),
     835    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            10,  5, 1 /*idxParam*/),
     836    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,             5,  5, 2 /*idxParam*/),
     837    DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOff,     15,  7, 2 /*idxParam*/),
     838    DIS_ARMV8_INSN_DECODE(kDisParmParseSetPostIndexed,  0,  0, 2 /*idxParam*/),
     839DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LdStRegPairPostIndex, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
     840                                                kDisArmV8OpcDecodeCollate,
     841                                                RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
     842                                                kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     843
     844
     845/*
    794846 * C4.1.94 - Loads and Stores - Load/Store register pair variants
    795847 *
     
    805857DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegPair)
    806858    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
    807     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     859    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPairPostIndex),
    808860    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPairOff),
    809     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     861    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPairPreIndex),
    810862DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegPair, RT_BIT_32(23) | RT_BIT_32(24), 23);
    811863
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S

    r105857 r105858  
    456456        ldp x0, x1, [x28, #504]
    457457
     458        ldp w0, w1, [x28, #4]!
     459        ldp w0, w1, [x28, #-256]!
     460        ldp w0, w1, [x28, #252]!
     461
     462        ldp x0, x1, [x28, #8]!
     463        ldp x0, x1, [x28, #-512]!
     464        ldp x0, x1, [x28, #504]!
     465
     466        ldp w0, w1, [x28], #4
     467        ldp w0, w1, [x28], #-256
     468        ldp w0, w1, [x28], #252
     469
     470        ldp x0, x1, [x28], #8
     471        ldp x0, x1, [x28], #-512
     472        ldp x0, x1, [x28], #504
     473
    458474        ldr  x0, [x1, x2]
    459475        ldr  w0, [x1, x2]
     
    551567        stp x0, x1, [x28, #-512]
    552568        stp x0, x1, [x28, #504]
     569
     570        stp w0, w1, [x28, #4]!
     571        stp w0, w1, [x28, #-256]!
     572        stp w0, w1, [x28, #252]!
     573
     574        stp x0, x1, [x28, #8]!
     575        stp x0, x1, [x28, #-512]!
     576        stp x0, x1, [x28, #504]!
     577
     578        stp w0, w1, [x28], #4
     579        stp w0, w1, [x28], #-256
     580        stp w0, w1, [x28], #252
     581
     582        stp x0, x1, [x28], #8
     583        stp x0, x1, [x28], #-512
     584        stp x0, x1, [x28], #504
    553585
    554586        str  x0, [x1, x2]
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1.cpp

    r105857 r105858  
    9393    { RT_STR_TUPLE("["),                        RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
    9494    { RT_STR_TUPLE("]"),                        RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
     95    { RT_STR_TUPLE("!"),                        RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
    9596    { NULL, 0,                                  RTSCRIPTLEXTOKTYPE_INVALID,    false, 0 }
    9697};
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