X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FDisassembler%2FARMDisassemblerCore.cpp;h=adb7795a746c31037f90b1c5ca0f1a1ef1eb8b64;hb=99405df044f2c584242e711cc9023ec90356da82;hp=b72571066d4e5eec1643d0fc0a5981868cf7dbb7;hpb=44398693e767f10c1c7edea3578796f12e05af6e;p=oota-llvm.git diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index b72571066d4..adb7795a746 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -2104,7 +2104,7 @@ static uint64_t decodeN1VImm(uint32_t insn, ElemSize esize) { case ESize64: { for (unsigned i = 0; i < 8; ++i) if ((Imm8 >> i) & 1) - Imm64 |= 0xFF << 8*i; + Imm64 |= (uint64_t)0xFF << 8*i; break; } default: @@ -2232,6 +2232,22 @@ static unsigned decodeN3VImm(uint32_t insn) { return (insn >> 8) & 0xF; } +static bool UseDRegPair(unsigned Opcode) { + switch (Opcode) { + default: + return false; + case ARM::VLD1q8_UPD: + case ARM::VLD1q16_UPD: + case ARM::VLD1q32_UPD: + case ARM::VLD1q64_UPD: + case ARM::VST1q8_UPD: + case ARM::VST1q16_UPD: + case ARM::VST1q32_UPD: + case ARM::VST1q64_UPD: + return true; + } +} + // VLD* // D[d] D[d2] ... Rn [TIED_TO Rn] align [Rm] // VLD*LN* @@ -2305,11 +2321,9 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn, RegClass = OpInfo[OpIdx].RegClass; while (OpIdx < NumOps && OpInfo[OpIdx].RegClass == RegClass) { - if (Opcode >= ARM::VST1q16 && Opcode <= ARM::VST1q8) - MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass, Rd, - true))); - else - MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass,Rd))); + MI.addOperand(MCOperand::CreateReg( + getRegisterEnum(B, RegClass, Rd, + UseDRegPair(Opcode)))); Rd += Inc; ++OpIdx; } @@ -2327,11 +2341,9 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn, RegClass = OpInfo[0].RegClass; while (OpIdx < NumOps && OpInfo[OpIdx].RegClass == RegClass) { - if (Opcode >= ARM::VLD1q16 && Opcode <= ARM::VLD1q8) - MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass, Rd, - true))); - else - MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass, Rd))); + MI.addOperand(MCOperand::CreateReg( + getRegisterEnum(B, RegClass, Rd, + UseDRegPair(Opcode)))); Rd += Inc; ++OpIdx; } @@ -2450,6 +2462,7 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned Opcode, case ARM::VMOVv1i64: case ARM::VMOVv2i64: esize = ESize64; + break; default: assert(0 && "Unreachable code!"); return false; @@ -3196,6 +3209,49 @@ bool ARMBasicMCBuilder::BuildIt(MCInst &MI, uint32_t insn) { return TryPredicateAndSBitModifier(MI, Opcode, insn, NumOps - NumOpsAdded); } +// A8.3 Conditional execution +// A8.3.1 Pseudocode details of conditional execution +// Condition bits '111x' indicate the instruction is always executed. +static uint32_t CondCode(uint32_t CondField) { + if (CondField == 0xF) + return ARMCC::AL; + return CondField; +} + +/// DoPredicateOperands - DoPredicateOperands process the predicate operands +/// of some Thumb instructions which come before the reglist operands. It +/// returns true if the two predicate operands have been processed. +bool ARMBasicMCBuilder::DoPredicateOperands(MCInst& MI, unsigned Opcode, + uint32_t /* insn */, unsigned short NumOpsRemaining) { + + assert(NumOpsRemaining > 0 && "Invalid argument"); + + const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo; + unsigned Idx = MI.getNumOperands(); + + // First, we check whether this instr specifies the PredicateOperand through + // a pair of TargetOperandInfos with isPredicate() property. + if (NumOpsRemaining >= 2 && + OpInfo[Idx].isPredicate() && OpInfo[Idx+1].isPredicate() && + OpInfo[Idx].RegClass == 0 && OpInfo[Idx+1].RegClass == ARM::CCRRegClassID) + { + // If we are inside an IT block, get the IT condition bits maintained via + // ARMBasicMCBuilder::ITState[7:0], through ARMBasicMCBuilder::GetITCond(). + // See also A2.5.2. + if (InITBlock()) + MI.addOperand(MCOperand::CreateImm(GetITCond())); + else + MI.addOperand(MCOperand::CreateImm(ARMCC::AL)); + MI.addOperand(MCOperand::CreateReg(ARM::CPSR)); + return true; + } + + return false; +} + +/// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process +/// the possible Predicate and SBitModifier, to build the remaining MCOperand +/// constituents. bool ARMBasicMCBuilder::TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode, uint32_t insn, unsigned short NumOpsRemaining) { @@ -3223,27 +3279,24 @@ bool ARMBasicMCBuilder::TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode, // // A8.6.16 B if (Name == "t2Bcc") - MI.addOperand(MCOperand::CreateImm(slice(insn, 25, 22))); + MI.addOperand(MCOperand::CreateImm(CondCode(slice(insn, 25, 22)))); else if (Name == "tBcc") - MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 8))); + MI.addOperand(MCOperand::CreateImm(CondCode(slice(insn, 11, 8)))); else MI.addOperand(MCOperand::CreateImm(ARMCC::AL)); } else { - // ARM Instructions. Check condition field. - int64_t CondVal = getCondField(insn); - if (CondVal == 0xF) - MI.addOperand(MCOperand::CreateImm(ARMCC::AL)); - else - MI.addOperand(MCOperand::CreateImm(CondVal)); + // ARM instructions get their condition field from Inst{31-28}. + MI.addOperand(MCOperand::CreateImm(CondCode(getCondField(insn)))); } } MI.addOperand(MCOperand::CreateReg(ARM::CPSR)); Idx += 2; NumOpsRemaining -= 2; - if (NumOpsRemaining == 0) - return true; } + if (NumOpsRemaining == 0) + return true; + // Next, if OptionalDefOperand exists, we check whether the 'S' bit is set. if (OpInfo[Idx].isOptionalDef() && OpInfo[Idx].RegClass==ARM::CCRRegClassID) { MI.addOperand(MCOperand::CreateReg(getSBit(insn) == 1 ? ARM::CPSR : 0)); @@ -3264,7 +3317,7 @@ bool ARMBasicMCBuilder::RunBuildAfterHook(bool Status, MCInst &MI, if (!SP) return Status; if (Opcode == ARM::t2IT) - SP->InitIT(slice(insn, 7, 0)); + Status = SP->InitIT(slice(insn, 7, 0)) ? Status : false; else if (InITBlock()) SP->UpdateIT(); @@ -3287,8 +3340,10 @@ ARMBasicMCBuilder::ARMBasicMCBuilder(unsigned opc, ARMFormat format, /// performed by the API clients to improve performance. ARMBasicMCBuilder *llvm::CreateMCBuilder(unsigned Opcode, ARMFormat Format) { // For "Unknown format", fail by returning a NULL pointer. - if ((unsigned)Format >= (array_lengthof(FuncPtrs) - 1)) + if ((unsigned)Format >= (array_lengthof(FuncPtrs) - 1)) { + DEBUG(errs() << "Unknown format\n"); return 0; + } return new ARMBasicMCBuilder(Opcode, Format, ARMInsts[Opcode].getNumOperands());