mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 09:02:00 +00:00
MIPS: Emulate the new MIPS R6 B{L,G}T{Z,}{AL,}C instructions
MIPS R6 added the following four instructions which share the BGTZ and BGTZL opcode: BLTZALC: Compact branch-and-link if GPR rt is < to zero BGTZALC: Compact branch-and-link if GPR rt is > to zero BLTZL : Compact branch if GPR rt is < to zero BGTZL : Compact branch if GPR rt is > to zero BLTC : Compact branch if GPR rs is less than GPR rt BLTUC : Similar to BLTC but unsigned Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
This commit is contained in:
parent
a8ff66f52d
commit
f1b44067c1
@ -635,6 +635,28 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
|
||||
if (NO_R6EMU)
|
||||
goto sigill_r6;
|
||||
case bgtz_op:
|
||||
/*
|
||||
* Compact branches for R6 for the
|
||||
* bgtz and bgtzl opcodes.
|
||||
* BGTZ | rs = 0 | rt != 0 == BGTZALC
|
||||
* BGTZ | rs = rt != 0 == BLTZALC
|
||||
* BGTZ | rs != 0 | rt != 0 == BLTUC
|
||||
* BGTZL | rs = 0 | rt != 0 == BGTZC
|
||||
* BGTZL | rs = rt != 0 == BLTZC
|
||||
* BGTZL | rs != 0 | rt != 0 == BLTC
|
||||
*
|
||||
* *ZALC varint for BGTZ &&& rt != 0
|
||||
* For real GTZ{,L}, rt is always 0.
|
||||
*/
|
||||
if (cpu_has_mips_r6 && insn.i_format.rt) {
|
||||
if ((insn.i_format.opcode == blez_op) &&
|
||||
((!insn.i_format.rs && insn.i_format.rt) ||
|
||||
(insn.i_format.rs == insn.i_format.rt)))
|
||||
regs->regs[31] = epc + 4;
|
||||
regs->cp0_epc += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
/* rt field assumed to be zero */
|
||||
if ((long)regs->regs[insn.i_format.rs] > 0) {
|
||||
epc = epc + 4 + (insn.i_format.simmediate << 2);
|
||||
|
@ -589,6 +589,31 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
|
||||
if (NO_R6EMU)
|
||||
break;
|
||||
case bgtz_op:
|
||||
/*
|
||||
* Compact branches for R6 for the
|
||||
* bgtz and bgtzl opcodes.
|
||||
* BGTZ | rs = 0 | rt != 0 == BGTZALC
|
||||
* BGTZ | rs = rt != 0 == BLTZALC
|
||||
* BGTZ | rs != 0 | rt != 0 == BLTUC
|
||||
* BGTZL | rs = 0 | rt != 0 == BGTZC
|
||||
* BGTZL | rs = rt != 0 == BLTZC
|
||||
* BGTZL | rs != 0 | rt != 0 == BLTC
|
||||
*
|
||||
* *ZALC varint for BGTZ &&& rt != 0
|
||||
* For real GTZ{,L}, rt is always 0.
|
||||
*/
|
||||
if (cpu_has_mips_r6 && insn.i_format.rt) {
|
||||
if ((insn.i_format.opcode == blez_op) &&
|
||||
((!insn.i_format.rs && insn.i_format.rt) ||
|
||||
(insn.i_format.rs == insn.i_format.rt)))
|
||||
regs->regs[31] = regs->cp0_epc +
|
||||
dec_insn.pc_inc;
|
||||
*contpc = regs->cp0_epc + dec_insn.pc_inc +
|
||||
dec_insn.next_pc_inc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((long)regs->regs[insn.i_format.rs] > 0)
|
||||
*contpc = regs->cp0_epc +
|
||||
dec_insn.pc_inc +
|
||||
|
Loading…
Reference in New Issue
Block a user