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 | 0491270f999f32651d50dd1b79fd973d8e01509d (patch) | |
tree | 31fa797d3559c7c2ed3fec842a97441f503f71c9 /llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | |
parent | e106aee6f5737cd478c98f70bac73f1eb089c46f (diff) | |
download | bcm5719-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.cpp | 70 |
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 }; |