diff options
author | Paul Burton <paul.burton@imgtec.com> | 2016-04-21 14:04:48 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-05-13 14:02:22 +0200 |
commit | 4b820d95dc53c15e6e727da964430a3ed60e05ef (patch) | |
tree | ba3801074945ae606c2feb8f1c57a9ad0d562acd | |
parent | b6d5c4eda7a771e72b3640500e026d72c4f64419 (diff) | |
download | linux-4b820d95dc53c15e6e727da964430a3ed60e05ef.tar.bz2 |
MIPS: math-emu: Emulate MIPSr6 sel.fmt instruction
Add support for emulating the MIPSr6 sel.fmt instruction, which was
previously missing from the FPU emulation code. This instruction selects
its result from 2 possible source registers, based upon bit 0 of the
destination register, and is valid only for S (single) & D (double) data
types.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Maciej W. Rozycki <macro@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/13153/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 99977c3bf10a..85dd17497151 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -1675,7 +1675,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, union ieee754sp(*b) (union ieee754sp, union ieee754sp); union ieee754sp(*u) (union ieee754sp); } handler; - union ieee754sp fs, ft; + union ieee754sp fd, fs, ft; switch (MIPSInst_FUNC(ir)) { /* binary ops */ @@ -1946,6 +1946,17 @@ copcsr: rfmt = w_fmt; goto copcsr; + case fsel_op: + if (!cpu_has_mips_r6) + return SIGILL; + + SPFROMREG(fd, MIPSInst_FD(ir)); + if (fd.bits & 0x1) + SPFROMREG(rv.s, MIPSInst_FT(ir)); + else + SPFROMREG(rv.s, MIPSInst_FS(ir)); + break; + case fcvtl_op: if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; @@ -1994,7 +2005,7 @@ copcsr: } case d_fmt: { - union ieee754dp fs, ft; + union ieee754dp fd, fs, ft; union { union ieee754dp(*b) (union ieee754dp, union ieee754dp); union ieee754dp(*u) (union ieee754dp); @@ -2244,6 +2255,17 @@ dcopuop: rfmt = w_fmt; goto copcsr; + case fsel_op: + if (!cpu_has_mips_r6) + return SIGILL; + + DPFROMREG(fd, MIPSInst_FD(ir)); + if (fd.bits & 0x1) + DPFROMREG(rv.d, MIPSInst_FT(ir)); + else + DPFROMREG(rv.d, MIPSInst_FS(ir)); + break; + case fcvtl_op: if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; |