* [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option
@ 2012-09-09 1:29 Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent Max Filippov
` (8 more replies)
0 siblings, 9 replies; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, Max Filippov
This series implements floating point coprocessor and coprocessor context
options for xtensa and fixes a couple of bugs to make it work.
Max Filippov (9):
softfloat: make float_muladd_negate_* flags independent
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 | 9 +-
fpu/softfloat.h | 2 +-
gdbstub.c | 8 +
target-xtensa/cpu.h | 8 +
target-xtensa/helper.h | 21 +++
target-xtensa/op_helper.c | 140 +++++++++++++++++
target-xtensa/overlay_tool.h | 1 +
target-xtensa/translate.c | 337 ++++++++++++++++++++++++++++++++++++++++--
8 files changed, 510 insertions(+), 16 deletions(-)
--
1.7.7.6
^ permalink raw reply [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 9:24 ` Aurelien Jarno
2012-09-09 1:29 ` [Qemu-devel] [PATCH 2/9] target-xtensa: handle boolean option in overlays Max Filippov
` (7 subsequent siblings)
8 siblings, 1 reply; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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>
---
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] 20+ messages in thread
* [Qemu-devel] [PATCH 2/9] target-xtensa: handle boolean option in overlays
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules Max Filippov
` (6 subsequent siblings)
8 siblings, 0 replies; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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] 20+ messages in thread
* [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 2/9] target-xtensa: handle boolean option in overlays Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 9:31 ` Peter Maydell
2012-09-09 1:29 ` [Qemu-devel] [PATCH 4/9] target-xtensa: add FP registers Max Filippov
` (5 subsequent siblings)
8 siblings, 1 reply; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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 | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 4902450..9d78f41 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -57,7 +57,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);
@@ -262,9 +263,13 @@ float32 float32_maybe_silence_nan( float32 a_ )
# error Rules for silencing a signaling NaN are target-specific
# endif
#else
+# if defined(TARGET_XTENSA)
+ return a_;
+# else
uint32_t a = float32_val(a_);
a |= (1 << 22);
return make_float32(a);
+# endif
#endif
}
return a_;
@@ -372,7 +377,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] 20+ messages in thread
* [Qemu-devel] [PATCH 4/9] target-xtensa: add FP registers
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
` (2 preceding siblings ...)
2012-09-09 1:29 ` [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 5/9] target-xtensa: implement LSCX and LSCI groups Max Filippov
` (4 subsequent siblings)
8 siblings, 0 replies; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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..7aba79e 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(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] = 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] 20+ messages in thread
* [Qemu-devel] [PATCH 5/9] target-xtensa: implement LSCX and LSCI groups
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
` (3 preceding siblings ...)
2012-09-09 1:29 ` [Qemu-devel] [PATCH 4/9] target-xtensa: add FP registers Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic Max Filippov
` (3 subsequent siblings)
8 siblings, 0 replies; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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] 20+ messages in thread
* [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
` (4 preceding siblings ...)
2012-09-09 1:29 ` [Qemu-devel] [PATCH 5/9] target-xtensa: implement LSCX and LSCI groups Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 10:05 ` Peter Maydell
2012-09-09 1:29 ` [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions Max Filippov
` (2 subsequent siblings)
8 siblings, 1 reply; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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..ec22f60 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.S*/
+ gen_helper_add_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 1: /*SUB.S*/
+ gen_helper_sub_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 2: /*MUL.S*/
+ gen_helper_mul_s(cpu_FR[RRR_R], cpu_env,
+ cpu_FR[RRR_S], cpu_FR[RRR_T]);
+ break;
+
+ case 4: /*MADD.S*/
+ 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.S*/
+ 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] 20+ messages in thread
* [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
` (5 preceding siblings ...)
2012-09-09 1:29 ` [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 11:06 ` Peter Maydell
2012-09-09 1:29 ` [Qemu-devel] [PATCH 8/9] target-xtensa: implement FP1 group Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 9/9] target-xtensa: implement coprocessor context option Max Filippov
8 siblings, 1 reply; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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>
---
target-xtensa/helper.h | 4 +++
target-xtensa/op_helper.c | 43 ++++++++++++++++++++++++++++++++++++++++
target-xtensa/translate.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 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..d85f9d0 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -821,3 +821,46 @@ 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_mul(v, uint32_to_float32(scale, &fp_status), &fp_status),
+ &fp_status);
+}
+
+uint32_t HELPER(ftoui)(float32 v, uint32_t rounding_mode, uint32_t scale)
+{
+ float_status fp_status = {0};
+ float32 zero = {0};
+ float32 res;
+
+ set_float_rounding_mode(rounding_mode, &fp_status);
+
+ res = float32_mul(v, uint32_to_float32(scale, &fp_status), &fp_status);
+
+ if (float32_compare_quiet(v, zero, &fp_status) == float_relation_less) {
+ 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_div(
+ int32_to_float32(v, &env->fp_status),
+ uint32_to_float32(scale, &env->fp_status),
+ &env->fp_status);
+}
+
+float32 HELPER(uitof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
+{
+ return float32_div(
+ uint32_to_float32(v, &env->fp_status),
+ uint32_to_float32(scale, &env->fp_status),
+ &env->fp_status);
+}
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index ec22f60..a6ab18a 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(1 << 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(1 << 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] 20+ messages in thread
* [Qemu-devel] [PATCH 8/9] target-xtensa: implement FP1 group
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
` (6 preceding siblings ...)
2012-09-09 1:29 ` [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 9/9] target-xtensa: implement coprocessor context option Max Filippov
8 siblings, 0 replies; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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 d85f9d0..cbaf3c7 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -864,3 +864,50 @@ float32 HELPER(uitof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
uint32_to_float32(scale, &env->fp_status),
&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 a6ab18a..d361f7f 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] 20+ messages in thread
* [Qemu-devel] [PATCH 9/9] target-xtensa: implement coprocessor context option
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
` (7 preceding siblings ...)
2012-09-09 1:29 ` [Qemu-devel] [PATCH 8/9] target-xtensa: implement FP1 group Max Filippov
@ 2012-09-09 1:29 ` Max Filippov
8 siblings, 0 replies; 20+ messages in thread
From: Max Filippov @ 2012-09-09 1:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl, 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 | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 42 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 d361f7f..5172194 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,12 @@ 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);
+ gen_jumpi_check_loop_end(dc, 0);
+}
+
static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
{
tcg_gen_andi_i32(cpu_SR[sr], v,
@@ -681,6 +698,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 +1850,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 +1910,31 @@ static void disas_xtensa_insn(DisasContext *dc)
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
switch (OP2) {
case 0: /*ADD.S*/
+ 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.S*/
+ 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.S*/
+ 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.S*/
+ 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.S*/
+ 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 +1945,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 +1974,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(1 << RRR_T);
@@ -1966,24 +1992,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 +2037,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 +2078,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 +2096,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 +2352,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 +2868,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] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent
2012-09-09 1:29 ` [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent Max Filippov
@ 2012-09-09 9:24 ` Aurelien Jarno
0 siblings, 0 replies; 20+ messages in thread
From: Aurelien Jarno @ 2012-09-09 9:24 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On Sun, Sep 09, 2012 at 05:29:50AM +0400, Max Filippov wrote:
> 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>
> ---
> 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,
> };
>
> /*----------------------------------------------------------------------------
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules
2012-09-09 1:29 ` [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules Max Filippov
@ 2012-09-09 9:31 ` Peter Maydell
2012-09-09 12:13 ` Max Filippov
0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2012-09-09 9:31 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On 9 September 2012 02:29, Max Filippov <jcmvbkbc@gmail.com> wrote:
> @@ -262,9 +263,13 @@ float32 float32_maybe_silence_nan( float32 a_ )
> # error Rules for silencing a signaling NaN are target-specific
> # endif
> #else
> +# if defined(TARGET_XTENSA)
> + return a_;
> +# else
> uint32_t a = float32_val(a_);
> a |= (1 << 22);
> return make_float32(a);
> +# endif
> #endif
> }
> return a_;
So this looks rather odd, because just returning a_ is making
no attempt to turn a signaling NaN into a quiet one. Looking at
the Xtensa ISA it says it doesn't have signaling NaNs. Maybe
it would be better to have a define for NO_SIGNALING_NANS
which made float*_is_signaling_nan() always return false and
float*_is_quiet_nan() always return true?
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic
2012-09-09 1:29 ` [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic Max Filippov
@ 2012-09-09 10:05 ` Peter Maydell
2012-09-09 12:25 ` Max Filippov
0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2012-09-09 10:05 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On 9 September 2012 02:29, Max Filippov <jcmvbkbc@gmail.com> wrote:
> +float32 HELPER(abs_s)(float32 v)
> +{
> + return float32_abs(v);
> +}
> +
> +float32 HELPER(neg_s)(float32 v)
> +{
> + return float32_chs(v);
> +}
Given that these are just 'v &= 0x7fffffff' and 'v ^= 0x80000000'
it seems like it would be better to just generate code for them
rather than calling out to a helper, though in some ways it does
break the abstraction layer of the softfloat library. I've been
toying with the idea of doing this for target-arm.
(we could have gen_float32_abs() and gen_float32_chs() in
softfloat.h, or would that be a worse layering violation in
the other direction? I dunno.)
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions
2012-09-09 1:29 ` [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions Max Filippov
@ 2012-09-09 11:06 ` Peter Maydell
2012-09-09 12:41 ` Max Filippov
0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2012-09-09 11:06 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On 9 September 2012 02:29, Max Filippov <jcmvbkbc@gmail.com> wrote:
> +uint32_t HELPER(ftoui)(float32 v, uint32_t rounding_mode, uint32_t scale)
> +{
> + float_status fp_status = {0};
> + float32 zero = {0};
This probably won't compile if you turn on USE_SOFTFLOAT_STRUCT_TYPES
in softfloat.h. (That's a define intended to assist in avoiding
accidental mixing of the softfloat types with native int/float types.)
In any case softfloat.h provides a float32_zero which is probably what
you want to use here.
> + float32 res;
> +
> + set_float_rounding_mode(rounding_mode, &fp_status);
> +
> + res = float32_mul(v, uint32_to_float32(scale, &fp_status), &fp_status);
Can you use the softflota scalbn function here instead?
> +
> + if (float32_compare_quiet(v, zero, &fp_status) == float_relation_less) {
> + return float32_to_int32(res, &fp_status);
> + } else {
> + return float32_to_uint32(res, &fp_status);
> + }
This looks rather odd...are you sure it's correct?
> +}
> +
> +float32 HELPER(itof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
> +{
> + return float32_div(
> + int32_to_float32(v, &env->fp_status),
> + uint32_to_float32(scale, &env->fp_status),
> + &env->fp_status);
> +}
> +
> +float32 HELPER(uitof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
> +{
> + return float32_div(
> + uint32_to_float32(v, &env->fp_status),
> + uint32_to_float32(scale, &env->fp_status),
> + &env->fp_status);
Again, scalbn should let you avoid this division. (check how the
ARM float-to-int and int-to-float are done, I think the semantics
are similar.)
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules
2012-09-09 9:31 ` Peter Maydell
@ 2012-09-09 12:13 ` Max Filippov
2012-09-09 15:14 ` Max Filippov
0 siblings, 1 reply; 20+ messages in thread
From: Max Filippov @ 2012-09-09 12:13 UTC (permalink / raw)
To: Peter Maydell; +Cc: Blue Swirl, qemu-devel
On Sun, Sep 9, 2012 at 1:31 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 September 2012 02:29, Max Filippov <jcmvbkbc@gmail.com> wrote:
>> @@ -262,9 +263,13 @@ float32 float32_maybe_silence_nan( float32 a_ )
>> # error Rules for silencing a signaling NaN are target-specific
>> # endif
>> #else
>> +# if defined(TARGET_XTENSA)
>> + return a_;
>> +# else
>> uint32_t a = float32_val(a_);
>> a |= (1 << 22);
>> return make_float32(a);
>> +# endif
>> #endif
>> }
>> return a_;
>
> So this looks rather odd, because just returning a_ is making
> no attempt to turn a signaling NaN into a quiet one. Looking at
I thought it would be quite in spirit of that 'maybe' part of the
function name (:
> the Xtensa ISA it says it doesn't have signaling NaNs. Maybe
> it would be better to have a define for NO_SIGNALING_NANS
> which made float*_is_signaling_nan() always return false and
> float*_is_quiet_nan() always return true?
Ok, will do so.
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic
2012-09-09 10:05 ` Peter Maydell
@ 2012-09-09 12:25 ` Max Filippov
2012-09-09 12:56 ` Peter Maydell
0 siblings, 1 reply; 20+ messages in thread
From: Max Filippov @ 2012-09-09 12:25 UTC (permalink / raw)
To: Peter Maydell; +Cc: Blue Swirl, qemu-devel
On Sun, Sep 9, 2012 at 2:05 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 September 2012 02:29, Max Filippov <jcmvbkbc@gmail.com> wrote:
>> +float32 HELPER(abs_s)(float32 v)
>> +{
>> + return float32_abs(v);
>> +}
>> +
>> +float32 HELPER(neg_s)(float32 v)
>> +{
>> + return float32_chs(v);
>> +}
>
> Given that these are just 'v &= 0x7fffffff' and 'v ^= 0x80000000'
> it seems like it would be better to just generate code for them
> rather than calling out to a helper, though in some ways it does
> break the abstraction layer of the softfloat library. I've been
> toying with the idea of doing this for target-arm.
I doubt that these opcodes are used often enough to justify such
hack.
> (we could have gen_float32_abs() and gen_float32_chs() in
> softfloat.h, or would that be a worse layering violation in
> the other direction? I dunno.)
IMHO this approach is a bit cleaner.
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions
2012-09-09 11:06 ` Peter Maydell
@ 2012-09-09 12:41 ` Max Filippov
0 siblings, 0 replies; 20+ messages in thread
From: Max Filippov @ 2012-09-09 12:41 UTC (permalink / raw)
To: Peter Maydell; +Cc: Blue Swirl, qemu-devel
On Sun, Sep 9, 2012 at 3:06 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 September 2012 02:29, Max Filippov <jcmvbkbc@gmail.com> wrote:
>> +uint32_t HELPER(ftoui)(float32 v, uint32_t rounding_mode, uint32_t scale)
>> +{
>> + float_status fp_status = {0};
>> + float32 zero = {0};
>
> This probably won't compile if you turn on USE_SOFTFLOAT_STRUCT_TYPES
It will, but thanks for the hint, gdbstub breaks with this macro defined.
> in softfloat.h. (That's a define intended to assist in avoiding
> accidental mixing of the softfloat types with native int/float types.)
>
> In any case softfloat.h provides a float32_zero which is probably what
> you want to use here.
>
>> + float32 res;
>> +
>> + set_float_rounding_mode(rounding_mode, &fp_status);
>> +
>> + res = float32_mul(v, uint32_to_float32(scale, &fp_status), &fp_status);
>
> Can you use the softflota scalbn function here instead?
Sure, had to search for it harder myself...
>> +
>> + if (float32_compare_quiet(v, zero, &fp_status) == float_relation_less) {
>> + return float32_to_int32(res, &fp_status);
>> + } else {
>> + return float32_to_uint32(res, &fp_status);
>> + }
>
> This looks rather odd...are you sure it's correct?
Unfortunately this is what Tensilica ISS does. Doesn't match what ISA
specifies and both are a bit counter-intuitive. I've mailed a question
to Tensilica
guys, will see what they answer.
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic
2012-09-09 12:25 ` Max Filippov
@ 2012-09-09 12:56 ` Peter Maydell
0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-09-09 12:56 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On 9 September 2012 13:25, Max Filippov <jcmvbkbc@gmail.com> wrote:
> On Sun, Sep 9, 2012 at 2:05 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> Given that these are just 'v &= 0x7fffffff' and 'v ^= 0x80000000'
>> it seems like it would be better to just generate code for them
>> rather than calling out to a helper, though in some ways it does
>> break the abstraction layer of the softfloat library. I've been
>> toying with the idea of doing this for target-arm.
>
> I doubt that these opcodes are used often enough to justify such
> hack.
>
>> (we could have gen_float32_abs() and gen_float32_chs() in
>> softfloat.h, or would that be a worse layering violation in
>> the other direction? I dunno.)
>
> IMHO this approach is a bit cleaner.
Mmm, maybe. I think you can reasonably leave your patch as it is,
anyway.
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules
2012-09-09 12:13 ` Max Filippov
@ 2012-09-09 15:14 ` Max Filippov
2012-09-09 15:44 ` Peter Maydell
0 siblings, 1 reply; 20+ messages in thread
From: Max Filippov @ 2012-09-09 15:14 UTC (permalink / raw)
To: Peter Maydell; +Cc: Blue Swirl, qemu-devel
On Sun, Sep 9, 2012 at 4:13 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> On Sun, Sep 9, 2012 at 1:31 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> the Xtensa ISA it says it doesn't have signaling NaNs. Maybe
>> it would be better to have a define for NO_SIGNALING_NANS
>> which made float*_is_signaling_nan() always return false and
>> float*_is_quiet_nan() always return true?
float*_is_quiet_nan should return float*_is_any_nan, but there's no
float16_is_any_nan. I guess it should look like this (any sign, all-ones
exponent part and non-zero mantissa part):
INLINE int float16_is_any_nan(float16 a)
{
return ((float16_val(a) & ~0x8000) > 0x7c00);
}
Is it correct?
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules
2012-09-09 15:14 ` Max Filippov
@ 2012-09-09 15:44 ` Peter Maydell
0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-09-09 15:44 UTC (permalink / raw)
To: Max Filippov; +Cc: Blue Swirl, qemu-devel
On 9 September 2012 16:14, Max Filippov <jcmvbkbc@gmail.com> wrote:
> On Sun, Sep 9, 2012 at 4:13 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
>> On Sun, Sep 9, 2012 at 1:31 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> the Xtensa ISA it says it doesn't have signaling NaNs. Maybe
>>> it would be better to have a define for NO_SIGNALING_NANS
>>> which made float*_is_signaling_nan() always return false and
>>> float*_is_quiet_nan() always return true?
>
> float*_is_quiet_nan should return float*_is_any_nan, but there's no
> float16_is_any_nan. I guess it should look like this (any sign, all-ones
> exponent part and non-zero mantissa part):
>
> INLINE int float16_is_any_nan(float16 a)
> {
> return ((float16_val(a) & ~0x8000) > 0x7c00);
> }
>
> Is it correct?
Yes, that looks right to me.
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2012-09-09 15:44 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-09 1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent Max Filippov
2012-09-09 9:24 ` Aurelien Jarno
2012-09-09 1:29 ` [Qemu-devel] [PATCH 2/9] target-xtensa: handle boolean option in overlays Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules Max Filippov
2012-09-09 9:31 ` Peter Maydell
2012-09-09 12:13 ` Max Filippov
2012-09-09 15:14 ` Max Filippov
2012-09-09 15:44 ` Peter Maydell
2012-09-09 1:29 ` [Qemu-devel] [PATCH 4/9] target-xtensa: add FP registers Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 5/9] target-xtensa: implement LSCX and LSCI groups Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic Max Filippov
2012-09-09 10:05 ` Peter Maydell
2012-09-09 12:25 ` Max Filippov
2012-09-09 12:56 ` Peter Maydell
2012-09-09 1:29 ` [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions Max Filippov
2012-09-09 11:06 ` Peter Maydell
2012-09-09 12:41 ` Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 8/9] target-xtensa: implement FP1 group Max Filippov
2012-09-09 1:29 ` [Qemu-devel] [PATCH 9/9] 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).