diff options
Diffstat (limited to 'lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 8a06664..9c7988f 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -323,8 +323,6 @@ static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address, - const void *Decoder); static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, @@ -507,6 +505,14 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, } MI.clear(); + result = decodeInstruction(DecoderTablev8Crypto32, MI, insn, Address, + this, STI); + if (result != MCDisassembler::Fail) { + Size = 4; + return result; + } + + MI.clear(); Size = 0; return MCDisassembler::Fail; } @@ -823,16 +829,28 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Check(result, AddThumbPredicate(MI)); return result; } - } - MI.clear(); - uint32_t NEONv8Insn = insn32; - NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26 - result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address, - this, STI); - if (result != MCDisassembler::Fail) { - Size = 4; - return result; + MI.clear(); + uint32_t NEONCryptoInsn = insn32; + NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24 + NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 + NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25 + result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn, + Address, this, STI); + if (result != MCDisassembler::Fail) { + Size = 4; + return result; + } + + MI.clear(); + uint32_t NEONv8Insn = insn32; + NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26 + result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address, + this, STI); + if (result != MCDisassembler::Fail) { + Size = 4; + return result; + } } MI.clear(); @@ -1185,20 +1203,22 @@ static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; - bool writebackLoad = false; - unsigned writebackReg = 0; + bool NeedDisjointWriteback = false; + unsigned WritebackReg = 0; switch (Inst.getOpcode()) { - default: - break; - case ARM::LDMIA_UPD: - case ARM::LDMDB_UPD: - case ARM::LDMIB_UPD: - case ARM::LDMDA_UPD: - case ARM::t2LDMIA_UPD: - case ARM::t2LDMDB_UPD: - writebackLoad = true; - writebackReg = Inst.getOperand(0).getReg(); - break; + default: + break; + case ARM::LDMIA_UPD: + case ARM::LDMDB_UPD: + case ARM::LDMIB_UPD: + case ARM::LDMDA_UPD: + case ARM::t2LDMIA_UPD: + case ARM::t2LDMDB_UPD: + case ARM::t2STMIA_UPD: + case ARM::t2STMDB_UPD: + NeedDisjointWriteback = true; + WritebackReg = Inst.getOperand(0).getReg(); + break; } // Empty register lists are not allowed. @@ -1208,7 +1228,7 @@ static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder))) return MCDisassembler::Fail; // Writeback not allowed if Rn is in the target list. - if (writebackLoad && writebackReg == Inst.end()[-1].getReg()) + if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg()) Check(S, MCDisassembler::SoftFail); } } @@ -1343,6 +1363,11 @@ static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, break; } + uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo() + .getFeatureBits(); + if ((featureBits & ARM::HasV8Ops) && (coproc != 14)) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::CreateImm(coproc)); Inst.addOperand(MCOperand::CreateImm(CRd)); if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) @@ -3794,6 +3819,11 @@ static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val, if (Val == 0xA || Val == 0xB) return MCDisassembler::Fail; + uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo() + .getFeatureBits(); + if ((featureBits & ARM::HasV8Ops) && !(Val == 14 || Val == 15)) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::CreateImm(Val)); return MCDisassembler::Success; } @@ -4901,15 +4931,6 @@ static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, return S; } -static DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address, - const void *Decoder) -{ - unsigned Imm = fieldFromInstruction(Insn, 0, 3); - if (Imm > 4) return MCDisassembler::Fail; - Inst.addOperand(MCOperand::CreateImm(Imm)); - return MCDisassembler::Success; -} - static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; |