* [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option
@ 2012-09-09 16:04 Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 01/10] softfloat: make float_muladd_negate_* flags independent Max Filippov
` (9 more replies)
0 siblings, 10 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Peter Maydell, Max Filippov
This series implements floating point coprocessor and coprocessor context
options for xtensa and fixes a couple of bugs to make it work.
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 | 69 +++++++++-
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, 570 insertions(+), 16 deletions(-)
--
1.7.7.6
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v2 01/10] softfloat: make float_muladd_negate_* flags independent
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 02/10] softfloat: add NO_SIGNALING_NANS Max Filippov
` (8 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 02/10] softfloat: add NO_SIGNALING_NANS
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 01/10] softfloat: make float_muladd_negate_* flags independent Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:18 ` Peter Maydell
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 03/10] target-xtensa: handle boolean option in overlays Max Filippov
` (7 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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 | 64 ++++++++++++++++++++++++++++++++++++++++++++
fpu/softfloat.h | 5 +++
2 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 4902450..2b203b9 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -41,6 +41,10 @@ these four paragraphs for those parts of this code that are retained.
#define SNAN_BIT_IS_ONE 0
#endif
+#if defined(TARGET_XTENSA)
+#define NO_SIGNALING_NANS 1
+#endif
+
/*----------------------------------------------------------------------------
| The pattern for a default generated half-precision NaN.
*----------------------------------------------------------------------------*/
@@ -127,6 +131,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 +171,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 +233,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 +273,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 +614,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 +658,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 +813,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 +867,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 +981,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 +1027,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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 03/10] target-xtensa: handle boolean option in overlays
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 01/10] softfloat: make float_muladd_negate_* flags independent Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 02/10] softfloat: add NO_SIGNALING_NANS Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 04/10] target-xtensa: specialize softfloat NaN rules Max Filippov
` (6 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 04/10] target-xtensa: specialize softfloat NaN rules
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (2 preceding siblings ...)
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 03/10] target-xtensa: handle boolean option in overlays Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 05/10] target-xtensa: add FP registers Max Filippov
` (5 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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>
---
Changes v1->v2:
- drop float32_maybe_silence_nan specialization
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 2b203b9..f9642f0 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -61,7 +61,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);
@@ -400,7 +401,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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 05/10] target-xtensa: add FP registers
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (3 preceding siblings ...)
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 04/10] target-xtensa: specialize softfloat NaN rules Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 06/10] target-xtensa: implement LSCX and LSCI groups Max Filippov
` (4 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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>
---
Changes v1->v2:
- add float32_val/make_float32 to fp registers accessors
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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 06/10] target-xtensa: implement LSCX and LSCI groups
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (4 preceding siblings ...)
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 05/10] target-xtensa: add FP registers Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 07/10] target-xtensa: implement FP0 arithmetic Max Filippov
` (3 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 07/10] target-xtensa: implement FP0 arithmetic
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (5 preceding siblings ...)
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 06/10] target-xtensa: implement LSCX and LSCI groups Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions Max Filippov
` (2 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (6 preceding siblings ...)
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 07/10] target-xtensa: implement FP0 arithmetic Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:16 ` Peter Maydell
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 09/10] target-xtensa: implement FP1 group Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 10/10] target-xtensa: implement coprocessor context option Max Filippov
9 siblings, 1 reply; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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 utrunc.s implementation follows ISS behaviour, not ISA.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- replace float32_mul/div in FP-to-integer convertors with float32_scalbn
- reimplement comparison with zero in FP-to-integer convertors
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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 09/10] target-xtensa: implement FP1 group
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (7 preceding siblings ...)
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 10/10] target-xtensa: implement coprocessor context option Max Filippov
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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] 17+ messages in thread
* [Qemu-devel] [PATCH v2 10/10] target-xtensa: implement coprocessor context option
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
` (8 preceding siblings ...)
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 09/10] target-xtensa: implement FP1 group Max Filippov
@ 2012-09-09 16:04 ` Max Filippov
9 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:04 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] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions Max Filippov
@ 2012-09-09 16:16 ` Peter Maydell
2012-09-09 16:38 ` Max Filippov
0 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2012-09-09 16:16 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On 9 September 2012 17:04, Max Filippov <jcmvbkbc@gmail.com> wrote:
> These are FP to integer and integer to FP conversion opcodes.
> See ISA, 4.3.10 for more details.
>
> Note that utrunc.s implementation follows ISS behaviour, not ISA.
ISS here means "instruction set simulator", right? Do you
have any actual silicon you can check behaviour against?
Basically there are three votes here (documentation, simulator
and silicon) and QEMU should follow the majority opinion in
the absence of any more official word.
-- PMM
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 02/10] softfloat: add NO_SIGNALING_NANS
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 02/10] softfloat: add NO_SIGNALING_NANS Max Filippov
@ 2012-09-09 16:18 ` Peter Maydell
0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2012-09-09 16:18 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On 9 September 2012 17:04, Max Filippov <jcmvbkbc@gmail.com> wrote:
> 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 | 64 ++++++++++++++++++++++++++++++++++++++++++++
> fpu/softfloat.h | 5 +++
> 2 files changed, 69 insertions(+), 0 deletions(-)
>
> diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
> index 4902450..2b203b9 100644
> --- a/fpu/softfloat-specialize.h
> +++ b/fpu/softfloat-specialize.h
> @@ -41,6 +41,10 @@ these four paragraphs for those parts of this code that are retained.
> #define SNAN_BIT_IS_ONE 0
> #endif
>
> +#if defined(TARGET_XTENSA)
> +#define NO_SIGNALING_NANS 1
> +#endif
This could use a comment, I think.
/* Define for architectures which deviate from IEEE in not supporting
* signaling NaNs (so all NaNs are treated as quiet).
*/
-- PMM
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions
2012-09-09 16:16 ` Peter Maydell
@ 2012-09-09 16:38 ` Max Filippov
2012-09-09 17:24 ` Marc Gauthier
2012-09-19 0:28 ` Max Filippov
0 siblings, 2 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 16:38 UTC (permalink / raw)
To: Peter Maydell; +Cc: Blue Swirl, Marc Gauthier, qemu-devel
On Sun, Sep 9, 2012 at 8:16 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 September 2012 17:04, Max Filippov <jcmvbkbc@gmail.com> wrote:
>> These are FP to integer and integer to FP conversion opcodes.
>> See ISA, 4.3.10 for more details.
>>
>> Note that utrunc.s implementation follows ISS behaviour, not ISA.
>
> ISS here means "instruction set simulator", right? Do you
> have any actual silicon you can check behaviour against?
> Basically there are three votes here (documentation, simulator
> and silicon) and QEMU should follow the majority opinion in
> the absence of any more official word.
I have no silicon core with FP and I doubt that I can easily access one.
IIUC Tensilica ISS core-specific code is autogenerated from the hardware
description, without human intervention.
Looks like it's either documentation error or silicon error, probably
there's an erratum issued. Marc, can you please comment?
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions
2012-09-09 16:38 ` Max Filippov
@ 2012-09-09 17:24 ` Marc Gauthier
2012-09-09 18:39 ` Max Filippov
2012-09-19 0:28 ` Max Filippov
1 sibling, 1 reply; 17+ messages in thread
From: Marc Gauthier @ 2012-09-09 17:24 UTC (permalink / raw)
To: Max Filippov, Peter Maydell; +Cc: Blue Swirl, qemu-devel@nongnu.org
Hi Max,
Max Filippov wrote:
> On Sun, Sep 9, 2012 at 8:16 PM, Peter Maydell
> <peter.maydell@linaro.org> wrote:
> > On 9 September 2012 17:04, Max Filippov <jcmvbkbc@gmail.com> wrote:
> >> These are FP to integer and integer to FP conversion opcodes.
> >> See ISA, 4.3.10 for more details.
> >>
> >> Note that utrunc.s implementation follows ISS behaviour, not ISA.
> >
> > ISS here means "instruction set simulator", right? Do you
> > have any actual silicon you can check behaviour against?
> > Basically there are three votes here (documentation, simulator
> > and silicon) and QEMU should follow the majority opinion in
> > the absence of any more official word.
>
> I have no silicon core with FP and I doubt that I can easily
> access one.
> IIUC Tensilica ISS core-specific code is autogenerated from
> the hardware
> description, without human intervention.
> Looks like it's either documentation error or silicon error, probably
> there's an erratum issued. Marc, can you please comment?
If it's the Tensilica ISS, behavior indeed should match hardware,
from a common description (am simplifying, but I expect here this
to hold). It also depends on which release of hardware/ISS
(do you know that exactly?).
I've forwarded the question to someone at Tensilica who may know
the answer, hopefully will have some answer during weekdays.
Thanks,
-Marc
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions
2012-09-09 17:24 ` Marc Gauthier
@ 2012-09-09 18:39 ` Max Filippov
0 siblings, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-09 18:39 UTC (permalink / raw)
To: Marc Gauthier; +Cc: Blue Swirl, Peter Maydell, qemu-devel@nongnu.org
On Sun, Sep 9, 2012 at 9:24 PM, Marc Gauthier <marc@tensilica.com> wrote:
> Hi Max,
>
> Max Filippov wrote:
>> On Sun, Sep 9, 2012 at 8:16 PM, Peter Maydell
>> <peter.maydell@linaro.org> wrote:
>> > On 9 September 2012 17:04, Max Filippov <jcmvbkbc@gmail.com> wrote:
>> >> These are FP to integer and integer to FP conversion opcodes.
>> >> See ISA, 4.3.10 for more details.
>> >>
>> >> Note that utrunc.s implementation follows ISS behaviour, not ISA.
>> >
>> > ISS here means "instruction set simulator", right? Do you
>> > have any actual silicon you can check behaviour against?
>> > Basically there are three votes here (documentation, simulator
>> > and silicon) and QEMU should follow the majority opinion in
>> > the absence of any more official word.
>>
>> I have no silicon core with FP and I doubt that I can easily
>> access one.
>> IIUC Tensilica ISS core-specific code is autogenerated from
>> the hardware
>> description, without human intervention.
>> Looks like it's either documentation error or silicon error, probably
>> there's an erratum issued. Marc, can you please comment?
>
> If it's the Tensilica ISS, behavior indeed should match hardware,
> from a common description (am simplifying, but I expect here this
> to hold). It also depends on which release of hardware/ISS
> (do you know that exactly?).
ISS is from the RC-2010.2-linux package, xt-run --help shows the following:
Xtensa 8.0.2 Instruction Set Simulator
core-isa.h for the core on which I run tests has the following:
#define XCHAL_SW_VERSION 800002 /* sw version of this header */
#define XCHAL_CORE_ID "dsp3400_RC2" /* alphanum core name
(CoreID) set in the Xtensa
Processor Generator */
#define XCHAL_BUILD_UNIQUE_ID 0x0002DC22 /* 22-bit sw build ID */
/*
* These definitions describe the hardware targeted by this software.
*/
#define XCHAL_HW_CONFIGID0 0xC3F3DBFE /* ConfigID hi 32 bits*/
#define XCHAL_HW_CONFIGID1 0x1082C3B0 /* ConfigID lo 32 bits*/
#define XCHAL_HW_VERSION_NAME "LX3.0.1" /* full version name */
#define XCHAL_HW_VERSION_MAJOR 2300 /* major ver# of targeted hw */
#define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */
#define XCHAL_HW_VERSION 230001 /* major*100+minor */
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions
2012-09-09 16:38 ` Max Filippov
2012-09-09 17:24 ` Marc Gauthier
@ 2012-09-19 0:28 ` Max Filippov
1 sibling, 0 replies; 17+ messages in thread
From: Max Filippov @ 2012-09-19 0:28 UTC (permalink / raw)
To: Peter Maydell; +Cc: Blue Swirl, Marc Gauthier, qemu-devel
On Sun, Sep 9, 2012 at 8:38 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> On Sun, Sep 9, 2012 at 8:16 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> On 9 September 2012 17:04, Max Filippov <jcmvbkbc@gmail.com> wrote:
>>> These are FP to integer and integer to FP conversion opcodes.
>>> See ISA, 4.3.10 for more details.
>>>
>>> Note that utrunc.s implementation follows ISS behaviour, not ISA.
>>
>> ISS here means "instruction set simulator", right? Do you
>> have any actual silicon you can check behaviour against?
>> Basically there are three votes here (documentation, simulator
>> and silicon) and QEMU should follow the majority opinion in
>> the absence of any more official word.
Short summary for the answer that I've got from Tensilica is the following:
- hardware and ISS behaviour must match,
- documentation (ISA) is wrong and will be fixed.
> I have no silicon core with FP and I doubt that I can easily access one.
> IIUC Tensilica ISS core-specific code is autogenerated from the hardware
> description, without human intervention.
> Looks like it's either documentation error or silicon error, probably
> there's an erratum issued. Marc, can you please comment?
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-09-19 0:28 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-09 16:04 [Qemu-devel] [PATCH v2 00/10] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 01/10] softfloat: make float_muladd_negate_* flags independent Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 02/10] softfloat: add NO_SIGNALING_NANS Max Filippov
2012-09-09 16:18 ` Peter Maydell
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 03/10] target-xtensa: handle boolean option in overlays Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 04/10] target-xtensa: specialize softfloat NaN rules Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 05/10] target-xtensa: add FP registers Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 06/10] target-xtensa: implement LSCX and LSCI groups Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 07/10] target-xtensa: implement FP0 arithmetic Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 08/10] target-xtensa: implement FP0 conversions Max Filippov
2012-09-09 16:16 ` Peter Maydell
2012-09-09 16:38 ` Max Filippov
2012-09-09 17:24 ` Marc Gauthier
2012-09-09 18:39 ` Max Filippov
2012-09-19 0:28 ` Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 09/10] target-xtensa: implement FP1 group Max Filippov
2012-09-09 16:04 ` [Qemu-devel] [PATCH v2 10/10] target-xtensa: implement coprocessor context option Max Filippov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).