Re: [PATCH] target/mips: Add MAC2008 support

2020-03-28 Thread Jiaxun Yang



于 2020年3月29日 GMT+08:00 上午3:09:16, Richard Henderson 
 写到:
>On 3/28/20 2:08 AM, Jiaxun Yang wrote:
>> -gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
>> +if (ctx->mac2008) {
>> +gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1,
>fp2);
>> +} else {
>> +gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1,
>fp2);
>> +}
>>  
>
>Surely this test is backward, that mac2008 invokes maddf.

 Sorry for my stupid fault.
Will fix in v2.

>
>
>r~

-- 
Jiaxun Yang



Re: [PATCH] target/mips: Add MAC2008 support

2020-03-28 Thread Richard Henderson
On 3/28/20 2:08 AM, Jiaxun Yang wrote:
> -gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
> +if (ctx->mac2008) {
> +gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
> +} else {
> +gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
> +}
>  

Surely this test is backward, that mac2008 invokes maddf.


r~



[PATCH] target/mips: Add MAC2008 support

2020-03-28 Thread Jiaxun Yang
MAC2008 was introduced in MIPS Release 3 but removed in MIPS Release 5.
However, there are some processors implemented this feature.
some Ingenic MCU can config MAC2008 status runtime while whole
Loongson-64 family are MAC2008 only.

FCSR.MAC2008 bit indicates FMA family of instructions on these
processors have fused behavior, similiar to FMA in Release 6,
so we can reuse helpers with them.

Signed-off-by: Jiaxun Yang 
---
 target/mips/cpu.h|  1 +
 target/mips/fpu_helper.c | 61 +
 target/mips/helper.h | 12 +++
 target/mips/translate.c  | 74 +---
 4 files changed, 107 insertions(+), 41 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 94d01ea798..b20e6e3387 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -63,6 +63,7 @@ struct CPUMIPSFPUContext {
 uint32_t fcr31_rw_bitmask;
 uint32_t fcr31;
 #define FCR31_FS 24
+#define FCR31_MAC2008 20
 #define FCR31_ABS2008 19
 #define FCR31_NAN2008 18
 #define SET_FP_COND(num, env) do { ((env).fcr31) |= \
diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 5287c86c61..2e50d50f36 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1357,7 +1357,7 @@ FLOAT_MINMAX(mina_d, 64, minnummag)
 }\
 }
 
-/* FMA based operations */
+/* FMA based operations (both unfused and fused) */
 #define FLOAT_FMA(name, type)\
 uint64_t helper_float_ ## name ## _d(CPUMIPSState *env,  \
  uint64_t fdt0, uint64_t fdt1,   \
@@ -1392,33 +1392,52 @@ uint64_t helper_float_ ## name ## _ps(CPUMIPSState 
*env, \
 UNFUSED_FMA(float32, fsth0, fsth1, fsth2, type); \
 update_fcr31(env, GETPC());  \
 return ((uint64_t)fsth0 << 32) | fst0;   \
+}\
+uint64_t helper_float_ ## name ## f_d(CPUMIPSState *env, \
+ uint64_t fdt0, uint64_t fdt1,   \
+ uint64_t fdt2)  \
+{\
+fdt0 = float64_muladd(fdt0, fdt1, fdt2, type,\
+>active_fpu.fp_status); \
+update_fcr31(env, GETPC());  \
+return fdt0; \
+}\
+ \
+uint32_t helper_float_ ## name ## f_s(CPUMIPSState *env, \
+ uint32_t fst0, uint32_t fst1,   \
+ uint32_t fst2)  \
+{\
+fst0 = float32_muladd(fst0, fst1, fst2, type,\
+>active_fpu.fp_status); \
+update_fcr31(env, GETPC());  \
+return fst0; \
+}\
+ \
+uint64_t helper_float_ ## name ## f_ps(CPUMIPSState *env,\
+  uint64_t fdt0, uint64_t fdt1,  \
+  uint64_t fdt2) \
+{\
+uint32_t fst0 = fdt0 & 0X;   \
+uint32_t fsth0 = fdt0 >> 32; \
+uint32_t fst1 = fdt1 & 0X;   \
+uint32_t fsth1 = fdt1 >> 32; \
+uint32_t fst2 = fdt2 & 0X;   \
+uint32_t fsth2 = fdt2 >> 32; \
+ \
+fst0 = float32_muladd(fst0, fst1, fst2, type,\
+>active_fpu.fp_status); \
+fsth0 = float32_muladd(fsth0, fsth1, fsth2, type,\
+>active_fpu.fp_status); \
+update_fcr31(env, GETPC());  \
+return ((uint64_t)fsth0 << 32) | fst0;   \
 }
+
 FLOAT_FMA(madd, 0)
 FLOAT_FMA(msub, float_muladd_negate_c)
 FLOAT_FMA(nmadd, float_muladd_negate_result)
 FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c)
 #undef FLOAT_FMA
 
-#define FLOAT_FMADDSUB(name, bits, muladd_arg)  \