X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FDisassembler%2FARMDisassemblerCore.cpp;h=98bb6716c7fa25cf68207eee34da6169d951b14a;hb=9899f70a7406d632c82849978bf6981f1ee4ccb5;hp=9f41455797c7c9d7f9c3f013cd356e63cfc14e3e;hpb=b35ae7f7d6fb6bbeb08246922760f0f55b7a8b5d;p=oota-llvm.git diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 9f41455797c..98bb6716c7f 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -8,8 +8,8 @@ //===----------------------------------------------------------------------===// // // This file is part of the ARM Disassembler. -// It contains code to represent the core concepts of Builder, Builder Factory, -// as well as the Algorithm to solve the problem of disassembling an ARM instr. +// It contains code to represent the core concepts of Builder and DisassembleFP +// to solve the problem of disassembling an ARM instr. // //===----------------------------------------------------------------------===// @@ -478,7 +478,7 @@ static inline ARM_AM::AMSubMode getAMSubModeForBits(unsigned bits) { /// followed by possible src(s). /// /// The processing of the predicate, and the 'S' modifier bit, if MI modifies -/// the CPSR, is factored into ARMBasicMCBuilder's class method named +/// the CPSR, is factored into ARMBasicMCBuilder's method named /// TryPredicateAndSBitModifier. static bool DisassemblePseudo(MCInst &MI, unsigned Opcode, uint32_t insn, @@ -694,6 +694,7 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn, return DisassembleCoprocessor(MI, Opcode, insn, NumOps, NumOpsAdded); const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo; + if (!OpInfo) return false; // MRS and MRSsys take one GPR reg Rd. if (Opcode == ARM::MRS || Opcode == ARM::MRSsys) { @@ -794,6 +795,8 @@ static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) { const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo; + if (!OpInfo) return false; + unsigned &OpIdx = NumOpsAdded; OpIdx = 0; @@ -1124,14 +1127,16 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, bool isStore) { const TargetInstrDesc &TID = ARMInsts[Opcode]; - unsigned short NumDefs = TID.getNumDefs(); bool isPrePost = isPrePostLdSt(TID.TSFlags); const TargetOperandInfo *OpInfo = TID.OpInfo; + if (!OpInfo) return false; + unsigned &OpIdx = NumOpsAdded; OpIdx = 0; - assert(((!isStore && NumDefs > 0) || (isStore && (NumDefs == 0 || isPrePost))) + assert(((!isStore && TID.getNumDefs() > 0) || + (isStore && (TID.getNumDefs() == 0 || isPrePost))) && "Invalid arguments"); // Operand 0 of a pre- and post-indexed store is the address base writeback. @@ -1235,14 +1240,16 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, bool isStore) { const TargetInstrDesc &TID = ARMInsts[Opcode]; - unsigned short NumDefs = TID.getNumDefs(); bool isPrePost = isPrePostLdSt(TID.TSFlags); const TargetOperandInfo *OpInfo = TID.OpInfo; + if (!OpInfo) return false; + unsigned &OpIdx = NumOpsAdded; OpIdx = 0; - assert(((!isStore && NumDefs > 0) || (isStore && (NumDefs == 0 || isPrePost))) + assert(((!isStore && TID.getNumDefs() > 0) || + (isStore && (TID.getNumDefs() == 0 || isPrePost))) && "Invalid arguments"); // Operand 0 of a pre- and post-indexed store is the address base writeback. @@ -1391,6 +1398,8 @@ static bool DisassembleLdStExFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) { const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo; + if (!OpInfo) return false; + unsigned &OpIdx = NumOpsAdded; OpIdx = 0; @@ -1681,6 +1690,7 @@ static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn, const TargetInstrDesc &TID = ARMInsts[Opcode]; const TargetOperandInfo *OpInfo = TID.OpInfo; + if (!OpInfo) return false; bool SP = slice(insn, 8, 8) == 0; // A8.6.295 & A8.6.297 bool fixed_point = slice(insn, 17, 17) == 1; // A8.6.297 @@ -1986,7 +1996,7 @@ static bool DisassembleVFPMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, // D = Inst{22}, Vd = Inst{15-12} static unsigned decodeNEONRd(uint32_t insn) { return ((insn >> ARMII::NEON_D_BitShift) & 1) << 4 - | (insn >> ARMII::NEON_RegRdShift) & ARMII::NEONRegMask; + | ((insn >> ARMII::NEON_RegRdShift) & ARMII::NEONRegMask); } // Extract/Decode NEON N/Vn: @@ -1997,7 +2007,7 @@ static unsigned decodeNEONRd(uint32_t insn) { // N = Inst{7}, Vn = Inst{19-16} static unsigned decodeNEONRn(uint32_t insn) { return ((insn >> ARMII::NEON_N_BitShift) & 1) << 4 - | (insn >> ARMII::NEON_RegRnShift) & ARMII::NEONRegMask; + | ((insn >> ARMII::NEON_RegRnShift) & ARMII::NEONRegMask); } // Extract/Decode NEON M/Vm: @@ -2008,7 +2018,7 @@ static unsigned decodeNEONRn(uint32_t insn) { // M = Inst{5}, Vm = Inst{3-0} static unsigned decodeNEONRm(uint32_t insn) { return ((insn >> ARMII::NEON_M_BitShift) & 1) << 4 - | (insn >> ARMII::NEON_RegRmShift) & ARMII::NEONRegMask; + | ((insn >> ARMII::NEON_RegRmShift) & ARMII::NEONRegMask); } namespace { @@ -2766,6 +2776,7 @@ static bool DisassembleNVTBLFrm(MCInst &MI, unsigned Opcode, uint32_t insn, const TargetInstrDesc &TID = ARMInsts[Opcode]; const TargetOperandInfo *OpInfo = TID.OpInfo; + if (!OpInfo) return false; assert(NumOps >= 3 && OpInfo[0].RegClass == ARM::DPRRegClassID && @@ -2828,10 +2839,10 @@ static bool DisassembleNEONGetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) { const TargetInstrDesc &TID = ARMInsts[Opcode]; - unsigned short NumDefs = TID.getNumDefs(); const TargetOperandInfo *OpInfo = TID.OpInfo; + if (!OpInfo) return false; - assert(NumDefs == 1 && NumOps >= 3 && + assert(TID.getNumDefs() == 1 && NumOps >= 3 && OpInfo[0].RegClass == ARM::GPRRegClassID && OpInfo[1].RegClass == ARM::DPRRegClassID && OpInfo[2].RegClass == 0 && @@ -2862,10 +2873,10 @@ static bool DisassembleNEONSetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) { const TargetInstrDesc &TID = ARMInsts[Opcode]; - unsigned short NumDefs = TID.getNumDefs(); const TargetOperandInfo *OpInfo = TID.OpInfo; + if (!OpInfo) return false; - assert(NumDefs == 1 && NumOps >= 3 && + assert(TID.getNumDefs() == 1 && NumOps >= 3 && OpInfo[0].RegClass == ARM::DPRRegClassID && OpInfo[1].RegClass == ARM::DPRRegClassID && TID.getOperandConstraint(1, TOI::TIED_TO) != -1 && @@ -3127,40 +3138,12 @@ static const DisassembleFP FuncPtrs[] = { NULL }; -/// Algorithms - Algorithms stores a map from Format to ARMAlgorithm*. -static std::vector Algorithms; - -/// DoCleanup - Do cleanup of Algorithms upon exit. -void ARMAlgorithm::DoCleanup() { - for (unsigned i = 0; i < array_lengthof(FuncPtrs); ++i) - if (Algorithms[i]) - delete Algorithms[i]; -} - -/// GetInstance - GetInstance returns an instance of ARMAlgorithm given the -/// encoding Format. API clients should not free up the returned instance. -ARMAlgorithm *ARMAlgorithm::GetInstance(ARMFormat Format) { - /// Init the first time. - if (Algorithms.size() == 0) { - Algorithms.resize(array_lengthof(FuncPtrs)); - for (unsigned i = 0, num = array_lengthof(FuncPtrs); i < num; ++i) - if (FuncPtrs[i]) - Algorithms[i] = new ARMAlgorithm(FuncPtrs[i]); - else - Algorithms[i] = NULL; - - // Register cleanup routine. - atexit(DoCleanup); - } - return Algorithms[Format]; -} - /// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder. /// The general idea is to set the Opcode for the MCInst, followed by adding /// the appropriate MCOperands to the MCInst. ARM Basic MC Builder delegates -/// to the Algo (ARM Disassemble Algorithm) object to perform Format-specific -/// disassembly, followed by class method TryPredicateAndSBitModifier() to do -/// PredicateOperand and OptionalDefOperand which follow the Dst/Src Operands. +/// to the Format-specific disassemble function for disassembly, followed by +/// TryPredicateAndSBitModifier() to do PredicateOperand and OptionalDefOperand +/// which follow the Dst/Src Operands. bool ARMBasicMCBuilder::BuildIt(MCInst &MI, uint32_t insn) { // Stage 1 sets the Opcode. MI.setOpcode(Opcode); @@ -3168,9 +3151,12 @@ bool ARMBasicMCBuilder::BuildIt(MCInst &MI, uint32_t insn) { if (NumOps == 0) return true; - // Stage 2 calls the ARM Disassembly Algorithm to build the operand list. + // Stage 2 calls the format-specific disassemble function to build the operand + // list. + if (Disasm == NULL) + return false; unsigned NumOpsAdded = 0; - bool OK = Algo.Solve(MI, Opcode, insn, NumOps, NumOpsAdded, this); + bool OK = (*Disasm)(MI, Opcode, insn, NumOps, NumOpsAdded, this); if (!OK) return false; if (NumOpsAdded >= NumOps) @@ -3256,6 +3242,15 @@ bool ARMBasicMCBuilder::RunBuildAfterHook(bool Status, MCInst &MI, return Status; } +/// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder. +ARMBasicMCBuilder::ARMBasicMCBuilder(unsigned opc, ARMFormat format, + unsigned short num) + : Opcode(opc), Format(format), NumOps(num), SP(0) { + unsigned Idx = (unsigned)format; + assert(Idx < (array_lengthof(FuncPtrs) - 1) && "Unknown format"); + Disasm = FuncPtrs[Idx]; +} + /// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC /// infrastructure of an MCInst given the Opcode and Format of the instr. /// Return NULL if it fails to create/return a proper builder. API clients @@ -3263,10 +3258,6 @@ bool ARMBasicMCBuilder::RunBuildAfterHook(bool Status, MCInst &MI, /// performed by the API clients to improve performance. ARMBasicMCBuilder *llvm::CreateMCBuilder(unsigned Opcode, ARMFormat Format) { - ARMAlgorithm *Algo = ARMAlgorithm::GetInstance(Format); - if (!Algo) - return NULL; - return new ARMBasicMCBuilder(Opcode, Format, - ARMInsts[Opcode].getNumOperands(), *Algo); + ARMInsts[Opcode].getNumOperands()); }