diff options
author | Owen Anderson <resistor@mac.com> | 2011-07-21 23:38:37 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-07-21 23:38:37 +0000 |
commit | 152d4a4bb6b75de740b4b8a9f48abb9069d50c17 (patch) | |
tree | 75a3b965a0f354f467e1d6e4b4930deaad0530e8 /lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | |
parent | 856e13ddace4174ad1b07f65ebb18b2fd835ed57 (diff) |
Get rid of the extraneous GPR operand on so_reg_imm operands, which in turn necessitates a lot of changes to related bits.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135722 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp')
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | 70 |
1 files changed, 68 insertions, 2 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 }; |