DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_5(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, i32)
DEF_HELPER_FLAGS_3(faddq, TCG_CALL_NO_WG, i128, env, i128, i128)
DEF_HELPER_FLAGS_3(fsubq, TCG_CALL_NO_WG, i128, env, i128, i128)
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_WG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_WG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_5(fmadds, TCG_CALL_NO_WG, f32, env, f32, f32, f32, i32)
DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_WG, f64, env, f32, f32)
DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_WG, i128, env, f64, f64)
%dfp_rd 25:5 !function=extract_dfpreg
%dfp_rs1 14:5 !function=extract_dfpreg
%dfp_rs2 0:5 !function=extract_dfpreg
+%dfp_rs3 9:5 !function=extract_dfpreg
%qfp_rd 25:5 !function=extract_qfpreg
%qfp_rs1 14:5 !function=extract_qfpreg
@q_d2 .. ..... ...... ..... . ........ ..... \
&r_r rd=%qfp_rd rs=%dfp_rs2
+&r_r_r_r rd rs1 rs2 rs3
+@r_r_r_r .. rd:5 ...... rs1:5 rs3:5 .... rs2:5 &r_r_r_r
+@d_d_d_d .. ..... ...... ..... ..... .... ..... \
+ &r_r_r_r rd=%dfp_rd rs1=%dfp_rs1 rs2=%dfp_rs2 rs3=%dfp_rs3
+
{
[
STBAR 10 00000 101000 01111 0 0000000000000
FPACK32 10 ..... 110110 ..... 0 0011 1010 ..... @d_d_d
FPACK16 10 ..... 110110 00000 0 0011 1011 ..... @r_d2
FPACKFIX 10 ..... 110110 00000 0 0011 1101 ..... @r_d2
- PDIST 10 ..... 110110 ..... 0 0011 1110 ..... @d_d_d
+ PDIST 10 ..... 110110 ..... 0 0011 1110 ..... \
+ &r_r_r_r rd=%dfp_rd rs1=%dfp_rd rs2=%dfp_rs1 rs3=%dfp_rs2
FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @d_d_d
FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @d_r_r
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
}
-NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
+{
+ [
+ FMADDs 10 ..... 110111 ..... ..... 0001 ..... @r_r_r_r
+ FMADDd 10 ..... 110111 ..... ..... 0010 ..... @d_d_d_d
+ FMSUBs 10 ..... 110111 ..... ..... 0101 ..... @r_r_r_r
+ FMSUBd 10 ..... 110111 ..... ..... 0110 ..... @d_d_d_d
+ FNMSUBs 10 ..... 110111 ..... ..... 1001 ..... @r_r_r_r
+ FNMSUBd 10 ..... 110111 ..... ..... 1010 ..... @d_d_d_d
+ FNMADDs 10 ..... 110111 ..... ..... 1101 ..... @r_r_r_r
+ FNMADDd 10 ..... 110111 ..... ..... 1110 ..... @d_d_d_d
+ ]
+ NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
+}
##
## Major Opcode 11 -- load and store instructions
#include "exec/helper-gen.h"
#include "exec/translator.h"
#include "exec/log.h"
+#include "fpu/softfloat.h"
#include "asi.h"
#define HELPER_H "helper.h"
tcg_gen_concat_i64_i128(dst, l, h);
}
+static void gen_op_fmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
+{
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(0));
+}
+
+static void gen_op_fmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
+{
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(0));
+}
+
+static void gen_op_fmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
+{
+ int op = float_muladd_negate_c;
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
+}
+
+static void gen_op_fmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
+{
+ int op = float_muladd_negate_c;
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
+}
+
+static void gen_op_fnmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
+{
+ int op = float_muladd_negate_c | float_muladd_negate_result;
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
+}
+
+static void gen_op_fnmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
+{
+ int op = float_muladd_negate_c | float_muladd_negate_result;
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
+}
+
+static void gen_op_fnmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
+{
+ int op = float_muladd_negate_result;
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
+}
+
+static void gen_op_fnmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
+{
+ int op = float_muladd_negate_result;
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
+}
+
static void gen_op_fpexception_im(DisasContext *dc, int ftt)
{
/*
# define avail_MUL(C) true
# define avail_POWERDOWN(C) false
# define avail_64(C) true
+# define avail_FMAF(C) ((C)->def->features & CPU_FEATURE_FMAF)
# define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL)
# define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
# define avail_VIS1(C) ((C)->def->features & CPU_FEATURE_VIS1)
# define avail_MUL(C) ((C)->def->features & CPU_FEATURE_MUL)
# define avail_POWERDOWN(C) ((C)->def->features & CPU_FEATURE_POWERDOWN)
# define avail_64(C) false
+# define avail_FMAF(C) false
# define avail_GL(C) false
# define avail_HYPV(C) false
# define avail_VIS1(C) false
return advance_pc(dc);
}
-static bool do_dddd(DisasContext *dc, arg_r_r_r *a,
+static bool do_ffff(DisasContext *dc, arg_r_r_r_r *a,
+ void (*func)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32))
+{
+ TCGv_i32 dst, src1, src2, src3;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ src1 = gen_load_fpr_F(dc, a->rs1);
+ src2 = gen_load_fpr_F(dc, a->rs2);
+ src3 = gen_load_fpr_F(dc, a->rs3);
+ dst = tcg_temp_new_i32();
+ func(dst, src1, src2, src3);
+ gen_store_fpr_F(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(FMADDs, FMAF, do_ffff, a, gen_op_fmadds)
+TRANS(FMSUBs, FMAF, do_ffff, a, gen_op_fmsubs)
+TRANS(FNMSUBs, FMAF, do_ffff, a, gen_op_fnmsubs)
+TRANS(FNMADDs, FMAF, do_ffff, a, gen_op_fnmadds)
+
+static bool do_dddd(DisasContext *dc, arg_r_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
{
- TCGv_i64 dst, src0, src1, src2;
+ TCGv_i64 dst, src1, src2, src3;
if (gen_trap_ifnofpu(dc)) {
return true;
}
dst = tcg_temp_new_i64();
- src0 = gen_load_fpr_D(dc, a->rd);
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
- func(dst, src0, src1, src2);
+ src3 = gen_load_fpr_D(dc, a->rs3);
+ func(dst, src1, src2, src3);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
TRANS(PDIST, VIS1, do_dddd, a, gen_helper_pdist)
+TRANS(FMADDd, FMAF, do_dddd, a, gen_op_fmaddd)
+TRANS(FMSUBd, FMAF, do_dddd, a, gen_op_fmsubd)
+TRANS(FNMSUBd, FMAF, do_dddd, a, gen_op_fnmsubd)
+TRANS(FNMADDd, FMAF, do_dddd, a, gen_op_fnmaddd)
static bool do_env_qqq(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i128, TCGv_env, TCGv_i128, TCGv_i128))