Skip to content

Conversation

jurahul
Copy link
Contributor

@jurahul jurahul commented Sep 4, 2025

Move all decode functions (except DecodeT2AddrModeImm8) that had forward declarations around so that they are defined before their first use and not need a forward declaration.

Work on #156560 : Reorder ARM disassembler decode functions to eliminate forward declarations

Copy link

github-actions bot commented Sep 4, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions cpp -- llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 1d19bc89c..6f572d775 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -572,10 +572,9 @@ static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
   return MCDisassembler::Success;
 }
 
-static const MCPhysReg QQPRDecoderTable[] = {
-     ARM::Q0_Q1,  ARM::Q1_Q2,  ARM::Q2_Q3,  ARM::Q3_Q4,
-     ARM::Q4_Q5,  ARM::Q5_Q6,  ARM::Q6_Q7
-};
+static const MCPhysReg QQPRDecoderTable[] = {ARM::Q0_Q1, ARM::Q1_Q2, ARM::Q2_Q3,
+                                             ARM::Q3_Q4, ARM::Q4_Q5, ARM::Q5_Q6,
+                                             ARM::Q6_Q7};
 
 static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
                                              uint64_t Address,
@@ -589,9 +588,8 @@ static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
 }
 
 static const MCPhysReg QQQQPRDecoderTable[] = {
-     ARM::Q0_Q1_Q2_Q3,  ARM::Q1_Q2_Q3_Q4,  ARM::Q2_Q3_Q4_Q5,
-     ARM::Q3_Q4_Q5_Q6,  ARM::Q4_Q5_Q6_Q7
-};
+    ARM::Q0_Q1_Q2_Q3, ARM::Q1_Q2_Q3_Q4, ARM::Q2_Q3_Q4_Q5, ARM::Q3_Q4_Q5_Q6,
+    ARM::Q4_Q5_Q6_Q7};
 
 static DecodeStatus DecodeMQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
                                                uint64_t Address,
@@ -1424,7 +1422,8 @@ static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
   // return failure here.  The '01' imod value is unprintable, so there's
   // nothing useful we could do even if we returned UNPREDICTABLE.
 
-  if (imod == 1) return MCDisassembler::Fail;
+  if (imod == 1)
+    return MCDisassembler::Fail;
 
   if (imod && M) {
     Inst.setOpcode(ARM::CPS3p);
@@ -1435,11 +1434,13 @@ static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
     Inst.setOpcode(ARM::CPS2p);
     Inst.addOperand(MCOperand::createImm(imod));
     Inst.addOperand(MCOperand::createImm(iflags));
-    if (mode) S = MCDisassembler::SoftFail;
+    if (mode)
+      S = MCDisassembler::SoftFail;
   } else if (!imod && M) {
     Inst.setOpcode(ARM::CPS1p);
     Inst.addOperand(MCOperand::createImm(mode));
-    if (iflags) S = MCDisassembler::SoftFail;
+    if (iflags)
+      S = MCDisassembler::SoftFail;
   } else {
     // imod == '00' && M == '0' --> UNPREDICTABLE
     Inst.setOpcode(ARM::CPS1p);
@@ -2488,9 +2489,12 @@ static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
                                             const MCDisassembler *Decoder) {
   unsigned type = fieldFromInstruction(Insn, 8, 4);
   unsigned align = fieldFromInstruction(Insn, 4, 2);
-  if (type == 6 && (align & 2)) return MCDisassembler::Fail;
-  if (type == 7 && (align & 2)) return MCDisassembler::Fail;
-  if (type == 10 && align == 3) return MCDisassembler::Fail;
+  if (type == 6 && (align & 2))
+    return MCDisassembler::Fail;
+  if (type == 7 && (align & 2))
+    return MCDisassembler::Fail;
+  if (type == 10 && align == 3)
+    return MCDisassembler::Fail;
 
   unsigned load = fieldFromInstruction(Insn, 21, 1);
   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
@@ -2501,12 +2505,15 @@ static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
   unsigned size = fieldFromInstruction(Insn, 6, 2);
-  if (size == 3) return MCDisassembler::Fail;
+  if (size == 3)
+    return MCDisassembler::Fail;
 
   unsigned type = fieldFromInstruction(Insn, 8, 4);
   unsigned align = fieldFromInstruction(Insn, 4, 2);
-  if (type == 8 && align == 3) return MCDisassembler::Fail;
-  if (type == 9 && align == 3) return MCDisassembler::Fail;
+  if (type == 8 && align == 3)
+    return MCDisassembler::Fail;
+  if (type == 9 && align == 3)
+    return MCDisassembler::Fail;
 
   unsigned load = fieldFromInstruction(Insn, 21, 1);
   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
@@ -2517,10 +2524,12 @@ static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
   unsigned size = fieldFromInstruction(Insn, 6, 2);
-  if (size == 3) return MCDisassembler::Fail;
+  if (size == 3)
+    return MCDisassembler::Fail;
 
   unsigned align = fieldFromInstruction(Insn, 4, 2);
-  if (align & 2) return MCDisassembler::Fail;
+  if (align & 2)
+    return MCDisassembler::Fail;
 
   unsigned load = fieldFromInstruction(Insn, 21, 1);
   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
@@ -2531,7 +2540,8 @@ static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
   unsigned size = fieldFromInstruction(Insn, 6, 2);
-  if (size == 3) return MCDisassembler::Fail;
+  if (size == 3)
+    return MCDisassembler::Fail;
 
   unsigned load = fieldFromInstruction(Insn, 21, 1);
   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
@@ -3059,21 +3069,21 @@ static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
 
   if (Rt == 15) {
     switch (Inst.getOpcode()) {
-      case ARM::t2LDRBpci:
-      case ARM::t2LDRHpci:
-        Inst.setOpcode(ARM::t2PLDpci);
-        break;
-      case ARM::t2LDRSBpci:
-        Inst.setOpcode(ARM::t2PLIpci);
-        break;
-      case ARM::t2LDRSHpci:
-        return MCDisassembler::Fail;
-      default:
-        break;
+    case ARM::t2LDRBpci:
+    case ARM::t2LDRHpci:
+      Inst.setOpcode(ARM::t2PLDpci);
+      break;
+    case ARM::t2LDRSBpci:
+      Inst.setOpcode(ARM::t2PLIpci);
+      break;
+    case ARM::t2LDRSHpci:
+      return MCDisassembler::Fail;
+    default:
+      break;
     }
   }
 
-  switch(Inst.getOpcode()) {
+  switch (Inst.getOpcode()) {
   case ARM::t2PLDpci:
     break;
   case ARM::t2PLIpci:

@jurahul jurahul marked this pull request as ready for review September 4, 2025 16:51
@llvmbot
Copy link
Member

llvmbot commented Sep 4, 2025

@llvm/pr-subscribers-backend-arm

Author: Rahul Joshi (jurahul)

Changes

Move all decode functions (except DecodeT2AddrModeImm8) that had forward declarations around so that they are defined before their first use and not need a forward declaration.

Work on #156560 : Reorder ARM disassembler decode functions to eliminate forward declarations


Patch is 25.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/156920.diff

1 Files Affected:

  • (modified) llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (+264-294)
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 41d554f2cece9..1d19bc89ccf92 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -161,47 +161,13 @@ class ARMDisassembler : public MCDisassembler {
 
 // Forward declare these because the autogenerated code will reference them.
 // Definitions are further down.
-static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder);
-static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
-
-static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
-                                         uint64_t Address,
-                                         const MCDisassembler *Decoder);
-
-static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
-
-static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
-                                         uint64_t Address,
-                                         const MCDisassembler *Decoder);
-
-static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder);
-
-static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
-                                      uint64_t Address,
-                                      const MCDisassembler *Decoder);
-
 static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);
 
-static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
-                                          uint64_t Address,
-                                          const MCDisassembler *Decoder);
-
 typedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);
-template <bool scalar, OperandDecoder predicate_decoder>
-static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
-                                  const MCDisassembler *Decoder);
 
 /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
 /// immediate Value in the MCInst.  The immediate Value has had any PC
@@ -239,6 +205,8 @@ static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
   Decoder->tryAddingPcLoadReferenceComment(Value, Address);
 }
 
+// Register class decoding functions.
+
 static const uint16_t GPRDecoderTable[] = {
   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
@@ -593,6 +561,51 @@ DecodeDPairSpacedRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
+                                            uint64_t Address,
+                                            const MCDisassembler *Decoder) {
+  if (RegNo > 7)
+    return MCDisassembler::Fail;
+
+  unsigned Register = QPRDecoderTable[RegNo];
+  Inst.addOperand(MCOperand::createReg(Register));
+  return MCDisassembler::Success;
+}
+
+static const MCPhysReg QQPRDecoderTable[] = {
+     ARM::Q0_Q1,  ARM::Q1_Q2,  ARM::Q2_Q3,  ARM::Q3_Q4,
+     ARM::Q4_Q5,  ARM::Q5_Q6,  ARM::Q6_Q7
+};
+
+static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
+                                             uint64_t Address,
+                                             const MCDisassembler *Decoder) {
+  if (RegNo > 6)
+    return MCDisassembler::Fail;
+
+  unsigned Register = QQPRDecoderTable[RegNo];
+  Inst.addOperand(MCOperand::createReg(Register));
+  return MCDisassembler::Success;
+}
+
+static const MCPhysReg QQQQPRDecoderTable[] = {
+     ARM::Q0_Q1_Q2_Q3,  ARM::Q1_Q2_Q3_Q4,  ARM::Q2_Q3_Q4_Q5,
+     ARM::Q3_Q4_Q5_Q6,  ARM::Q4_Q5_Q6_Q7
+};
+
+static DecodeStatus DecodeMQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
+                                               uint64_t Address,
+                                               const MCDisassembler *Decoder) {
+  if (RegNo > 4)
+    return MCDisassembler::Fail;
+
+  unsigned Register = QQQQPRDecoderTable[RegNo];
+  Inst.addOperand(MCOperand::createReg(Register));
+  return MCDisassembler::Success;
+}
+
+// Operand decoding functions.
+
 static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
@@ -1389,6 +1402,54 @@ static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
   return S;
 }
 
+static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
+                                         uint64_t Address,
+                                         const MCDisassembler *Decoder) {
+  unsigned imod = fieldFromInstruction(Insn, 18, 2);
+  unsigned M = fieldFromInstruction(Insn, 17, 1);
+  unsigned iflags = fieldFromInstruction(Insn, 6, 3);
+  unsigned mode = fieldFromInstruction(Insn, 0, 5);
+
+  DecodeStatus S = MCDisassembler::Success;
+
+  // This decoder is called from multiple location that do not check
+  // the full encoding is valid before they do.
+  if (fieldFromInstruction(Insn, 5, 1) != 0 ||
+      fieldFromInstruction(Insn, 16, 1) != 0 ||
+      fieldFromInstruction(Insn, 20, 8) != 0x10)
+    return MCDisassembler::Fail;
+
+  // imod == '01' --> UNPREDICTABLE
+  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
+  // return failure here.  The '01' imod value is unprintable, so there's
+  // nothing useful we could do even if we returned UNPREDICTABLE.
+
+  if (imod == 1) return MCDisassembler::Fail;
+
+  if (imod && M) {
+    Inst.setOpcode(ARM::CPS3p);
+    Inst.addOperand(MCOperand::createImm(imod));
+    Inst.addOperand(MCOperand::createImm(iflags));
+    Inst.addOperand(MCOperand::createImm(mode));
+  } else if (imod && !M) {
+    Inst.setOpcode(ARM::CPS2p);
+    Inst.addOperand(MCOperand::createImm(imod));
+    Inst.addOperand(MCOperand::createImm(iflags));
+    if (mode) S = MCDisassembler::SoftFail;
+  } else if (!imod && M) {
+    Inst.setOpcode(ARM::CPS1p);
+    Inst.addOperand(MCOperand::createImm(mode));
+    if (iflags) S = MCDisassembler::SoftFail;
+  } else {
+    // imod == '00' && M == '0' --> UNPREDICTABLE
+    Inst.setOpcode(ARM::CPS1p);
+    Inst.addOperand(MCOperand::createImm(mode));
+    S = MCDisassembler::SoftFail;
+  }
+
+  return S;
+}
+
 static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
@@ -1529,54 +1590,6 @@ static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
   return S;
 }
 
-static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
-                                         uint64_t Address,
-                                         const MCDisassembler *Decoder) {
-  unsigned imod = fieldFromInstruction(Insn, 18, 2);
-  unsigned M = fieldFromInstruction(Insn, 17, 1);
-  unsigned iflags = fieldFromInstruction(Insn, 6, 3);
-  unsigned mode = fieldFromInstruction(Insn, 0, 5);
-
-  DecodeStatus S = MCDisassembler::Success;
-
-  // This decoder is called from multiple location that do not check
-  // the full encoding is valid before they do.
-  if (fieldFromInstruction(Insn, 5, 1) != 0 ||
-      fieldFromInstruction(Insn, 16, 1) != 0 ||
-      fieldFromInstruction(Insn, 20, 8) != 0x10)
-    return MCDisassembler::Fail;
-
-  // imod == '01' --> UNPREDICTABLE
-  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
-  // return failure here.  The '01' imod value is unprintable, so there's
-  // nothing useful we could do even if we returned UNPREDICTABLE.
-
-  if (imod == 1) return MCDisassembler::Fail;
-
-  if (imod && M) {
-    Inst.setOpcode(ARM::CPS3p);
-    Inst.addOperand(MCOperand::createImm(imod));
-    Inst.addOperand(MCOperand::createImm(iflags));
-    Inst.addOperand(MCOperand::createImm(mode));
-  } else if (imod && !M) {
-    Inst.setOpcode(ARM::CPS2p);
-    Inst.addOperand(MCOperand::createImm(imod));
-    Inst.addOperand(MCOperand::createImm(iflags));
-    if (mode) S = MCDisassembler::SoftFail;
-  } else if (!imod && M) {
-    Inst.setOpcode(ARM::CPS1p);
-    Inst.addOperand(MCOperand::createImm(mode));
-    if (iflags) S = MCDisassembler::SoftFail;
-  } else {
-    // imod == '00' && M == '0' --> UNPREDICTABLE
-    Inst.setOpcode(ARM::CPS1p);
-    Inst.addOperand(MCOperand::createImm(mode));
-    S = MCDisassembler::SoftFail;
-  }
-
-  return S;
-}
-
 static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
@@ -1727,28 +1740,6 @@ static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
   return S;
 }
 
-static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
-                                         uint64_t Address,
-                                         const MCDisassembler *Decoder) {
-  DecodeStatus S = MCDisassembler::Success;
-
-  unsigned Pred = fieldFromInstruction(Insn, 28, 4);
-  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
-  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
-
-  if (Pred == 0xF)
-    return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
-
-  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
-    return MCDisassembler::Fail;
-  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
-    return MCDisassembler::Fail;
-  if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
-    return MCDisassembler::Fail;
-
-  return S;
-}
-
 static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
@@ -1778,6 +1769,28 @@ static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
   return S;
 }
 
+static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
+                                         uint64_t Address,
+                                         const MCDisassembler *Decoder) {
+  DecodeStatus S = MCDisassembler::Success;
+
+  unsigned Pred = fieldFromInstruction(Insn, 28, 4);
+  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
+  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
+
+  if (Pred == 0xF)
+    return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
+
+  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+    return MCDisassembler::Fail;
+  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
+    return MCDisassembler::Fail;
+  if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
+    return MCDisassembler::Fail;
+
+  return S;
+}
+
 static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
                                                uint64_t Address,
                                                const MCDisassembler *Decoder) {
@@ -2199,61 +2212,6 @@ static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
   return S;
 }
 
-static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder) {
-  unsigned type = fieldFromInstruction(Insn, 8, 4);
-  unsigned align = fieldFromInstruction(Insn, 4, 2);
-  if (type == 6 && (align & 2)) return MCDisassembler::Fail;
-  if (type == 7 && (align & 2)) return MCDisassembler::Fail;
-  if (type == 10 && align == 3) return MCDisassembler::Fail;
-
-  unsigned load = fieldFromInstruction(Insn, 21, 1);
-  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
-              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
-}
-
-static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder) {
-  unsigned size = fieldFromInstruction(Insn, 6, 2);
-  if (size == 3) return MCDisassembler::Fail;
-
-  unsigned type = fieldFromInstruction(Insn, 8, 4);
-  unsigned align = fieldFromInstruction(Insn, 4, 2);
-  if (type == 8 && align == 3) return MCDisassembler::Fail;
-  if (type == 9 && align == 3) return MCDisassembler::Fail;
-
-  unsigned load = fieldFromInstruction(Insn, 21, 1);
-  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
-              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
-}
-
-static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder) {
-  unsigned size = fieldFromInstruction(Insn, 6, 2);
-  if (size == 3) return MCDisassembler::Fail;
-
-  unsigned align = fieldFromInstruction(Insn, 4, 2);
-  if (align & 2) return MCDisassembler::Fail;
-
-  unsigned load = fieldFromInstruction(Insn, 21, 1);
-  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
-              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
-}
-
-static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder) {
-  unsigned size = fieldFromInstruction(Insn, 6, 2);
-  if (size == 3) return MCDisassembler::Fail;
-
-  unsigned load = fieldFromInstruction(Insn, 21, 1);
-  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
-              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
-}
-
 static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder) {
@@ -2522,7 +2480,62 @@ static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
       break;
   }
 
-  return S;
+  return S;
+}
+
+static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
+                                            uint64_t Address,
+                                            const MCDisassembler *Decoder) {
+  unsigned type = fieldFromInstruction(Insn, 8, 4);
+  unsigned align = fieldFromInstruction(Insn, 4, 2);
+  if (type == 6 && (align & 2)) return MCDisassembler::Fail;
+  if (type == 7 && (align & 2)) return MCDisassembler::Fail;
+  if (type == 10 && align == 3) return MCDisassembler::Fail;
+
+  unsigned load = fieldFromInstruction(Insn, 21, 1);
+  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
+              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
+}
+
+static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
+                                            uint64_t Address,
+                                            const MCDisassembler *Decoder) {
+  unsigned size = fieldFromInstruction(Insn, 6, 2);
+  if (size == 3) return MCDisassembler::Fail;
+
+  unsigned type = fieldFromInstruction(Insn, 8, 4);
+  unsigned align = fieldFromInstruction(Insn, 4, 2);
+  if (type == 8 && align == 3) return MCDisassembler::Fail;
+  if (type == 9 && align == 3) return MCDisassembler::Fail;
+
+  unsigned load = fieldFromInstruction(Insn, 21, 1);
+  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
+              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
+}
+
+static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
+                                            uint64_t Address,
+                                            const MCDisassembler *Decoder) {
+  unsigned size = fieldFromInstruction(Insn, 6, 2);
+  if (size == 3) return MCDisassembler::Fail;
+
+  unsigned align = fieldFromInstruction(Insn, 4, 2);
+  if (align & 2) return MCDisassembler::Fail;
+
+  unsigned load = fieldFromInstruction(Insn, 21, 1);
+  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
+              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
+}
+
+static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
+                                            uint64_t Address,
+                                            const MCDisassembler *Decoder) {
+  unsigned size = fieldFromInstruction(Insn, 6, 2);
+  if (size == 3) return MCDisassembler::Fail;
+
+  unsigned load = fieldFromInstruction(Insn, 21, 1);
+  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
+              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
 }
 
 static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
@@ -3030,6 +3043,60 @@ static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
   return S;
 }
 
+static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
+                                      uint64_t Address,
+                                      const MCDisassembler *Decoder) {
+  DecodeStatus S = MCDisassembler::Success;
+
+  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
+  unsigned U = fieldFromInstruction(Insn, 23, 1);
+  int imm = fieldFromInstruction(Insn, 0, 12);
+
+  const FeatureBitset &featureBits =
+      Decoder->getSubtargetInfo().getFeatureBits();
+
+  bool hasV7Ops = featureBits[ARM::HasV7Ops];
+
+  if (Rt == 15) {
+    switch (Inst.getOpcode()) {
+      case ARM::t2LDRBpci:
+      case ARM::t2LDRHpci:
+        Inst.setOpcode(ARM::t2PLDpci);
+        break;
+      case ARM::t2LDRSBpci:
+        Inst.setOpcode(ARM::t2PLIpci);
+        break;
+      case ARM::t2LDRSHpci:
+        return MCDisassembler::Fail;
+      default:
+        break;
+    }
+  }
+
+  switch(Inst.getOpcode()) {
+  case ARM::t2PLDpci:
+    break;
+  case ARM::t2PLIpci:
+    if (!hasV7Ops)
+      return MCDisassembler::Fail;
+    break;
+  default:
+    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
+      return MCDisassembler::Fail;
+  }
+
+  if (!U) {
+    // Special case for #-0.
+    if (imm == 0)
+      imm = INT32_MIN;
+    else
+      imm = -imm;
+  }
+  Inst.addOperand(MCOperand::createImm(imm));
+
+  return S;
+}
+
 static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
@@ -3199,6 +3266,33 @@ static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
   return S;
 }
 
+static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
+                                          uint64_t Address,
+                                          const MCDisassembler *Decoder) {
+  DecodeStatus S = MCDisassembler::Success;
+
+  unsigned Rn = fieldFromInstruction(Val, 13, 4);
+  unsigned imm = fieldFromInstruction(Val, 0, 12);
+
+  // Thumb stores cannot use PC as dest register.
+  switch (Inst.getOpcode()) {
+  case ARM::t2STRi12:
+  case ARM::t2STRBi12:
+  case ARM::t2STRHi12:
+    if (Rn == 15)
+      return MCDisassembler::Fail;
+    break;
+  default:
+    break;
+  }
+
+  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
+    return MCDisassembler::Fail;
+  Inst.addOperand(MCOperand::createImm(imm));
+
+  return S;
+}
+
 static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
@@ -3319,60 +3413,6 @@ static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, uint64_t Address,
   return S;
 }
 
-static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsign...
[truncated]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants