summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-07-21 23:38:37 +0000
committerOwen Anderson <resistor@mac.com>2011-07-21 23:38:37 +0000
commit0491270f999f32651d50dd1b79fd973d8e01509d (patch)
tree31fa797d3559c7c2ed3fec842a97441f503f71c9 /llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
parente106aee6f5737cd478c98f70bac73f1eb089c46f (diff)
downloadbcm5719-llvm-0491270f999f32651d50dd1b79fd973d8e01509d.tar.gz
bcm5719-llvm-0491270f999f32651d50dd1b79fd973d8e01509d.zip
Get rid of the extraneous GPR operand on so_reg_imm operands, which in turn necessitates a lot of changes to related bits.
llvm-svn: 135722
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp')
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp70
1 files changed, 68 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index d40a9f7b14b..40e48129a8a 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/llvm/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
};
OpenPOWER on IntegriCloud