Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 7 ++
target/sparc/translate.c | 145 +++++++++++++++++++++++---------------
2 files changed, 96 insertions(+), 56 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index d4487e326a..f197bb0b36 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -296,6 +296,13 @@ FMOVRs 10 rd:5 110101 rs1:5 0 cond:3 00101 rs2:5
FMOVRd 10 rd:5 110101 rs1:5 0 cond:3 00110 rs2:5
FMOVRq 10 rd:5 110101 rs1:5 0 cond:3 00111 rs2:5
+FCMPs 10 000 cc:2 110101 rs1:5 0 0101 0001 rs2:5
+FCMPd 10 000 cc:2 110101 rs1:5 0 0101 0010 rs2:5
+FCMPq 10 000 cc:2 110101 rs1:5 0 0101 0011 rs2:5
+FCMPEs 10 000 cc:2 110101 rs1:5 0 0101 0101 rs2:5
+FCMPEd 10 000 cc:2 110101 rs1:5 0 0101 0110 rs2:5
+FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5
+
{
[
EDGE8cc 10 ..... 110110 ..... 0 0000 0000 ..... @r_r_r
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ff18dc0482..ddde64dfb4 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5125,6 +5125,82 @@ TRANS(FMOVsfcc, 64, do_fmovfcc, a, false, gen_fmovs)
TRANS(FMOVdfcc, 64, do_fmovfcc, a, false, gen_fmovd)
TRANS(FMOVqfcc, 64, do_fmovfcc, a, true, gen_fmovq)
+static bool do_fcmps(DisasContext *dc, arg_FCMPs *a, bool e)
+{
+ TCGv_i32 src1, src2;
+
+ if (avail_32(dc) && a->cc != 0) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ gen_op_clear_ieee_excp_and_FTT();
+ src1 = gen_load_fpr_F(dc, a->rs1);
+ src2 = gen_load_fpr_F(dc, a->rs2);
+ if (e) {
+ gen_op_fcmpes(a->cc, src1, src2);
+ } else {
+ gen_op_fcmps(a->cc, src1, src2);
+ }
+ return advance_pc(dc);
+}
+
+TRANS(FCMPs, ALL, do_fcmps, a, false)
+TRANS(FCMPEs, ALL, do_fcmps, a, true)
+
+static bool do_fcmpd(DisasContext *dc, arg_FCMPd *a, bool e)
+{
+ TCGv_i64 src1, src2;
+
+ if (avail_32(dc) && a->cc != 0) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ gen_op_clear_ieee_excp_and_FTT();
+ src1 = gen_load_fpr_D(dc, a->rs1);
+ src2 = gen_load_fpr_D(dc, a->rs2);
+ if (e) {
+ gen_op_fcmped(a->cc, src1, src2);
+ } else {
+ gen_op_fcmpd(a->cc, src1, src2);
+ }
+ return advance_pc(dc);
+}
+
+TRANS(FCMPd, ALL, do_fcmpd, a, false)
+TRANS(FCMPEd, ALL, do_fcmpd, a, true)
+
+static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
+{
+ if (avail_32(dc) && a->cc != 0) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (gen_trap_float128(dc)) {
+ return true;
+ }
+
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_op_load_fpr_QT0(QFPREG(a->rs1));
+ gen_op_load_fpr_QT1(QFPREG(a->rs2));
+ if (e) {
+ gen_op_fcmpeq(a->cc);
+ } else {
+ gen_op_fcmpq(a->cc);
+ }
+ return advance_pc(dc);
+}
+
+TRANS(FCMPq, ALL, do_fcmpq, a, false)
+TRANS(FCMPEq, ALL, do_fcmpq, a, true)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5135,15 +5211,7 @@ TRANS(FMOVqfcc, 64, do_fmovfcc, a, true, gen_fmovq)
/* before an instruction, dc->pc must be static */
static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
{
- unsigned int opc, rs1, rs2, rd;
- TCGv cpu_src1 __attribute__((unused));
- TCGv_i32 cpu_src1_32, cpu_src2_32;
- TCGv_i64 cpu_src1_64, cpu_src2_64;
- TCGv_i32 cpu_dst_32 __attribute__((unused));
- TCGv_i64 cpu_dst_64 __attribute__((unused));
-
- opc = GET_FIELD(insn, 0, 1);
- rd = GET_FIELD(insn, 2, 6);
+ unsigned int opc = GET_FIELD(insn, 0, 1);
switch (opc) {
case 0:
@@ -5153,61 +5221,22 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 2: /* FPU & Logical Operations */
{
unsigned int xop = GET_FIELD(insn, 7, 12);
- TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
if (xop == 0x34) { /* FPU Operations */
goto illegal_insn; /* in decodetree */
} else if (xop == 0x35) { /* FPU Operations */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_op_clear_ieee_excp_and_FTT();
- rs1 = GET_FIELD(insn, 13, 17);
- rs2 = GET_FIELD(insn, 27, 31);
- xop = GET_FIELD(insn, 18, 26);
-
- switch (xop) {
- case 0x51: /* fcmps, V9 %fcc */
- cpu_src1_32 = gen_load_fpr_F(dc, rs1);
- cpu_src2_32 = gen_load_fpr_F(dc, rs2);
- gen_op_fcmps(rd & 3, cpu_src1_32, cpu_src2_32);
- break;
- case 0x52: /* fcmpd, V9 %fcc */
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_op_fcmpd(rd & 3, cpu_src1_64, cpu_src2_64);
- break;
- case 0x53: /* fcmpq, V9 %fcc */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_op_load_fpr_QT0(QFPREG(rs1));
- gen_op_load_fpr_QT1(QFPREG(rs2));
- gen_op_fcmpq(rd & 3);
- break;
- case 0x55: /* fcmpes, V9 %fcc */
- cpu_src1_32 = gen_load_fpr_F(dc, rs1);
- cpu_src2_32 = gen_load_fpr_F(dc, rs2);
- gen_op_fcmpes(rd & 3, cpu_src1_32, cpu_src2_32);
- break;
- case 0x56: /* fcmped, V9 %fcc */
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_op_fcmped(rd & 3, cpu_src1_64, cpu_src2_64);
- break;
- case 0x57: /* fcmpeq, V9 %fcc */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_op_load_fpr_QT0(QFPREG(rs1));
- gen_op_load_fpr_QT1(QFPREG(rs2));
- gen_op_fcmpeq(rd & 3);
- break;
- default:
- goto illegal_insn;
- }
+ goto illegal_insn; /* in decodetree */
} else if (xop == 0x36) {
#ifdef TARGET_SPARC64
/* VIS */
+ TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
+ TCGv_i32 cpu_dst_32;
+ TCGv cpu_dst = tcg_temp_new();
int opf = GET_FIELD_SP(insn, 5, 13);
- rs1 = GET_FIELD(insn, 13, 17);
- rs2 = GET_FIELD(insn, 27, 31);
+ int rs1 = GET_FIELD(insn, 13, 17);
+ int rs2 = GET_FIELD(insn, 27, 31);
+ int rd = GET_FIELD(insn, 2, 6);
+
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
@@ -5392,14 +5421,18 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
goto illegal_insn; /* in decodetree */
}
advance_pc(dc);
+#ifdef TARGET_SPARC64
jmp_insn:
+#endif
return;
illegal_insn:
gen_exception(dc, TT_ILL_INSN);
return;
+#ifdef TARGET_SPARC64
nfpu_insn:
gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
return;
+#endif
}
static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
--
2.34.1