Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-04-03 Thread Aleksandar Markovic

Hello, Leon, thank you very much for the kind feedback. Let me clarify my take 
on the involved issues.

1) Class operations

I am going to correct the code as you hinted.

The reason I wanted separate handling of MSA class operation is code and module 
decoupling. Handling of MSA instructions (in file msa_helper.c) and regular 
instructions (in file op_helper.c) have many overlaping areas - however, my 
understanding is that the designer of MSA module wanted it to be as independant 
on code in other files/modulas as possible. Handling class operation is on of 
the rare instances where code in msa_helper.c relies on the code in 
op_helper.c., and it made sense to me that this dependence should be removed, 
for the sake of consistency within MSA module - even if the functionalitied are 
virtually identical. That said, I will anyway listen to your advice, since you 
most probably see more than myself regarding this, and I am going to revert to 
a single handling of class operations, for both MSA and regular versions.

2) Flush subnormals

My impression is that his set of features should be treated and implemented 
separately, at some later point in time.

Although the implementation seems not to be too complex (defining FCR31_FS, 
invoking appropriately set_flush_to_zero() and set_flush_inputs_to_zero() on 
CPU init, plus special exception handling, like it is already done for MSA 
equivalents), it looks to me that it would have added a lot of risk into a 
patch series that is already touching a lot of sensitive areas, and therefore 
introducing a lot of risks. Once this patch series is hopefully intergrated, 
flush subnormals will be much easier to integrate, since it will be mips-only 
issue. Therefore, if you agree, I will leave it for the future. I will 
definitely mention it in commit messages though (as a limitaion), for future 
reference.

Thanks again for your consideration of this matter.

Sincerely yours,
Aleksandar


 Original Message 
Subject: Re: [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for 
R6 and MSA instructions
Date: Friday, April 1, 2016 21:07 CEST
From: Leon Alrae 
To: Aleksandar Markovic ,
CC: , , 
,, , 
,, , 
,, , 
,, 
,, 
,, 

References: 
<1458910214-12239-1-git-send-email-aleksandar.marko...@rt-rk.com><1458910214-12239-3-git-send-email-aleksandar.marko...@rt-rk.com>


 On 25/03/16 12:50, Aleksandar Markovic wrote:
> +#define MSA_CLASS_SIGNALING_NAN 0x001
> +#define MSA_CLASS_QUIET_NAN 0x002
> +#define MSA_CLASS_NEGATIVE_INFINITY 0x004
> +#define MSA_CLASS_NEGATIVE_NORMAL 0x008
> +#define MSA_CLASS_NEGATIVE_SUBNORMAL 0x010
> +#define MSA_CLASS_NEGATIVE_ZERO 0x020
> +#define MSA_CLASS_POSITIVE_INFINITY 0x040
> +#define MSA_CLASS_POSITIVE_NORMAL 0x080
> +#define MSA_CLASS_POSITIVE_SUBNORMAL 0x100
> +#define MSA_CLASS_POSITIVE_ZERO 0x200
> +
> +#define MSA_CLASS(name, bits) \
> +uint ## bits ## _t helper_msa_ ## name (CPUMIPSState *env, \
> + uint ## bits ## _t arg) \
> +{ \
> + if (float ## bits ## _is_signaling_nan(arg, \
> + >active_tc.msa_fp_status)) { \
> + return MSA_CLASS_SIGNALING_NAN; \
> + } else if (float ## bits ## _is_quiet_nan(arg, \
> + >active_tc.msa_fp_status)) { \
> + return MSA_CLASS_QUIET_NAN; \
> + } else if (float ## bits ## _is_neg(arg)) { \
> + if (float ## bits ## _is_infinity(arg)) { \
> + return MSA_CLASS_NEGATIVE_INFINITY; \
> + } else if (float ## bits ## _is_zero(arg)) { \
> + return MSA_CLASS_NEGATIVE_ZERO; \
> + } else if (float ## bits ## _is_zero_or_denormal(arg)) { \
> + return MSA_CLASS_NEGATIVE_SUBNORMAL; \
> + } else { \
> + return MSA_CLASS_NEGATIVE_NORMAL; \
> + } \
> + } else { \
> + if (float ## bits ## _is_infinity(arg)) { \
> + return MSA_CLASS_POSITIVE_INFINITY; \
> + } else if (float ## bits ## _is_zero(arg)) { \
> + return MSA_CLASS_POSITIVE_ZERO; \
> + } else if (float ## bits ## _is_zero_or_denormal(arg)) { \
> + return MSA_CLASS_POSITIVE_SUBNORMAL; \
> + } else { \
> + return MSA_CLASS_POSITIVE_NORMAL; \
> + } \
> + } \
> +}

Duplicating the class operation is unnecessary. We can just have common
function for FPU and MSA which takes additional float_status argument.

Also I noticed that this patch series doesn't provide Flush Subnormals
(the FCSR.FS bit), but probably this functionality can come later...

Leon


 

Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-04-01 Thread Leon Alrae
On 25/03/16 12:50, Aleksandar Markovic wrote:
> +#define MSA_CLASS_SIGNALING_NAN  0x001
> +#define MSA_CLASS_QUIET_NAN  0x002
> +#define MSA_CLASS_NEGATIVE_INFINITY  0x004
> +#define MSA_CLASS_NEGATIVE_NORMAL0x008
> +#define MSA_CLASS_NEGATIVE_SUBNORMAL 0x010
> +#define MSA_CLASS_NEGATIVE_ZERO  0x020
> +#define MSA_CLASS_POSITIVE_INFINITY  0x040
> +#define MSA_CLASS_POSITIVE_NORMAL0x080
> +#define MSA_CLASS_POSITIVE_SUBNORMAL 0x100
> +#define MSA_CLASS_POSITIVE_ZERO  0x200
> +
> +#define MSA_CLASS(name, bits)\
> +uint ## bits ## _t helper_msa_ ## name (CPUMIPSState *env,   \
> +uint ## bits ## _t arg)  \
> +{\
> +if (float ## bits ## _is_signaling_nan(arg,  \
> +>active_tc.msa_fp_status)) {\
> +return MSA_CLASS_SIGNALING_NAN;  \
> +} else if (float ## bits ## _is_quiet_nan(arg,   \
> +>active_tc.msa_fp_status)) {\
> +return MSA_CLASS_QUIET_NAN;  \
> +} else if (float ## bits ## _is_neg(arg)) {  \
> +if (float ## bits ## _is_infinity(arg)) {\
> +return MSA_CLASS_NEGATIVE_INFINITY;  \
> +} else if (float ## bits ## _is_zero(arg)) { \
> +return MSA_CLASS_NEGATIVE_ZERO;  \
> +} else if (float ## bits ## _is_zero_or_denormal(arg)) { \
> +return MSA_CLASS_NEGATIVE_SUBNORMAL; \
> +} else { \
> +return MSA_CLASS_NEGATIVE_NORMAL;\
> +}\
> +} else { \
> +if (float ## bits ## _is_infinity(arg)) {\
> +return MSA_CLASS_POSITIVE_INFINITY;  \
> +} else if (float ## bits ## _is_zero(arg)) { \
> +return MSA_CLASS_POSITIVE_ZERO;  \
> +} else if (float ## bits ## _is_zero_or_denormal(arg)) { \
> +return MSA_CLASS_POSITIVE_SUBNORMAL; \
> +} else { \
> +return MSA_CLASS_POSITIVE_NORMAL;\
> +}\
> +}\
> +}

Duplicating the class operation is unnecessary. We can just have common
function for FPU and MSA which takes additional float_status argument.

Also I noticed that this patch series doesn't provide Flush Subnormals
(the FCSR.FS bit), but probably this functionality can come later...

Leon



Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-03-31 Thread Richard Henderson
On 03/31/2016 04:55 AM, Aleksandar Markovic wrote:
> Hi, Richard, what would you think about this approach:
> 
> Functionality of . and ..
> instructions is dependent on flags ABS2008 and NAN2008 in FCR31. There are
> MIPS architectures (for example mips32r5) that allow implementations
> with different values of these flags. So, in order to detect the desired
> behavior in translate-time, insn_flags field can't be used - and, therefore,
> it makes sense to add two new members to the MIPS's DisasContext:
> 
> typedef struct DisasContext {
> . . .
> bool nan2008;
> bool abs2008;
> } DisasContext;
> 
> Their initialization could be in gen_intermediate_code_internal():
> 
> ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
> ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
> 
> Now, ABS.D (and all .) handling might look like this:
> 
> case OPC_ABS_D:
> check_cp1_registers(ctx, fs | fd);
> {
> TCGv_i64 fp0 = tcg_temp_new_i64();
> 
> gen_load_fpr64(ctx, fp0, fs);
> if (ctx->abs2008) {
> tcg_gen_andi_i64(fp0, fp0, 0x7fffULL);
> } else {
> gen_helper_float_abs_d(fp0, fp0);
> }
> gen_store_fpr64(ctx, fp0, fd);
> tcg_temp_free_i64(fp0);
> }
> opn = "abs.d";
> break;
> 
> Here, 2008-style ABS.D is implemented inline, without a helper, and
> gen_helper_float_abs_d() is an old pre-2008 helper that would be intact
> (the same as it is currently) with this change.

Yes, that's exactly what I had in mind.

> On the other hand, CVT.L.D (and all ..)
> handling would take this form:
> 
> case OPC_CVT_L_D:
> check_cp1_64bitmode(ctx);
> {
> TCGv_i64 fp0 = tcg_temp_new_i64();
> 
> gen_load_fpr64(ctx, fp0, fs);
> if (ctx->nan2008) {
> gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
> } else {
> gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
> }
> gen_store_fpr64(ctx, fp0, fd);
> tcg_temp_free_i64(fp0);
> }
> opn = "cvt.l.d";
> break;
> 
> Function helper_float_cvt_2008_l_d() is a new, only-2008-style helper for
> CVT.L.D and would look like this:
> 
> uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
> {
> uint64_t dt2;
> 
> dt2 = float64_to_int64(fdt0, >active_fpu.fp_status);
> if (get_float_exception_flags(>active_fpu.fp_status)
> & (float_flag_invalid | float_flag_overflow)) {
> dt2 = DBL_TO_INT64_OVERFLOW(fdt0)
> }
> update_fcr31(env, GETPC());
> return dt2;
> }

That looks fine as well.



r~



Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-03-31 Thread Aleksandar Markovic
Hi, Richard, what would you think about this approach:

Functionality of <ABS|NEG>.<S|D> and <CVT|FLOOR|CEIL|TRUNC|ROUND>.<L|W>.<S|D>
instructions is dependent on flags ABS2008 and NAN2008 in FCR31. There are
MIPS architectures (for example mips32r5) that allow implementations
with different values of these flags. So, in order to detect the desired
behavior in translate-time, insn_flags field can't be used - and, therefore,
it makes sense to add two new members to the MIPS's DisasContext:

typedef struct DisasContext {
. . .
bool nan2008;
bool abs2008;
} DisasContext;

Their initialization could be in gen_intermediate_code_internal():

ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;

Now, ABS.D (and all <ABS|NEG>.<S|D>) handling might look like this:

case OPC_ABS_D:
check_cp1_registers(ctx, fs | fd);
{
TCGv_i64 fp0 = tcg_temp_new_i64();

gen_load_fpr64(ctx, fp0, fs);
if (ctx->abs2008) {
tcg_gen_andi_i64(fp0, fp0, 0x7fffULL);
} else {
gen_helper_float_abs_d(fp0, fp0);
}
gen_store_fpr64(ctx, fp0, fd);
tcg_temp_free_i64(fp0);
}
opn = "abs.d";
break;

Here, 2008-style ABS.D is implemented inline, without a helper, and
gen_helper_float_abs_d() is an old pre-2008 helper that would be intact
(the same as it is currently) with this change.

On the other hand, CVT.L.D (and all <CVT|FLOOR|CEIL|TRUNC|ROUND>.<L|W>.<S|D>)
handling would take this form:

case OPC_CVT_L_D:
check_cp1_64bitmode(ctx);
{
TCGv_i64 fp0 = tcg_temp_new_i64();

gen_load_fpr64(ctx, fp0, fs);
if (ctx->nan2008) {
gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
} else {
gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
}
gen_store_fpr64(ctx, fp0, fd);
tcg_temp_free_i64(fp0);
}
opn = "cvt.l.d";
break;

Function helper_float_cvt_2008_l_d() is a new, only-2008-style helper for
CVT.L.D and would look like this:

uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
{
uint64_t dt2;

dt2 = float64_to_int64(fdt0, >active_fpu.fp_status);
if (get_float_exception_flags(>active_fpu.fp_status)
& (float_flag_invalid | float_flag_overflow)) {
dt2 = DBL_TO_INT64_OVERFLOW(fdt0)
}
update_fcr31(env, GETPC());
return dt2;
}

(macro DBL_TO_INT64_OVERFLOW(x) would be defined this way:

#define DBL_TO_INT64_OVERFLOW(x) \
float64_is_any_nan(x) ? 0 : (float64_is_neg(x) ? INT64_MIN : INT64_MAX);

to avoid awkward repeating "if" statements in multiple headers)

gen_helper_float_cvt_l_d() and all old style helpers for instructions
<CVT|FLOOR|CEIL|TRUNC|ROUND>.<L|W>.<S|D> would remain the same.

Please let me know about your opinion. I greatly appreciate your kind
consideration of this matter. I am looking forward to hearing from you.

Yours,
Aleksandar

From: qemu-devel-bounces+aleksandar.markovic=imgtec@nongnu.org 
[qemu-devel-bounces+aleksandar.markovic=imgtec@nongnu.org] on behalf of 
Richard Henderson [r...@twiddle.net]
Sent: Monday, March 28, 2016 2:49 PM
To: Aleksandar Markovic; qemu-devel@nongnu.org
Cc: peter.mayd...@linaro.org; ehabk...@redhat.com; 
kbast...@mail.uni-paderborn.de; mark.cave-ayl...@ilande.co.uk; ag...@suse.de; 
Petar Jovanovic; blauwir...@gmail.com; jcmvb...@gmail.com; Miodrag Dinic; 
qemu-...@nongnu.org; qemu-...@nongnu.org; edgar.igles...@gmail.com; 
pbonz...@redhat.com; g...@mprc.pku.edu.cn; Leon Alrae; afaer...@suse.de; 
aurel...@aurel32.net; pro...@gmail.com
Subject: Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 
functionality for R6 and MSA instructions

On 03/25/2016 05:50 AM, Aleksandar Markovic wrote:
> @@ -2621,9 +2621,23 @@ uint64_t helper_float_cvtl_d(CPUMIPSState *env, 
> uint64_t fdt0)
>   uint64_t dt2;
>
>   dt2 = float64_to_int64(fdt0, >active_fpu.fp_status);
> -if (get_float_exception_flags(>active_fpu.fp_status)
> -& (float_flag_invalid | float_flag_overflow)) {
> -dt2 = FP_TO_INT64_OVERFLOW;
> +if (env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) {
> +if (get_float_exception_flags(>active_fpu.fp_status)
> +& (float_flag_invalid | float_flag_overflow)) {
> +if (float64_is_any_nan(fdt0)) {
> +dt2 = 0;
> +} else {
> +if (float64_is_neg(fdt0))
> +dt2 = INT64_MIN;
> +else
>

Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-03-30 Thread Aleksandar Markovic
I really appreciate your guidance and help. I will respond shortly with a 
proposal that will address all issues that you brought up. Thanks again for 
your support and time.

Aleksandar

From: qemu-devel-bounces+aleksandar.markovic=imgtec@nongnu.org 
[qemu-devel-bounces+aleksandar.markovic=imgtec@nongnu.org] on behalf of 
Richard Henderson [r...@twiddle.net]
Sent: Monday, March 28, 2016 2:49 PM
To: Aleksandar Markovic; qemu-devel@nongnu.org
Cc: peter.mayd...@linaro.org; ehabk...@redhat.com; 
kbast...@mail.uni-paderborn.de; mark.cave-ayl...@ilande.co.uk; ag...@suse.de; 
Petar Jovanovic; blauwir...@gmail.com; jcmvb...@gmail.com; Miodrag Dinic; 
qemu-...@nongnu.org; qemu-...@nongnu.org; edgar.igles...@gmail.com; 
pbonz...@redhat.com; g...@mprc.pku.edu.cn; Leon Alrae; afaer...@suse.de; 
aurel...@aurel32.net; pro...@gmail.com
Subject: Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 
functionality for R6 and MSA instructions

On 03/25/2016 05:50 AM, Aleksandar Markovic wrote:
> @@ -2621,9 +2621,23 @@ uint64_t helper_float_cvtl_d(CPUMIPSState *env, 
> uint64_t fdt0)
>   uint64_t dt2;
>
>   dt2 = float64_to_int64(fdt0, >active_fpu.fp_status);
> -if (get_float_exception_flags(>active_fpu.fp_status)
> -& (float_flag_invalid | float_flag_overflow)) {
> -dt2 = FP_TO_INT64_OVERFLOW;
> +if (env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) {
> +if (get_float_exception_flags(>active_fpu.fp_status)
> +& (float_flag_invalid | float_flag_overflow)) {
> +if (float64_is_any_nan(fdt0)) {
> +dt2 = 0;
> +} else {
> +if (float64_is_neg(fdt0))
> +dt2 = INT64_MIN;
> +else
> +dt2 = INT64_MAX;
> +}
> +}
> +} else {
> +if (get_float_exception_flags(>active_fpu.fp_status)
> +& (float_flag_invalid | float_flag_overflow)) {
> +dt2 = FP_TO_INT64_OVERFLOW;
> +}

Better to swap the tests here, so that you test the exception flags first (and
once).  That is the exceptional condition, the one that will be true least
often.  After that, FCR31_NAN2008 will be tested only when needed.

But also, this pattern is replicated so many times you'd do well to pull this
sequence out to helper functions (one for s, one for d).

> +uint64_t helper_float_abs_d(CPUMIPSState *env, uint64_t fdt0)
> +{
> +uint64_t fdt1;
> +
> +if (env->active_fpu.fcr31 & (1 << FCR31_ABS2008)) {
> +fdt1 = float64_abs(fdt0);
> +} else {
> +if (float64_is_neg(fdt0)) {
> +fdt1 = float64_sub(0, fdt0, >active_fpu.fp_status);
> +} else {
> +fdt1 = float64_add(0, fdt0, >active_fpu.fp_status);
> +}
> +update_fcr31(env, GETPC());

Here you're better off using two separate helper functions, and chose the
correct one during translation.  Indeed, since the 2008 version is a simple
bit-flip, you needn't actually have a helper; just expand the sequence inline.


r~




Re: [Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-03-28 Thread Richard Henderson

On 03/25/2016 05:50 AM, Aleksandar Markovic wrote:

@@ -2621,9 +2621,23 @@ uint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t 
fdt0)
  uint64_t dt2;

  dt2 = float64_to_int64(fdt0, >active_fpu.fp_status);
-if (get_float_exception_flags(>active_fpu.fp_status)
-& (float_flag_invalid | float_flag_overflow)) {
-dt2 = FP_TO_INT64_OVERFLOW;
+if (env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) {
+if (get_float_exception_flags(>active_fpu.fp_status)
+& (float_flag_invalid | float_flag_overflow)) {
+if (float64_is_any_nan(fdt0)) {
+dt2 = 0;
+} else {
+if (float64_is_neg(fdt0))
+dt2 = INT64_MIN;
+else
+dt2 = INT64_MAX;
+}
+}
+} else {
+if (get_float_exception_flags(>active_fpu.fp_status)
+& (float_flag_invalid | float_flag_overflow)) {
+dt2 = FP_TO_INT64_OVERFLOW;
+}


Better to swap the tests here, so that you test the exception flags first (and 
once).  That is the exceptional condition, the one that will be true least 
often.  After that, FCR31_NAN2008 will be tested only when needed.


But also, this pattern is replicated so many times you'd do well to pull this 
sequence out to helper functions (one for s, one for d).



+uint64_t helper_float_abs_d(CPUMIPSState *env, uint64_t fdt0)
+{
+uint64_t fdt1;
+
+if (env->active_fpu.fcr31 & (1 << FCR31_ABS2008)) {
+fdt1 = float64_abs(fdt0);
+} else {
+if (float64_is_neg(fdt0)) {
+fdt1 = float64_sub(0, fdt0, >active_fpu.fp_status);
+} else {
+fdt1 = float64_add(0, fdt0, >active_fpu.fp_status);
+}
+update_fcr31(env, GETPC());


Here you're better off using two separate helper functions, and chose the 
correct one during translation.  Indeed, since the 2008 version is a simple 
bit-flip, you needn't actually have a helper; just expand the sequence inline.



r~



[Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-03-25 Thread Aleksandar Markovic
From: Aleksandar Markovic 

This patch utilizes provisions from the previous patch, and configures
Mips R6 CPUs and Mips MSA units appropriately with reference to the meaning
of the signaling NaN bit (this is mentioned in point 3 in the list below).
The majority of involved MIPS instructions will be fixed just with that
change. Certain number of other IEEE 754-2008 standard-related MIPS issues
are addreessed with this patch as well.

The changes can be summarized this way:

1) Definitions of Mips processors are updated to reflect supported
   IEEE-754-2008-related features. (file target-mips/translate_init.c)

2) Functions fpu_init() and msa_reset() are updated so that flag
   snan_bit_is_one is properly set for any Mips configuration.
   (file target-mips/translate_init.c)

3) Helpers helper_float_abs_() and helper_float_chs_() are
   rewritten to reflect new behavior of instructions ABS.fmt and NEG.fmt
   in MIPS Release 6. Affected MIPS instructions are:

   ABS.S
   ABS.D
   NEG.S
   NEG.D

   Note that legacy (pre-R6) ABS and NEG instructions are arithmetic
   (any NaN operand signals invalid operation), while R6 ones are
   non-arithmetic, always changing the sign bit, even for NaN-like operands.

   Details on these instructions are documented in [1] p. 35 and 359.

   Affected files are target-mips/helper.h and target-mips/op_helper.c.

4) Helpers helper_float_ceilxxx(), helper_float_cvtxxx(),
   helper_float_floorxxx(), helper_float_roundxxx(), and
   helper_float_truncxxx() are rewritten to reflect the behavior of
   relevant instructions if its operands are floating numbers out of
   the range of the integer destination.

   Affected MIPS instructions are:

   CEIL.L.fmt
   CEIL.W.fmt
   CVT.L.fmt
   CVT.W.fmt
   FLOOR.L.fmt
   FLOOR.W.fmt
   ROUND.L.fmt
   ROUND.W.fmt
   TRUNC.L.fmt
   TRUNC.W.fmt

   Details on these instructions are presented in [1] p. 129, 130, 149,
   155, 222, 223, 393, 394, 504, 505.

   Affected files are target-mips/helper.h and target-mips/translate.c.

5) Helpers helper_msa_class_s() and helper_msa_class_d() added so that
   MSA version of instruction CLASS can operate independently of the one
   from the base set of instructions. Affected MIPS instructions are:

   FCLASS.W
   FCLASS.D

   Details on these instructions can be found in [2] p. 158.

   Affected source code files are target-mips/helper.h and
   target-mips/msa_helper.c.

6) Handling og instructions CVT.S.PU and CVT.S.PL is updated to reflect
   the fact that they are removed in Mips R6 architecture and belong to
   so-called paired-single class of instructions. Details on these
   instructions can be found in [1], p. 152 and 153. Affected source
   code file is target-mips/translate.c.

[1] "MIPS® Architecture For Programmers Volume II-A:
The MIPS64® Instruction Set Reference Manual",
Imagination Technologies LTD, Revision 6.04, November 13, 2015
(https://imagination-technologies-cloudfront-assets.s3.amazonaws.com/
 documentation/MD00087-2B-MIPS64BIS-AFP-06.04.pdf)

[2] "MIPS Architecture for Programmers Volume IV-j:
The MIPS32® SIMD Architecture Module",
Imagination Technologies LTD, Revision 1.12, February 3, 2016
(https://imagination-technologies-cloudfront-assets.s3.amazonaws.com/
 documentation/MD00866-2B-MSA32-AFP-01.12.pdf)

Signed-off-by: Aleksandar Markovic 
---
 target-mips/helper.h |  10 +-
 target-mips/msa_helper.c |  60 -
 target-mips/op_helper.c  | 516 ---
 target-mips/translate.c  |  16 +-
 target-mips/translate_init.c |  22 +-
 5 files changed, 520 insertions(+), 104 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 1aaa316..952af63 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -254,10 +254,10 @@ FOP_PROTO(recip)
 FOP_PROTO(rint)
 #undef FOP_PROTO
 
-#define FOP_PROTO(op)   \
-DEF_HELPER_1(float_ ## op ## _s, i32, i32)  \
-DEF_HELPER_1(float_ ## op ## _d, i64, i64)  \
-DEF_HELPER_1(float_ ## op ## _ps, i64, i64)
+#define FOP_PROTO(op)\
+DEF_HELPER_2(float_ ## op ## _s, i32, env, i32)  \
+DEF_HELPER_2(float_ ## op ## _d, i64, env, i64)  \
+DEF_HELPER_2(float_ ## op ## _ps, i64, env, i64)
 FOP_PROTO(abs)
 FOP_PROTO(chs)
 #undef FOP_PROTO
@@ -924,6 +924,8 @@ DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
 
+DEF_HELPER_2(msa_class_s, i32, env, i32)
+DEF_HELPER_2(msa_class_d, i64, env, i64)
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 47fbba0..fed430d 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -2924,19 +2924,67 @@