VirtualBox

Changeset 106004 in vbox


Ignore:
Timestamp:
Sep 10, 2024 11:51:08 AM (3 months ago)
Author:
vboxsync
Message:

Disassembler/ArmV8: Updates and start on floating point and SIMD instructions, bugref:10394

Location:
trunk
Files:
1 added
7 edited

Legend:

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

    r105850 r106004  
    44
    55/*
    6  * Copyright (C) 2023 Oracle and/or its affiliates.
     6 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
    77 *
    88 * This file is part of VirtualBox base platform packages, as
     
    4949/** @addtogroup grp_dis   VBox Disassembler
    5050 * @{ */
     51
     52typedef enum DISOPPARAMARMV8REGTYPE
     53{
     54    kDisOpParamArmV8RegType_Gpr_32Bit = 0,
     55    kDisOpParamArmV8RegType_Gpr_64Bit,
     56    kDisOpParamArmV8RegType_FpReg_Single,
     57    kDisOpParamArmV8RegType_FpReg_Double,
     58    kDisOpParamArmV8RegType_FpReg_Half,
     59    kDisOpParamArmV8RegType_Simd_Scalar_64Bit,
     60    kDisOpParamArmV8RegType_Simd_Scalar_128Bit,
     61    kDisOpParamArmV8RegType_Simd_Vector
     62} DISOPPARAMARMV8REGTYPE;
     63
    5164/**
    52  * GPR definition
     65 * Register definition
    5366 */
    5467typedef struct
    5568{
    56     /** Flag whether this is a 32-bit or 64-bit register. */
    57                      bool    f32Bit : 1;
    58     /** The register index. */
    59     RT_GCC_EXTENSION uint8_t idGpr  : 7;
     69    /** The register type (DISOPPARAMARMV8REGTYPE). */
     70    uint8_t  enmRegType;
     71    /** The register ID. */
     72    uint8_t  idReg;
    6073} DISOPPARAMARMV8REG;
    61 AssertCompileSize(DISOPPARAMARMV8REG, sizeof(uint8_t));
     74AssertCompileSize(DISOPPARAMARMV8REG, sizeof(uint16_t));
    6275/** Pointer to a disassembler GPR. */
    6376typedef DISOPPARAMARMV8REG *PDISOPPARAMARMV8REG;
     
    7588    /** Any extension applied (DISARMV8OPPARMEXTEND). */
    7689    uint8_t                         enmExtend;
    77     /** The register operand. */
     90    /** The operand. */
    7891    union
    7992    {
    8093        /** General register index (DISGREG_XXX), applicable if DISUSE_REG_GEN32
    8194         * or DISUSE_REG_GEN64 is set in fUse. */
    82         DISOPPARAMARMV8REG          Gpr;
     95        DISOPPARAMARMV8REG          Reg;
    8396        /** IPRT System register encoding. */
    8497        uint16_t                    idSysReg;
    85         /**
    86          *  Conditional parameter (not a register I know but this saves us struct size and
    87          *  and these never occur at the same time, might get renamed if everything is done).
    88          *
    89          *  DISARMV8INSTRCOND
    90          */
     98        /** Conditional parameter - DISARMV8INSTRCOND */
    9199        uint8_t                     enmCond;
    92     } Reg;
     100        /** PState field (for MSR) - DISARMV8INSTRPSTATE. */
     101        uint8_t                     enmPState;
     102    } Op;
    93103    /** Register holding the offset. Applicable if DISUSE_INDEX is set in fUse. */
    94104    DISOPPARAMARMV8REG              GprIndex;
     
    117127    /** Condition flag for the instruction - kArmv8InstrCond_Al if not conditional instruction. */
    118128    DISARMV8INSTRCOND   enmCond;
     129    /** Floating point type for floating point instructions. */
     130    DISARMV8INSTRFPTYPE enmFpType;
    119131    /** Operand size (for loads/stores primarily). */
    120132    uint8_t             cbOperand;
  • trunk/include/VBox/disopcode-armv8.h

    r105849 r106004  
    163163    OP_ARMV8_A64_ESB,
    164164    OP_ARMV8_A64_EXTR,
     165    OP_ARMV8_A64_FABS,
     166    OP_ARMV8_A64_FADD,
     167    OP_ARMV8_A64_FCCMP,
     168    OP_ARMV8_A64_FCCMPE,
     169    OP_ARMV8_A64_FCMP,
     170    OP_ARMV8_A64_FCMPE,
     171    OP_ARMV8_A64_FCSEL,
     172    OP_ARMV8_A64_FCVT,
     173    OP_ARMV8_A64_FCVTZS,
     174    OP_ARMV8_A64_FCVTZU,
     175    OP_ARMV8_A64_FDIV,
     176    OP_ARMV8_A64_FMADD,
     177    OP_ARMV8_A64_FMAX,
     178    OP_ARMV8_A64_FMAXNM,
     179    OP_ARMV8_A64_FMIN,
     180    OP_ARMV8_A64_FMINNM,
     181    OP_ARMV8_A64_FMOV,
     182    OP_ARMV8_A64_FMSUB,
     183    OP_ARMV8_A64_FMUL,
     184    OP_ARMV8_A64_FNEG,
     185    OP_ARMV8_A64_FNMADD,
     186    OP_ARMV8_A64_FNMSUB,
     187    OP_ARMV8_A64_FNMUL,
     188    OP_ARMV8_A64_FRINT32X,
     189    OP_ARMV8_A64_FRINT32Z,
     190    OP_ARMV8_A64_FRINT64X,
     191    OP_ARMV8_A64_FRINT64Z,
     192    OP_ARMV8_A64_FRINTA,
     193    OP_ARMV8_A64_FRINTI,
     194    OP_ARMV8_A64_FRINTM,
     195    OP_ARMV8_A64_FRINTN,
     196    OP_ARMV8_A64_FRINTP,
     197    OP_ARMV8_A64_FRINTX,
     198    OP_ARMV8_A64_FRINTZ,
     199    OP_ARMV8_A64_FSQRT,
     200    OP_ARMV8_A64_FSUB,
    165201    OP_ARMV8_A64_GMI,
    166202    OP_ARMV8_A64_HINT,
     
    371407    OP_ARMV8_A64_SBFM,
    372408    OP_ARMV8_A64_SBFX,
     409    OP_ARMV8_A64_SCVTF,
    373410    OP_ARMV8_A64_SDIV,
    374411    OP_ARMV8_A64_SETF8,
     
    400437    OP_ARMV8_A64_SEV,
    401438    OP_ARMV8_A64_SEVL,
     439    OP_ARMV8_A64_SHL,
    402440    OP_ARMV8_A64_SMADDL,
    403441    OP_ARMV8_A64_SMC,
     
    408446    OP_ARMV8_A64_SMULH,
    409447    OP_ARMV8_A64_SMULL,
     448    OP_ARMV8_A64_SQRSHRN,
     449    OP_ARMV8_A64_SQSHL,
     450    OP_ARMV8_A64_SQSHRN,
     451    OP_ARMV8_A64_SRSHR,
     452    OP_ARMV8_A64_SRSRA,
    410453    OP_ARMV8_A64_SSBB,
     454    OP_ARMV8_A64_SSHR,
     455    OP_ARMV8_A64_SSRA,
    411456    OP_ARMV8_A64_ST2G,
    412457    OP_ARMV8_A64_ST64B,
     
    498543    OP_ARMV8_A64_UBFM,
    499544    OP_ARMV8_A64_UBFX,
     545    OP_ARMV8_A64_UCVTF,
    500546    OP_ARMV8_A64_UDF,
    501547    OP_ARMV8_A64_UDIV,
     
    553599
    554600
     601/** Armv8 PState fields.    */
     602typedef enum DISARMV8INSTRPSTATE
     603{
     604    kDisArmv8InstrPState_SPSel = 0,
     605    kDisArmv8InstrPState_DAIFSet,
     606    kDisArmv8InstrPState_DAIFClr,
     607    kDisArmv8InstrPState_UAO,
     608    kDisArmv8InstrPState_PAN,
     609    kDisArmv8InstrPState_ALLINT,
     610    kDisArmv8InstrPState_PM,
     611    kDisArmv8InstrPState_SSBS,
     612    kDisArmv8InstrPState_DIT,
     613    kDisArmv8InstrPState_SVCRSM,
     614    kDisArmv8InstrPState_SVCRZA,
     615    kDisArmv8InstrPState_SVCRSMZA,
     616    kDisArmv8InstrPState_TCO
     617} DISARMV8INSTRPSTATE;
     618
     619
     620/**
     621 * Floating point types.
     622 */
     623typedef enum DISARMV8INSTRFPTYPE
     624{
     625    kDisArmv8InstrFpType_Invalid = 0,
     626    kDisArmv8InstrFpType_Single,
     627    kDisArmv8InstrFpType_Double,
     628    kDisArmv8InstrFpType_Half
     629} DISARMV8INSTRFPTYPE;
     630
     631
    555632/** @defgroup grp_dis_opparam_armv8 Opcode parameters (DISOPCODE::fParam1,
    556633 *            DISOPCODE::fParam2, DISOPCODE::fParam3)
     
    566643    /** Parameter is not used. */
    567644    kDisArmv8OpParmNone = 0,
    568     /** Imediate value. */
     645    /** Immediate value. */
    569646    kDisArmv8OpParmImm,
    570647    /** Relative address immediate. */
    571648    kDisArmv8OpParmImmRel,
    572     /** General purpose register. */
    573     kDisArmv8OpParmGpr,
     649    /** Register. */
     650    kDisArmv8OpParmReg,
    574651    /** System register. */
    575652    kDisArmv8OpParmSysReg,
     
    577654    kDisArmv8OpParmAddrInGpr,
    578655    /** Conditional as parameter (CCMN/CCMP). */
    579     kDisArmv8OpParmCond
     656    kDisArmv8OpParmCond,
     657    /** PSTATE field (specific to MSR). */
     658    kDisArmv8OpParmPState
    580659} DISARMV8OPPARM;
    581660
  • trunk/src/VBox/Disassembler/DisasmCore-armv8.cpp

    r105858 r106004  
    55
    66/*
    7  * Copyright (C) 2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    7878static FNDISPARSEARMV8 disArmV8ParseImmRel;
    7979static FNDISPARSEARMV8 disArmV8ParseImmAdr;
     80static FNDISPARSEARMV8 disArmV8ParseImmZero;
    8081static FNDISPARSEARMV8 disArmV8ParseReg;
    8182static FNDISPARSEARMV8 disArmV8ParseRegOff;
     
    9697static FNDISPARSEARMV8 disArmV8ParseSetPreIndexed;
    9798static FNDISPARSEARMV8 disArmV8ParseSetPostIndexed;
     99static FNDISPARSEARMV8 disArmV8ParseFpType;
     100static FNDISPARSEARMV8 disArmV8ParseFpReg;
     101static FNDISPARSEARMV8 disArmV8ParseFpScale;
     102static FNDISPARSEARMV8 disArmV8ParseFpFixupFCvt;
     103static FNDISPARSEARMV8 disArmV8ParseSimdRegScalar;
     104static FNDISPARSEARMV8 disArmV8ParseImmHImmB;
    98105/** @}  */
    99106
     
    118125    disArmV8ParseImmRel,
    119126    disArmV8ParseImmAdr,
     127    disArmV8ParseImmZero,
    120128    disArmV8ParseReg,
    121129    disArmV8ParseRegOff,
     
    136144    disArmV8ParseS,
    137145    disArmV8ParseSetPreIndexed,
    138     disArmV8ParseSetPostIndexed
     146    disArmV8ParseSetPostIndexed,
     147    disArmV8ParseFpType,
     148    disArmV8ParseFpReg,
     149    disArmV8ParseFpScale,
     150    disArmV8ParseFpFixupFCvt,
     151    disArmV8ParseSimdRegScalar,
     152    disArmV8ParseImmHImmB
    139153};
    140154
     
    266280
    267281
     282static int disArmV8ParseImmZero(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     283{
     284    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pf64Bit, pInsnParm);
     285
     286    pParam->uValue  = 0;
     287    pParam->fUse |= DISUSE_IMMEDIATE8;
     288    return VINF_SUCCESS;
     289}
     290
     291
    268292static int disArmV8ParseReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    269293{
    270294    RT_NOREF(pDis, pOp, pInsnClass);
    271     pParam->armv8.Reg.Gpr.idGpr = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     295    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    272296    if (*pf64Bit || (pParam->armv8.enmType == kDisArmv8OpParmAddrInGpr))
    273         pParam->armv8.Reg.Gpr.f32Bit = false;
     297        pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Gpr_64Bit;
    274298    else
    275         pParam->armv8.Reg.Gpr.f32Bit = true;
     299        pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Gpr_32Bit;
    276300    return VINF_SUCCESS;
    277301}
     
    281305{
    282306    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
    283     pParam->armv8.GprIndex.idGpr = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    284     pParam->armv8.Reg.Gpr.f32Bit = false; /* Might get overwritten later on. */
    285     pParam->fUse                |= DISUSE_INDEX;
     307    pParam->armv8.GprIndex.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     308    pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Gpr_64Bit; /* Might get overwritten later on. */
     309    pParam->fUse                   |= DISUSE_INDEX;
    286310    return VINF_SUCCESS;
    287311}
     
    343367        /* Conditional as a parameter (CCMP/CCMN). */
    344368        Assert(pParam->armv8.enmType == kDisArmv8OpParmCond);
    345         pParam->armv8.Reg.enmCond = (DISARMV8INSTRCOND)disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     369        pParam->armv8.Op.enmCond = (DISARMV8INSTRCOND)disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    346370    }
    347371    else /* Conditional for the base instruction. */
     
    353377static int disArmV8ParsePState(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
    354378{
    355     RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
    356     //AssertFailed();
    357     /** @todo */
     379    RT_NOREF(pDis, pOp, pInsnClass, pInsnParm, pf64Bit);
     380    uint32_t u32Op1 = disArmV8ExtractBitVecFromInsn(u32Insn, 16, 3);
     381    uint32_t u32Op2 = disArmV8ExtractBitVecFromInsn(u32Insn,  5, 3);
     382
     383    Assert(pDis->aParams[1].armv8.enmType == kDisArmv8OpParmImm);
     384    Assert(pDis->aParams[1].armv8.cb      == sizeof(uint8_t));
     385    Assert(pDis->aParams[1].uValue        <  16); /* 4 bit field. */
     386
     387    uint8_t bCRm = (uint8_t)pDis->aParams[1].uValue;
     388
     389    /* See C6.2.249 for the defined values. */
     390    switch ((u32Op1 << 3) | u32Op2)
     391    {
     392        case 0x03: /* 000 011 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_UAO;     break;
     393        case 0x04: /* 000 100 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_PAN;     break;
     394        case 0x05: /* 000 101 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_SPSel;   break;
     395        case 0x08: /* 001 000 */
     396        {
     397            pDis->aParams[1].uValue = bCRm & 0x1;
     398            switch (bCRm & 0xe)
     399            {
     400                case 0: /* 000x */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_ALLINT; break;
     401                case 2: /* 001x */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_PM;     break;
     402                default:
     403                    return VERR_DIS_INVALID_OPCODE;
     404            }
     405            break;
     406        }
     407        case 0x19: /* 011 001 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_SSBS;    break;
     408        case 0x1a: /* 011 010 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_DIT;     break;
     409        case 0x1b: /* 011 011 */
     410        {
     411            pDis->aParams[1].uValue = bCRm & 0x1;
     412            switch (bCRm & 0xe)
     413            {
     414                case 2: /* 001x */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_SVCRSM;   break;
     415                case 4: /* 010x */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_SVCRZA;   break;
     416                case 6: /* 011x */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_SVCRSMZA; break;
     417                default:
     418                    return VERR_DIS_INVALID_OPCODE;
     419            }
     420            break;
     421        }
     422        case 0x1c: /* 011 100 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_TCO;     break;
     423        case 0x1e: /* 011 110 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_DAIFSet; break;
     424        case 0x1f: /* 011 111 */ pParam->armv8.Op.enmPState = kDisArmv8InstrPState_DAIFClr; break;
     425        default:
     426            return VERR_DIS_INVALID_OPCODE;
     427    }
     428
    358429    return VINF_SUCCESS;
    359430}
     
    367438    /* Assumes a op0:op1:CRn:CRm:op2 encoding in the instruction starting at the given bit position. */
    368439    uint32_t u32ImmRaw = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
    369     pParam->armv8.Reg.idSysReg = ARMV8_AARCH64_SYSREG_ID_CREATE(2 + ((u32ImmRaw >> 14) & 0x1),
    370                                                                 (u32ImmRaw >> 11) & 0x7,
    371                                                                 (u32ImmRaw >> 7) & 0xf,
    372                                                                 (u32ImmRaw >> 3) & 0xf,
    373                                                                 u32ImmRaw & 0x7);
     440    pParam->armv8.Op.idSysReg = ARMV8_AARCH64_SYSREG_ID_CREATE(2 + ((u32ImmRaw >> 14) & 0x1),
     441                                                               (u32ImmRaw >> 11) & 0x7,
     442                                                               (u32ImmRaw >> 7) & 0xf,
     443                                                               (u32ImmRaw >> 3) & 0xf,
     444                                                               u32ImmRaw & 0x7);
    374445    pParam->armv8.cb = 0;
    375446    pParam->fUse    |= DISUSE_REG_SYSTEM;
     
    539610
    540611    /* When option<0> is set to 0, the 32-bit name of the GPR is used, 64-bit when option<0> is set to 1. */
    541     pParam->armv8.GprIndex.f32Bit = !RT_BOOL(u32Opt & 0x1);
     612    pParam->armv8.GprIndex.enmRegType =   RT_BOOL(u32Opt & 0x1)
     613                                        ? kDisOpParamArmV8RegType_Gpr_64Bit
     614                                        : kDisOpParamArmV8RegType_Gpr_32Bit;
    542615    return VINF_SUCCESS;
    543616}
     
    594667
    595668
     669static int disArmV8ParseFpType(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     670{
     671    RT_NOREF(pOp, pInsnClass, pParam, pf64Bit);
     672
     673    Assert(pDis->armv8.enmFpType == kDisArmv8InstrFpType_Invalid);
     674    uint32_t u32FpType = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     675    switch (u32FpType)
     676    {
     677        case 0: pDis->armv8.enmFpType = kDisArmv8InstrFpType_Single; break;
     678        case 1: pDis->armv8.enmFpType = kDisArmv8InstrFpType_Double; break;
     679        case 3: pDis->armv8.enmFpType = kDisArmv8InstrFpType_Half; break;
     680        default: return VERR_DIS_INVALID_OPCODE;
     681    }
     682    return VINF_SUCCESS;
     683}
     684
     685
     686static int disArmV8ParseFpReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     687{
     688    RT_NOREF(pOp, pInsnClass, pParam, pf64Bit);
     689
     690    Assert(pDis->armv8.enmFpType != kDisArmv8InstrFpType_Invalid);
     691    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     692    switch (pDis->armv8.enmFpType)
     693    {
     694        case kDisArmv8InstrFpType_Single: pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_FpReg_Single; break;
     695        case kDisArmv8InstrFpType_Double: pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_FpReg_Double; break;
     696        case kDisArmv8InstrFpType_Half:   pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_FpReg_Half;   break;
     697        default: return VERR_DIS_INVALID_OPCODE;
     698    }
     699    return VINF_SUCCESS;
     700}
     701
     702
     703static int disArmV8ParseFpScale(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     704{
     705    RT_NOREF(pDis, pOp, pInsnClass);
     706    Assert(pDis->armv8.enmFpType != kDisArmv8InstrFpType_Invalid);
     707
     708    uint32_t u32Scale = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     709    if (   !*pf64Bit
     710        && (u32Scale & RT_BIT_32(5)) == 0)
     711        return VERR_DIS_INVALID_OPCODE;
     712
     713    pParam->uValue   = 64 - u32Scale;
     714    pParam->armv8.cb = sizeof(uint8_t);
     715    pParam->fUse    |= DISUSE_IMMEDIATE8;
     716    return VINF_SUCCESS;
     717}
     718
     719
     720static int disArmV8ParseFpFixupFCvt(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     721{
     722    RT_NOREF(pDis, pInsnClass, pParam, pInsnParm, pf64Bit);
     723
     724    /* Nothing to do if this isn't about fcvt. */
     725    if (pOp->Opc.uOpcode != OP_ARMV8_A64_FCVT)
     726        return VINF_SUCCESS;
     727
     728    Assert(pDis->armv8.enmFpType != kDisArmv8InstrFpType_Invalid);
     729    Assert(   pDis->aParams[0].armv8.enmType == kDisArmv8OpParmReg
     730           && pDis->aParams[1].armv8.enmType == kDisArmv8OpParmReg);
     731
     732    /* Convert source and guest register floating point types to the correct widths. */
     733    uint32_t u32Opc = (u32Insn & (RT_BIT_32(15) | RT_BIT_32(16))) >> 15;
     734#ifdef VBOX_STRICT
     735    uint32_t u32FpType = disArmV8ExtractBitVecFromInsn(u32Insn, 22, 2);
     736    Assert(   u32Opc != u32FpType
     737           && u32Opc != 2);
     738#endif
     739
     740    static const DISOPPARAMARMV8REGTYPE s_aOpc2FpWidth[] =
     741    {
     742        kDisOpParamArmV8RegType_FpReg_Single,
     743        kDisOpParamArmV8RegType_FpReg_Double,
     744        (DISOPPARAMARMV8REGTYPE)UINT8_MAX,    /* Invalid encoding. */
     745        kDisOpParamArmV8RegType_FpReg_Half
     746    };
     747
     748    pDis->aParams[0].armv8.Op.Reg.enmRegType = s_aOpc2FpWidth[u32Opc];
     749    return VINF_SUCCESS;
     750}
     751
     752
     753static int disArmV8ParseSimdRegScalar(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     754{
     755    RT_NOREF(pDis, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
     756
     757    pParam->armv8.Op.Reg.idReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     758    pParam->armv8.Op.Reg.enmRegType = kDisOpParamArmV8RegType_Simd_Scalar_64Bit;
     759    return VINF_SUCCESS;
     760}
     761
     762
     763static int disArmV8ParseImmHImmB(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
     764{
     765    RT_NOREF(pDis, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
     766
     767    Assert(pInsnParm->cBits == 7);
     768    uint32_t u32ImmRaw = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     769    if (!(u32ImmRaw & RT_BIT_32(6))) /* immh == 0xxx is reserved for the scalar variant. */
     770        return VERR_DIS_INVALID_OPCODE;
     771
     772    pParam->uValue = 2 * 64 - u32ImmRaw;
     773    pParam->armv8.cb = sizeof(uint8_t);
     774    pParam->fUse |= DISUSE_IMMEDIATE8;
     775    return VINF_SUCCESS;
     776}
     777
     778
    596779static uint32_t disArmV8DecodeIllegal(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass)
    597780{
     
    661844        {
    662845            /* Check for possible MOV conversion for the register variant when: shift is None and the first source is the zero register. */
    663             Assert(pDis->aParams[1].armv8.enmType == kDisArmv8OpParmGpr);
    664 
    665             if (   pDis->aParams[2].armv8.enmType == kDisArmv8OpParmGpr
     846            Assert(pDis->aParams[1].armv8.enmType == kDisArmv8OpParmReg);
     847            Assert(   pDis->aParams[1].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_32Bit
     848                   || pDis->aParams[1].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_64Bit);
     849
     850            if (   pDis->aParams[2].armv8.enmType == kDisArmv8OpParmReg
    666851                && pDis->aParams[2].armv8.enmExtend == kDisArmv8OpParmExtendNone
    667                 && pDis->aParams[1].armv8.Reg.Gpr.idGpr == ARMV8_A64_REG_XZR)
     852                && pDis->aParams[1].armv8.Op.Reg.idReg == ARMV8_A64_REG_XZR)
    668853            {
    669854                DIS_ARMV8_ALIAS_CREATE(Mov, "mov", OP_ARMV8_A64_MOV, DISOPTYPE_HARMLESS);
     
    677862        case OP_ARMV8_A64_SUBS:
    678863        {
    679             Assert(pDis->aParams[0].armv8.enmType == kDisArmv8OpParmGpr);
    680             if (pDis->aParams[0].armv8.Reg.Gpr.idGpr == ARMV8_A64_REG_XZR)
     864            Assert(pDis->aParams[0].armv8.enmType == kDisArmv8OpParmReg);
     865            Assert(   pDis->aParams[0].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_32Bit
     866                   || pDis->aParams[0].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_64Bit);
     867
     868            if (pDis->aParams[0].armv8.Op.Reg.idReg == ARMV8_A64_REG_XZR)
    681869            {
    682870                DIS_ARMV8_ALIAS_CREATE(Cmp, "cmp", OP_ARMV8_A64_CMP, DISOPTYPE_HARMLESS);
     
    701889    AssertPtr(pOp);
    702890    AssertPtr(pDis);
    703     Assert((u32Insn & pInsnClass->fFixedInsn) == pOp->fValue);
     891    //Assert((u32Insn & pInsnClass->fFixedInsn) == pOp->fValue);
     892    if ((u32Insn & pInsnClass->fFixedInsn) != pOp->fValue)
     893        return VERR_DIS_INVALID_OPCODE;
    704894
    705895    /* Should contain the parameter type on input. */
     
    717907    pDis->aParams[3].armv8.enmExtend = kDisArmv8OpParmExtendNone;
    718908    pDis->armv8.enmCond              = kDisArmv8InstrCond_Al;
     909    pDis->armv8.enmFpType            = kDisArmv8InstrFpType_Invalid;
    719910    pDis->armv8.cbOperand            = 0;
    720911
  • trunk/src/VBox/Disassembler/DisasmFormatArmV8.cpp

    r105858 r106004  
    11/* $Id$ */
    22/** @file
    3  * VBox Disassembler - Yasm(/Nasm) Style Formatter.
     3 * VBox Disassembler - ARMv8 Style Formatter.
    44 */
    55
    66/*
    7  * Copyright (C) 2008-2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2008-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    5555    "x16",   "x17",   "x18",   "x19",   "x20",   "x21",   "x22",   "x23",   "x24",   "x25",   "x26",  "x27",  "x28",  "x29",  "x30",  "xzr"
    5656};
     57static const char g_aszArmV8RegFpSingle[32][4] =
     58{
     59    "s0\0",  "s1\0",  "s2\0",  "s3\0",  "s4\0",  "s5\0",  "s6\0",  "s7\0",  "s8\0",  "s9\0",  "s10",  "s11",  "s12",  "s13",  "s14",  "s15",
     60    "s16",   "s17",   "s18",   "s19",   "s20",   "s21",   "s22",   "s23",   "s24",   "s25",   "s26",  "s27",  "s28",  "s29",  "s30",  "s31"
     61};
     62static const char g_aszArmV8RegFpDouble[32][4] =
     63{
     64    "d0\0",  "d1\0",  "d2\0",  "d3\0",  "d4\0",  "d5\0",  "d6\0",  "d7\0",  "d8\0",  "d9\0",  "d10",  "d11",  "d12",  "d13",  "d14",  "d15",
     65    "d16",   "d17",   "d18",   "d19",   "d20",   "d21",   "d22",   "d23",   "d24",   "d25",   "d26",  "d27",  "d28",  "d29",  "d30",  "d31"
     66};
     67static const char g_aszArmV8RegFpHalf[32][4] =
     68{
     69    "h0\0",  "h1\0",  "h2\0",  "h3\0",  "h4\0",  "h5\0",  "h6\0",  "h7\0",  "h8\0",  "h9\0",  "h10",  "h11",  "h12",  "h13",  "h14",  "h15",
     70    "h16",   "h17",   "h18",   "h19",   "h20",   "h21",   "h22",   "h23",   "h24",   "h25",   "h26",  "h27",  "h28",  "h29",  "h30",  "h31"
     71};
     72static const char g_aszArmV8RegSimdScalar128Bit[32][4] =
     73{
     74    "q0\0",  "q1\0",  "q2\0",  "q3\0",  "q4\0",  "q5\0",  "q6\0",  "q7\0",  "q8\0",  "q9\0",  "q10",  "q11",  "q12",  "q13",  "q14",  "q15",
     75    "q16",   "q17",   "q18",   "q19",   "q20",   "q21",   "q22",   "q23",   "q24",   "q25",   "q26",  "q27",  "q28",  "q29",  "q30",  "q31"
     76};
    5777static const char g_aszArmV8Cond[16][3] =
    5878{
    5979    "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al", "al"
     80};
     81static const char *g_apszArmV8PState[] =
     82{
     83    /* kDisArmv8InstrPState_SPSel    */ "spsel",
     84    /* kDisArmv8InstrPState_DAIFSet  */ "daifset",
     85    /* kDisArmv8InstrPState_DAIFClr  */ "daifclr",
     86    /* kDisArmv8InstrPState_UAO      */ "uao",
     87    /* kDisArmv8InstrPState_PAN      */ "pan",
     88    /* kDisArmv8InstrPState_ALLINT   */ "allint",
     89    /* kDisArmv8InstrPState_PM       */ "pm",
     90    /* kDisArmv8InstrPState_SSBS     */ "ssbs",
     91    /* kDisArmv8InstrPState_DIT      */ "dit",
     92    /* kDisArmv8InstrPState_SVCRSM   */ "svcrsm",
     93    /* kDisArmv8InstrPState_SVCRZA   */ "svcrza",
     94    /* kDisArmv8InstrPState_SVCRSMZA */ "svcrsmza",
     95    /* kDisArmv8InstrPState_TCO      */ "tco"
    6096};
    6197
     
    310346    RT_NOREF_PV(pDis);
    311347
    312     if (pReg->f32Bit)
     348    switch (pReg->enmRegType)
    313349    {
    314         Assert(pReg->idGpr < RT_ELEMENTS(g_aszArmV8RegGen32));
    315         const char *psz = g_aszArmV8RegGen32[pReg->idGpr];
    316         *pcchReg = 2 + !!psz[2];
    317         return psz;
     350        case kDisOpParamArmV8RegType_Gpr_32Bit:
     351        {
     352            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegGen32));
     353            const char *psz = g_aszArmV8RegGen32[pReg->idReg];
     354            *pcchReg = 2 + !!psz[2];
     355            return psz;
     356        }
     357        case kDisOpParamArmV8RegType_Gpr_64Bit:
     358        {
     359            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegGen64));
     360            const char *psz = g_aszArmV8RegGen64[pReg->idReg];
     361            *pcchReg = 2 + !!psz[2];
     362            return psz;
     363        }
     364        case kDisOpParamArmV8RegType_FpReg_Single:
     365        {
     366            Assert(pDis->armv8.enmFpType != kDisArmv8InstrFpType_Invalid);
     367            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegFpSingle));
     368            const char *psz = g_aszArmV8RegFpSingle[pReg->idReg];
     369            *pcchReg = 2 + !!psz[2];
     370            return psz;
     371        }
     372        case kDisOpParamArmV8RegType_FpReg_Double:
     373        {
     374            Assert(pDis->armv8.enmFpType != kDisArmv8InstrFpType_Invalid);
     375            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegFpDouble));
     376            const char *psz = g_aszArmV8RegFpDouble[pReg->idReg];
     377            *pcchReg = 2 + !!psz[2];
     378            return psz;
     379        }
     380        case kDisOpParamArmV8RegType_FpReg_Half:
     381        {
     382            Assert(pDis->armv8.enmFpType != kDisArmv8InstrFpType_Invalid);
     383            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegFpHalf));
     384            const char *psz = g_aszArmV8RegFpHalf[pReg->idReg];
     385            *pcchReg = 2 + !!psz[2];
     386            return psz;
     387        }
     388        case kDisOpParamArmV8RegType_Simd_Scalar_64Bit:
     389        {
     390            /* Using the floating point double register names here. */
     391            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegFpDouble));
     392            const char *psz = g_aszArmV8RegFpDouble[pReg->idReg];
     393            *pcchReg = 2 + !!psz[2];
     394            return psz;
     395        }
     396        case kDisOpParamArmV8RegType_Simd_Scalar_128Bit:
     397        {
     398            Assert(pReg->idReg < RT_ELEMENTS(g_aszArmV8RegSimdScalar128Bit));
     399            const char *psz = g_aszArmV8RegSimdScalar128Bit[pReg->idReg];
     400            *pcchReg = 2 + !!psz[2];
     401            return psz;
     402        }
     403        default:
     404            AssertFailed();
     405            *pcchReg = 0;
     406            return NULL;
    318407    }
    319 
    320     Assert(pReg->idGpr < RT_ELEMENTS(g_aszArmV8RegGen64));
    321     const char *psz = g_aszArmV8RegGen64[pReg->idGpr];
    322     *pcchReg = 2 + !!psz[2];
    323     return psz;
    324408}
    325409
     
    343427    for (uint32_t i = 0; i < RT_ELEMENTS(g_aArmV8SysReg64); i++)
    344428    {
    345         if (g_aArmV8SysReg64[i].idSysReg == pParam->armv8.Reg.idSysReg)
     429        if (g_aArmV8SysReg64[i].idSysReg == pParam->armv8.Op.idSysReg)
    346430        {
    347431            *pcchReg = g_aArmV8SysReg64[i].cchSysReg;
     
    351435
    352436    /* Generate S<op0>_<op1>_<Cn>_<Cm>_<op2> identifier. */
    353     uint32_t const idSysReg = pParam->armv8.Reg.idSysReg;
     437    uint32_t const idSysReg = pParam->armv8.Op.idSysReg;
    354438    uint8_t idx = 0;
    355439    pachTmp[idx++] = 'S';
     
    385469
    386470/**
    387  * Formats the current instruction in Yasm (/ Nasm) style.
     471 * Formats the current instruction in ARMv8 style.
    388472 *
    389473 *
     
    680764                    break;
    681765                }
    682                 case kDisArmv8OpParmGpr:
     766                case kDisArmv8OpParmReg:
    683767                {
    684768                    Assert(!(pParam->fUse & (DISUSE_DISPLACEMENT8 | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT32 | DISUSE_DISPLACEMENT64 | DISUSE_RIPDISPLACEMENT32)));
    685769
    686770                    size_t cchReg;
    687                     const char *pszReg = disasmFormatArmV8Reg(pDis, &pParam->armv8.Reg.Gpr, &cchReg);
     771                    const char *pszReg = disasmFormatArmV8Reg(pDis, &pParam->armv8.Op.Reg, &cchReg);
    688772                    PUT_STR(pszReg, cchReg);
    689773                    break;
     
    710794
    711795                    size_t cchReg;
    712                     const char *pszReg = disasmFormatArmV8Reg(pDis, &pParam->armv8.Reg.Gpr, &cchReg);
     796                    const char *pszReg = disasmFormatArmV8Reg(pDis, &pParam->armv8.Op.Reg, &cchReg);
    713797                    PUT_STR(pszReg, cchReg);
    714798
     
    766850                case kDisArmv8OpParmCond:
    767851                {
    768                     Assert((uint16_t)pParam->armv8.Reg.enmCond < RT_ELEMENTS(g_aszArmV8Cond));
    769                     PUT_STR(g_aszArmV8Cond[pParam->armv8.Reg.enmCond], sizeof(g_aszArmV8Cond[0]) - 1);
     852                    Assert((uint16_t)pParam->armv8.Op.enmCond < RT_ELEMENTS(g_aszArmV8Cond));
     853                    PUT_STR(g_aszArmV8Cond[pParam->armv8.Op.enmCond], sizeof(g_aszArmV8Cond[0]) - 1);
     854                    break;
     855                }
     856                case kDisArmv8OpParmPState:
     857                {
     858                    Assert((uint16_t)pParam->armv8.Op.enmPState < RT_ELEMENTS(g_apszArmV8PState));
     859                    PUT_PSZ(g_apszArmV8PState[pParam->armv8.Op.enmPState]);
    770860                    break;
    771861                }
     
    778868            {
    779869                Assert(   pParam->armv8.enmType == kDisArmv8OpParmImm
    780                        || pParam->armv8.enmType == kDisArmv8OpParmGpr);
     870                       || pParam->armv8.enmType == kDisArmv8OpParmReg);
    781871                PUT_SZ(", ");
    782872                switch (pParam->armv8.enmExtend)
     
    862952
    863953/**
    864  * Formats the current instruction in Yasm (/ Nasm) style.
    865  *
    866  * This is a simplified version of DISFormatYasmEx() provided for your convenience.
     954 * Formats the current instruction in ARMv8 style.
     955 *
     956 * This is a simplified version of DISFormatArmV8Ex() provided for your convenience.
    867957 *
    868958 *
  • trunk/src/VBox/Disassembler/DisasmInternal-armv8.h

    r105858 r106004  
    55
    66/*
    7  * Copyright (C) 2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    5555    kDisParmParseImmRel,
    5656    kDisParmParseImmAdr,
     57    kDisParmParseImmZero,
    5758    kDisParmParseReg,
    5859    kDisParmParseRegOff,
     
    7475    kDisParmParseSetPreIndexed,
    7576    kDisParmParseSetPostIndexed,
     77    kDisParmParseFpType,
     78    kDisParmParseFpReg,
     79    kDisParmParseFpScale,
     80    kDisParmParseFpFixupFCvt,
     81    kDisParmParseSimdRegScalar,
     82    kDisParmParseImmHImmB,
    7683    kDisParmParseMax
    7784} DISPARMPARSEIDX;
     
    297304                                                                 a_fMask, a_cShift, & g_aArmV8A64Insn ## a_Name ## MapHdrs[0] }
    298305
     306#define DIS_ARMV8_DECODE_MAP_DEFINE_END_SINGLE_BIT(a_Name, a_idxBit) \
     307    }; \
     308    static const DISARMV8DECODEMAP g_aArmV8A64Insn ## a_Name = { { kDisArmV8DecodeType_Map, RT_ELEMENTS(g_aArmV8A64Insn ## a_Name ## MapHdrs) }, \
     309                                                                 RT_BIT_32(a_idxBit), a_idxBit, & g_aArmV8A64Insn ## a_Name ## MapHdrs[0] }
     310
     311
    299312#define DIS_ARMV8_DECODE_MAP_DEFINE_END_NON_STATIC(a_Name, a_fMask, a_cShift) \
    300313    }; \
  • trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp

    r105858 r106004  
    55
    66/*
    7  * Copyright (C) 2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    5858};
    5959
     60
     61/* Include the secondary tables. */
     62#include "DisasmTables-armv8-a64-simd-fp.cpp.h"
    6063
    6164/* UDF */
     
    7780DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(Adr, 0x9f000000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
    7881                                                kDisArmV8OpcDecodeNop, RT_BIT_32(31), 31,
    79                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmImmRel);
     82                                                kDisArmv8OpParmReg, kDisArmv8OpParmImmRel);
    8083
    8184
     
    9396DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(AddSubImm, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    9497                                                kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
    95                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmImm);
     98                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm);
    9699
    97100
     
    110113DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(AddSubShiftReg, 0x7f200000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    111114                                                kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
    112                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmGpr);
     115                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmReg);
    113116
    114117
     
    125128DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LogicalImm, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    126129                                                kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
    127                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmImm);
     130                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm);
    128131
    129132
     
    140143DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(MoveWide, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    141144                                                kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
    142                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmImm);
     145                                                kDisArmv8OpParmReg, kDisArmv8OpParmImm);
    143146
    144147
     
    156159DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_4(Bitfield, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF | DISARMV8INSNCLASS_F_N_FORCED_1_ON_64BIT,
    157160                                                kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
    158                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmImm, kDisArmv8OpParmImm);
     161                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm, kDisArmv8OpParmImm);
    159162
    160163
     
    223226DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(SysReg, 0xffffffe0 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
    224227                                                kDisArmV8OpcDecodeNop, 0xfe0, 5,
    225                                                 kDisArmv8OpParmGpr);
     228                                                kDisArmv8OpParmReg);
    226229
    227230
     
    268271/* MSR (and potentially CFINV,XAFLAG,AXFLAG) */
    269272DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(PState)
    270     DIS_ARMV8_OP(0xd503305f, "msr",             OP_ARMV8_A64_MSR,       DISOPTYPE_HARMLESS),
     273    DIS_ARMV8_OP(0xd500401f, "msr",             OP_ARMV8_A64_MSR,       DISOPTYPE_HARMLESS),
    271274DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(PState)
     275    DIS_ARMV8_INSN_DECODE(kDisParmParseImm,            8,  4, 1 /*idxParam*/), /* CRm field encodes the immediate value, gets validated by the next decoder stage. */
    272276    DIS_ARMV8_INSN_DECODE(kDisParmParsePState,         0,  0, 0 /*idxParam*/), /* This is special for the MSR instruction. */
    273     DIS_ARMV8_INSN_DECODE(kDisParmParseImm,            8,  4, 1 /*idxParam*/), /* CRm field encodes the immediate value */
    274 DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(PState, 0xfffff0ff /*fFixedInsn*/, 0 /*fClass*/,
     277DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(PState, 0xfff8f01f /*fFixedInsn*/, 0 /*fClass*/,
    275278                                                kDisArmV8OpcDecodeNop, 0, 0,
    276                                                 kDisArmv8OpParmImm, kDisArmv8OpParmNone); /** @todo */
     279                                                kDisArmv8OpParmPState, kDisArmv8OpParmImm);
    277280
    278281
     
    285288DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(SysResult, 0xfffffffe /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
    286289                                                kDisArmV8OpcDecodeNop, RT_BIT_32(8) | RT_BIT_32(9) | RT_BIT_32(10) | RT_BIT_32(11), 8,
    287                                                 kDisArmv8OpParmGpr);
     290                                                kDisArmv8OpParmReg);
    288291
    289292
     
    320323DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(Msr, 0xfff00000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
    321324                                                kDisArmV8OpcDecodeNop, 0, 0,
    322                                                 kDisArmv8OpParmSysReg, kDisArmv8OpParmGpr);
     325                                                kDisArmv8OpParmSysReg, kDisArmv8OpParmReg);
    323326
    324327
     
    331334DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(Mrs, 0xfff00000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
    332335                                                kDisArmV8OpcDecodeNop, 0, 0,
    333                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmSysReg);
     336                                                kDisArmv8OpParmReg, kDisArmv8OpParmSysReg);
    334337
    335338
     
    346349DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(BrBlrRet, 0xfffffc1f /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
    347350                                                kDisArmV8OpcDecodeLookup, 0xfffffc1f, 0,
    348                                                 kDisArmv8OpParmGpr);
     351                                                kDisArmv8OpParmReg);
    349352
    350353
     
    390393DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(CmpBrImm, 0x7f000000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    391394                                                kDisArmV8OpcDecodeNop, RT_BIT_32(24), 24,
    392                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmImmRel);
     395                                                kDisArmv8OpParmReg, kDisArmv8OpParmImmRel);
    393396
    394397
     
    403406DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(TestBrImm, 0x7f000000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF, /* Not an SF bit but has the same meaning. */
    404407                                                kDisArmV8OpcDecodeNop, RT_BIT_32(24), 24,
    405                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmImm, kDisArmv8OpParmImmRel);
     408                                                kDisArmv8OpParmReg, kDisArmv8OpParmImm, kDisArmv8OpParmImmRel);
    406409
    407410
     
    439442DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LogShiftRegN0, 0x7f200000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    440443                                                kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
    441                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmGpr);
     444                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmReg);
    442445
    443446
     
    456459DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LogShiftRegN1, 0x7f200000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    457460                                                kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
    458                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmGpr);
     461                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmReg);
    459462
    460463
     
    493496DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_4(CondCmpReg, 0x7fe00c10 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
    494497                                                kDisArmV8OpcDecodeNop, RT_BIT_32(30), 30,
    495                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmImm, kDisArmv8OpParmCond);
     498                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm, kDisArmv8OpParmCond);
    496499
    497500
     
    575578                                                kDisArmV8OpcDecodeCollate,
    576579                                                RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
    577                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     580                                                kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
    578581
    579582
     
    626629                                                kDisArmV8OpcDecodeCollate,
    627630                                                RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
    628                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     631                                                kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
    629632
    630633
     
    695698                                                kDisArmV8OpcDecodeCollate,
    696699                                                RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
    697                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     700                                                kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
    698701
    699702
     
    788791                                                kDisArmV8OpcDecodeCollate,
    789792                                                RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
    790                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     793                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
    791794
    792795
     
    814817                                                kDisArmV8OpcDecodeCollate,
    815818                                                RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
    816                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     819                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
    817820
    818821
     
    840843                                                kDisArmV8OpcDecodeCollate,
    841844                                                RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
    842                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
     845                                                kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
    843846
    844847
     
    932935    DIS_ARMV8_DECODE_MAP_ENTRY(LogicalAddSubReg),                   /* Data processing (register) (see op1 in C4.1.68). */
    933936    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
    934     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Data processing (SIMD & FP) */
     937    DIS_ARMV8_DECODE_MAP_ENTRY(DataProcSimdFpBit28_0),              /* Data processing (SIMD & FP) (op0<0> 0) */
    935938    DIS_ARMV8_DECODE_MAP_ENTRY(DataProcessingImm),                  /* Data processing (immediate). */
    936939    DIS_ARMV8_DECODE_MAP_ENTRY(DataProcessingImm),                  /* Data processing (immediate). */
     
    940943    DIS_ARMV8_DECODE_MAP_ENTRY(DataProcReg),                        /* Data processing (register) (see op1 in C4.1.68). */
    941944    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
    942     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY                              /* Data processing (SIMD & FP). */
     945    DIS_ARMV8_DECODE_MAP_ENTRY(DataProcSimdFpBit28_1)               /* Data processing (SIMD & FP) (op0<0> 1). */
    943946DIS_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

    r105858 r106004  
    55
    66/*
    7  * Copyright (C) 2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    665665        ccmn w0, w1, #0xf, al
    666666
     667        msr spsel,   #1
     668        msr spsel,   #0
     669        msr daifset, #0
     670        msr daifset, #15
     671        msr daifclr, #0
     672        msr daifclr, #15
     673        msr uao,     #1
     674        msr uao,     #0
     675        msr pan,     #1
     676        msr pan,     #0
     677        ; msr allint,  #1 Not supported by the toolchain
     678        ; msr allint,  #0 Not supported by the toolchain
     679        msr pm,      #1
     680        msr pm,      #0
     681        msr ssbs,    #1
     682        msr ssbs,    #0
     683        msr dit,     #1
     684        msr dit,     #0
     685        ; msr tco,     #1 Not supported by the toolchain
     686        ; msr tco,     #0 Not supported by the toolchain
     687        ; msr svcrsm,  #1 Not supported by the toolchain
     688        ; msr svcrsm,  #0 Not supported by the toolchain
     689        ; msr svcrza,  #1 Not supported by the toolchain
     690        ; msr svcrza,  #0 Not supported by the toolchain
     691        ; msr svcrsma, #1 Not supported by the toolchain
     692        ; msr svcrsma, #0 Not supported by the toolchain
     693
     694        ; Floating Point instructions.
     695        fmadd  s0, s1, s3, s31
     696        fmadd  d0, d1, d3, d31
     697        fmadd  h0, h1, h3, h31
     698
     699        fmsub  s0, s1, s3, s31
     700        fmsub  d0, d1, d3, d31
     701        fmsub  h0, h1, h3, h31
     702
     703        fnmadd s0, s1, s3, s31
     704        fnmadd d0, d1, d3, d31
     705        fnmadd h0, h1, h3, h31
     706
     707        fnmsub s0, s1, s3, s31
     708        fnmsub d0, d1, d3, d31
     709        fnmsub h0, h1, h3, h31
     710
     711        fcvtzu x0, s0, #1
     712        fcvtzu x0, s0, #31
     713        fcvtzu x0, s0, #63
     714        fcvtzu w0, s0, #1
     715        fcvtzu w0, s0, #32
     716
     717        fcvtzu x0, d0, #1
     718        fcvtzu x0, d0, #31
     719        fcvtzu x0, d0, #63
     720        fcvtzu w0, d0, #1
     721        fcvtzu w0, d0, #32
     722
     723        fcvtzu x0, h0, #1
     724        fcvtzu x0, h0, #31
     725        fcvtzu x0, h0, #63
     726        fcvtzu w0, h0, #1
     727        fcvtzu w0, h0, #32
     728
     729        fcvtzs x0, s0, #1
     730        fcvtzs x0, s0, #31
     731        fcvtzs x0, s0, #63
     732        fcvtzs w0, s0, #1
     733        fcvtzs w0, s0, #32
     734
     735        fcvtzs x0, d0, #1
     736        fcvtzs x0, d0, #31
     737        fcvtzs x0, d0, #63
     738        fcvtzs w0, d0, #1
     739        fcvtzs w0, d0, #32
     740
     741        fcvtzs x0, h0, #1
     742        fcvtzs x0, h0, #31
     743        fcvtzs x0, h0, #63
     744        fcvtzs w0, h0, #1
     745        fcvtzs w0, h0, #32
     746
     747        ucvtf  s0, x0, #1
     748        ucvtf  s0, x0, #31
     749        ucvtf  s0, x0, #63
     750        ucvtf  s0, w0, #1
     751        ucvtf  s0, w0, #32
     752
     753        ucvtf  d0, x0, #1
     754        ucvtf  d0, x0, #31
     755        ucvtf  d0, x0, #63
     756        ucvtf  d0, w0, #1
     757        ucvtf  d0, w0, #32
     758
     759        ucvtf  h0, x0, #1
     760        ucvtf  h0, x0, #31
     761        ucvtf  h0, x0, #63
     762        ucvtf  h0, w0, #1
     763        ucvtf  h0, w0, #32
     764
     765        scvtf  s0, x0, #1
     766        scvtf  s0, x0, #31
     767        scvtf  s0, x0, #63
     768        scvtf  s0, w0, #1
     769        scvtf  s0, w0, #32
     770
     771        scvtf  d0, x0, #1
     772        scvtf  d0, x0, #31
     773        scvtf  d0, x0, #63
     774        scvtf  d0, w0, #1
     775        scvtf  d0, w0, #32
     776
     777        scvtf  h0, x0, #1
     778        scvtf  h0, x0, #31
     779        scvtf  h0, x0, #63
     780        scvtf  h0, w0, #1
     781        scvtf  h0, w0, #32
     782
     783        fcsel  s0, s1, s2, eq
     784        fcsel  d0, d1, d2, eq
     785        fcsel  h0, h1, h2, eq
     786
     787        fmul   s0, s1, s2
     788        fmul   d0, d1, d2
     789        fmul   h0, h1, h2
     790
     791        fdiv   s0, s1, s2
     792        fdiv   d0, d1, d2
     793        fdiv   h0, h1, h2
     794
     795        fadd   s0, s1, s2
     796        fadd   d0, d1, d2
     797        fadd   h0, h1, h2
     798
     799        fsub   s0, s1, s2
     800        fsub   d0, d1, d2
     801        fsub   h0, h1, h2
     802
     803        fmax   s0, s1, s2
     804        fmax   d0, d1, d2
     805        fmax   h0, h1, h2
     806
     807        fmin   s0, s1, s2
     808        fmin   d0, d1, d2
     809        fmin   h0, h1, h2
     810
     811        fmaxnm s0, s1, s2
     812        fmaxnm d0, d1, d2
     813        fmaxnm h0, h1, h2
     814
     815        fminnm s0, s1, s2
     816        fminnm d0, d1, d2
     817        fminnm h0, h1, h2
     818
     819        fnmul  s0, s1, s2
     820        fnmul  d0, d1, d2
     821        fnmul  h0, h1, h2
     822
     823        fccmp  s0, s1, #0,  eq
     824        fccmp  s0, s1, #15, ne
     825        fccmp  d0, d1, #0,  eq
     826        fccmp  d0, d1, #15, ne
     827        fccmp  h0, h1, #0,  eq
     828        fccmp  h0, h1, #15, ne
     829
     830        fccmpe s0, s1, #0,  eq
     831        fccmpe s0, s1, #15, ne
     832        fccmpe d0, d1, #0,  eq
     833        fccmpe d0, d1, #15, ne
     834        fccmpe h0, h1, #0,  eq
     835        fccmpe h0, h1, #15, ne
     836
     837        ;fmov   s0, #1 @todo Needs FP immediate parsing
     838
     839        fcmp s0, s1
     840        ;fcmp s0, #0.0
     841        fcmp d0, d1
     842        ;fcmp d0, #0.0
     843        fcmp h0, h1
     844        ;fcmp h0, #0.0
     845
     846        fcmpe s0, s1
     847        ;fcmpe s0, #0.0
     848        fcmpe d0, d1
     849        ;fcmpe d0, #0.0
     850        fcmpe h0, h1
     851        ;fcmpe h0, #0.0
     852
     853        fmov  s0, s1
     854        fmov  d0, d1
     855        fmov  h0, h1
     856
     857        fabs  s0, s1
     858        fabs  d0, d1
     859        fabs  h0, h1
     860
     861        fneg  s0, s1
     862        fneg  d0, d1
     863        fneg  h0, h1
     864
     865        fsqrt s0, s1
     866        fsqrt d0, d1
     867        fsqrt h0, h1
     868
     869        fcvt s0, d1
     870        fcvt s0, h1
     871        fcvt d0, s1
     872        fcvt d0, h1
     873        fcvt h0, s1
     874        fcvt h0, d1
     875
     876        frintn s0, s1
     877        frintn d0, d1
     878        frintn h0, h1
     879
     880        frintp s0, s1
     881        frintp d0, d1
     882        frintp h0, h1
     883
     884        frintm s0, s1
     885        frintm d0, d1
     886        frintm h0, h1
     887
     888        frintz s0, s1
     889        frintz d0, d1
     890        frintz h0, h1
     891
     892        frinta s0, s1
     893        frinta d0, d1
     894        frinta h0, h1
     895
     896        frintx s0, s1
     897        frintx d0, d1
     898        frintx h0, h1
     899
     900        frinti s0, s1
     901        frinti d0, d1
     902        frinti h0, h1
     903
     904        frint32z s0, s1
     905        frint32z d0, d1
     906
     907        frint32x s0, s1
     908        frint32x d0, d1
     909
     910        frint64z s0, s1
     911        frint64z d0, d1
     912
     913        frint64x s0, s1
     914        frint64x d0, d1
     915
     916        sshr d0, d1, #1
     917        sshr d0, d1, #64
     918
     919        ssra d0, d1, #1
     920        ssra d0, d1, #64
     921
     922        srshr d0, d1, #1
     923        srshr d0, d1, #64
     924
     925        srsra d0, d1, #1
     926        srsra d0, d1, #64
     927
     928        ; @todo
     929        ;shl   d0, d1, #0
     930        ;shl   d0, d1, #63
     931
     932        ;sqshl d0, d1, #0
     933        ;sqshl d0, d1, #63
     934
     935        ;sqshrn q0, q1, #1
     936        ;sqshrn q0, q1, #64
     937
     938        ;sqrshrn q0, dq, #1
     939        ;sqrshrn q0, q1, #64
     940
    667941        ;
    668942        ; Keep last so the testcase can catch errors in
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