diff options
Diffstat (limited to 'llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index fabd58f3ef0..f8ac809343f 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -455,6 +455,16 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, const void *Decoder); +template <typename InsnType> +static DecodeStatus +DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder); + +template <typename InsnType> +static DecodeStatus +DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -2133,3 +2143,87 @@ static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2))); return MCDisassembler::Success; } + +template <typename InsnType> +static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, + uint64_t Address, + const void *Decoder) { + // We have: + // 0b000111 ttttt sssss iiiiiiiiiiiiiiii + // Invalid if rt == 0 + // BGTZALC_MMR6 if rs == 0 && rt != 0 + // BLTZALC_MMR6 if rs != 0 && rs == rt + // BLTUC_MMR6 if rs != 0 && rs != rt + + InsnType Rt = fieldFromInstruction(insn, 21, 5); + InsnType Rs = fieldFromInstruction(insn, 16, 5); + InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2; + bool HasRs = false; + bool HasRt = false; + + if (Rt == 0) + return MCDisassembler::Fail; + else if (Rs == 0) { + MI.setOpcode(Mips::BGTZALC_MMR6); + HasRt = true; + } + else if (Rs == Rt) { + MI.setOpcode(Mips::BLTZALC_MMR6); + HasRs = true; + } + else { + MI.setOpcode(Mips::BLTUC_MMR6); + HasRs = true; + HasRt = true; + } + + if (HasRs) + MI.addOperand( + MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); + + if (HasRt) + MI.addOperand( + MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); + + MI.addOperand(MCOperand::createImm(Imm)); + + return MCDisassembler::Success; +} + +template <typename InsnType> +static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, + uint64_t Address, + const void *Decoder) { + // We have: + // 0b000110 ttttt sssss iiiiiiiiiiiiiiii + // Invalid if rs == 0 + // BLEZALC_MMR6 if rs == 0 && rt != 0 + // BGEZALC_MMR6 if rs == rt && rt != 0 + // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0 + + InsnType Rt = fieldFromInstruction(insn, 21, 5); + InsnType Rs = fieldFromInstruction(insn, 16, 5); + InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2; + bool HasRs = false; + + if (Rt == 0) + return MCDisassembler::Fail; + else if (Rs == 0) + MI.setOpcode(Mips::BLEZALC_MMR6); + else if (Rs == Rt) + MI.setOpcode(Mips::BGEZALC_MMR6); + else { + HasRs = true; + MI.setOpcode(Mips::BGEUC_MMR6); + } + + if (HasRs) + MI.addOperand( + MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); + MI.addOperand( + MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); + + MI.addOperand(MCOperand::createImm(Imm)); + + return MCDisassembler::Success; +} |