diff mbox

[v2,08/10] target-xtensa: implement FP0 conversions

Message ID 1347206679-428-9-git-send-email-jcmvbkbc@gmail.com
State New
Headers show

Commit Message

Max Filippov Sept. 9, 2012, 4:04 p.m. UTC
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(-)

Comments

Marc Gauthier Sept. 9, 2012, 5:24 p.m. UTC | #1
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
Max Filippov Sept. 9, 2012, 6:39 p.m. UTC | #2
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 */
Max Filippov Sept. 19, 2012, 12:28 a.m. UTC | #3
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?
diff mbox

Patch

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*/