[Lldb-commits] [lldb] [lldb/aarch64] Add STR/LDR instructions for FP register to Emulator (PR #168187)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Mon Nov 17 06:50:04 PST 2025


================
@@ -930,9 +940,27 @@ template <EmulateInstructionARM64::AddrMode a_mode>
 bool EmulateInstructionARM64::EmulateLDRSTRImm(const uint32_t opcode) {
   uint32_t size = Bits32(opcode, 31, 30);
   uint32_t opc = Bits32(opcode, 23, 22);
+  uint32_t vr = Bit32(opcode, 26);
   uint32_t n = Bits32(opcode, 9, 5);
   uint32_t t = Bits32(opcode, 4, 0);
 
+  MemOp memop;
+  if (vr) {
+    if (Bit32(opc, 1) == 1)
+      size += 4;
----------------
DavidSpickett wrote:

Took me a while to realise what this was doing (not because you were being cryptic, because instruction encodings aren't always straightforward). I'm looking at one of the instructions, "C7.2.208 LDR (immediate, SIMD&FP)" in the Arm manual.

The sizes when opc is 01 are - 0 =1 byte, 1 = 2 bytes, 2 = 4 bytes, 3 = 8 bytes. Size 0 and opc 11 means 128-bit, but we can think of that as size being 4 (though it is only a 2 bit field in reality).

Which means `register size (in bits) = 2 ^ (3+ size)`. Makes sense since the minimum is 8 bit.

Please add a comment to explain the 4. Maybe:
```
// When opc == 01, size can be 0 (1 byte) to 3 (8 bytes). 128-bit registers are encoded using opc == 11, and size 0, but we can handle this as size 4, to continue the pattern:
// register size (bits) = 2 ^ (3 + size)
```

https://github.com/llvm/llvm-project/pull/168187


More information about the lldb-commits mailing list