aboutsummaryrefslogtreecommitdiff
path: root/target-mips/op_helper.c
diff options
context:
space:
mode:
authorLeon Alrae <leon.alrae@imgtec.com>2015-04-21 16:06:28 +0100
committerLeon Alrae <leon.alrae@imgtec.com>2015-06-11 10:13:28 +0100
commit7c979afd11b09a16634699dd6344e3ba10c9677e (patch)
tree2175a47d3d9f5a95406887a1b0e17c3c5c00b9d6 /target-mips/op_helper.c
parenteab9944c7801525737626fa45cddaf00932dd2c8 (diff)
target-mips: add Config5.FRE support allowing Status.FR=0 emulation
This relatively small architectural feature adds the following: FIR.FREP: Read-only. If FREP=1, then Config5.FRE and Config5.UFE are available. Config5.FRE: When enabled all single-precision FP arithmetic instructions, LWC1/LWXC1/MTC1, SWC1/SWXC1/MFC1 cause a Reserved Instructions exception. Config5.UFE: Allows user to write/read Config5.FRE using CTC1/CFC1 instructions. Enable the feature in MIPS64R6-generic CPU. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r--target-mips/op_helper.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 73a8e458fc..dd89068f92 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2303,6 +2303,16 @@ target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
}
}
break;
+ case 5:
+ /* FRE Support - read Config5.FRE bit */
+ if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
+ if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
+ arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
+ } else {
+ helper_raise_exception(env, EXCP_RI);
+ }
+ }
+ break;
case 25:
arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | ((env->active_fpu.fcr31 >> 23) & 0x1);
break;
@@ -2347,6 +2357,30 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
helper_raise_exception(env, EXCP_RI);
}
break;
+ case 5:
+ /* FRE Support - clear Config5.FRE bit */
+ if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
+ return;
+ }
+ if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
+ env->CP0_Config5 &= ~(1 << CP0C5_FRE);
+ compute_hflags(env);
+ } else {
+ helper_raise_exception(env, EXCP_RI);
+ }
+ break;
+ case 6:
+ /* FRE Support - set Config5.FRE bit */
+ if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
+ return;
+ }
+ if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
+ env->CP0_Config5 |= (1 << CP0C5_FRE);
+ compute_hflags(env);
+ } else {
+ helper_raise_exception(env, EXCP_RI);
+ }
+ break;
case 25:
if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) {
return;