[ARM] Accept .w suffixes for some memory instructions
authorJirui Wu <jirui.wu@arm.com>
Tue, 31 Jan 2023 10:11:24 +0000 (10:11 +0000)
committerJirui Wu <jirui.wu@arm.com>
Fri, 24 Feb 2023 09:55:35 +0000 (09:55 +0000)
Some memory instructions in the following sections of Armv7-M ARM allow
the .w mnemonic suffix, even though the preferred disassembly is without
the suffix.

A7.7.46 LDRB (immediate) T3
A7.7.55 LDRH (immediate) T3
A7.7.59 LDRSB (immediate) T2
A7.7.63 LDRSH (immediate) T2
A7.7.163 STRB (immediate) T3
A7.7.170 STRH (immediate) T3

This patch accepts the .w suffixes for theses instructions.
Pseudo-instructions and custom parsing logic are used instead of simple
aliases. More discussions are in these relevant patches:
https://reviews.llvm.org/D68916
https://reviews.llvm.org/D96632

Differential Revision: https://reviews.llvm.org/D142980

llvm/lib/Target/ARM/ARMInstrThumb2.td
llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/test/MC/ARM/basic-thumb2-instructions.s

index 6c47b85..8a11b3e 100644 (file)
@@ -1596,6 +1596,46 @@ def t2LDR_PRE_imm : t2AsmPseudo<"ldr${p}.w $Rt, $addr!",
 def t2LDR_POST_imm : t2AsmPseudo<"ldr${p}.w $Rt, $Rn, $imm",
                          (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
 
+// A7.7.46 LDRB (immediate) T3
+// .w suffixes; Constraints can't be used on t2InstAlias to describe
+// "$Rn =  $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE.
+def t2LDRB_OFFSET_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $addr",
+                         (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>;
+def t2LDRB_PRE_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $addr!",
+                         (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>;
+def t2LDRB_POST_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $Rn, $imm",
+                         (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
+
+// A7.7.55 LDRH (immediate) T3
+// .w suffixes; Constraints can't be used on t2InstAlias to describe
+// "$Rn =  $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE.
+def t2LDRH_OFFSET_imm : t2AsmPseudo<"ldrh${p}.w $Rt, $addr",
+                         (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>;
+def t2LDRH_PRE_imm : t2AsmPseudo<"ldrh${p}.w $Rt, $addr!",
+                         (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>;
+def t2LDRH_POST_imm : t2AsmPseudo<"ldrh${p}.w $Rt, $Rn, $imm",
+                         (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
+
+// A7.7.59 LDRSB (immediate) T2
+// .w suffixes; Constraints can't be used on t2InstAlias to describe
+// "$Rn =  $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE.
+def t2LDRSB_OFFSET_imm : t2AsmPseudo<"ldrsb${p}.w $Rt, $addr",
+                         (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>;
+def t2LDRSB_PRE_imm : t2AsmPseudo<"ldrsb${p}.w $Rt, $addr!",
+                         (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>;
+def t2LDRSB_POST_imm : t2AsmPseudo<"ldrsb${p}.w $Rt, $Rn, $imm",
+                         (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
+
+// A7.7.63 LDRSH (immediate) T2
+// .w suffixes; Constraints can't be used on t2InstAlias to describe
+// "$Rn =  $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE.
+def t2LDRSH_OFFSET_imm : t2AsmPseudo<"ldrsh${p}.w $Rt, $addr",
+                         (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>;
+def t2LDRSH_PRE_imm : t2AsmPseudo<"ldrsh${p}.w $Rt, $addr!",
+                         (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>;
+def t2LDRSH_POST_imm : t2AsmPseudo<"ldrsh${p}.w $Rt, $Rn, $imm",
+                         (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
+
 // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110).
 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
@@ -1762,6 +1802,26 @@ def t2STR_PRE_imm : t2AsmPseudo<"str${p}.w $Rt, $addr!",
 def t2STR_POST_imm : t2AsmPseudo<"str${p}.w $Rt, $Rn, $imm",
   (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
 
+// A7.7.163 STRB (immediate) T3
+// .w suffixes; Constraints can't be used on t2InstAlias to describe
+// "$Rn =  $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE.
+def t2STRB_OFFSET_imm : t2AsmPseudo<"strb${p}.w $Rt, $addr",
+  (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>;
+def t2STRB_PRE_imm : t2AsmPseudo<"strb${p}.w $Rt, $addr!",
+  (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>;
+def t2STRB_POST_imm : t2AsmPseudo<"strb${p}.w $Rt, $Rn, $imm",
+  (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
+
+// A7.7.170 STRH (immediate) T3
+// .w suffixes; Constraints can't be used on t2InstAlias to describe
+// "$Rn =  $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE.
+def t2STRH_OFFSET_imm : t2AsmPseudo<"strh${p}.w $Rt, $addr",
+  (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>;
+def t2STRH_PRE_imm : t2AsmPseudo<"strh${p}.w $Rt, $addr!",
+  (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>;
+def t2STRH_POST_imm : t2AsmPseudo<"strh${p}.w $Rt, $Rn, $imm",
+  (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>;
+
 // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
 // only.
 // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
index c5003da..37852ea 100644 (file)
@@ -7831,6 +7831,107 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
     }
     return false;
   }
+
+  case ARM::t2LDRB_OFFSET_imm:
+  case ARM::t2LDRB_PRE_imm:
+  case ARM::t2LDRB_POST_imm:
+  case ARM::t2STRB_OFFSET_imm:
+  case ARM::t2STRB_PRE_imm:
+  case ARM::t2STRB_POST_imm: {
+    if (Inst.getOpcode() == ARM::t2LDRB_POST_imm ||
+        Inst.getOpcode() == ARM::t2STRB_POST_imm ||
+        Inst.getOpcode() == ARM::t2LDRB_PRE_imm ||
+        Inst.getOpcode() == ARM::t2STRB_PRE_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 255 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [-255, 255]");
+    } else if (Inst.getOpcode() == ARM::t2LDRB_OFFSET_imm ||
+               Inst.getOpcode() == ARM::t2STRB_OFFSET_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 0 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [0, 255] with a negative sign");
+    }
+    if (Inst.getOperand(0).getReg() == ARM::PC) {
+      return Error(Operands[3]->getStartLoc(),
+                   "if operand is PC, should call the LDRB (literal)");
+    }
+    return false;
+  }
+
+  case ARM::t2LDRH_OFFSET_imm:
+  case ARM::t2LDRH_PRE_imm:
+  case ARM::t2LDRH_POST_imm:
+  case ARM::t2STRH_OFFSET_imm:
+  case ARM::t2STRH_PRE_imm:
+  case ARM::t2STRH_POST_imm: {
+    if (Inst.getOpcode() == ARM::t2LDRH_POST_imm ||
+        Inst.getOpcode() == ARM::t2STRH_POST_imm ||
+        Inst.getOpcode() == ARM::t2LDRH_PRE_imm ||
+        Inst.getOpcode() == ARM::t2STRH_PRE_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 255 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [-255, 255]");
+    } else if (Inst.getOpcode() == ARM::t2LDRH_OFFSET_imm ||
+               Inst.getOpcode() == ARM::t2STRH_OFFSET_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 0 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [0, 255] with a negative sign");
+    }
+    if (Inst.getOperand(0).getReg() == ARM::PC) {
+      return Error(Operands[3]->getStartLoc(),
+                   "if operand is PC, should call the LDRH (literal)");
+    }
+    return false;
+  }
+
+  case ARM::t2LDRSB_OFFSET_imm:
+  case ARM::t2LDRSB_PRE_imm:
+  case ARM::t2LDRSB_POST_imm: {
+    if (Inst.getOpcode() == ARM::t2LDRSB_POST_imm ||
+        Inst.getOpcode() == ARM::t2LDRSB_PRE_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 255 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [-255, 255]");
+    } else if (Inst.getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 0 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [0, 255] with a negative sign");
+    }
+    if (Inst.getOperand(0).getReg() == ARM::PC) {
+      return Error(Operands[3]->getStartLoc(),
+                   "if operand is PC, should call the LDRH (literal)");
+    }
+    return false;
+  }
+
+  case ARM::t2LDRSH_OFFSET_imm:
+  case ARM::t2LDRSH_PRE_imm:
+  case ARM::t2LDRSH_POST_imm: {
+    if (Inst.getOpcode() == ARM::t2LDRSH_POST_imm ||
+        Inst.getOpcode() == ARM::t2LDRSH_PRE_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 255 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [-255, 255]");
+    } else if (Inst.getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
+      int Imm = Inst.getOperand(2).getImm();
+      if (Imm > 0 || Imm < -255)
+        return Error(Operands[5]->getStartLoc(),
+                     "operand must be in range [0, 255] with a negative sign");
+    }
+    if (Inst.getOperand(0).getReg() == ARM::PC) {
+      return Error(Operands[3]->getStartLoc(),
+                   "if operand is PC, should call the LDRH (literal)");
+    }
+    return false;
+  }
+
   case ARM::LDR_PRE_IMM:
   case ARM::LDR_PRE_REG:
   case ARM::t2LDR_PRE:
@@ -8849,6 +8950,156 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,
     Inst = TmpInst;
     return true;
   }
+  // Aliases for imm syntax of LDRB instructions.
+  case ARM::t2LDRB_OFFSET_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(ARM::t2LDRBi8);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  case ARM::t2LDRB_PRE_imm:
+  case ARM::t2LDRB_POST_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRB_PRE_imm
+                          ? ARM::t2LDRB_PRE
+                          : ARM::t2LDRB_POST);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  // Aliases for imm syntax of STRB instructions.
+  case ARM::t2STRB_OFFSET_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(ARM::t2STRBi8);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  case ARM::t2STRB_PRE_imm:
+  case ARM::t2STRB_POST_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm
+                          ? ARM::t2STRB_PRE
+                          : ARM::t2STRB_POST);
+    TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  // Aliases for imm syntax of LDRH instructions.
+  case ARM::t2LDRH_OFFSET_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(ARM::t2LDRHi8);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  case ARM::t2LDRH_PRE_imm:
+  case ARM::t2LDRH_POST_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRH_PRE_imm
+                          ? ARM::t2LDRH_PRE
+                          : ARM::t2LDRH_POST);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  // Aliases for imm syntax of STRH instructions.
+  case ARM::t2STRH_OFFSET_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(ARM::t2STRHi8);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  case ARM::t2STRH_PRE_imm:
+  case ARM::t2STRH_POST_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRH_PRE_imm
+                          ? ARM::t2STRH_PRE
+                          : ARM::t2STRH_POST);
+    TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  // Aliases for imm syntax of LDRSB instructions.
+  case ARM::t2LDRSB_OFFSET_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(ARM::t2LDRSBi8);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  case ARM::t2LDRSB_PRE_imm:
+  case ARM::t2LDRSB_POST_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSB_PRE_imm
+                          ? ARM::t2LDRSB_PRE
+                          : ARM::t2LDRSB_POST);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  // Aliases for imm syntax of LDRSH instructions.
+  case ARM::t2LDRSH_OFFSET_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(ARM::t2LDRSHi8);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
+  case ARM::t2LDRSH_PRE_imm:
+  case ARM::t2LDRSH_POST_imm: {
+    MCInst TmpInst;
+    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSH_PRE_imm
+                          ? ARM::t2LDRSH_PRE
+                          : ARM::t2LDRSH_POST);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rt
+    TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // imm
+    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+    Inst = TmpInst;
+    return true;
+  }
   // Aliases for alternate PC+imm syntax of LDR instructions.
   case ARM::t2LDRpcrel:
     // Select the narrow version if the immediate will fit.
index 1492492..98768b5 100644 (file)
@@ -1123,6 +1123,10 @@ adds sp, #-4096
         ldrb lr, [r3], #255
         ldrb r9, [r2], #4
         ldrb r3, [sp], #-4
+        ldrb.w r5, [r5, #-4]
+        ldrb.w r5, [r6, #32]
+        ldrb.w r5, [r8, #255]!
+        ldrb.w r9, [r2], #4
 
 @ CHECK: ldrb  r5, [r5, #-4]           @ encoding: [0x15,0xf8,0x04,0x5c]
 @ CHECK: ldrb.w        r5, [r6, #32]           @ encoding: [0x96,0xf8,0x20,0x50]
@@ -1135,6 +1139,10 @@ adds sp, #-4096
 @ CHECK: ldrb  lr, [r3], #255          @ encoding: [0x13,0xf8,0xff,0xeb]
 @ CHECK: ldrb  r9, [r2], #4            @ encoding: [0x12,0xf8,0x04,0x9b]
 @ CHECK: ldrb  r3, [sp], #-4           @ encoding: [0x1d,0xf8,0x04,0x39]
+@ CHECK: ldrb   r5, [r5, #-4]           @ encoding: [0x15,0xf8,0x04,0x5c]
+@ CHECK: ldrb.w        r5, [r6, #32]           @ encoding: [0x96,0xf8,0x20,0x50]
+@ CHECK: ldrb  r5, [r8, #255]!         @ encoding: [0x18,0xf8,0xff,0x5f]
+@ CHECK: ldrb  r9, [r2], #4            @ encoding: [0x12,0xf8,0x04,0x9b]
 
 
 @------------------------------------------------------------------------------
@@ -1230,6 +1238,10 @@ adds sp, #-4096
         ldrh lr, [r3], #255
         ldrh r9, [r2], #4
         ldrh r3, [sp], #-4
+        ldrh.w r5, [r5, #-4]
+        ldrh.w r5, [r6, #32]
+        ldrh.w r5, [r8, #255]!
+        ldrh.w r9, [r2], #4
 
 @ CHECK: ldrh  r5, [r5, #-4]           @ encoding: [0x35,0xf8,0x04,0x5c]
 @ CHECK: ldrh  r5, [r6, #32]           @ encoding: [0x35,0x8c]
@@ -1242,6 +1254,10 @@ adds sp, #-4096
 @ CHECK: ldrh  lr, [r3], #255          @ encoding: [0x33,0xf8,0xff,0xeb]
 @ CHECK: ldrh  r9, [r2], #4            @ encoding: [0x32,0xf8,0x04,0x9b]
 @ CHECK: ldrh  r3, [sp], #-4           @ encoding: [0x3d,0xf8,0x04,0x39]
+@ CHECK: ldrh  r5, [r5, #-4]           @ encoding: [0x35,0xf8,0x04,0x5c]
+@ CHECK: ldrh.w        r5, [r6, #32]           @ encoding: [0xb6,0xf8,0x20,0x50]
+@ CHECK: ldrh  r5, [r8, #255]!         @ encoding: [0x38,0xf8,0xff,0x5f]
+@ CHECK: ldrh  r9, [r2], #4            @ encoding: [0x32,0xf8,0x04,0x9b]
 
 
 @------------------------------------------------------------------------------
@@ -1295,12 +1311,32 @@ adds sp, #-4096
         ldrsb r5, [r6, #33]
         ldrsb r5, [r6, #257]
         ldrsb.w lr, [r7, #257]
+        ldrsb r5, [r8, #255]!
+        ldrsb r2, [r5, #4]!
+        ldrsb r1, [r4, #-4]!
+        ldrsb lr, [r3], #255
+        ldrsb r9, [r2], #4
+        ldrsb r3, [sp], #-4
+        ldrsb.w r5, [r5, #-4]
+        ldrsb.w r5, [r6, #32]
+        ldrsb.w r5, [r8, #255]!
+        ldrsb.w r9, [r2], #4
 
 @ CHECK: ldrsb r5, [r5, #-4]            @ encoding: [0x15,0xf9,0x04,0x5c]
 @ CHECK: ldrsb.w r5, [r6, #32]           @ encoding: [0x96,0xf9,0x20,0x50]
 @ CHECK: ldrsb.w r5, [r6, #33]           @ encoding: [0x96,0xf9,0x21,0x50]
 @ CHECK: ldrsb.w r5, [r6, #257]          @ encoding: [0x96,0xf9,0x01,0x51]
 @ CHECK: ldrsb.w lr, [r7, #257]          @ encoding: [0x97,0xf9,0x01,0xe1]
+@ CHECK: ldrsb r5, [r8, #255]!          @ encoding: [0x18,0xf9,0xff,0x5f]
+@ CHECK: ldrsb r2, [r5, #4]!            @ encoding: [0x15,0xf9,0x04,0x2f]
+@ CHECK: ldrsb r1, [r4, #-4]!           @ encoding: [0x14,0xf9,0x04,0x1d]
+@ CHECK: ldrsb lr, [r3], #255           @ encoding: [0x13,0xf9,0xff,0xeb]
+@ CHECK: ldrsb r9, [r2], #4             @ encoding: [0x12,0xf9,0x04,0x9b]
+@ CHECK: ldrsb r3, [sp], #-4            @ encoding: [0x1d,0xf9,0x04,0x39]
+@ CHECK: ldrsb r5, [r5, #-4]            @ encoding: [0x15,0xf9,0x04,0x5c]
+@ CHECK: ldrsb.w r5, [r6, #32]           @ encoding: [0x96,0xf9,0x20,0x50]
+@ CHECK: ldrsb r5, [r8, #255]!          @ encoding: [0x18,0xf9,0xff,0x5f]
+@ CHECK: ldrsb  r9, [r2], #4             @ encoding: [0x12,0xf9,0x04,0x9b]
 
 
 @------------------------------------------------------------------------------
@@ -1366,12 +1402,32 @@ adds sp, #-4096
         ldrsh r5, [r6, #33]
         ldrsh r5, [r6, #257]
         ldrsh.w lr, [r7, #257]
+        ldrsh r5, [r8, #255]!
+        ldrsh r2, [r5, #4]!
+        ldrsh r1, [r4, #-4]!
+        ldrsh lr, [r3], #255
+        ldrsh r9, [r2], #4
+        ldrsh r3, [sp], #-4
+        ldrsh.w r5, [r5, #-4]
+        ldrsh.w r5, [r6, #32]
+        ldrsh.w r5, [r8, #255]!
+        ldrsh.w r9, [r2], #4
 
 @ CHECK: ldrsh r5, [r5, #-4]           @ encoding: [0x35,0xf9,0x04,0x5c]
 @ CHECK: ldrsh.w r5, [r6, #32]          @ encoding: [0xb6,0xf9,0x20,0x50]
 @ CHECK: ldrsh.w r5, [r6, #33]          @ encoding: [0xb6,0xf9,0x21,0x50]
 @ CHECK: ldrsh.w r5, [r6, #257]         @ encoding: [0xb6,0xf9,0x01,0x51]
 @ CHECK: ldrsh.w lr, [r7, #257]         @ encoding: [0xb7,0xf9,0x01,0xe1]
+@ CHECK: ldrsh r5, [r8, #255]!         @ encoding: [0x38,0xf9,0xff,0x5f]
+@ CHECK: ldrsh r2, [r5, #4]!           @ encoding: [0x35,0xf9,0x04,0x2f]
+@ CHECK: ldrsh r1, [r4, #-4]!          @ encoding: [0x34,0xf9,0x04,0x1d]
+@ CHECK: ldrsh lr, [r3], #255          @ encoding: [0x33,0xf9,0xff,0xeb]
+@ CHECK: ldrsh r9, [r2], #4            @ encoding: [0x32,0xf9,0x04,0x9b]
+@ CHECK: ldrsh r3, [sp], #-4           @ encoding: [0x3d,0xf9,0x04,0x39]
+@ CHECK: ldrsh r5, [r5, #-4]           @ encoding: [0x35,0xf9,0x04,0x5c]
+@ CHECK: ldrsh.w r5, [r6, #32]          @ encoding: [0xb6,0xf9,0x20,0x50]
+@ CHECK: ldrsh r5, [r8, #255]!         @ encoding: [0x38,0xf9,0xff,0x5f]
+@ CHECK: ldrsh  r9, [r2], #4            @ encoding: [0x32,0xf9,0x04,0x9b]
 
 
 @------------------------------------------------------------------------------
@@ -3066,6 +3122,10 @@ adds sp, #-4096
         strb r3, [sp], #-4
         strb r4, [r8, #-0]!
         strb r1, [r0], #-0
+        strb.w r5, [r5, #-4]
+        strb.w r5, [r6, #32]
+        strb.w r5, [r8, #255]!
+        strb.w r9, [r2], #4
 
 @ CHECK: strb  r5, [r5, #-4]           @ encoding: [0x05,0xf8,0x04,0x5c]
 @ CHECK: strb.w        r5, [r6, #32]           @ encoding: [0x86,0xf8,0x20,0x50]
@@ -3080,6 +3140,10 @@ adds sp, #-4096
 @ CHECK: strb  r3, [sp], #-4           @ encoding: [0x0d,0xf8,0x04,0x39]
 @ CHECK: strb  r4, [r8, #-0]!          @ encoding: [0x08,0xf8,0x00,0x4d]
 @ CHECK: strb  r1, [r0], #-0           @ encoding: [0x00,0xf8,0x00,0x19]
+@ CHECK: strb  r5, [r5, #-4]           @ encoding: [0x05,0xf8,0x04,0x5c]
+@ CHECK: strb.w        r5, [r6, #32]           @ encoding: [0x86,0xf8,0x20,0x50]
+@ CHECK: strb  r5, [r8, #255]!         @ encoding: [0x08,0xf8,0xff,0x5f]
+@ CHECK: strb  r9, [r2], #4            @ encoding: [0x02,0xf8,0x04,0x9b]
 
 
 @------------------------------------------------------------------------------
@@ -3176,6 +3240,10 @@ adds sp, #-4096
         strh lr, [r3], #255
         strh r9, [r2], #4
         strh r3, [sp], #-4
+        strh.w r5, [r5, #-4]
+        strh.w r5, [r6, #32]
+        strh.w r5, [r8, #255]!
+        strh.w r9, [r2], #4
 
 @ CHECK: strh  r5, [r5, #-4]           @ encoding: [0x25,0xf8,0x04,0x5c]
 @ CHECK: strh  r5, [r6, #32]           @ encoding: [0x35,0x84]
@@ -3188,6 +3256,10 @@ adds sp, #-4096
 @ CHECK: strh  lr, [r3], #255          @ encoding: [0x23,0xf8,0xff,0xeb]
 @ CHECK: strh  r9, [r2], #4            @ encoding: [0x22,0xf8,0x04,0x9b]
 @ CHECK: strh  r3, [sp], #-4           @ encoding: [0x2d,0xf8,0x04,0x39]
+@ CHECK: strh  r5, [r5, #-4]           @ encoding: [0x25,0xf8,0x04,0x5c]
+@ CHECK: strh.w        r5, [r6, #32]           @ encoding: [0xa6,0xf8,0x20,0x50]
+@ CHECK: strh  r5, [r8, #255]!         @ encoding: [0x28,0xf8,0xff,0x5f]
+@ CHECK: strh  r9, [r2], #4            @ encoding: [0x22,0xf8,0x04,0x9b]
 
 
 @------------------------------------------------------------------------------