Hello. On 12/18/2014 6:10 PM, Markos Chandras wrote:
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
Not <=?
BGEZC: Compact branch if GPR rt is > to zero
Not >=?
Signed-off-by: Markos Chandras <markos.chandras@xxxxxxxxxx> --- arch/mips/kernel/branch.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index e6d78ab52aa7..7bc2df026b51 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -402,6 +402,16 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs) * @returns: -EFAULT on error and forces SIGBUS, and on success * returns 0 or BRANCH_LIKELY_TAKEN as appropriate after * evaluating the branch. + * + * MIPS R6 Compact branches and forbidden slots: + * Compact branches do not throw exceptions because they do + * not have delay slots. The forbidden slot instruction ($PC+4) + * is only executed if the branch was not taken. Otherwise the + * forbidden slot is skipped entirely. This means that they
s/they/the/? [...]
@@ -609,6 +619,18 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, ret = -SIGILL; break; } + /* blezalc, bgezalc, blezc, bgezc */ + if (cpu_has_mips_r6) { + if (insn.i_format.rt) {
Perhaps those *if* statements can be collapsed to save on indentation?
+ if (insn.i_format.opcode == blez_op) + if ((insn.i_format.rs == + insn.i_format.rt) || + !insn.i_format.rs) + regs->regs[31] = epc + 4;
And these also?
+ regs->cp0_epc += 8; + break; + } + }
[...] WBR, Sergei