|
@@ -151,25 +151,108 @@ static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Set the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes
|
|
|
- * for the FPU emulator. Clear the flags where required in case called
|
|
|
- * from `fpu_disable', to override details obtained from FPU hardware.
|
|
|
+ * IEEE 754 conformance mode to use. Affects the NaN encoding and the
|
|
|
+ * ABS.fmt/NEG.fmt execution mode.
|
|
|
+ */
|
|
|
+static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT;
|
|
|
+
|
|
|
+/*
|
|
|
+ * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
|
|
|
+ * to support by the FPU emulator according to the IEEE 754 conformance
|
|
|
+ * mode selected. Note that "relaxed" straps the emulator so that it
|
|
|
+ * allows 2008-NaN binaries even for legacy processors.
|
|
|
*/
|
|
|
static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
|
|
|
{
|
|
|
+ c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY);
|
|
|
c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
|
|
|
- if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
|
|
|
- MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
|
|
|
- MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
|
|
|
- c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
|
|
|
- c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
|
|
|
- } else {
|
|
|
- c->options &= ~MIPS_CPU_NAN_2008;
|
|
|
+ c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
|
|
|
+
|
|
|
+ switch (ieee754) {
|
|
|
+ case STRICT:
|
|
|
+ if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
|
|
|
+ MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
|
|
|
+ MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
|
|
|
+ c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
|
|
|
+ } else {
|
|
|
+ c->options |= MIPS_CPU_NAN_LEGACY;
|
|
|
+ c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case LEGACY:
|
|
|
c->options |= MIPS_CPU_NAN_LEGACY;
|
|
|
c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
|
|
|
+ break;
|
|
|
+ case STD2008:
|
|
|
+ c->options |= MIPS_CPU_NAN_2008;
|
|
|
+ c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
|
|
|
+ c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
|
|
|
+ break;
|
|
|
+ case RELAXED:
|
|
|
+ c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
|
|
|
+ * according to the "ieee754=" parameter.
|
|
|
+ */
|
|
|
+static void cpu_set_nan_2008(struct cpuinfo_mips *c)
|
|
|
+{
|
|
|
+ switch (ieee754) {
|
|
|
+ case STRICT:
|
|
|
+ mips_use_nan_legacy = !!cpu_has_nan_legacy;
|
|
|
+ mips_use_nan_2008 = !!cpu_has_nan_2008;
|
|
|
+ break;
|
|
|
+ case LEGACY:
|
|
|
+ mips_use_nan_legacy = !!cpu_has_nan_legacy;
|
|
|
+ mips_use_nan_2008 = !cpu_has_nan_legacy;
|
|
|
+ break;
|
|
|
+ case STD2008:
|
|
|
+ mips_use_nan_legacy = !cpu_has_nan_2008;
|
|
|
+ mips_use_nan_2008 = !!cpu_has_nan_2008;
|
|
|
+ break;
|
|
|
+ case RELAXED:
|
|
|
+ mips_use_nan_legacy = true;
|
|
|
+ mips_use_nan_2008 = true;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override
|
|
|
+ * settings:
|
|
|
+ *
|
|
|
+ * strict: accept binaries that request a NaN encoding supported by the FPU
|
|
|
+ * legacy: only accept legacy-NaN binaries
|
|
|
+ * 2008: only accept 2008-NaN binaries
|
|
|
+ * relaxed: accept any binaries regardless of whether supported by the FPU
|
|
|
+ */
|
|
|
+static int __init ieee754_setup(char *s)
|
|
|
+{
|
|
|
+ if (!s)
|
|
|
+ return -1;
|
|
|
+ else if (!strcmp(s, "strict"))
|
|
|
+ ieee754 = STRICT;
|
|
|
+ else if (!strcmp(s, "legacy"))
|
|
|
+ ieee754 = LEGACY;
|
|
|
+ else if (!strcmp(s, "2008"))
|
|
|
+ ieee754 = STD2008;
|
|
|
+ else if (!strcmp(s, "relaxed"))
|
|
|
+ ieee754 = RELAXED;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ if (!(boot_cpu_data.options & MIPS_CPU_FPU))
|
|
|
+ cpu_set_nofpu_2008(&boot_cpu_data);
|
|
|
+ cpu_set_nan_2008(&boot_cpu_data);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+early_param("ieee754", ieee754_setup);
|
|
|
+
|
|
|
/*
|
|
|
* Set the FIR feature flags for the FPU emulator.
|
|
|
*/
|
|
@@ -212,6 +295,7 @@ static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
|
|
|
|
|
|
cpu_set_fpu_fcsr_mask(c);
|
|
|
cpu_set_fpu_2008(c);
|
|
|
+ cpu_set_nan_2008(c);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -223,6 +307,7 @@ static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
|
|
|
c->fpu_msk31 = mips_nofpu_msk31;
|
|
|
|
|
|
cpu_set_nofpu_2008(c);
|
|
|
+ cpu_set_nan_2008(c);
|
|
|
cpu_set_nofpu_id(c);
|
|
|
}
|
|
|
|