Index: /trunk/include/VBox/dis-armv8.h
===================================================================
--- /trunk/include/VBox/dis-armv8.h	(revision 105814)
+++ /trunk/include/VBox/dis-armv8.h	(revision 105815)
@@ -99,4 +99,6 @@
     /** Condition flag for the instruction - kArmv8InstrCond_Al if not conditional instruction. */
     DISARMV8INSTRCOND   enmCond;
+    /** Operand size (for loads/stores primarily). */
+    uint8_t             cbOperand;
 } DIS_STATE_ARMV8_T;
 AssertCompile(sizeof(DIS_STATE_ARMV8_T) <= 32);
Index: /trunk/src/VBox/Disassembler/DisasmCore-armv8.cpp
===================================================================
--- /trunk/src/VBox/Disassembler/DisasmCore-armv8.cpp	(revision 105814)
+++ /trunk/src/VBox/Disassembler/DisasmCore-armv8.cpp	(revision 105815)
@@ -50,5 +50,5 @@
  * @remark no DECLCALLBACK() here because it's considered to be internal and
  *         there is no point in enforcing CDECL. */
-typedef int FNDISPARSEARMV8(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit);
+typedef int FNDISPARSEARMV8(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit);
 /** Pointer to a disassembler parser function. */
 typedef FNDISPARSEARMV8 *PFNDISPARSEARMV8;
@@ -74,5 +74,5 @@
  * @{ */
 static FNDISPARSEARMV8 disArmV8ParseIllegal;
-static FNDISPARSEARMV8 disArmV8ParseIs32Bit;
+static FNDISPARSEARMV8 disArmV8ParseSize;
 static FNDISPARSEARMV8 disArmV8ParseImm;
 static FNDISPARSEARMV8 disArmV8ParseImmRel;
@@ -96,4 +96,5 @@
 static FNDISDECODEARMV8 disArmV8DecodeIllegal;
 static FNDISDECODEARMV8 disArmV8DecodeLookup;
+static FNDISDECODEARMV8 disArmV8DecodeCollate;
 /** @} */
 
@@ -106,5 +107,5 @@
 {
     disArmV8ParseIllegal,
-    disArmV8ParseIs32Bit,
+    disArmV8ParseSize,
     disArmV8ParseImm,
     disArmV8ParseImmRel,
@@ -130,4 +131,5 @@
     disArmV8DecodeIllegal,
     disArmV8DecodeLookup,
+    disArmV8DecodeCollate
 };
 
@@ -135,5 +137,5 @@
 DECLINLINE(uint32_t) disArmV8ExtractBitVecFromInsn(uint32_t u32Insn, uint8_t idxBitStart, uint8_t cBits)
 {
-    uint32_t fMask = RT_BIT_32(idxBitStart + cBits) - 1;
+    uint32_t fMask = (uint32_t)(RT_BIT_64(idxBitStart + cBits) - 1);
     return (u32Insn & fMask) >> idxBitStart;
 }
@@ -152,7 +154,7 @@
 
 
-static int disArmV8ParseIllegal(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, u32Insn, pInsnClass, pParam, pInsnParm, pf64Bit);
+static int disArmV8ParseIllegal(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
     AssertFailed();
     return VERR_INTERNAL_ERROR;
@@ -160,17 +162,28 @@
 
 
-static int disArmV8ParseIs32Bit(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pParam);
-
-    AssertReturn(pInsnParm->idxBitStart < 32 && pInsnParm->cBits == 1, VERR_INTERNAL_ERROR_2);
-    *pf64Bit = RT_BOOL(u32Insn & RT_BIT_32(pInsnParm->idxBitStart));
-    return VINF_SUCCESS;
-}
-
-
-static int disArmV8ParseImm(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseSize(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pInsnClass, pParam);
+
+    Assert(pInsnParm->cBits == 2);
+    uint32_t u32Size = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
+    switch (u32Size)
+    {
+        case 0: pDis->armv8.cbOperand = sizeof(uint8_t); break;
+        case 1: pDis->armv8.cbOperand = sizeof(uint16_t); break;
+        case 2: pDis->armv8.cbOperand = sizeof(uint32_t); break;
+        case 3: pDis->armv8.cbOperand = sizeof(uint64_t); break;
+        default:
+            AssertReleaseFailed();
+    }
+    *pf64Bit =    pDis->armv8.cbOperand == sizeof(uint64_t)
+               || (pOp->fFlags & DISARMV8INSNCLASS_F_FORCED_64BIT);
+    return VINF_SUCCESS;
+}
+
+
+static int disArmV8ParseImm(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
 
     AssertReturn(pInsnParm->idxBitStart + pInsnParm->cBits < 32, VERR_INTERNAL_ERROR_2);
@@ -199,7 +212,7 @@
 
 
-static int disArmV8ParseImmRel(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseImmRel(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
 
     AssertReturn(pInsnParm->idxBitStart + pInsnParm->cBits < 32, VERR_INTERNAL_ERROR_2);
@@ -228,7 +241,7 @@
 
 
-static int disArmV8ParseImmAdr(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit, pInsnParm);
+static int disArmV8ParseImmAdr(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit, pInsnParm);
 
     pParam->uValue  = disArmV8ExtractBitVecFromInsn(u32Insn, 5, 19);
@@ -239,7 +252,7 @@
 
 
-static int disArmV8ParseReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass);
+static int disArmV8ParseReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass);
     pParam->armv8.Reg.idxGenReg = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
     pParam->armv8.cb            = *pf64Bit ? sizeof(uint64_t) : sizeof(uint32_t);
@@ -251,7 +264,7 @@
 
 
-static int disArmV8ParseImmsImmrN(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis);
+static int disArmV8ParseImmsImmrN(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp);
     AssertReturn(pInsnParm->cBits == 13, VERR_INTERNAL_ERROR_2);
 
@@ -276,7 +289,7 @@
 
 
-static int disArmV8ParseHw(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pParam);
+static int disArmV8ParseHw(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pParam);
     Assert(pInsnParm->cBits == 2);
 
@@ -298,7 +311,7 @@
 
 
-static int disArmV8ParseCond(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pInsnClass, pParam, pf64Bit);
+static int disArmV8ParseCond(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pInsnClass, pOp, pParam, pf64Bit);
     Assert(pInsnParm->cBits <= 4);
     if (pParam)
@@ -314,7 +327,7 @@
 
 
-static int disArmV8ParsePState(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, u32Insn, pInsnClass, pParam, pInsnParm, pf64Bit);
+static int disArmV8ParsePState(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, u32Insn, pOp, pInsnClass, pParam, pInsnParm, pf64Bit);
     //AssertFailed();
     /** @todo */
@@ -323,7 +336,7 @@
 
 
-static int disArmV8ParseSysReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseSysReg(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
     AssertReturn(pInsnParm->cBits == 15, VERR_INTERNAL_ERROR_2);
 
@@ -341,7 +354,7 @@
 
 
-static int disArmV8ParseSh12(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseSh12(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
     Assert(pInsnParm->cBits == 1);
     if (u32Insn & RT_BIT_32(pInsnParm->idxBitStart))
@@ -375,7 +388,7 @@
 
 
-static int disArmV8ParseImmTbz(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseImmTbz(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
 
     AssertReturn(!pInsnParm->idxBitStart && !pInsnParm->cBits, VERR_INTERNAL_ERROR_2);
@@ -390,7 +403,7 @@
 
 
-static int disArmV8ParseShift(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseShift(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
 
     AssertReturn(pInsnParm->cBits == 2, VERR_INTERNAL_ERROR_2);
@@ -410,7 +423,7 @@
 
 
-static int disArmV8ParseShiftAmount(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseShiftAmount(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pDis, pOp, pInsnClass, pf64Bit);
 
     uint32_t u32Amount = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
@@ -430,12 +443,21 @@
 
 
-static int disArmV8ParseImmMemOff(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
-{
-    RT_NOREF(pDis, pInsnClass, pf64Bit);
+static int disArmV8ParseImmMemOff(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8OPCODE pOp, PCDISARMV8INSNCLASS pInsnClass, PDISOPPARAM pParam, PCDISARMV8INSNPARAM pInsnParm, bool *pf64Bit)
+{
+    RT_NOREF(pInsnClass, pOp, pf64Bit);
 
     AssertReturn(pInsnParm->cBits <= 12, VERR_INTERNAL_ERROR_2);
-
-    uint8_t const uScale = *pf64Bit ? 8 : 4;
-    pParam->armv8.u.offBase = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits) * uScale;
+    AssertReturn(pDis->armv8.cbOperand != 0, VERR_INTERNAL_ERROR_2);
+
+    pParam->armv8.u.offBase = disArmV8ExtractBitVecFromInsn(u32Insn, pInsnParm->idxBitStart, pInsnParm->cBits);
+    switch (pDis->armv8.cbOperand)
+    {
+        case sizeof(uint8_t): break;
+        case sizeof(uint16_t): pParam->armv8.u.offBase <<= 1; break;
+        case sizeof(uint32_t): pParam->armv8.u.offBase <<= 2; break;
+        case sizeof(uint64_t): pParam->armv8.u.offBase <<= 3; break;
+        default:
+            AssertReleaseFailed();
+    }
     pParam->armv8.cb = sizeof(uint16_t);
     return VINF_SUCCESS;
@@ -461,4 +483,33 @@
             return i;
     }
+
+    return UINT32_MAX;
+}
+
+
+static uint32_t disArmV8DecodeCollate(PDISSTATE pDis, uint32_t u32Insn, PCDISARMV8INSNCLASS pInsnClass)
+{
+    RT_NOREF(pDis);
+
+    /* Need to build a compact representation of the relevant bits from the mask to create an index. */
+    uint32_t fMask = pInsnClass->fMask >> pInsnClass->cShift;
+
+    /** @todo Optimize. */
+    uint32_t idx = 0;
+    uint32_t cShift = 0;
+    while (fMask)
+    {
+        if (fMask & 0x1)
+        {
+            idx |= (u32Insn & 1) << cShift;
+            cShift++;
+        }
+
+        u32Insn >>= 1;
+        fMask   >>= 1;
+    }
+
+    if (RT_LIKELY(idx < pInsnClass->Hdr.cDecode))
+        return idx;
 
     return UINT32_MAX;
@@ -533,4 +584,5 @@
     pDis->aParams[3].armv8.enmShift = kDisArmv8OpParmShiftNone;
     pDis->armv8.enmCond             = kDisArmv8InstrCond_Al;
+    pDis->armv8.cbOperand           = 0;
 
     pDis->pCurInstr = &pOp->Opc;
@@ -549,5 +601,5 @@
            && RT_SUCCESS(rc))
     {
-        rc = g_apfnDisasm[pDecode->idxParse](pDis, u32Insn, pInsnClass,
+        rc = g_apfnDisasm[pDecode->idxParse](pDis, u32Insn, pOp, pInsnClass,
                                                pDecode->idxParam != DIS_ARMV8_INSN_PARAM_UNSET
                                              ? &pDis->aParams[pDecode->idxParam]
Index: /trunk/src/VBox/Disassembler/DisasmInternal-armv8.h
===================================================================
--- /trunk/src/VBox/Disassembler/DisasmInternal-armv8.h	(revision 105814)
+++ /trunk/src/VBox/Disassembler/DisasmInternal-armv8.h	(revision 105815)
@@ -51,5 +51,5 @@
 {
     kDisParmParseNop = 0,
-    kDisParmParseIs32Bit,
+    kDisParmParseSize,
     kDisParmParseImm,
     kDisParmParseImmRel,
@@ -77,6 +77,8 @@
 typedef struct DISARMV8OPCODE
 {
-    /** The value of masked bits of the isntruction. */
+    /** The value of the fixed bits of the instruction. */
     uint32_t            fValue;
+    /** Special flags for the opcode. */
+    uint32_t            fFlags;
     /** The generic opcode structure. */
     DISOPCODE           Opc;
@@ -113,4 +115,5 @@
     kDisArmV8OpcDecodeNop = 0,
     kDisArmV8OpcDecodeLookup,
+    kDisArmV8OpcDecodeCollate,
     kDisArmV8OpcDecodeMax
 } DISARMV8OPCDECODE;
Index: /trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp
===================================================================
--- /trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp	(revision 105814)
+++ /trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp	(revision 105815)
@@ -40,5 +40,7 @@
 
 #define DIS_ARMV8_OP(a_fValue, a_szOpcode, a_uOpcode, a_fOpType) \
-    { a_fValue, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
+    { a_fValue, 0, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
+#define DIS_ARMV8_OP_EX(a_fValue, a_szOpcode, a_uOpcode, a_fOpType, a_fFlags) \
+    { a_fValue, a_fFlags, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
 
 #ifndef DIS_CORE_ONLY
@@ -544,15 +546,90 @@
 
 
-DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdSt)
+/* STRB/LDRB/LDRSB/STR/LDR/STRH/LDRH/LDRSH/LDRSW/PRFM
+ *
+ * Note: The size,opc bitfields are concatenated to form an index.
+ */
+DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegUImmGpr)
+    DIS_ARMV8_OP(0x39000000, "strb",            OP_ARMV8_A64_STRB,      DISOPTYPE_HARMLESS),
+    DIS_ARMV8_OP(0x39400000, "ldrb",            OP_ARMV8_A64_LDRB,      DISOPTYPE_HARMLESS),
+ DIS_ARMV8_OP_EX(0x39800000, "ldrsb",           OP_ARMV8_A64_LDRSB,     DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
+    DIS_ARMV8_OP(0x39c00000, "ldrsb",           OP_ARMV8_A64_LDRSB,     DISOPTYPE_HARMLESS),
+    DIS_ARMV8_OP(0x79000000, "strh",            OP_ARMV8_A64_STRH,      DISOPTYPE_HARMLESS),
+    DIS_ARMV8_OP(0x79400000, "ldrh",            OP_ARMV8_A64_LDRH,      DISOPTYPE_HARMLESS),
+ DIS_ARMV8_OP_EX(0x79800000, "ldrsh",           OP_ARMV8_A64_LDRSH,     DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
+    DIS_ARMV8_OP(0x79c00000, "ldrsh",           OP_ARMV8_A64_LDRSH,     DISOPTYPE_HARMLESS),
+    DIS_ARMV8_OP(0xb9000000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS),
     DIS_ARMV8_OP(0xb9400000, "ldr",             OP_ARMV8_A64_LDR,       DISOPTYPE_HARMLESS),
-    DIS_ARMV8_OP(0xb9000000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS),
-DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdSt)
-    DIS_ARMV8_INSN_DECODE(kDisParmParseIs32Bit,       30,  1, DIS_ARMV8_INSN_PARAM_UNSET),
+ DIS_ARMV8_OP_EX(0xb9800000, "ldrsw",           OP_ARMV8_A64_LDRSW,     DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
+    INVALID_OPCODE,
+    DIS_ARMV8_OP(0xf9000000, "str",             OP_ARMV8_A64_STR,       DISOPTYPE_HARMLESS),
+    DIS_ARMV8_OP(0xf9400000, "ldr",             OP_ARMV8_A64_LDR,       DISOPTYPE_HARMLESS),
+    INVALID_OPCODE, /** @todo PRFM */
+    INVALID_OPCODE,
+DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegUImmGpr)
+    DIS_ARMV8_INSN_DECODE(kDisParmParseSize,          30,  2, DIS_ARMV8_INSN_PARAM_UNSET),
     DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            0,  5, 0 /*idxParam*/),
     DIS_ARMV8_INSN_DECODE(kDisParmParseReg,            5,  5, 1 /*idxParam*/),
     DIS_ARMV8_INSN_DECODE(kDisParmParseImmMemOff,     10, 12, 1 /*idxParam*/),
-DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdSt, 0xbfc00000 /*fFixedInsn*/, 0 /*fClass*/,
-                                                kDisArmV8OpcDecodeLookup, 0xbfc00000, 0,
+DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdStRegUImmGpr, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
+                                                kDisArmV8OpcDecodeCollate,
+                                                RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
                                                 kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr);
+
+
+/*
+ * C4.1.94 - Loads and Stores - Load/Store register variants
+ *
+ * Differentiate further based on the VR field.
+ *
+ *     Bit  26
+ *     +-------------------------------------------
+ *           0 GPR variants.
+ *           1 SIMD/FP variants
+ */
+DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegUImm)
+    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImmGpr),
+    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
+DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegUImm, RT_BIT_32(26), 26);
+
+
+/*
+ * C4.1.94 - Loads and Stores - Load/Store register variants
+ *
+ * Differentiate further based on the op2<14> field.
+ *
+ *     Bit  14
+ *     +-------------------------------------------
+ *           0 All the other Load/store register variants and Atomic memory operations.
+ *           1 Load/store register (unsigned immediate).
+ */
+DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStReg)
+    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
+    DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImm),
+DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStReg, RT_BIT_32(24), 24);
+
+
+/*
+ * C4.1.94 - Loads and Stores
+ *
+ * Differentiate further based on the op0<1:0> field.
+ * Splitting this up because the decoding would get insane otherwise with tables doing cross referencing...
+ *
+ *     Bit  29 28
+ *     +-------------------------------------------
+ *           0  0 Compare and swap pair / Advanced SIMD loads/stores / Load/store exclusive pair / Load/store exclusive register
+ *                Load/store ordered / Compare and swap
+ *           0  1 RCW compare and swap / 128-bit atomic memory instructions / GCS load/store / Load/store memory tags /
+ *                LDIAPP/STILP / LDAPR/STLR / Load register (literal) / Memory Copy and Set
+ *           1  0 Load/store no-allocate pair / Load/store register pair /
+ *           1  1 Load/store register / Atomic memory operations
+ */
+DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStOp0Lo)
+    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
+    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
+    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,             /** @todo */
+    DIS_ARMV8_DECODE_MAP_ENTRY(LdStReg),
+DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStOp0Lo, RT_BIT_32(28) | RT_BIT_32(29), 28);
+
 
 /*
@@ -599,7 +676,7 @@
     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /** @todo SVE */
     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Unallocated */
-    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Load/Stores */
+    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
     DIS_ARMV8_DECODE_MAP_ENTRY(LogicalAddSubReg),                   /* Data processing (register) (see op1 in C4.1.68). */
-    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Load/Stores */
+    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Data processing (SIMD & FP) */
     DIS_ARMV8_DECODE_MAP_ENTRY(DataProcessingImm),                  /* Data processing (immediate). */
@@ -607,7 +684,7 @@
     DIS_ARMV8_DECODE_MAP_ENTRY(BrExcpSys),                          /* Branches / Exception generation and system instructions. */
     DIS_ARMV8_DECODE_MAP_ENTRY(BrExcpSys),                          /* Branches / Exception generation and system instructions. */
-    DIS_ARMV8_DECODE_MAP_ENTRY(LdSt),                               /* Load/Stores. */
+    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
     DIS_ARMV8_DECODE_MAP_ENTRY(DataProcReg),                        /* Data processing (register) (see op1 in C4.1.68). */
-    DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,                             /* Load/Stores. */
+    DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo),                          /* Load/Stores. */
     DIS_ARMV8_DECODE_MAP_INVALID_ENTRY                              /* Data processing (SIMD & FP). */
 DIS_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);
Index: /trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S
===================================================================
--- /trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S	(revision 105814)
+++ /trunk/src/VBox/Disassembler/testcase/tstDisasmArmv8-1-asm.S	(revision 105815)
@@ -373,4 +373,28 @@
 
         ; Memory loads
+        ldrb w0, [x28]
+        ldrb w0, [x28, #1]
+        ldrb w0, [x28, #4095]
+
+        ldrsb w0, [x28]
+        ldrsb w0, [x28, #1]
+        ldrsb w0, [x28, #4095]
+
+        ldrsb x0, [x28]
+        ldrsb x0, [x28, #1]
+        ldrsb x0, [x28, #4095]
+
+        ldrh w0, [x28]
+        ldrh w0, [x28, #2]
+        ldrh w0, [x28, #1024]
+
+        ldrsh w0, [x28]
+        ldrsh w0, [x28, #2]
+        ldrsh w0, [x28, #1024]
+
+        ldrsh x0, [x28]
+        ldrsh x0, [x28, #2]
+        ldrsh x0, [x28, #1024]
+
         ldr x0, [x28]
         ldr x0, [x28, #8]
@@ -381,5 +405,17 @@
         ldr w0, [x28, #16380]
 
+        ldrsw x0, [x28]
+        ldrsw x0, [x28, #4]
+        ldrsw x0, [x28, #16380]
+
         ; Memory stores
+        strb w0, [x28]
+        strb w0, [x28, #1]
+        strb w0, [x28, #4095]
+
+        strh w0, [x28]
+        strh w0, [x28, #2]
+        strh w0, [x28, #1024]
+
         str x0, [x28]
         str x0, [x28, #8]
