diff options
author | Markos Chandras <markos.chandras@imgtec.com> | 2014-11-26 07:57:54 -0500 |
---|---|---|
committer | Markos Chandras <markos.chandras@imgtec.com> | 2015-02-17 10:37:33 -0500 |
commit | a8ff66f52d3f17b5ae793955270675c197f73d6c (patch) | |
tree | ae86a8dfde65eecdcd9bd7591034ef5f65a65997 /arch/mips/math-emu/cp1emu.c | |
parent | c8a34581ec09a5ee11dd833d6c5cf41fdbef706f (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.c | 24 |
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 + |