diff options
author | Bob Wilson <bob.wilson@apple.com> | 2010-08-11 00:01:18 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2010-08-11 00:01:18 +0000 |
commit | 9a1c189d9e7472f336f3c6d61be76bc46b25749e (patch) | |
tree | ec4aba2f13b3c97383a34d3dcbe9fa0b768a8c46 /lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | |
parent | 0a16b22e64336d01967bc2a25c7c3a3bde0358af (diff) |
Add a separate ARM instruction format for Saturate instructions.
(I discovered 2 more copies of the ARM instruction format list, bringing the
total to 4!! Two of them were already out of sync. I haven't yet gotten into
the disassembler enough to know the best way to fix this, but something needs
to be done.) Add support for encoding these instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110754 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp')
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | 90 |
1 files changed, 34 insertions, 56 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index d2fd8bde80..f9c57634ef 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -908,34 +908,6 @@ static inline bool getBFCInvMask(uint32_t insn, uint32_t &mask) { return true; } -static inline bool SaturateOpcode(unsigned Opcode) { - switch (Opcode) { - case ARM::SSATlsl: case ARM::SSATasr: case ARM::SSAT16: - case ARM::USATlsl: case ARM::USATasr: case ARM::USAT16: - return true; - default: - return false; - } -} - -static inline unsigned decodeSaturatePos(unsigned Opcode, uint32_t insn) { - switch (Opcode) { - case ARM::SSATlsl: - case ARM::SSATasr: - return slice(insn, 20, 16) + 1; - case ARM::SSAT16: - return slice(insn, 19, 16) + 1; - case ARM::USATlsl: - case ARM::USATasr: - return slice(insn, 20, 16); - case ARM::USAT16: - return slice(insn, 19, 16); - default: - assert(0 && "Invalid opcode passed in"); - return 0; - } -} - // A major complication is the fact that some of the saturating add/subtract // operations have Rd Rm Rn, instead of the "normal" Rd Rn Rm. // They are QADD, QDADD, QDSUB, and QSUB. @@ -961,34 +933,6 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn, if (OpIdx >= NumOps) return false; - // SSAT/SSAT16/USAT/USAT16 has imm operand after Rd. - if (SaturateOpcode(Opcode)) { - MI.addOperand(MCOperand::CreateImm(decodeSaturatePos(Opcode, insn))); - - MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, - decodeRm(insn)))); - - if (Opcode == ARM::SSAT16 || Opcode == ARM::USAT16) { - OpIdx += 2; - return true; - } - - // For SSAT operand reg (Rm) has been disassembled above. - // Now disassemble the shift amount. - - // Inst{11-7} encodes the imm5 shift amount. - unsigned ShAmt = slice(insn, 11, 7); - - // A8.6.183. Possible ASR shift amount of 32... - if (Opcode == ARM::SSATasr && ShAmt == 0) - ShAmt = 32; - - MI.addOperand(MCOperand::CreateImm(ShAmt)); - - OpIdx += 3; - return true; - } - // Special-case handling of BFC/BFI/SBFX/UBFX. if (Opcode == ARM::BFC || Opcode == ARM::BFI) { MI.addOperand(MCOperand::CreateReg(0)); @@ -1509,6 +1453,39 @@ static bool DisassembleArithMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, return true; } +/// DisassembleSatFrm - Disassemble saturate instructions: +/// SSAT, SSAT16, USAT, and USAT16. +static bool DisassembleSatFrm(MCInst &MI, unsigned Opcode, uint32_t insn, + unsigned short NumOps, unsigned &NumOpsAdded, BO B) { + + const TargetInstrDesc &TID = ARMInsts[Opcode]; + NumOpsAdded = TID.getNumOperands() - 2; // ignore predicate operands + + // Disassemble register def. + MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, + decodeRd(insn)))); + + unsigned Pos = slice(insn, 20, 16); + if (Opcode == ARM::SSATlsl || + Opcode == ARM::SSATasr || + Opcode == ARM::SSAT16) + Pos += 1; + MI.addOperand(MCOperand::CreateImm(Pos)); + + MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, + decodeRm(insn)))); + + if (NumOpsAdded == 4) { + // Inst{11-7} encodes the imm5 shift amount. + unsigned ShAmt = slice(insn, 11, 7); + // A8.6.183. Possible ASR shift amount of 32... + if ((Opcode == ARM::SSATasr || Opcode == ARM::USATasr) && ShAmt == 0) + ShAmt = 32; + MI.addOperand(MCOperand::CreateImm(ShAmt)); + } + return true; +} + // Extend instructions. // SXT* and UXT*: Rd [Rn] Rm [rot_imm]. // The 2nd operand register is Rn and the 3rd operand regsiter is Rm for the @@ -3085,6 +3062,7 @@ static const DisassembleFP FuncPtrs[] = { &DisassembleLdStMulFrm, &DisassembleLdStExFrm, &DisassembleArithMiscFrm, + &DisassembleSatFrm, &DisassembleExtFrm, &DisassembleVFPUnaryFrm, &DisassembleVFPBinaryFrm, |