diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2015-04-03 18:26:49 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-04-07 19:10:05 -0400 |
commit | 2d83fea786d7aeb5b3b76bd492d9b3bccc0f823c (patch) | |
tree | ff3ca66d494d9b367aeefa99f07b70aa5eeb72e7 /arch/mips/math-emu | |
parent | 80cbfad790962125b542cb0cb637954c04386b30 (diff) |
MIPS: Correct FP ISA requirements
Correct ISA requirements for floating-point instructions:
* the CU3 exception signifies a real COP3 instruction in MIPS I & II,
* the BC1FL and BC1TL instructions are not supported in MIPS I,
* the SQRT.fmt instructions are indeed supported in MIPS II,
* the LDC1 and SDC1 instructions are indeed supported in MIPS32r1,
* the CEIL.W.fmt, FLOOR.W.fmt, ROUND.W.fmt and TRUNC.W.fmt instructions
are indeed supported in MIPS32,
* the CVT.L.fmt and CVT.fmt.L instructions are indeed supported in
MIPS32r2 and MIPS32r6,
* the CEIL.L.fmt, FLOOR.L.fmt, ROUND.L.fmt and TRUNC.L.fmt instructions
are indeed supported in MIPS32r2 and MIPS32r6,
* the RSQRT.fmt and RECIP.fmt instructions are indeed supported in
MIPS64r1,
Also simplify conditionals for MIPS III and MIPS IV FPU instructions and
the handling of the MOVCI minor opcode.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9700/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/math-emu')
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index be983850eb39..732c3a37d7b9 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -1115,17 +1115,18 @@ emul: | |||
1115 | likely = 0; | 1115 | likely = 0; |
1116 | switch (MIPSInst_RT(ir) & 3) { | 1116 | switch (MIPSInst_RT(ir) & 3) { |
1117 | case bcfl_op: | 1117 | case bcfl_op: |
1118 | likely = 1; | 1118 | if (cpu_has_mips_2_3_4_5_r) |
1119 | likely = 1; | ||
1120 | /* Fall through */ | ||
1119 | case bcf_op: | 1121 | case bcf_op: |
1120 | cond = !cond; | 1122 | cond = !cond; |
1121 | break; | 1123 | break; |
1122 | case bctl_op: | 1124 | case bctl_op: |
1123 | likely = 1; | 1125 | if (cpu_has_mips_2_3_4_5_r) |
1126 | likely = 1; | ||
1127 | /* Fall through */ | ||
1124 | case bct_op: | 1128 | case bct_op: |
1125 | break; | 1129 | break; |
1126 | default: | ||
1127 | /* thats an illegal instruction */ | ||
1128 | return SIGILL; | ||
1129 | } | 1130 | } |
1130 | 1131 | ||
1131 | set_delay_slot(xcp); | 1132 | set_delay_slot(xcp); |
@@ -1165,36 +1166,34 @@ emul: | |||
1165 | 1166 | ||
1166 | switch (MIPSInst_OPCODE(ir)) { | 1167 | switch (MIPSInst_OPCODE(ir)) { |
1167 | case lwc1_op: | 1168 | case lwc1_op: |
1168 | goto emul; | ||
1169 | |||
1170 | case swc1_op: | 1169 | case swc1_op: |
1171 | goto emul; | 1170 | goto emul; |
1172 | 1171 | ||
1173 | case ldc1_op: | 1172 | case ldc1_op: |
1174 | case sdc1_op: | 1173 | case sdc1_op: |
1175 | if (cpu_has_mips_2_3_4_5 || | 1174 | if (cpu_has_mips_2_3_4_5_r) |
1176 | cpu_has_mips64) | ||
1177 | goto emul; | 1175 | goto emul; |
1178 | 1176 | ||
1179 | return SIGILL; | 1177 | return SIGILL; |
1180 | goto emul; | ||
1181 | 1178 | ||
1182 | case cop1_op: | 1179 | case cop1_op: |
1183 | goto emul; | 1180 | goto emul; |
1184 | 1181 | ||
1185 | case cop1x_op: | 1182 | case cop1x_op: |
1186 | if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2) | 1183 | if (cpu_has_mips_4_5_64_r2_r6) |
1187 | /* its one of ours */ | 1184 | /* its one of ours */ |
1188 | goto emul; | 1185 | goto emul; |
1189 | 1186 | ||
1190 | return SIGILL; | 1187 | return SIGILL; |
1191 | 1188 | ||
1192 | case spec_op: | 1189 | case spec_op: |
1193 | if (!cpu_has_mips_4_5_r) | 1190 | switch (MIPSInst_FUNC(ir)) { |
1194 | return SIGILL; | 1191 | case movc_op: |
1192 | if (cpu_has_mips_4_5_r) | ||
1193 | goto emul; | ||
1195 | 1194 | ||
1196 | if (MIPSInst_FUNC(ir) == movc_op) | 1195 | return SIGILL; |
1197 | goto emul; | 1196 | } |
1198 | break; | 1197 | break; |
1199 | } | 1198 | } |
1200 | 1199 | ||
@@ -1228,7 +1227,7 @@ emul: | |||
1228 | break; | 1227 | break; |
1229 | 1228 | ||
1230 | case cop1x_op: | 1229 | case cop1x_op: |
1231 | if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2) | 1230 | if (!cpu_has_mips_4_5_64_r2_r6) |
1232 | return SIGILL; | 1231 | return SIGILL; |
1233 | 1232 | ||
1234 | sig = fpux_emu(xcp, ctx, ir, fault_addr); | 1233 | sig = fpux_emu(xcp, ctx, ir, fault_addr); |
@@ -1561,7 +1560,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1561 | 1560 | ||
1562 | /* unary ops */ | 1561 | /* unary ops */ |
1563 | case fsqrt_op: | 1562 | case fsqrt_op: |
1564 | if (!cpu_has_mips_4_5_r) | 1563 | if (!cpu_has_mips_2_3_4_5_r) |
1565 | return SIGILL; | 1564 | return SIGILL; |
1566 | 1565 | ||
1567 | handler.u = ieee754sp_sqrt; | 1566 | handler.u = ieee754sp_sqrt; |
@@ -1573,14 +1572,14 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1573 | * achieve full IEEE-754 accuracy - however this emulator does. | 1572 | * achieve full IEEE-754 accuracy - however this emulator does. |
1574 | */ | 1573 | */ |
1575 | case frsqrt_op: | 1574 | case frsqrt_op: |
1576 | if (!cpu_has_mips_4_5_r2_r6) | 1575 | if (!cpu_has_mips_4_5_64_r2_r6) |
1577 | return SIGILL; | 1576 | return SIGILL; |
1578 | 1577 | ||
1579 | handler.u = fpemu_sp_rsqrt; | 1578 | handler.u = fpemu_sp_rsqrt; |
1580 | goto scopuop; | 1579 | goto scopuop; |
1581 | 1580 | ||
1582 | case frecip_op: | 1581 | case frecip_op: |
1583 | if (!cpu_has_mips_4_5_r2_r6) | 1582 | if (!cpu_has_mips_4_5_64_r2_r6) |
1584 | return SIGILL; | 1583 | return SIGILL; |
1585 | 1584 | ||
1586 | handler.u = fpemu_sp_recip; | 1585 | handler.u = fpemu_sp_recip; |
@@ -1682,7 +1681,7 @@ copcsr: | |||
1682 | case ftrunc_op: | 1681 | case ftrunc_op: |
1683 | case fceil_op: | 1682 | case fceil_op: |
1684 | case ffloor_op: | 1683 | case ffloor_op: |
1685 | if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64) | 1684 | if (!cpu_has_mips_2_3_4_5_r) |
1686 | return SIGILL; | 1685 | return SIGILL; |
1687 | 1686 | ||
1688 | oldrm = ieee754_csr.rm; | 1687 | oldrm = ieee754_csr.rm; |
@@ -1694,7 +1693,7 @@ copcsr: | |||
1694 | goto copcsr; | 1693 | goto copcsr; |
1695 | 1694 | ||
1696 | case fcvtl_op: | 1695 | case fcvtl_op: |
1697 | if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) | 1696 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
1698 | return SIGILL; | 1697 | return SIGILL; |
1699 | 1698 | ||
1700 | SPFROMREG(fs, MIPSInst_FS(ir)); | 1699 | SPFROMREG(fs, MIPSInst_FS(ir)); |
@@ -1706,7 +1705,7 @@ copcsr: | |||
1706 | case ftruncl_op: | 1705 | case ftruncl_op: |
1707 | case fceill_op: | 1706 | case fceill_op: |
1708 | case ffloorl_op: | 1707 | case ffloorl_op: |
1709 | if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) | 1708 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
1710 | return SIGILL; | 1709 | return SIGILL; |
1711 | 1710 | ||
1712 | oldrm = ieee754_csr.rm; | 1711 | oldrm = ieee754_csr.rm; |
@@ -1775,13 +1774,13 @@ copcsr: | |||
1775 | * achieve full IEEE-754 accuracy - however this emulator does. | 1774 | * achieve full IEEE-754 accuracy - however this emulator does. |
1776 | */ | 1775 | */ |
1777 | case frsqrt_op: | 1776 | case frsqrt_op: |
1778 | if (!cpu_has_mips_4_5_r2_r6) | 1777 | if (!cpu_has_mips_4_5_64_r2_r6) |
1779 | return SIGILL; | 1778 | return SIGILL; |
1780 | 1779 | ||
1781 | handler.u = fpemu_dp_rsqrt; | 1780 | handler.u = fpemu_dp_rsqrt; |
1782 | goto dcopuop; | 1781 | goto dcopuop; |
1783 | case frecip_op: | 1782 | case frecip_op: |
1784 | if (!cpu_has_mips_4_5_r2_r6) | 1783 | if (!cpu_has_mips_4_5_64_r2_r6) |
1785 | return SIGILL; | 1784 | return SIGILL; |
1786 | 1785 | ||
1787 | handler.u = fpemu_dp_recip; | 1786 | handler.u = fpemu_dp_recip; |
@@ -1871,7 +1870,7 @@ dcopuop: | |||
1871 | goto copcsr; | 1870 | goto copcsr; |
1872 | 1871 | ||
1873 | case fcvtl_op: | 1872 | case fcvtl_op: |
1874 | if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) | 1873 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
1875 | return SIGILL; | 1874 | return SIGILL; |
1876 | 1875 | ||
1877 | DPFROMREG(fs, MIPSInst_FS(ir)); | 1876 | DPFROMREG(fs, MIPSInst_FS(ir)); |
@@ -1883,7 +1882,7 @@ dcopuop: | |||
1883 | case ftruncl_op: | 1882 | case ftruncl_op: |
1884 | case fceill_op: | 1883 | case fceill_op: |
1885 | case ffloorl_op: | 1884 | case ffloorl_op: |
1886 | if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) | 1885 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
1887 | return SIGILL; | 1886 | return SIGILL; |
1888 | 1887 | ||
1889 | oldrm = ieee754_csr.rm; | 1888 | oldrm = ieee754_csr.rm; |
@@ -1942,7 +1941,7 @@ dcopuop: | |||
1942 | 1941 | ||
1943 | case l_fmt: | 1942 | case l_fmt: |
1944 | 1943 | ||
1945 | if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) | 1944 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
1946 | return SIGILL; | 1945 | return SIGILL; |
1947 | 1946 | ||
1948 | DIFROMREG(bits, MIPSInst_FS(ir)); | 1947 | DIFROMREG(bits, MIPSInst_FS(ir)); |
@@ -2006,7 +2005,7 @@ dcopuop: | |||
2006 | SITOREG(rv.w, MIPSInst_FD(ir)); | 2005 | SITOREG(rv.w, MIPSInst_FD(ir)); |
2007 | break; | 2006 | break; |
2008 | case l_fmt: | 2007 | case l_fmt: |
2009 | if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) | 2008 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
2010 | return SIGILL; | 2009 | return SIGILL; |
2011 | 2010 | ||
2012 | DITOREG(rv.l, MIPSInst_FD(ir)); | 2011 | DITOREG(rv.l, MIPSInst_FD(ir)); |