VirtualBox

Changeset 105830 in vbox


Ignore:
Timestamp:
Aug 22, 2024 6:13:37 PM (5 weeks ago)
Author:
vboxsync
Message:

Disassembler/ARMv8: Implement decoding of the ldp/stp unsigned variant instructions and add testcases, bugref:10394

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

Legend:

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

    r105815 r105830  
    8989static FNDISPARSEARMV8 disArmV8ParseShiftAmount;
    9090static FNDISPARSEARMV8 disArmV8ParseImmMemOff;
     91static FNDISPARSEARMV8 disArmV8ParseSImmMemOff;
    9192/** @}  */
    9293
     
    122123    disArmV8ParseShift,
    123124    disArmV8ParseShiftAmount,
    124     disArmV8ParseImmMemOff
     125    disArmV8ParseImmMemOff,
     126    disArmV8ParseSImmMemOff
    125127};
    126128
     
    460462            AssertReleaseFailed();
    461463    }
    462     pParam->armv8.cb = sizeof(uint16_t);
     464    pParam->armv8.cb = sizeof(int16_t);
     465    return VINF_SUCCESS;
     466}
     467
     468
     469static int disArmV8ParseSImmMemOff(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     470{
     471    RT_NOREF(pInsnClass, pf64Bit);
     472
     473    AssertReturn(pInsnParm->cBits <= 7, VERR_INTERNAL_ERROR_2);
     474    AssertReturn(   (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_32BIT)
     475                 || (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_64BIT),
     476                 VERR_INTERNAL_ERROR_2);
     477
     478    pParam->armv8.cb = sizeof(int16_t);
     479    pParam->armv8.u.offBase = disArmV8ExtractBitVecFromInsnSignExtend(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     480    pParam->armv8.u.offBase <<= (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_32BIT) ? 2 : 3;
     481    pDis->armv8.cbOperand   =   (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_32BIT) ? sizeof(uint32_t) : sizeof(uint64_t);
    463482    return VINF_SUCCESS;
    464483}
     
    591610    bool f64Bit = false;
    592611
     612    /** @todo Get rid of these and move them to the per opcode
     613     * (SF can become a decoder step). */
    593614    if (pInsnClass->fClass & DISARMV8INSNCLASS_F_SF)
    594615        f64Bit = RT_BOOL(u32Insn & RT_BIT_32(31));
    595616    else if (pInsnClass->fClass & DISARMV8INSNCLASS_F_FORCED_64BIT)
     617        f64Bit = true;
     618
     619    if (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_32BIT)
     620        f64Bit = false;
     621    else if (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_64BIT)
    596622        f64Bit = true;
    597623
  • trunk/src/VBox/Disassembler/DisasmFormatArmV8.cpp

    r105810 r105830  
    724724                    {
    725725                        PUT_SZ(", #");
    726                         PUT_NUM_16(pParam->armv8.u.offBase);
     726                        PUT_NUM_S16(pParam->armv8.u.offBase);
    727727                    }
    728728
  • trunk/src/VBox/Disassembler/DisasmInternal-armv8.h

    r105815 r105830  
    6767    kDisParmParseShiftAmount,
    6868    kDisParmParseImmMemOff,
     69    kDisParmParseSImmMemOff,
    6970    kDisParmParseMax
    7071} DISPARMPARSEIDX;
     
    184185/** The instruction class is using the 64-bit register encoding only. */
    185186#define DISARMV8INSNCLASS_F_FORCED_64BIT                RT_BIT_32(2)
     187/** The instruction class is using the 32-bit register encoding only. */
     188#define DISARMV8INSNCLASS_F_FORCED_32BIT                RT_BIT_32(3)
    186189
    187190
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp

    r105815 r105830  
    611611
    612612/*
     613 * STP/LDP/STGP/LDPSW
     614 *
     615 * Note: The opc,L bitfields are concatenated to form an index.
     616 */
     617DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegPairOff)
     618 DIS_ARMV8_OP_EX(0x29000000, "stp",             OP_ARMV8_A64_STP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
     619 DIS_ARMV8_OP_EX(0x29400000, "ldp",             OP_ARMV8_A64_LDP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
     620    INVALID_OPCODE,
     621    INVALID_OPCODE,
     622 DIS_ARMV8_OP_EX(0xa9000000, "stp",             OP_ARMV8_A64_STP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     623 DIS_ARMV8_OP_EX(0xa9400000, "ldp",             OP_ARMV8_A64_LDP,       DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     624    INVALID_OPCODE,
     625    INVALID_OPCODE,
     626DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegPairOff)
     627    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            0,  5, 0 /*idxParam*/),
     628    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,           10,  5, 1 /*idxParam*/),
     629    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            5,  5, 2 /*idxParam*/),
     630    DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOff,    15,  7, 2 /*idxParam*/),
     631DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LdStRegPairOff, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
     632                                                kDisArmV8OpcDecodeCollate,
     633                                                RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
     634                                                kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     635
     636
     637/*
     638 * C4.1.94 - Loads and Stores - Load/Store register pair variants
     639 *
     640 * Differentiate further based on the op2<14:13> field.
     641 *
     642 *     Bit  24 23
     643 *     +-------------------------------------------
     644 *           0  0 Load/store no-allocate pair (offset)
     645 *           0  1 Load/store register pair (post-indexed)
     646 *           1  0 Load/store register pair (offset).
     647 *           1  1 Load/store register pair (pre-indexed).
     648 */
     649DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegPair)
     650    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     651    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     652    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPairOff),
     653    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     654DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegPair, RT_BIT_32(23) | RT_BIT_32(24), 23);
     655
     656
     657/*
    613658 * C4.1.94 - Loads and Stores
    614659 *
     
    628673    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
    629674    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
    630     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     675    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPair),
    631676    DIS_ARMV8_DECODE_MAP_ENTRY(LdStReg),
    632677DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStOp0Lo, RT_BIT_32(28) | RT_BIT_32(29), 28);
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S

    r105815 r105830  
    2828.private_extern _TestProcA64
    2929_TestProcA64:
     30
    3031        ; Miscellaneous instructions without a parameter
    3132        nop
     
    409410        ldrsw x0, [x28, #16380]
    410411
     412        ldp w0, w1, [x28]
     413        ldp w0, w1, [x28, #4]
     414        ldp w0, w1, [x28, #-256]
     415        ldp w0, w1, [x28, #252]
     416
     417        ldp x0, x1, [x28]
     418        ldp x0, x1, [x28, #8]
     419        ldp x0, x1, [x28, #-512]
     420        ldp x0, x1, [x28, #504]
     421
    411422        ; Memory stores
    412423        strb w0, [x28]
     
    425436        str w0, [x28, #4]
    426437        str w0, [x28, #16380]
     438
     439        stp w0, w1, [x28]
     440        stp w0, w1, [x28, #4]
     441        stp w0, w1, [x28, #-256]
     442        stp w0, w1, [x28, #252]
     443
     444        stp x0, x1, [x28]
     445        stp x0, x1, [x28, #8]
     446        stp x0, x1, [x28, #-512]
     447        stp x0, x1, [x28, #504]
    427448
    428449        ; Conditional compare
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