aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/math-emu/cp1emu.c
diff options
context:
space:
mode:
authorMarkos Chandras <markos.chandras@imgtec.com>2014-11-26 07:57:54 -0500
committerMarkos Chandras <markos.chandras@imgtec.com>2015-02-17 10:37:33 -0500
commita8ff66f52d3f17b5ae793955270675c197f73d6c (patch)
treeae86a8dfde65eecdcd9bd7591034ef5f65a65997 /arch/mips/math-emu/cp1emu.c
parentc8a34581ec09a5ee11dd833d6c5cf41fdbef706f (diff)
MIPS: Emulate the new MIPS R6 B{L,G}Ε{Z,}{AL,}C instructions
MIPS R6 added the following four instructions which share the BLEZ and BLEZL opcodes: BLEZALC: Compact branch-and-link if GPR rt is <= to zero BGEZALC: Compact branch-and-link if GPR rt is >= to zero BLEZC : Compact branch if GPR rt is <= to zero BGEZC : Compact branch if GPR rt is >= to zero BGEC : Compact branch if GPR rs is less than or equal to GPR rt BGEUC : Similar to BGEC but unsigned. Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Diffstat (limited to 'arch/mips/math-emu/cp1emu.c')
-rw-r--r--arch/mips/math-emu/cp1emu.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 798204e492fc..c770617dc340 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -552,6 +552,30 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
552 if (NO_R6EMU) 552 if (NO_R6EMU)
553 break; 553 break;
554 case blez_op: 554 case blez_op:
555
556 /*
557 * Compact branches for R6 for the
558 * blez and blezl opcodes.
559 * BLEZ | rs = 0 | rt != 0 == BLEZALC
560 * BLEZ | rs = rt != 0 == BGEZALC
561 * BLEZ | rs != 0 | rt != 0 == BGEUC
562 * BLEZL | rs = 0 | rt != 0 == BLEZC
563 * BLEZL | rs = rt != 0 == BGEZC
564 * BLEZL | rs != 0 | rt != 0 == BGEC
565 *
566 * For real BLEZ{,L}, rt is always 0.
567 */
568 if (cpu_has_mips_r6 && insn.i_format.rt) {
569 if ((insn.i_format.opcode == blez_op) &&
570 ((!insn.i_format.rs && insn.i_format.rt) ||
571 (insn.i_format.rs == insn.i_format.rt)))
572 regs->regs[31] = regs->cp0_epc +
573 dec_insn.pc_inc;
574 *contpc = regs->cp0_epc + dec_insn.pc_inc +
575 dec_insn.next_pc_inc;
576
577 return 1;
578 }
555 if ((long)regs->regs[insn.i_format.rs] <= 0) 579 if ((long)regs->regs[insn.i_format.rs] <= 0)
556 *contpc = regs->cp0_epc + 580 *contpc = regs->cp0_epc +
557 dec_insn.pc_inc + 581 dec_insn.pc_inc +