* [Qemu-devel] [PATCH v3 01/10] softfloat: make float_muladd_negate_* flags independent
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 02/10] softfloat: add NO_SIGNALING_NANS Max Filippov
` (9 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
Flags passed into float{32,64}_muladd are treated as bits; assign
independent bits to float_muladd_negate_* to allow precise control over
what gets negated in float{32,64}_muladd.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
---
fpu/softfloat.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index feec3a1..2860ca0 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -219,7 +219,7 @@ void float_raise( int8 flags STATUS_PARAM);
enum {
float_muladd_negate_c = 1,
float_muladd_negate_product = 2,
- float_muladd_negate_result = 3,
+ float_muladd_negate_result = 4,
};
/*----------------------------------------------------------------------------
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 02/10] softfloat: add NO_SIGNALING_NANS
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 01/10] softfloat: make float_muladd_negate_* flags independent Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 03/10] target-xtensa: handle boolean option in overlays Max Filippov
` (8 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
Architectures that don't have signaling NaNs can define
NO_SIGNALING_NANS, it will make float*_is_quiet_nan return 1 for any NaN
and float*_is_signaling_nan always return 0.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
fpu/softfloat-specialize.h | 67 ++++++++++++++++++++++++++++++++++++++++++++
fpu/softfloat.h | 5 +++
2 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 4902450..50b54b8 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -41,6 +41,13 @@ these four paragraphs for those parts of this code that are retained.
#define SNAN_BIT_IS_ONE 0
#endif
+#if defined(TARGET_XTENSA)
+/* Define for architectures which deviate from IEEE in not supporting
+ * signaling NaNs (so all NaNs are treated as quiet).
+ */
+#define NO_SIGNALING_NANS 1
+#endif
+
/*----------------------------------------------------------------------------
| The pattern for a default generated half-precision NaN.
*----------------------------------------------------------------------------*/
@@ -127,6 +134,17 @@ typedef struct {
uint64_t high, low;
} commonNaNT;
+#ifdef NO_SIGNALING_NANS
+int float16_is_quiet_nan(float16 a_)
+{
+ return float16_is_any_nan(a_);
+}
+
+int float16_is_signaling_nan(float16 a_)
+{
+ return 0;
+}
+#else
/*----------------------------------------------------------------------------
| Returns 1 if the half-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
@@ -156,6 +174,7 @@ int float16_is_signaling_nan(float16 a_)
return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
#endif
}
+#endif
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the half-precision floating point value `a' is a
@@ -217,6 +236,17 @@ static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
}
}
+#ifdef NO_SIGNALING_NANS
+int float32_is_quiet_nan(float32 a_)
+{
+ return float32_is_any_nan(a_);
+}
+
+int float32_is_signaling_nan(float32 a_)
+{
+ return 0;
+}
+#else
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
@@ -246,6 +276,7 @@ int float32_is_signaling_nan( float32 a_ )
return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
#endif
}
+#endif
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the single-precision floating point value `a' is a
@@ -586,6 +617,17 @@ static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
}
}
+#ifdef NO_SIGNALING_NANS
+int float64_is_quiet_nan(float64 a_)
+{
+ return float64_is_any_nan(a_);
+}
+
+int float64_is_signaling_nan(float64 a_)
+{
+ return 0;
+}
+#else
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
@@ -619,6 +661,7 @@ int float64_is_signaling_nan( float64 a_ )
&& ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
#endif
}
+#endif
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the double-precision floating point value `a' is a
@@ -773,6 +816,17 @@ static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
}
}
+#ifdef NO_SIGNALING_NANS
+int floatx80_is_quiet_nan(floatx80 a_)
+{
+ return floatx80_is_any_nan(a_);
+}
+
+int floatx80_is_signaling_nan(floatx80 a_)
+{
+ return 0;
+}
+#else
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is a
| quiet NaN; otherwise returns 0. This slightly differs from the same
@@ -816,6 +870,7 @@ int floatx80_is_signaling_nan( floatx80 a )
&& ( a.low == aLow );
#endif
}
+#endif
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the extended double-precision floating point value
@@ -929,6 +984,17 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
}
}
+#ifdef NO_SIGNALING_NANS
+int float128_is_quiet_nan(float128 a_)
+{
+ return float128_is_any_nan(a_);
+}
+
+int float128_is_signaling_nan(float128 a_)
+{
+ return 0;
+}
+#else
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
@@ -964,6 +1030,7 @@ int float128_is_signaling_nan( float128 a )
&& ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
#endif
}
+#endif
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 2860ca0..d8999b3 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -251,6 +251,11 @@ int float16_is_quiet_nan( float16 );
int float16_is_signaling_nan( float16 );
float16 float16_maybe_silence_nan( float16 );
+INLINE int float16_is_any_nan(float16 a)
+{
+ return ((float16_val(a) & ~0x8000) > 0x7c00);
+}
+
/*----------------------------------------------------------------------------
| The pattern for a default generated half-precision NaN.
*----------------------------------------------------------------------------*/
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 03/10] target-xtensa: handle boolean option in overlays
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 01/10] softfloat: make float_muladd_negate_* flags independent Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 02/10] softfloat: add NO_SIGNALING_NANS Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 04/10] target-xtensa: specialize softfloat NaN rules Max Filippov
` (7 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
target-xtensa/overlay_tool.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h
index a3a5650..e395053 100644
--- a/target-xtensa/overlay_tool.h
+++ b/target-xtensa/overlay_tool.h
@@ -58,6 +58,7 @@
XCHAL_OPTION(XCHAL_HAVE_SEXT, XTENSA_OPTION_MISC_OP_SEXT) | \
XCHAL_OPTION(XCHAL_HAVE_CLAMPS, XTENSA_OPTION_MISC_OP_CLAMPS) | \
XCHAL_OPTION(XCHAL_HAVE_CP, XTENSA_OPTION_COPROCESSOR) | \
+ XCHAL_OPTION(XCHAL_HAVE_BOOLEANS, XTENSA_OPTION_BOOLEAN) | \
XCHAL_OPTION(XCHAL_HAVE_FP, XTENSA_OPTION_FP_COPROCESSOR) | \
XCHAL_OPTION(XCHAL_HAVE_RELEASE_SYNC, XTENSA_OPTION_MP_SYNCHRO) | \
XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 04/10] target-xtensa: specialize softfloat NaN rules
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (2 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 03/10] target-xtensa: handle boolean option in overlays Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 05/10] target-xtensa: add FP registers Max Filippov
` (6 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
NaN propagation rule: leftmost NaN in the expression gets propagated to
the result.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
fpu/softfloat-specialize.h | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 50b54b8..a1d489e 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -64,7 +64,8 @@ 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)
+#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
+ defined(TARGET_XTENSA)
const float32 float32_default_nan = const_float32(0x7FC00000);
#elif SNAN_BIT_IS_ONE
const float32 float32_default_nan = const_float32(0x7FBFFFFF);
@@ -403,7 +404,7 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
return 1;
}
}
-#elif defined(TARGET_PPC)
+#elif defined(TARGET_PPC) || defined(TARGET_XTENSA)
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
flag aIsLargerSignificand)
{
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 05/10] target-xtensa: add FP registers
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (3 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 04/10] target-xtensa: specialize softfloat NaN rules Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 06/10] target-xtensa: implement LSCX and LSCI groups Max Filippov
` (5 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
There are 16 32-bit FP registers (f0 - f15), control and status user
registers (fcr, fsr).
See ISA, 4.3.10 for more details.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
gdbstub.c | 8 +++++++
target-xtensa/cpu.h | 3 ++
target-xtensa/helper.h | 2 +
target-xtensa/op_helper.c | 13 +++++++++++
target-xtensa/translate.c | 52 ++++++++++++++++++++++++++++++++++++++------
5 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/gdbstub.c b/gdbstub.c
index 5d37dd9..c28c6b5 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1660,6 +1660,10 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
GET_REG32(env->uregs[reg->targno & 0xff]);
break;
+ case 4: /*f*/
+ GET_REG32(float32_val(env->fregs[reg->targno & 0x0f]));
+ break;
+
case 8: /*a*/
GET_REG32(env->regs[reg->targno & 0x0f]);
break;
@@ -1700,6 +1704,10 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
env->uregs[reg->targno & 0xff] = tmp;
break;
+ case 4: /*f*/
+ env->fregs[reg->targno & 0x0f] = make_float32(tmp);
+ break;
+
case 8: /*a*/
env->regs[reg->targno & 0x0f] = tmp;
break;
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 177094a..b456283 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -36,6 +36,7 @@
#include "config.h"
#include "qemu-common.h"
#include "cpu-defs.h"
+#include "fpu/softfloat.h"
#define TARGET_HAS_ICE 1
@@ -325,6 +326,8 @@ typedef struct CPUXtensaState {
uint32_t sregs[256];
uint32_t uregs[256];
uint32_t phys_regs[MAX_NAREG];
+ float32 fregs[16];
+ float_status fp_status;
xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE];
xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE];
diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h
index 152fec0..1662552 100644
--- a/target-xtensa/helper.h
+++ b/target-xtensa/helper.h
@@ -36,4 +36,6 @@ DEF_HELPER_3(wsr_ibreaka, void, env, i32, i32)
DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32)
DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32)
+DEF_HELPER_2(wur_fcr, void, env, i32)
+
#include "def-helper.h"
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 2659c0e..3bf7339 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -771,3 +771,16 @@ void HELPER(wsr_dbreakc)(CPUXtensaState *env, uint32_t i, uint32_t v)
}
env->sregs[DBREAKC + i] = v;
}
+
+void HELPER(wur_fcr)(CPUXtensaState *env, uint32_t v)
+{
+ static const int rounding_mode[] = {
+ float_round_nearest_even,
+ float_round_to_zero,
+ float_round_up,
+ float_round_down,
+ };
+
+ env->uregs[FCR] = v & 0xfffff07f;
+ set_float_rounding_mode(rounding_mode[v & 3], &env->fp_status);
+}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 1900bd5..97c388a 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -70,6 +70,7 @@ typedef struct DisasContext {
static TCGv_ptr cpu_env;
static TCGv_i32 cpu_pc;
static TCGv_i32 cpu_R[16];
+static TCGv_i32 cpu_FR[16];
static TCGv_i32 cpu_SR[256];
static TCGv_i32 cpu_UR[256];
@@ -155,6 +156,12 @@ void xtensa_translate_init(void)
"ar8", "ar9", "ar10", "ar11",
"ar12", "ar13", "ar14", "ar15",
};
+ static const char * const fregnames[] = {
+ "f0", "f1", "f2", "f3",
+ "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11",
+ "f12", "f13", "f14", "f15",
+ };
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
@@ -167,6 +174,12 @@ void xtensa_translate_init(void)
regnames[i]);
}
+ for (i = 0; i < 16; i++) {
+ cpu_FR[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUXtensaState, fregs[i]),
+ fregnames[i]);
+ }
+
for (i = 0; i < 256; ++i) {
if (sregnames[i]) {
cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
@@ -692,6 +705,23 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
}
}
+static void gen_wur(uint32_t ur, TCGv_i32 s)
+{
+ switch (ur) {
+ case FCR:
+ gen_helper_wur_fcr(cpu_env, s);
+ break;
+
+ case FSR:
+ tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80);
+ break;
+
+ default:
+ tcg_gen_mov_i32(cpu_UR[ur], s);
+ break;
+ }
+}
+
static void gen_load_store_alignment(DisasContext *dc, int shift,
TCGv_i32 addr, bool no_hw_alignment)
{
@@ -1761,13 +1791,11 @@ static void disas_xtensa_insn(DisasContext *dc)
case 15: /*WUR*/
gen_window_check1(dc, RRR_T);
- {
- if (uregnames[RSR_SR]) {
- tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);
- } else {
- qemu_log("WUR %d not implemented, ", RSR_SR);
- TBD();
- }
+ if (uregnames[RSR_SR]) {
+ gen_wur(RSR_SR, cpu_R[RRR_T]);
+ } else {
+ qemu_log("WUR %d not implemented, ", RSR_SR);
+ TBD();
}
break;
@@ -2710,6 +2738,16 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
(i % 4) == 3 ? '\n' : ' ');
}
+
+ if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
+ cpu_fprintf(f, "\n");
+
+ for (i = 0; i < 16; ++i) {
+ cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
+ float32_val(env->fregs[i]),
+ *(float *)&env->fregs[i], (i % 2) == 1 ? '\n' : ' ');
+ }
+ }
}
void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, int pc_pos)
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 06/10] target-xtensa: implement LSCX and LSCI groups
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (4 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 05/10] target-xtensa: add FP registers Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 07/10] target-xtensa: implement FP0 arithmetic Max Filippov
` (4 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
These are load/store instructions for FP registers with immediate or
register index and optional base post-update.
See ISA, 4.3.10 for more details.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
target-xtensa/translate.c | 58 +++++++++++++++++++++++++++++++++++++++++---
1 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 97c388a..d167e9d 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -1825,8 +1825,33 @@ static void disas_xtensa_insn(DisasContext *dc)
break;
case 8: /*LSCXp*/
- HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
- TBD();
+ switch (OP2) {
+ case 0: /*LSXf*/
+ case 1: /*LSXUf*/
+ case 4: /*SSXf*/
+ case 5: /*SSXUf*/
+ HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
+ gen_window_check2(dc, RRR_S, RRR_T);
+ {
+ TCGv_i32 addr = tcg_temp_new_i32();
+ tcg_gen_add_i32(addr, cpu_R[RRR_S], cpu_R[RRR_T]);
+ gen_load_store_alignment(dc, 2, addr, false);
+ if (OP2 & 0x4) {
+ tcg_gen_qemu_st32(cpu_FR[RRR_R], addr, dc->cring);
+ } else {
+ tcg_gen_qemu_ld32u(cpu_FR[RRR_R], addr, dc->cring);
+ }
+ if (OP2 & 0x1) {
+ tcg_gen_mov_i32(cpu_R[RRR_S], addr);
+ }
+ tcg_temp_free(addr);
+ }
+ break;
+
+ default: /*reserved*/
+ RESERVED();
+ break;
+ }
break;
case 9: /*LSC4*/
@@ -2100,8 +2125,33 @@ static void disas_xtensa_insn(DisasContext *dc)
break;
case 3: /*LSCIp*/
- HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
- TBD();
+ switch (RRI8_R) {
+ case 0: /*LSIf*/
+ case 4: /*SSIf*/
+ case 8: /*LSIUf*/
+ case 12: /*SSIUf*/
+ HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
+ gen_window_check1(dc, RRI8_S);
+ {
+ TCGv_i32 addr = tcg_temp_new_i32();
+ tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
+ gen_load_store_alignment(dc, 2, addr, false);
+ if (RRI8_R & 0x4) {
+ tcg_gen_qemu_st32(cpu_FR[RRI8_T], addr, dc->cring);
+ } else {
+ tcg_gen_qemu_ld32u(cpu_FR[RRI8_T], addr, dc->cring);
+ }
+ if (RRI8_R & 0x8) {
+ tcg_gen_mov_i32(cpu_R[RRI8_S], addr);
+ }
+ tcg_temp_free(addr);
+ }
+ break;
+
+ default: /*reserved*/
+ RESERVED();
+ break;
+ }
break;
case 4: /*MAC16d*/
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 07/10] target-xtensa: implement FP0 arithmetic
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (5 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 06/10] target-xtensa: implement LSCX and LSCI groups Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 08/10] target-xtensa: implement FP0 conversions Max Filippov
` (3 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
These are FP arithmetic opcodes.
See ISA, 4.3.10 for more details.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
target-xtensa/helper.h | 7 +++++
target-xtensa/op_helper.c | 37 +++++++++++++++++++++++++++
target-xtensa/translate.c | 61 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 104 insertions(+), 1 deletions(-)
diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h
index 1662552..4e6e417 100644
--- a/target-xtensa/helper.h
+++ b/target-xtensa/helper.h
@@ -37,5 +37,12 @@ DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32)
DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32)
DEF_HELPER_2(wur_fcr, void, env, i32)
+DEF_HELPER_FLAGS_1(abs_s, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32)
+DEF_HELPER_FLAGS_1(neg_s, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32)
+DEF_HELPER_3(add_s, f32, env, f32, f32)
+DEF_HELPER_3(sub_s, f32, env, f32, f32)
+DEF_HELPER_3(mul_s, f32, env, f32, f32)
+DEF_HELPER_4(madd_s, f32, env, f32, f32, f32)
+DEF_HELPER_4(msub_s, f32, env, f32, f32, f32)
#include "def-helper.h"
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 3bf7339..ba935a8 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -784,3 +784,40 @@ void HELPER(wur_fcr)(CPUXtensaState *env, uint32_t v)
env->uregs[FCR] = v & 0xfffff07f;
set_float_rounding_mode(rounding_mode[v & 3], &env->fp_status);
}
+
+float32 HELPER(abs_s)(float32 v)
+{
+ return float32_abs(v);
+}
+
+float32 HELPER(neg_s)(float32 v)
+{
+ return float32_chs(v);
+}
+
+float32 HELPER(add_s)(CPUXtensaState *env, float32 a, float32 b)
+{
+ return float32_add(a, b, &env->fp_status);
+}
+
+float32 HELPER(sub_s)(CPUXtensaState *env, float32 a, float32 b)
+{
+ return float32_sub(a, b, &env->fp_status);
+}
+
+float32 HELPER(mul_s)(CPUXtensaState *env, float32 a, float32 b)
+{
+ return float32_mul(a, b, &env->fp_status);
+}
+
+float32 HELPER(madd_s)(CPUXtensaState *env, float32 a, float32 b, float32 c)
+{
+ return float32_muladd(b, c, a, 0,
+ &env->fp_status);
+}
+
+float32 HELPER(msub_s)(CPUXtensaState *env, float32 a, float32 b, float32 c)
+{
+ return float32_muladd(b, c, a, float_muladd_negate_product,
+ &env->fp_status);
+}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index d167e9d..a2ce286 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -1889,7 +1889,66 @@ static void disas_xtensa_insn(DisasContext *dc)
case 10: /*FP0*/
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
- TBD();
+ switch (OP2) {
+ case 0: /*ADD.Sf*/
+ gen_helper_add_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 1: /*SUB.Sf*/
+ gen_helper_sub_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 2: /*MUL.Sf*/
+ gen_helper_mul_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 4: /*MADD.Sf*/
+ gen_helper_madd_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 5: /*MSUB.Sf*/
+ gen_helper_msub_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 15: /*FP1OP*/
+ switch (RRR_T) {
+ case 0: /*MOV.Sf*/
+ tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
+ break;
+
+ case 1: /*ABS.Sf*/
+ gen_helper_abs_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
+ break;
+
+ case 4: /*RFRf*/
+ gen_window_check1(dc, RRR_R);
+ tcg_gen_mov_i32(cpu_R[RRR_R], cpu_FR[RRR_S]);
+ break;
+
+ case 5: /*WFRf*/
+ gen_window_check1(dc, RRR_S);
+ tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_R[RRR_S]);
+ break;
+
+ case 6: /*NEG.Sf*/
+ gen_helper_neg_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
+ break;
+
+ default: /*reserved*/
+ RESERVED();
+ break;
+ }
+ break;
+
+ default: /*reserved*/
+ RESERVED();
+ break;
+ }
break;
case 11: /*FP1*/
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 08/10] target-xtensa: implement FP0 conversions
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (6 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 07/10] target-xtensa: implement FP0 arithmetic Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 21:59 ` Richard Henderson
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 09/10] target-xtensa: implement FP1 group Max Filippov
` (2 subsequent siblings)
10 siblings, 1 reply; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
These are FP to integer and integer to FP conversion opcodes.
See ISA, 4.3.10 for more details.
Note that ISA description for utrunc.s is currently incorrect and will
be fixed in future revisions.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
target-xtensa/helper.h | 4 +++
target-xtensa/op_helper.c | 37 ++++++++++++++++++++++++++++++++++
target-xtensa/translate.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h
index 4e6e417..9557347 100644
--- a/target-xtensa/helper.h
+++ b/target-xtensa/helper.h
@@ -44,5 +44,9 @@ DEF_HELPER_3(sub_s, f32, env, f32, f32)
DEF_HELPER_3(mul_s, f32, env, f32, f32)
DEF_HELPER_4(madd_s, f32, env, f32, f32, f32)
DEF_HELPER_4(msub_s, f32, env, f32, f32, f32)
+DEF_HELPER_FLAGS_3(ftoi, TCG_CALL_CONST | TCG_CALL_PURE, i32, f32, i32, i32)
+DEF_HELPER_FLAGS_3(ftoui, TCG_CALL_CONST | TCG_CALL_PURE, i32, f32, i32, i32)
+DEF_HELPER_3(itof, f32, env, i32, i32)
+DEF_HELPER_3(uitof, f32, env, i32, i32)
#include "def-helper.h"
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index ba935a8..5cf9c02 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -821,3 +821,40 @@ float32 HELPER(msub_s)(CPUXtensaState *env, float32 a, float32 b, float32 c)
return float32_muladd(b, c, a, float_muladd_negate_product,
&env->fp_status);
}
+
+uint32_t HELPER(ftoi)(float32 v, uint32_t rounding_mode, uint32_t scale)
+{
+ float_status fp_status = {0};
+
+ set_float_rounding_mode(rounding_mode, &fp_status);
+ return float32_to_int32(
+ float32_scalbn(v, scale, &fp_status), &fp_status);
+}
+
+uint32_t HELPER(ftoui)(float32 v, uint32_t rounding_mode, uint32_t scale)
+{
+ float_status fp_status = {0};
+ float32 res;
+
+ set_float_rounding_mode(rounding_mode, &fp_status);
+
+ res = float32_scalbn(v, scale, &fp_status);
+
+ if (float32_is_neg(v) && !float32_is_any_nan(v)) {
+ return float32_to_int32(res, &fp_status);
+ } else {
+ return float32_to_uint32(res, &fp_status);
+ }
+}
+
+float32 HELPER(itof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
+{
+ return float32_scalbn(int32_to_float32(v, &env->fp_status),
+ (int32_t)scale, &env->fp_status);
+}
+
+float32 HELPER(uitof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
+{
+ return float32_scalbn(uint32_to_float32(v, &env->fp_status),
+ (int32_t)scale, &env->fp_status);
+}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index a2ce286..fabde4f 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -1915,6 +1915,54 @@ static void disas_xtensa_insn(DisasContext *dc)
cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
break;
+ case 8: /*ROUND.Sf*/
+ case 9: /*TRUNC.Sf*/
+ case 10: /*FLOOR.Sf*/
+ case 11: /*CEIL.Sf*/
+ case 14: /*UTRUNC.Sf*/
+ gen_window_check1(dc, RRR_R);
+ {
+ static const unsigned rounding_mode_const[] = {
+ float_round_nearest_even,
+ float_round_to_zero,
+ float_round_down,
+ float_round_up,
+ [6] = float_round_to_zero,
+ };
+ TCGv_i32 rounding_mode = tcg_const_i32(
+ rounding_mode_const[OP2 & 7]);
+ TCGv_i32 scale = tcg_const_i32(RRR_T);
+
+ if (OP2 == 14) {
+ gen_helper_ftoui(cpu_R[RRR_R], cpu_FR[RRR_S],
+ rounding_mode, scale);
+ } else {
+ gen_helper_ftoi(cpu_R[RRR_R], cpu_FR[RRR_S],
+ rounding_mode, scale);
+ }
+
+ tcg_temp_free(rounding_mode);
+ tcg_temp_free(scale);
+ }
+ break;
+
+ case 12: /*FLOAT.Sf*/
+ case 13: /*UFLOAT.Sf*/
+ gen_window_check1(dc, RRR_S);
+ {
+ TCGv_i32 scale = tcg_const_i32(-RRR_T);
+
+ if (OP2 == 13) {
+ gen_helper_uitof(cpu_FR[RRR_R], cpu_env,
+ cpu_R[RRR_S], scale);
+ } else {
+ gen_helper_itof(cpu_FR[RRR_R], cpu_env,
+ cpu_R[RRR_S], scale);
+ }
+ tcg_temp_free(scale);
+ }
+ break;
+
case 15: /*FP1OP*/
switch (RRR_T) {
case 0: /*MOV.Sf*/
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 08/10] target-xtensa: implement FP0 conversions
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 08/10] target-xtensa: implement FP0 conversions Max Filippov
@ 2012-09-19 21:59 ` Richard Henderson
2012-09-19 22:47 ` Max Filippov
0 siblings, 1 reply; 14+ messages in thread
From: Richard Henderson @ 2012-09-19 21:59 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, Peter Maydell, qemu-devel
On 09/18/2012 05:23 PM, Max Filippov wrote:
> +uint32_t HELPER(ftoi)(float32 v, uint32_t rounding_mode, uint32_t scale)
> +{
> + float_status fp_status = {0};
> +
> + set_float_rounding_mode(rounding_mode, &fp_status);
> + return float32_to_int32(
> + float32_scalbn(v, scale, &fp_status), &fp_status);
> +}
> +
> +uint32_t HELPER(ftoui)(float32 v, uint32_t rounding_mode, uint32_t scale)
> +{
> + float_status fp_status = {0};
> + float32 res;
> +
> + set_float_rounding_mode(rounding_mode, &fp_status);
> +
> + res = float32_scalbn(v, scale, &fp_status);
> +
> + if (float32_is_neg(v) && !float32_is_any_nan(v)) {
> + return float32_to_int32(res, &fp_status);
> + } else {
> + return float32_to_uint32(res, &fp_status);
> + }
> +}
Are you really intending to discard any exceptions raised here?
r~
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 08/10] target-xtensa: implement FP0 conversions
2012-09-19 21:59 ` Richard Henderson
@ 2012-09-19 22:47 ` Max Filippov
0 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 22:47 UTC (permalink / raw)
To: Richard Henderson; +Cc: Blue Swirl, Peter Maydell, qemu-devel
On Thu, Sep 20, 2012 at 1:59 AM, Richard Henderson <rth@twiddle.net> wrote:
> On 09/18/2012 05:23 PM, Max Filippov wrote:
>> +uint32_t HELPER(ftoi)(float32 v, uint32_t rounding_mode, uint32_t scale)
>> +{
>> + float_status fp_status = {0};
>> +
>> + set_float_rounding_mode(rounding_mode, &fp_status);
>> + return float32_to_int32(
>> + float32_scalbn(v, scale, &fp_status), &fp_status);
>> +}
>> +
>> +uint32_t HELPER(ftoui)(float32 v, uint32_t rounding_mode, uint32_t scale)
>> +{
>> + float_status fp_status = {0};
>> + float32 res;
>> +
>> + set_float_rounding_mode(rounding_mode, &fp_status);
>> +
>> + res = float32_scalbn(v, scale, &fp_status);
>> +
>> + if (float32_is_neg(v) && !float32_is_any_nan(v)) {
>> + return float32_to_int32(res, &fp_status);
>> + } else {
>> + return float32_to_uint32(res, &fp_status);
>> + }
>> +}
>
> Are you really intending to discard any exceptions raised here?
Yes, as specified in the ISA and as unit tests on Tensilica ISS show.
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 09/10] target-xtensa: implement FP1 group
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (7 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 08/10] target-xtensa: implement FP0 conversions Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 10/10] target-xtensa: implement coprocessor context option Max Filippov
2012-09-22 18:00 ` [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Blue Swirl
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
These are comparison and conditional move opcodes.
See ISA, 4.3.10 for more details.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
target-xtensa/helper.h | 8 ++++
target-xtensa/op_helper.c | 47 ++++++++++++++++++++++++++
target-xtensa/translate.c | 81 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 135 insertions(+), 1 deletions(-)
diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h
index 9557347..4cc0088 100644
--- a/target-xtensa/helper.h
+++ b/target-xtensa/helper.h
@@ -49,4 +49,12 @@ DEF_HELPER_FLAGS_3(ftoui, TCG_CALL_CONST | TCG_CALL_PURE, i32, f32, i32, i32)
DEF_HELPER_3(itof, f32, env, i32, i32)
DEF_HELPER_3(uitof, f32, env, i32, i32)
+DEF_HELPER_4(un_s, void, env, i32, f32, f32)
+DEF_HELPER_4(oeq_s, void, env, i32, f32, f32)
+DEF_HELPER_4(ueq_s, void, env, i32, f32, f32)
+DEF_HELPER_4(olt_s, void, env, i32, f32, f32)
+DEF_HELPER_4(ult_s, void, env, i32, f32, f32)
+DEF_HELPER_4(ole_s, void, env, i32, f32, f32)
+DEF_HELPER_4(ule_s, void, env, i32, f32, f32)
+
#include "def-helper.h"
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 5cf9c02..ae0c099 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -858,3 +858,50 @@ float32 HELPER(uitof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
return float32_scalbn(uint32_to_float32(v, &env->fp_status),
(int32_t)scale, &env->fp_status);
}
+
+static inline void set_br(CPUXtensaState *env, bool v, uint32_t br)
+{
+ if (v) {
+ env->sregs[BR] |= br;
+ } else {
+ env->sregs[BR] &= ~br;
+ }
+}
+
+void HELPER(un_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+{
+ set_br(env, float32_unordered_quiet(a, b, &env->fp_status), br);
+}
+
+void HELPER(oeq_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+{
+ set_br(env, float32_eq_quiet(a, b, &env->fp_status), br);
+}
+
+void HELPER(ueq_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+{
+ int v = float32_compare_quiet(a, b, &env->fp_status);
+ set_br(env, v == float_relation_equal || v == float_relation_unordered, br);
+}
+
+void HELPER(olt_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+{
+ set_br(env, float32_lt_quiet(a, b, &env->fp_status), br);
+}
+
+void HELPER(ult_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+{
+ int v = float32_compare_quiet(a, b, &env->fp_status);
+ set_br(env, v == float_relation_less || v == float_relation_unordered, br);
+}
+
+void HELPER(ole_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+{
+ set_br(env, float32_le_quiet(a, b, &env->fp_status), br);
+}
+
+void HELPER(ule_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+{
+ int v = float32_compare_quiet(a, b, &env->fp_status);
+ set_br(env, v != float_relation_greater, br);
+}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index fabde4f..652f9bb 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2001,7 +2001,86 @@ static void disas_xtensa_insn(DisasContext *dc)
case 11: /*FP1*/
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
- TBD();
+
+#define gen_compare(rel, br, a, b) \
+ do { \
+ TCGv_i32 bit = tcg_const_i32(1 << br); \
+ \
+ gen_helper_##rel(cpu_env, bit, cpu_FR[a], cpu_FR[b]); \
+ tcg_temp_free(bit); \
+ } while (0)
+
+ switch (OP2) {
+ case 1: /*UN.Sf*/
+ gen_compare(un_s, RRR_R, RRR_S, RRR_T);
+ break;
+
+ case 2: /*OEQ.Sf*/
+ gen_compare(oeq_s, RRR_R, RRR_S, RRR_T);
+ break;
+
+ case 3: /*UEQ.Sf*/
+ gen_compare(ueq_s, RRR_R, RRR_S, RRR_T);
+ break;
+
+ case 4: /*OLT.Sf*/
+ gen_compare(olt_s, RRR_R, RRR_S, RRR_T);
+ break;
+
+ case 5: /*ULT.Sf*/
+ gen_compare(ult_s, RRR_R, RRR_S, RRR_T);
+ break;
+
+ case 6: /*OLE.Sf*/
+ gen_compare(ole_s, RRR_R, RRR_S, RRR_T);
+ break;
+
+ case 7: /*ULE.Sf*/
+ gen_compare(ule_s, RRR_R, RRR_S, RRR_T);
+ break;
+
+#undef gen_compare
+
+ case 8: /*MOVEQZ.Sf*/
+ case 9: /*MOVNEZ.Sf*/
+ case 10: /*MOVLTZ.Sf*/
+ case 11: /*MOVGEZ.Sf*/
+ gen_window_check1(dc, RRR_T);
+ {
+ static const TCGCond cond[] = {
+ TCG_COND_NE,
+ TCG_COND_EQ,
+ TCG_COND_GE,
+ TCG_COND_LT
+ };
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
+ tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
+ gen_set_label(label);
+ }
+ break;
+
+ case 12: /*MOVF.Sf*/
+ case 13: /*MOVT.Sf*/
+ HAS_OPTION(XTENSA_OPTION_BOOLEAN);
+ {
+ int label = gen_new_label();
+ TCGv_i32 tmp = tcg_temp_new_i32();
+
+ tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
+ tcg_gen_brcondi_i32(
+ OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
+ tmp, 0, label);
+ tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
+ gen_set_label(label);
+ tcg_temp_free(tmp);
+ }
+ break;
+
+ default: /*reserved*/
+ RESERVED();
+ break;
+ }
break;
default: /*reserved*/
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 10/10] target-xtensa: implement coprocessor context option
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (8 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 09/10] target-xtensa: implement FP1 group Max Filippov
@ 2012-09-19 0:23 ` Max Filippov
2012-09-22 18:00 ` [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Blue Swirl
10 siblings, 0 replies; 14+ messages in thread
From: Max Filippov @ 2012-09-19 0:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
In case Coprocessor Context option is enabled CPENABLE SR bits control
whether access to coprocessors is allowed or would rise one of
CoprocessorXDisabled exceptions.
See ISA, 4.4.5 for more details.
FP is coprocessor 0.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
target-xtensa/cpu.h | 5 +++++
target-xtensa/translate.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index b456283..7348277 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -468,6 +468,8 @@ static inline int cpu_mmu_index(CPUXtensaState *env)
#define XTENSA_TBFLAG_LITBASE 0x8
#define XTENSA_TBFLAG_DEBUG 0x10
#define XTENSA_TBFLAG_ICOUNT 0x20
+#define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0
+#define XTENSA_TBFLAG_CPENABLE_SHIFT 6
static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
@@ -491,6 +493,9 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
*flags |= XTENSA_TBFLAG_ICOUNT;
}
}
+ if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
+ *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
+ }
}
#include "cpu-all.h"
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 652f9bb..0a1d190 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -65,6 +65,8 @@ typedef struct DisasContext {
bool debug;
bool icount;
TCGv_i32 next_icount;
+
+ unsigned cpenable;
} DisasContext;
static TCGv_ptr cpu_env;
@@ -331,6 +333,15 @@ static void gen_check_privilege(DisasContext *dc)
}
}
+static void gen_check_cpenable(DisasContext *dc, unsigned cp)
+{
+ if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) &&
+ !(dc->cpenable & (1 << cp))) {
+ gen_exception_cause(dc, COPROCESSOR0_DISABLED + cp);
+ dc->is_jmp = DISAS_UPDATE;
+ }
+}
+
static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
{
tcg_gen_mov_i32(cpu_pc, dest);
@@ -579,6 +590,13 @@ static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
}
}
+static void gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
+{
+ tcg_gen_andi_i32(cpu_SR[sr], v, 0xff);
+ /* This can change tb->flags, so exit tb */
+ gen_jumpi_check_loop_end(dc, -1);
+}
+
static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
{
tcg_gen_andi_i32(cpu_SR[sr], v,
@@ -681,6 +699,7 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
[DBREAKA + 1] = gen_wsr_dbreaka,
[DBREAKC] = gen_wsr_dbreakc,
[DBREAKC + 1] = gen_wsr_dbreakc,
+ [CPENABLE] = gen_wsr_cpenable,
[INTSET] = gen_wsr_intset,
[INTCLEAR] = gen_wsr_intclear,
[INTENABLE] = gen_wsr_intenable,
@@ -1832,6 +1851,7 @@ static void disas_xtensa_insn(DisasContext *dc)
case 5: /*SSXUf*/
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
gen_window_check2(dc, RRR_S, RRR_T);
+ gen_check_cpenable(dc, 0);
{
TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_add_i32(addr, cpu_R[RRR_S], cpu_R[RRR_T]);
@@ -1891,26 +1911,31 @@ static void disas_xtensa_insn(DisasContext *dc)
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
switch (OP2) {
case 0: /*ADD.Sf*/
+ gen_check_cpenable(dc, 0);
gen_helper_add_s(cpu_FR[RRR_R], cpu_env,
cpu_FR[RRR_S], cpu_FR[RRR_T]);
break;
case 1: /*SUB.Sf*/
+ gen_check_cpenable(dc, 0);
gen_helper_sub_s(cpu_FR[RRR_R], cpu_env,
cpu_FR[RRR_S], cpu_FR[RRR_T]);
break;
case 2: /*MUL.Sf*/
+ gen_check_cpenable(dc, 0);
gen_helper_mul_s(cpu_FR[RRR_R], cpu_env,
cpu_FR[RRR_S], cpu_FR[RRR_T]);
break;
case 4: /*MADD.Sf*/
+ gen_check_cpenable(dc, 0);
gen_helper_madd_s(cpu_FR[RRR_R], cpu_env,
cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
break;
case 5: /*MSUB.Sf*/
+ gen_check_cpenable(dc, 0);
gen_helper_msub_s(cpu_FR[RRR_R], cpu_env,
cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
break;
@@ -1921,6 +1946,7 @@ static void disas_xtensa_insn(DisasContext *dc)
case 11: /*CEIL.Sf*/
case 14: /*UTRUNC.Sf*/
gen_window_check1(dc, RRR_R);
+ gen_check_cpenable(dc, 0);
{
static const unsigned rounding_mode_const[] = {
float_round_nearest_even,
@@ -1949,6 +1975,7 @@ static void disas_xtensa_insn(DisasContext *dc)
case 12: /*FLOAT.Sf*/
case 13: /*UFLOAT.Sf*/
gen_window_check1(dc, RRR_S);
+ gen_check_cpenable(dc, 0);
{
TCGv_i32 scale = tcg_const_i32(-RRR_T);
@@ -1966,24 +1993,29 @@ static void disas_xtensa_insn(DisasContext *dc)
case 15: /*FP1OP*/
switch (RRR_T) {
case 0: /*MOV.Sf*/
+ gen_check_cpenable(dc, 0);
tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
break;
case 1: /*ABS.Sf*/
+ gen_check_cpenable(dc, 0);
gen_helper_abs_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
break;
case 4: /*RFRf*/
gen_window_check1(dc, RRR_R);
+ gen_check_cpenable(dc, 0);
tcg_gen_mov_i32(cpu_R[RRR_R], cpu_FR[RRR_S]);
break;
case 5: /*WFRf*/
gen_window_check1(dc, RRR_S);
+ gen_check_cpenable(dc, 0);
tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_R[RRR_S]);
break;
case 6: /*NEG.Sf*/
+ gen_check_cpenable(dc, 0);
gen_helper_neg_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
break;
@@ -2006,6 +2038,7 @@ static void disas_xtensa_insn(DisasContext *dc)
do { \
TCGv_i32 bit = tcg_const_i32(1 << br); \
\
+ gen_check_cpenable(dc, 0); \
gen_helper_##rel(cpu_env, bit, cpu_FR[a], cpu_FR[b]); \
tcg_temp_free(bit); \
} while (0)
@@ -2046,6 +2079,7 @@ static void disas_xtensa_insn(DisasContext *dc)
case 10: /*MOVLTZ.Sf*/
case 11: /*MOVGEZ.Sf*/
gen_window_check1(dc, RRR_T);
+ gen_check_cpenable(dc, 0);
{
static const TCGCond cond[] = {
TCG_COND_NE,
@@ -2063,6 +2097,7 @@ static void disas_xtensa_insn(DisasContext *dc)
case 12: /*MOVF.Sf*/
case 13: /*MOVT.Sf*/
HAS_OPTION(XTENSA_OPTION_BOOLEAN);
+ gen_check_cpenable(dc, 0);
{
int label = gen_new_label();
TCGv_i32 tmp = tcg_temp_new_i32();
@@ -2318,6 +2353,7 @@ static void disas_xtensa_insn(DisasContext *dc)
case 12: /*SSIUf*/
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
gen_window_check1(dc, RRI8_S);
+ gen_check_cpenable(dc, 0);
{
TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
@@ -2833,6 +2869,8 @@ static void gen_intermediate_code_internal(
dc.ccount_delta = 0;
dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
+ dc.cpenable = (tb->flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
+ XTENSA_TBFLAG_CPENABLE_SHIFT;
init_litbase(&dc);
init_sar_tracker(&dc);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option
2012-09-19 0:23 [Qemu-devel] [PATCH v3 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (9 preceding siblings ...)
2012-09-19 0:23 ` [Qemu-devel] [PATCH v3 10/10] target-xtensa: implement coprocessor context option Max Filippov
@ 2012-09-22 18:00 ` Blue Swirl
10 siblings, 0 replies; 14+ messages in thread
From: Blue Swirl @ 2012-09-22 18:00 UTC (permalink / raw)
To: Max Filippov; +Cc: Peter Maydell, qemu-devel
On Wed, Sep 19, 2012 at 12:23 AM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> This series implements floating point coprocessor and coprocessor context
> options for xtensa and fixes a couple of bugs to make it work.
Thanks, applied all.
>
> Changes v2->v3:
> - add comment to the NO_SIGNALING_NANS definition
> - reword explanation for UTRUNC.S
>
> Changes v1->v2:
> - add NO_SIGNALING_NANS and drop float32_maybe_silence_nan specialization
> - fix fp registers access in gdbstub
> - replace float32_mul/div in FP-to-integer convertors with float32_scalbn
> - reimplement comparison with zero in FP-to-integer convertors
>
> Max Filippov (10):
> softfloat: make float_muladd_negate_* flags independent
> softfloat: add NO_SIGNALING_NANS
> target-xtensa: handle boolean option in overlays
> target-xtensa: specialize softfloat NaN rules
> target-xtensa: add FP registers
> target-xtensa: implement LSCX and LSCI groups
> target-xtensa: implement FP0 arithmetic
> target-xtensa: implement FP0 conversions
> target-xtensa: implement FP1 group
> target-xtensa: implement coprocessor context option
>
> fpu/softfloat-specialize.h | 72 +++++++++-
> fpu/softfloat.h | 7 +-
> gdbstub.c | 8 +
> target-xtensa/cpu.h | 8 +
> target-xtensa/helper.h | 21 +++
> target-xtensa/op_helper.c | 134 +++++++++++++++++
> target-xtensa/overlay_tool.h | 1 +
> target-xtensa/translate.c | 338 ++++++++++++++++++++++++++++++++++++++++--
> 8 files changed, 573 insertions(+), 16 deletions(-)
>
> --
> 1.7.7.6
>
^ permalink raw reply [flat|nested] 14+ messages in thread