* [Qemu-devel] [PATCH v3 1/7] target-tricore: Add FPU infrastructure
2016-03-09 10:42 [Qemu-devel] [PATCH v3 0/7] TriCore FPU patches Bastian Koppelmann
@ 2016-03-09 10:42 ` Bastian Koppelmann
2016-03-09 15:59 ` Richard Henderson
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 2/7] target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide Bastian Koppelmann
` (5 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 10:42 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
This patch adds a file for all the FPU related helpers with all the includes,
useful defines, and a function to update the status bits. Additionally it adds
a mask for the rounding mode bits of PSW as well as all the opcodes for the
FPU instructions.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
v2 -> v3:
- remove f_get_excp_flags(), which used a magic number
- f_update_psw_flags() now computes FPU_FS conditionally
- remove double check on float_flag_invalid in f_update_psw_flags()
fpu/softfloat-specialize.h | 2 +-
target-tricore/Makefile.objs | 2 +-
target-tricore/cpu.h | 6 ++-
target-tricore/fpu_helper.c | 79 ++++++++++++++++++++++++++++++++++++++++
target-tricore/helper.c | 10 +++++
target-tricore/translate.c | 1 +
target-tricore/tricore-opcodes.h | 18 +++++++++
7 files changed, 114 insertions(+), 4 deletions(-)
create mode 100644 target-tricore/fpu_helper.c
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 0875436..a4cbdad 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -113,7 +113,7 @@ const float16 float16_default_nan = const_float16(0xFE00);
#if defined(TARGET_SPARC)
const float32 float32_default_nan = const_float32(0x7FFFFFFF);
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
- defined(TARGET_XTENSA) || defined(TARGET_S390X)
+ defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE)
const float32 float32_default_nan = const_float32(0x7FC00000);
#elif SNAN_BIT_IS_ONE
const float32 float32_default_nan = const_float32(0x7FBFFFFF);
diff --git a/target-tricore/Makefile.objs b/target-tricore/Makefile.objs
index 21e820d..7a05670 100644
--- a/target-tricore/Makefile.objs
+++ b/target-tricore/Makefile.objs
@@ -1 +1 @@
-obj-y += translate.o helper.o cpu.o op_helper.o
+obj-y += translate.o helper.o cpu.o op_helper.o fpu_helper.o
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index 5fee376..90045a9 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -183,8 +183,7 @@ struct CPUTriCoreState {
uint32_t M2CNT;
uint32_t M3CNT;
/* Floating Point Registers */
- /* XXX: */
-
+ float_status fp_status;
/* QEMU */
int error_code;
uint32_t hflags; /* CPU State */
@@ -217,6 +216,7 @@ struct CPUTriCoreState {
#define MASK_PSW_GW 0x00000100
#define MASK_PSW_CDE 0x00000080
#define MASK_PSW_CDC 0x0000007f
+#define MASK_PSW_FPU_RM 0x3000000
#define MASK_SYSCON_PRO_TEN 0x2
#define MASK_SYSCON_FCD_SF 0x1
@@ -339,6 +339,8 @@ enum {
uint32_t psw_read(CPUTriCoreState *env);
void psw_write(CPUTriCoreState *env, uint32_t val);
+void fpu_set_state(CPUTriCoreState *env);
+
#include "cpu-qom.h"
#define MMU_USER_IDX 2
diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
new file mode 100644
index 0000000..8e89979
--- /dev/null
+++ b/target-tricore/fpu_helper.c
@@ -0,0 +1,79 @@
+/*
+ * TriCore emulation for qemu: fpu helper.
+ *
+ * Copyright (c) 2016 Bastian Koppelmann University of Paderborn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+
+#define ADD_NAN 0x7cf00001
+#define DIV_NAN 0x7fc00008
+#define MUL_NAN 0x7fc00002
+#define FPU_FS PSW_USB_C
+#define FPU_FI PSW_USB_V
+#define FPU_FV PSW_USB_SV
+#define FPU_FZ PSW_USB_AV
+#define FPU_FU PSW_USB_SAV
+
+static inline bool f_is_pos_inf(float32 arg)
+{
+ return !float32_is_neg(arg) && float32_is_infinity(arg);
+}
+
+static inline bool f_is_neg_inf(float32 arg)
+{
+ return float32_is_neg(arg) && float32_is_infinity(arg);
+}
+
+static inline bool f_is_denormal(float32 arg)
+{
+ return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
+}
+
+static inline void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
+{
+ uint8_t some_excp = 0;
+ set_float_exception_flags(0, &env->fp_status);
+
+ if (flags & float_flag_invalid) {
+ env->FPU_FI = (flags & float_flag_invalid) << 31;
+ some_excp = 1;
+ }
+
+ if (flags & float_flag_overflow) {
+ env->FPU_FV = 1 << 31;
+ some_excp = 1;
+ }
+
+ if (flags & float_flag_underflow || flags & float_flag_output_denormal) {
+ env->FPU_FU = 1 << 31;
+ some_excp = 1;
+ }
+
+ if (flags & float_flag_divbyzero) {
+ env->FPU_FZ = 1 << 31;
+ some_excp = 1;
+ }
+
+ if (flags & float_flag_inexact || flags & float_flag_output_denormal) {
+ env->PSW |= 1 << 26;
+ some_excp = 1;
+ }
+
+ env->FPU_FS = some_excp;
+}
diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index 7d96dad..5d0add6 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -110,6 +110,14 @@ void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf)
g_slist_free(list);
}
+void fpu_set_state(CPUTriCoreState *env)
+{
+ set_float_rounding_mode(env->PSW & MASK_PSW_FPU_RM, &env->fp_status);
+ set_flush_inputs_to_zero(1, &env->fp_status);
+ set_flush_to_zero(1, &env->fp_status);
+ set_default_nan_mode(1, &env->fp_status);
+}
+
uint32_t psw_read(CPUTriCoreState *env)
{
/* clear all USB bits */
@@ -132,4 +140,6 @@ void psw_write(CPUTriCoreState *env, uint32_t val)
env->PSW_USB_AV = (val & MASK_USB_AV) << 3;
env->PSW_USB_SAV = (val & MASK_USB_SAV) << 4;
env->PSW = val;
+
+ fpu_set_state(env);
}
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index d13e5c8..06ac41a 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -8771,6 +8771,7 @@ void cpu_state_reset(CPUTriCoreState *env)
{
/* Reset Regs to Default Value */
env->PSW = 0xb80;
+ fpu_set_state(env);
}
static void tricore_tcg_init_csfr(void)
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 1bfed0c..df666b0 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1126,6 +1126,20 @@ enum {
OPC2_32_RR_CRC32 = 0x03,
OPC2_32_RR_DIV = 0x20,
OPC2_32_RR_DIV_U = 0x21,
+ OPC2_32_RR_MUL_F = 0x04,
+ OPC2_32_RR_DIV_F = 0x05,
+ OPC2_32_RR_FTOI = 0x10,
+ OPC2_32_RR_ITOF = 0x14,
+ OPC2_32_RR_CMP_F = 0x00,
+ OPC2_32_RR_FTOIZ = 0x13,
+ OPC2_32_RR_FTOQ31 = 0x11,
+ OPC2_32_RR_FTOQ31Z = 0x18,
+ OPC2_32_RR_FTOU = 0x12,
+ OPC2_32_RR_FTOUZ = 0x17,
+ OPC2_32_RR_Q31TOF = 0x15,
+ OPC2_32_RR_QSEED_F = 0x19,
+ OPC2_32_RR_UPDFL = 0x0c,
+ OPC2_32_RR_UTOF = 0x16,
};
/* OPCM_32_RR_IDIRECT */
enum {
@@ -1209,6 +1223,10 @@ enum {
OPC2_32_RRR_IXMIN = 0x08,
OPC2_32_RRR_IXMIN_U = 0x09,
OPC2_32_RRR_PACK = 0x00,
+ OPC2_32_RRR_ADD_F = 0x02,
+ OPC2_32_RRR_SUB_F = 0x03,
+ OPC2_32_RRR_MADD_F = 0x06,
+ OPC2_32_RRR_MSUB_F = 0x07,
};
/*
* RRR1 Format
--
2.7.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v3 1/7] target-tricore: Add FPU infrastructure
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
@ 2016-03-09 15:59 ` Richard Henderson
2016-03-09 17:30 ` Bastian Koppelmann
0 siblings, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2016-03-09 15:59 UTC (permalink / raw)
To: Bastian Koppelmann, qemu-devel
On 03/09/2016 05:42 AM, Bastian Koppelmann wrote:
> This patch adds a file for all the FPU related helpers with all the includes,
> useful defines, and a function to update the status bits. Additionally it adds
> a mask for the rounding mode bits of PSW as well as all the opcodes for the
> FPU instructions.
>
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> ---
> v2 -> v3:
> - remove f_get_excp_flags(), which used a magic number
Actually I liked f_get_excp_flags, since it immediately discards the exceptions
that you don't care about. I just wanted it to be written
return get_float_exception_flags(&env->fp_status)
& (float_flag_invalid
| float_flag_overflow
| float_flag_underflow
| float_flag_output_denormal
| float_flag_divbyzero
| float_flag_inexact);
instead of "& 0xbf".
> - remove double check on float_flag_invalid in f_update_psw_flags()
...
> + if (flags & float_flag_invalid) {
> + env->FPU_FI = (flags & float_flag_invalid) << 31;
> + some_excp = 1;
> + }
You didn't, actually.
r~
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v3 1/7] target-tricore: Add FPU infrastructure
2016-03-09 15:59 ` Richard Henderson
@ 2016-03-09 17:30 ` Bastian Koppelmann
0 siblings, 0 replies; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 17:30 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 03/09/2016 04:59 PM, Richard Henderson wrote:
> On 03/09/2016 05:42 AM, Bastian Koppelmann wrote:
>> This patch adds a file for all the FPU related helpers with all the
>> includes,
>> useful defines, and a function to update the status bits. Additionally
>> it adds
>> a mask for the rounding mode bits of PSW as well as all the opcodes
>> for the
>> FPU instructions.
>>
>> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
>> ---
>> v2 -> v3:
>> - remove f_get_excp_flags(), which used a magic number
>
> Actually I liked f_get_excp_flags, since it immediately discards the
> exceptions that you don't care about. I just wanted it to be written
>
> return get_float_exception_flags(&env->fp_status)
> & (float_flag_invalid
> | float_flag_overflow
> | float_flag_underflow
> | float_flag_output_denormal
> | float_flag_divbyzero
> | float_flag_inexact);
>
> instead of "& 0xbf".
Okay, I see. Thanks for the clarification.
>
>> - remove double check on float_flag_invalid in f_update_psw_flags()
> ...
>> + if (flags & float_flag_invalid) {
>> + env->FPU_FI = (flags & float_flag_invalid) << 31;
>> + some_excp = 1;
>> + }
>
> You didn't, actually.
>
Errr.. That was not supposed to happen, sorry.
Cheers,
Bastian
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v3 2/7] target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide
2016-03-09 10:42 [Qemu-devel] [PATCH v3 0/7] TriCore FPU patches Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
@ 2016-03-09 10:42 ` Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 3/7] target-tricore: add add.f/sub.f instructions Bastian Koppelmann
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 10:42 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
The add.f and sub.f to be implemented don't use 64 bit registers
and a general usage of CHECK_REG_PAIR would always generate an
exception for them.
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/translate.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 06ac41a..469f721 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -7013,45 +7013,51 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx)
r3 = MASK_OP_RRR_S3(ctx->opcode);
r4 = MASK_OP_RRR_D(ctx->opcode);
- CHECK_REG_PAIR(r3);
-
switch (op2) {
case OPC2_32_RRR_DVADJ:
+ CHECK_REG_PAIR(r3);
CHECK_REG_PAIR(r4);
GEN_HELPER_RRR(dvadj, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR_DVSTEP:
+ CHECK_REG_PAIR(r3);
CHECK_REG_PAIR(r4);
GEN_HELPER_RRR(dvstep, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR_DVSTEP_U:
+ CHECK_REG_PAIR(r3);
CHECK_REG_PAIR(r4);
GEN_HELPER_RRR(dvstep_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR_IXMAX:
+ CHECK_REG_PAIR(r3);
CHECK_REG_PAIR(r4);
GEN_HELPER_RRR(ixmax, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR_IXMAX_U:
+ CHECK_REG_PAIR(r3);
CHECK_REG_PAIR(r4);
GEN_HELPER_RRR(ixmax_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR_IXMIN:
+ CHECK_REG_PAIR(r3);
CHECK_REG_PAIR(r4);
GEN_HELPER_RRR(ixmin, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR_IXMIN_U:
+ CHECK_REG_PAIR(r3);
CHECK_REG_PAIR(r4);
GEN_HELPER_RRR(ixmin_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR_PACK:
+ CHECK_REG_PAIR(r3);
gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
break;
--
2.7.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v3 3/7] target-tricore: add add.f/sub.f instructions
2016-03-09 10:42 [Qemu-devel] [PATCH v3 0/7] TriCore FPU patches Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 2/7] target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide Bastian Koppelmann
@ 2016-03-09 10:42 ` Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 4/7] target-tricore: Add mul.f instruction Bastian Koppelmann
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 10:42 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
v2 -> v3:
- substitute f_get_excp_flags() with get_float_exception_flags()
- remove float32_squash_input_denormal()
target-tricore/fpu_helper.c | 29 ++++++++++++++++++++++++++++-
target-tricore/helper.h | 2 ++
target-tricore/translate.c | 6 ++++++
3 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index 8e89979..f8d29b0 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -45,7 +45,7 @@ static inline bool f_is_denormal(float32 arg)
return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
}
-static inline void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
+static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
{
uint8_t some_excp = 0;
set_float_exception_flags(0, &env->fp_status);
@@ -77,3 +77,30 @@ static inline void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
env->FPU_FS = some_excp;
}
+
+#define FADD_SUB(op) \
+uint32_t helper_f##op(CPUTriCoreState *env, uint32_t r1, uint32_t r2) \
+{ \
+ float32 arg1 = make_float32(r1); \
+ float32 arg2 = make_float32(r2); \
+ uint32_t flags; \
+ float32 f_result; \
+ \
+ f_result = float32_##op(arg2, arg1, &env->fp_status); \
+ flags = get_float_exception_flags(&env->fp_status); \
+ if (flags) { \
+ /* If the output is a NaN, but the inputs aren't, \
+ we return a unique value. */ \
+ if ((flags & float_flag_invalid) \
+ && !float32_is_any_nan(arg1) \
+ && !float32_is_any_nan(arg2)) { \
+ f_result = ADD_NAN; \
+ } \
+ f_update_psw_flags(env, flags); \
+ } else { \
+ env->FPU_FS = 0; \
+ } \
+ return (uint32_t)f_result; \
+}
+FADD_SUB(add)
+FADD_SUB(sub)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 2c8ed78..2f4a2bb 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -105,6 +105,8 @@ DEF_HELPER_FLAGS_1(parity, TCG_CALL_NO_RWG_SE, i32, i32)
/* float */
DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32)
DEF_HELPER_1(unpack, i64, i32)
+DEF_HELPER_3(fadd, i32, env, i32, i32)
+DEF_HELPER_3(fsub, i32, env, i32, i32)
/* dvinit */
DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 469f721..3f54987 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -7061,6 +7061,12 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx)
gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
break;
+ case OPC2_32_RRR_ADD_F:
+ gen_helper_fadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
+ break;
+ case OPC2_32_RRR_SUB_F:
+ gen_helper_fsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
+ break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
--
2.7.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v3 4/7] target-tricore: Add mul.f instruction
2016-03-09 10:42 [Qemu-devel] [PATCH v3 0/7] TriCore FPU patches Bastian Koppelmann
` (2 preceding siblings ...)
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 3/7] target-tricore: add add.f/sub.f instructions Bastian Koppelmann
@ 2016-03-09 10:42 ` Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 5/7] target-tricore: Add div.f instruction Bastian Koppelmann
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 10:42 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
v2 -> v3:
- substitute f_get_excp_flags() with get_float_exception_flags()
- remove float32_squash_input_denormal()
target-tricore/fpu_helper.c | 26 ++++++++++++++++++++++++++
target-tricore/helper.h | 1 +
target-tricore/translate.c | 3 +++
3 files changed, 30 insertions(+)
diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index f8d29b0..332d471 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -104,3 +104,29 @@ uint32_t helper_f##op(CPUTriCoreState *env, uint32_t r1, uint32_t r2) \
}
FADD_SUB(add)
FADD_SUB(sub)
+
+uint32_t helper_fmul(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ uint32_t flags;
+ float32 arg1 = make_float32(r1);
+ float32 arg2 = make_float32(r2);
+ float32 f_result;
+
+ f_result = float32_mul(arg1, arg2, &env->fp_status);
+
+ flags = get_float_exception_flags(&env->fp_status);
+ if (flags) {
+ /* If the output is a NaN, but the inputs aren't,
+ we return a unique value. */
+ if ((flags & float_flag_invalid)
+ && !float32_is_any_nan(arg1)
+ && !float32_is_any_nan(arg2)) {
+ f_result = MUL_NAN;
+ }
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+ return (uint32_t)f_result;
+
+}
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 2f4a2bb..ac41190 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -107,6 +107,7 @@ DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32)
DEF_HELPER_1(unpack, i64, i32)
DEF_HELPER_3(fadd, i32, env, i32, i32)
DEF_HELPER_3(fsub, i32, env, i32, i32)
+DEF_HELPER_3(fmul, i32, env, i32, i32)
/* dvinit */
DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 3f54987..38ac8d6 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6672,6 +6672,9 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
break;
+ case OPC2_32_RR_MUL_F:
+ gen_helper_fmul(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
--
2.7.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v3 5/7] target-tricore: Add div.f instruction
2016-03-09 10:42 [Qemu-devel] [PATCH v3 0/7] TriCore FPU patches Bastian Koppelmann
` (3 preceding siblings ...)
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 4/7] target-tricore: Add mul.f instruction Bastian Koppelmann
@ 2016-03-09 10:42 ` Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 6/7] target-tricore: Add cmp.f instruction Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 7/7] target-tricore: Add ftoi and itof instructions Bastian Koppelmann
6 siblings, 0 replies; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 10:42 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
v2 -> v3:
- substitute f_get_excp_flags() with get_float_exception_flags()
- remove float32_squash_input_denormal()
target-tricore/fpu_helper.c | 26 ++++++++++++++++++++++++++
target-tricore/helper.h | 1 +
target-tricore/translate.c | 3 +++
3 files changed, 30 insertions(+)
diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index 332d471..566529c 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -130,3 +130,29 @@ uint32_t helper_fmul(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
return (uint32_t)f_result;
}
+
+uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ uint32_t flags;
+ float32 arg1 = make_float32(r1);
+ float32 arg2 = make_float32(r2);
+ float32 f_result;
+
+ f_result = float32_div(arg1, arg2 , &env->fp_status);
+
+ flags = get_float_exception_flags(&env->fp_status);
+ if (flags) {
+ /* If the output is a NaN, but the inputs aren't,
+ we return a unique value. */
+ if ((flags & float_flag_invalid)
+ && !float32_is_any_nan(arg1)
+ && !float32_is_any_nan(arg2)) {
+ f_result = DIV_NAN;
+ }
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+
+ return (uint32_t)f_result;
+}
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index ac41190..f5eff36 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -108,6 +108,7 @@ DEF_HELPER_1(unpack, i64, i32)
DEF_HELPER_3(fadd, i32, env, i32, i32)
DEF_HELPER_3(fsub, i32, env, i32, i32)
DEF_HELPER_3(fmul, i32, env, i32, i32)
+DEF_HELPER_3(fdiv, i32, env, i32, i32)
/* dvinit */
DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 38ac8d6..6adeebb 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6675,6 +6675,9 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RR_MUL_F:
gen_helper_fmul(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
+ case OPC2_32_RR_DIV_F:
+ gen_helper_fdiv(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
--
2.7.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v3 6/7] target-tricore: Add cmp.f instruction
2016-03-09 10:42 [Qemu-devel] [PATCH v3 0/7] TriCore FPU patches Bastian Koppelmann
` (4 preceding siblings ...)
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 5/7] target-tricore: Add div.f instruction Bastian Koppelmann
@ 2016-03-09 10:42 ` Bastian Koppelmann
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 7/7] target-tricore: Add ftoi and itof instructions Bastian Koppelmann
6 siblings, 0 replies; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 10:42 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/fpu_helper.c | 23 +++++++++++++++++++++++
target-tricore/helper.h | 1 +
target-tricore/translate.c | 3 +++
3 files changed, 27 insertions(+)
diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index 566529c..93d0e3c 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -156,3 +156,26 @@ uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
return (uint32_t)f_result;
}
+
+uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ uint32_t result, flags;
+ float32 arg1 = make_float32(r1);
+ float32 arg2 = make_float32(r2);
+
+ set_flush_inputs_to_zero(0, &env->fp_status);
+
+ result = 1 << (float32_compare_quiet(arg1, arg2, &env->fp_status) + 1);
+ result |= f_is_denormal(arg1) << 4;
+ result |= f_is_denormal(arg2) << 5;
+
+ flags = get_float_exception_flags(&env->fp_status);
+ if (flags) {
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+
+ set_flush_inputs_to_zero(1, &env->fp_status);
+ return result;
+}
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index f5eff36..489530f 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -109,6 +109,7 @@ DEF_HELPER_3(fadd, i32, env, i32, i32)
DEF_HELPER_3(fsub, i32, env, i32, i32)
DEF_HELPER_3(fmul, i32, env, i32, i32)
DEF_HELPER_3(fdiv, i32, env, i32, i32)
+DEF_HELPER_3(fcmp, i32, env, i32, i32)
/* dvinit */
DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 6adeebb..d1ddaad 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6678,6 +6678,9 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RR_DIV_F:
gen_helper_fdiv(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
+ case OPC2_32_RR_CMP_F:
+ gen_helper_fcmp(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
--
2.7.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v3 7/7] target-tricore: Add ftoi and itof instructions
2016-03-09 10:42 [Qemu-devel] [PATCH v3 0/7] TriCore FPU patches Bastian Koppelmann
` (5 preceding siblings ...)
2016-03-09 10:42 ` [Qemu-devel] [PATCH v3 6/7] target-tricore: Add cmp.f instruction Bastian Koppelmann
@ 2016-03-09 10:42 ` Bastian Koppelmann
6 siblings, 0 replies; 10+ messages in thread
From: Bastian Koppelmann @ 2016-03-09 10:42 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/fpu_helper.c | 34 ++++++++++++++++++++++++++++++++++
target-tricore/helper.h | 2 ++
target-tricore/translate.c | 6 ++++++
3 files changed, 42 insertions(+)
diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index 93d0e3c..802f071 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -179,3 +179,37 @@ uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
set_flush_inputs_to_zero(1, &env->fp_status);
return result;
}
+
+uint32_t helper_ftoi(CPUTriCoreState *env, uint32_t arg)
+{
+ float32 f_arg = make_float32(arg);
+ int32_t result, flags;
+
+ result = float32_to_int32(f_arg, &env->fp_status);
+
+ flags = get_float_exception_flags(&env->fp_status);
+ if (flags) {
+ if (float32_is_any_nan(f_arg)) {
+ result = 0;
+ }
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+ return (uint32_t)result;
+}
+
+uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg)
+{
+ float32 f_result;
+ uint32_t flags;
+ f_result = int32_to_float32(arg, &env->fp_status);
+
+ flags = get_float_exception_flags(&env->fp_status);
+ if (flags) {
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+ return (uint32_t)f_result;
+}
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 489530f..9333e16 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -110,6 +110,8 @@ DEF_HELPER_3(fsub, i32, env, i32, i32)
DEF_HELPER_3(fmul, i32, env, i32, i32)
DEF_HELPER_3(fdiv, i32, env, i32, i32)
DEF_HELPER_3(fcmp, i32, env, i32, i32)
+DEF_HELPER_2(ftoi, i32, env, i32)
+DEF_HELPER_2(itof, i32, env, i32)
/* dvinit */
DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index d1ddaad..fe77d8a 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6681,6 +6681,12 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RR_CMP_F:
gen_helper_fcmp(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
+ case OPC2_32_RR_FTOI:
+ gen_helper_ftoi(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RR_ITOF:
+ gen_helper_itof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
--
2.7.2
^ permalink raw reply related [flat|nested] 10+ messages in thread