VirtualBox

Changeset 105857 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 25, 2024 12:22:39 PM (3 months ago)
Author:
vboxsync
Message:

Disassembler/ARMv8: Implement decoding of the ldr/str (unscaled immedate) 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

    r105848 r105857  
    9191static FNDISPARSEARMV8 disArmV8ParseImmMemOff;
    9292static FNDISPARSEARMV8 disArmV8ParseSImmMemOff;
     93static FNDISPARSEARMV8 disArmV8ParseSImmMemOffUnscaled;
    9394static FNDISPARSEARMV8 disArmV8ParseOption;
    9495static FNDISPARSEARMV8 disArmV8ParseS;
     
    129130    disArmV8ParseImmMemOff,
    130131    disArmV8ParseSImmMemOff,
     132    disArmV8ParseSImmMemOffUnscaled,
    131133    disArmV8ParseOption,
    132134    disArmV8ParseS
     
    485487static int disArmV8ParseSImmMemOff(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    486488{
    487     RT_NOREF(pInsnClass, pf64Bit);
     489    RT_NOREF(pDis, pInsnClass, pf64Bit);
    488490
    489491    AssertReturn(pInsnParm->cBits <= 7, VERR_INTERNAL_ERROR_2);
     
    495497    pParam->armv8.u.offBase = disArmV8ExtractBitVecFromInsnSignExtend(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    496498    pParam->armv8.u.offBase <<= (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_32BIT) ? 2 : 3;
    497     pDis->armv8.cbOperand   =   (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_32BIT) ? sizeof(uint32_t) : sizeof(uint64_t);
     499    return VINF_SUCCESS;
     500}
     501
     502
     503static int disArmV8ParseSImmMemOffUnscaled(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     504{
     505    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
     506
     507    AssertReturn(pInsnParm->cBits <= 9, VERR_INTERNAL_ERROR_2);
     508    pParam->armv8.u.offBase = disArmV8ExtractBitVecFromInsnSignExtend(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    498509    return VINF_SUCCESS;
    499510}
  • trunk/src/VBox/Disassembler/DisasmInternal-armv8.h

    r105848 r105857  
    6969    kDisParmParseImmMemOff,
    7070    kDisParmParseSImmMemOff,
     71    kDisParmParseSImmMemOffUnscaled,
    7172    kDisParmParseOption,
    7273    kDisParmParseS,
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp

    r105848 r105857  
    594594
    595595
    596 /* STRB/LDRB/LDRSB/STR/LDR/STRH/LDRH/LDRSH/LDRSW/PRFM
     596/*
     597 * STRB/LDRB/LDRSB/STR/LDR/STRH/LDRH/LDRSH/LDRSW/PRFM
    597598 *
    598599 * Note: The size,opc bitfields are concatenated to form an index.
     
    656657 *           1  1 Load/store register (pac)
    657658 */
    658 DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp_0_1)
     659DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp2_11_1)
    659660    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo */
    660661    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo */
    661662    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOff),
    662663    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo */
    663 DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp_0_1, RT_BIT_32(11) | RT_BIT_32(11), 10);
     664DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp2_11_1, RT_BIT_32(10) | RT_BIT_32(11), 10);
     665
     666
     667/*
     668 * STURB/LDURB/LDURSB/STURH/LDURH/LDURSH/STUR/LDUR/LDURSW/PRFUM
     669 *
     670 * Note: The size,opc bitfields are concatenated to form an index.
     671 */
     672DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegUnscaledImmGpr)
     673    DIS_ARMV8_OP(0x38000000, "sturb",           OP_ARMV8_A64_STURB,     DISOPTYPE_HARMLESS),
     674    DIS_ARMV8_OP(0x38400000, "ldurb",           OP_ARMV8_A64_LDURB,     DISOPTYPE_HARMLESS),
     675 DIS_ARMV8_OP_EX(0x38800000, "ldursb",          OP_ARMV8_A64_LDURSB,    DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     676    DIS_ARMV8_OP(0x38c00000, "ldursb",          OP_ARMV8_A64_LDURSB,    DISOPTYPE_HARMLESS),
     677    DIS_ARMV8_OP(0x78000000, "sturh",           OP_ARMV8_A64_STURH,     DISOPTYPE_HARMLESS),
     678    DIS_ARMV8_OP(0x78400000, "ldurh",           OP_ARMV8_A64_LDURH,     DISOPTYPE_HARMLESS),
     679 DIS_ARMV8_OP_EX(0x78800000, "ldursh",          OP_ARMV8_A64_LDURSH,    DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     680    DIS_ARMV8_OP(0x78c00000, "ldursh",          OP_ARMV8_A64_LDURSH,    DISOPTYPE_HARMLESS),
     681    DIS_ARMV8_OP(0xb8000000, "stur",            OP_ARMV8_A64_STUR,      DISOPTYPE_HARMLESS),
     682    DIS_ARMV8_OP(0xb8400000, "ldur",            OP_ARMV8_A64_LDUR,      DISOPTYPE_HARMLESS),
     683 DIS_ARMV8_OP_EX(0xb8800000, "ldursw",          OP_ARMV8_A64_LDURSW,    DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
     684    INVALID_OPCODE,
     685    DIS_ARMV8_OP(0xf8000000, "stur",            OP_ARMV8_A64_STUR,      DISOPTYPE_HARMLESS),
     686    DIS_ARMV8_OP(0xf8400000, "ldur",            OP_ARMV8_A64_LDUR,      DISOPTYPE_HARMLESS),
     687    INVALID_OPCODE, /** @todo PRFUM */
     688    INVALID_OPCODE,
     689DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegUnscaledImmGpr)
     690    DIS_ARMV8_INSN_DECODE(kDisParmParseSize,               30,  2, DIS_ARMV8_INSN_PARAM_UNSET),
     691    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,                 0,  5, 0 /*idxParam*/),
     692    DIS_ARMV8_INSN_DECODE(kDisParmParseReg,                 5,  5, 1 /*idxParam*/),
     693    DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOffUnscaled, 12,  9, 1 /*idxParam*/),
     694DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdStRegUnscaledImmGpr, 0xffe00c00 /*fFixedInsn*/, 0 /*fClass*/,
     695                                                kDisArmV8OpcDecodeCollate,
     696                                                RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
     697                                                kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     698
     699
     700/*
     701 * C4.1.94 - Loads and Stores - Load/Store register (register offset) variants
     702 *
     703 * Differentiate further based on the VR field.
     704 *
     705 *     Bit  26
     706 *     +-------------------------------------------
     707 *           0 GPR variants.
     708 *           1 SIMD/FP variants
     709 */
     710DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegUnscaledImm)
     711    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUnscaledImmGpr),
     712    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
     713DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegUnscaledImm, RT_BIT_32(26), 26);
     714
     715
     716/*
     717 * C4.1.94 - Loads and Stores - Load/Store register variants
     718 *
     719 * Differentiate further based on the op2<1:0> field.
     720 *
     721 *     Bit  11 10
     722 *     +-------------------------------------------
     723 *           0  0 Load/store register (unscaled immediate)
     724 *           0  1 Load/store register (immediate post-indexed)
     725 *           1  0 Load/store register (unprivileged)
     726 *           1  1 Load/store register (immediate pre-indexed)
     727 */
     728DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp2_11_0)
     729    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUnscaledImm),
     730    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo */
     731    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo */
     732    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo */
     733DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp2_11_0, RT_BIT_32(10) | RT_BIT_32(11), 10);
    664734
    665735
     
    674744 *           1 Atomic memory operations / Load/store register (register offset) / Load/store register (pac).
    675745 */
    676 DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp11)
    677     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,         /** @todo */
    678     DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp_0_1),
    679 DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp11, RT_BIT_32(21), 21);
     746DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp2_11)
     747    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp2_11_0),
     748    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp2_11_1),
     749DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp2_11, RT_BIT_32(21), 21);
    680750
    681751
     
    691761 */
    692762DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStReg)
    693     DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp11),
     763    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp2_11),
    694764    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImm),
    695765DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStReg, RT_BIT_32(24), 24);
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S

    r105848 r105857  
    410410        ldrsw x0, [x28, #16380]
    411411
     412        ldurb w0, [x28]
     413        ldurb w0, [x28, #-256]
     414        ldurb w0, [x28, #255]
     415
     416        ldursb w0, [x28]
     417        ldursb w0, [x28, #-256]
     418        ldursb w0, [x28, #255]
     419
     420        ldursb x0, [x28]
     421        ldursb x0, [x28, #-256]
     422        ldursb x0, [x28, #255]
     423
     424        ldurh w0, [x28]
     425        ldurh w0, [x28, #-256]
     426        ldurh w0, [x28, #255]
     427
     428        ldursh w0, [x28]
     429        ldursh w0, [x28, #-256]
     430        ldursh w0, [x28, #255]
     431
     432        ldursh x0, [x28]
     433        ldursh x0, [x28, #-256]
     434        ldursh x0, [x28, #255]
     435
     436        ldur x0, [x28]
     437        ldur x0, [x28, #-256]
     438        ldur x0, [x28, #255]
     439
     440        ldur w0, [x28]
     441        ldur w0, [x28, #-256]
     442        ldur w0, [x28, #255]
     443
     444        ldursw x0, [x28]
     445        ldursw x0, [x28, #-256]
     446        ldursw x0, [x28, #255]
     447
    412448        ldp w0, w1, [x28]
    413449        ldp w0, w1, [x28, #4]
     
    488524        str w0, [x28, #4]
    489525        str w0, [x28, #16380]
     526
     527
     528        sturb w0, [x28]
     529        sturb w0, [x28, #-256]
     530        sturb w0, [x28, #255]
     531
     532        sturh w0, [x28]
     533        sturh w0, [x28, #-256]
     534        sturh w0, [x28, #255]
     535
     536        stur x0, [x28]
     537        stur x0, [x28, #-256]
     538        stur x0, [x28, #255]
     539
     540        stur w0, [x28]
     541        stur w0, [x28, #-256]
     542        stur w0, [x28, #255]
    490543
    491544        stp w0, w1, [x28]
  • trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1.cpp

    r105848 r105857  
    383383            RTTestIPrintf(RTTESTLVL_ALWAYS, "%s\n", szOutput);
    384384        }
     385        else
     386            break;
    385387
    386388        /* Check with size-only. */
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