* [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches
@ 2016-03-11 15:03 Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Hi,
this patch-series adds the inital infrastructure for FPU instructions and adds
the first few: add, sub, mul, div, cmp, ftoi, and itof. Patch [02/07] moves
the general CHECK_REG_PAIR to each single instruction since add.f and sub.f
do not use 64-bit registers and would generate a false exception.
Cheers,
Bastian
v3 -> v4:
- re-introduce f_get_excp_flags() which explicitly states which flags to use
- actually remove double check on float_flag_invalid in f_update_psw_flags()
- substitute get_float_exception_flags() with f_get_excp_flags() for fadd/fsub/fmul/fdiv
v2 -> v3:
- substitute f_get_excp_flags() with get_float_exception_flags() for fadd/fsub/fmul/fdiv
- remove float32_squash_input_denormal() for fadd/fsub/fmul/fdiv
- 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()
v1 -> v2:
- ftoi/itof now use f_update_psw_flags to update exception flags
- fcmp now uses float32_compare_quiet instead of doing it by hand
- fcmp now uses f_update_psw_flags to set excp flags
- Make exceptional case exceptional for fadd/fsub/fmul/fdiv
- switch arg1 and arg2 in float32_##op() since sub would otherwise
produce false results
- add TriCore to softfloat-specialize.h
- add fpu_set_state() which sets fpu config on psw_write() and cpu_reset
- add f_get_excp_flags which is used to ignore input_denormal flag
Bastian Koppelmann (7):
target-tricore: Add FPU infrastructure
target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide
target-tricore: add add.f/sub.f instructions
target-tricore: Add mul.f instruction
target-tricore: Add div.f instruction
target-tricore: Add cmp.f instruction
target-tricore: Add ftoi and itof instructions
fpu/softfloat-specialize.h | 2 +-
target-tricore/Makefile.objs | 2 +-
target-tricore/cpu.h | 6 +-
target-tricore/fpu_helper.c | 227 +++++++++++++++++++++++++++++++++++++++
target-tricore/helper.c | 10 ++
target-tricore/helper.h | 7 ++
target-tricore/translate.c | 32 +++++-
target-tricore/tricore-opcodes.h | 18 ++++
8 files changed, 298 insertions(+), 6 deletions(-)
create mode 100644 target-tricore/fpu_helper.c
--
2.7.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v4 1/7] target-tricore: Add FPU infrastructure
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
@ 2016-03-11 15:03 ` Bastian Koppelmann
2016-03-12 22:03 ` Richard Henderson
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 2/7] target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide Bastian Koppelmann
` (5 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 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>
---
v3 -> v4:
- re-introduce f_get_excp_flags which explicitly states which flags to use
- actually 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 | 91 ++++++++++++++++++++++++++++++++++++++++
target-tricore/helper.c | 10 +++++
target-tricore/translate.c | 1 +
target-tricore/tricore-opcodes.h | 18 ++++++++
7 files changed, 126 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..ab00dd0
--- /dev/null
+++ b/target-tricore/fpu_helper.c
@@ -0,0 +1,91 @@
+/*
+ * 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
+
+/* we don't care about input_denormal */
+static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
+{
+ 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);
+}
+
+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 = 1 << 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] 9+ messages in thread
* [Qemu-devel] [PATCH v4 2/7] target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
@ 2016-03-11 15:03 ` Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 3/7] target-tricore: add add.f/sub.f instructions Bastian Koppelmann
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 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] 9+ messages in thread
* [Qemu-devel] [PATCH v4 3/7] target-tricore: add add.f/sub.f instructions
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 2/7] target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide Bastian Koppelmann
@ 2016-03-11 15:03 ` Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 4/7] target-tricore: Add mul.f instruction Bastian Koppelmann
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 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>
---
v3 -> v4:
- use f_get_excp_flags() again
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 ab00dd0..f81527d 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -57,7 +57,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);
@@ -89,3 +89,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 = f_get_excp_flags(env); \
+ 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] 9+ messages in thread
* [Qemu-devel] [PATCH v4 4/7] target-tricore: Add mul.f instruction
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
` (2 preceding siblings ...)
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 3/7] target-tricore: add add.f/sub.f instructions Bastian Koppelmann
@ 2016-03-11 15:03 ` Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 5/7] target-tricore: Add div.f instruction Bastian Koppelmann
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 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>
---
v3 -> v4:
- use f_get_excp_flags() again
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 f81527d..885b1c9 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -116,3 +116,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 = f_get_excp_flags(env);
+ 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] 9+ messages in thread
* [Qemu-devel] [PATCH v4 5/7] target-tricore: Add div.f instruction
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
` (3 preceding siblings ...)
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 4/7] target-tricore: Add mul.f instruction Bastian Koppelmann
@ 2016-03-11 15:03 ` Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 6/7] target-tricore: Add cmp.f instruction Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 7/7] target-tricore: Add ftoi and itof instructions Bastian Koppelmann
6 siblings, 0 replies; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 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>
---
v3 -> v4:
- use f_get_excp_flags() again
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 885b1c9..eca63eb 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -142,3 +142,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 = f_get_excp_flags(env);
+ 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] 9+ messages in thread
* [Qemu-devel] [PATCH v4 6/7] target-tricore: Add cmp.f instruction
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
` (4 preceding siblings ...)
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 5/7] target-tricore: Add div.f instruction Bastian Koppelmann
@ 2016-03-11 15:03 ` Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 7/7] target-tricore: Add ftoi and itof instructions Bastian Koppelmann
6 siblings, 0 replies; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 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>
---
v3 -> v4:
- use f_get_excp_flags() again
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 eca63eb..6586020 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -168,3 +168,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 = f_get_excp_flags(env);
+ 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] 9+ messages in thread
* [Qemu-devel] [PATCH v4 7/7] target-tricore: Add ftoi and itof instructions
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
` (5 preceding siblings ...)
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 6/7] target-tricore: Add cmp.f instruction Bastian Koppelmann
@ 2016-03-11 15:03 ` Bastian Koppelmann
6 siblings, 0 replies; 9+ messages in thread
From: Bastian Koppelmann @ 2016-03-11 15:03 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>
---
v3 -> v4:
- use f_get_excp_flags() again
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 6586020..71735af 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -191,3 +191,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 = f_get_excp_flags(env);
+ 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 = f_get_excp_flags(env);
+ 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] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4 1/7] target-tricore: Add FPU infrastructure
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
@ 2016-03-12 22:03 ` Richard Henderson
0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2016-03-12 22:03 UTC (permalink / raw)
To: Bastian Koppelmann, qemu-devel
On 03/11/2016 07:03 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>
> ---
> v3 -> v4:
> - re-introduce f_get_excp_flags which explicitly states which flags to use
> - actually remove double check on float_flag_invalid in f_update_psw_flags()
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-03-12 22:03 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-11 15:03 [Qemu-devel] [PATCH v4 0/7] TriCore FPU patches Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 1/7] target-tricore: Add FPU infrastructure Bastian Koppelmann
2016-03-12 22:03 ` Richard Henderson
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 2/7] target-tricore: Move general CHECK_REG_PAIR of decode_rrr_divide Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 3/7] target-tricore: add add.f/sub.f instructions Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 4/7] target-tricore: Add mul.f instruction Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 5/7] target-tricore: Add div.f instruction Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 6/7] target-tricore: Add cmp.f instruction Bastian Koppelmann
2016-03-11 15:03 ` [Qemu-devel] [PATCH v4 7/7] target-tricore: Add ftoi and itof instructions Bastian Koppelmann
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.