aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/Disassembler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/Disassembler')
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp70
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.h5
2 files changed, 71 insertions, 4 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index d40a9f7b14..40e48129a8 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -1090,7 +1090,7 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
-static bool DisassembleDPSoRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
+static bool DisassembleDPSoRegRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const MCInstrDesc &MCID = ARMInsts[Opcode];
@@ -1180,6 +1180,69 @@ static bool DisassembleDPSoRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
+static bool DisassembleDPSoRegImmFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+
+ const MCInstrDesc &MCID = ARMInsts[Opcode];
+ unsigned short NumDefs = MCID.getNumDefs();
+ bool isUnary = isUnaryDP(MCID.TSFlags);
+ const MCOperandInfo *OpInfo = MCID.OpInfo;
+ unsigned &OpIdx = NumOpsAdded;
+
+ OpIdx = 0;
+
+ // Disassemble register def if there is one.
+ if (NumDefs && (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID)) {
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ decodeRd(insn))));
+ ++OpIdx;
+ }
+
+ // Disassemble the src operands.
+ if (OpIdx >= NumOps)
+ return false;
+
+ // BinaryDP has an Rn operand.
+ if (!isUnary) {
+ assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
+ "Reg operand expected");
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ decodeRn(insn))));
+ ++OpIdx;
+ }
+
+ // If this is a two-address operand, skip it, e.g., MOVCCs operand 1.
+ if (isUnary && (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)) {
+ MI.addOperand(MCOperand::CreateReg(0));
+ ++OpIdx;
+ }
+
+ // Disassemble operand 2, which consists of two components.
+ if (OpIdx + 1 >= NumOps)
+ return false;
+
+ assert((OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) &&
+ (OpInfo[OpIdx+1].RegClass < 0) &&
+ "Expect 2 reg operands");
+
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ decodeRm(insn))));
+
+ // Inst{6-5} encodes the shift opcode.
+ ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
+ // Inst{11-7} encodes the imm5 shift amount.
+ unsigned ShImm = slice(insn, 11, 7);
+
+ // A8.4.1. Possible rrx or shift amount of 32...
+ getImmShiftSE(ShOp, ShImm);
+ MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShImm)));
+
+ OpIdx += 2;
+
+ return true;
+}
+
+
static bool BadRegsLdStFrm(unsigned Opcode, uint32_t insn, bool Store, bool WBack,
bool Imm) {
const StringRef Name = ARMInsts[Opcode].Name;
@@ -3484,7 +3547,7 @@ static const DisassembleFP FuncPtrs[] = {
&DisassembleBrFrm,
&DisassembleBrMiscFrm,
&DisassembleDPFrm,
- &DisassembleDPSoRegFrm,
+ &DisassembleDPSoRegRegFrm,
&DisassembleLdFrm,
&DisassembleStFrm,
&DisassembleLdMiscFrm,
@@ -3552,6 +3615,9 @@ static const DisassembleFP FuncPtrs[] = {
// values in a table and generate a new vector.
&DisassembleNVTBLFrm,
+ &DisassembleDPSoRegImmFrm,
+
+
NULL
};
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
index a7ba14141c..c1ebd3edf8 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
@@ -51,7 +51,7 @@ public:
ENTRY(ARM_FORMAT_BRFRM, 2) \
ENTRY(ARM_FORMAT_BRMISCFRM, 3) \
ENTRY(ARM_FORMAT_DPFRM, 4) \
- ENTRY(ARM_FORMAT_DPSOREGFRM, 5) \
+ ENTRY(ARM_FORMAT_DPSOREGREGFRM, 5) \
ENTRY(ARM_FORMAT_LDFRM, 6) \
ENTRY(ARM_FORMAT_STFRM, 7) \
ENTRY(ARM_FORMAT_LDMISCFRM, 8) \
@@ -87,7 +87,8 @@ public:
ENTRY(ARM_FORMAT_N3RegVecSh, 38) \
ENTRY(ARM_FORMAT_NVecExtract, 39) \
ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
- ENTRY(ARM_FORMAT_NVTBL, 41)
+ ENTRY(ARM_FORMAT_NVTBL, 41) \
+ ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42)
// ARM instruction format specifies the encoding used by the instruction.
#define ENTRY(n, v) n = v,