diff options
author | Richard Henderson <rth@twiddle.net> | 2011-10-17 17:32:26 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2011-10-26 13:58:48 -0700 |
commit | f888300b818a46bb1b339d68d6748bc097396a7b (patch) | |
tree | e566afff5ad8ac8509d6c77a850fdda5a164a38e | |
parent | 445167723d12d6e14d4f11b4104c48c8b25329db (diff) |
target-sparc: Implement PDIST.
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r-- | target-sparc/helper.h | 1 | ||||
-rw-r--r-- | target-sparc/translate.c | 21 | ||||
-rw-r--r-- | target-sparc/vis_helper.c | 21 |
3 files changed, 41 insertions, 2 deletions
diff --git a/target-sparc/helper.h b/target-sparc/helper.h index 22fb8ef8d2..22f9dce9ac 100644 --- a/target-sparc/helper.h +++ b/target-sparc/helper.h @@ -137,6 +137,7 @@ DEF_HELPER_FLAGS_2(fmul8ulx16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(fmuld8sux16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(fmuld8ulx16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(fexpand, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_3(pdist, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64, i64) #define VIS_HELPER(name) \ DEF_HELPER_FLAGS_2(f ## name ## 16, TCG_CALL_CONST | TCG_CALL_PURE, \ i64, i64, i64) \ diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 0b9ace323e..2646aaf1db 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1738,6 +1738,21 @@ static inline void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, gen_store_fpr_D(dc, rd, dst); } + +static inline void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) +{ + TCGv_i64 dst, src0, src1, src2; + + src1 = gen_load_fpr_D(dc, rs1); + src2 = gen_load_fpr_D(dc, rs2); + src0 = gen_load_fpr_D(dc, rd); + dst = gen_dest_fpr_D(); + + gen(dst, src0, src1, src2); + + gen_store_fpr_D(dc, rd, dst); +} #endif static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs, @@ -4059,9 +4074,11 @@ static void disas_sparc_insn(DisasContext * dc) case 0x03a: /* VIS I fpack32 */ case 0x03b: /* VIS I fpack16 */ case 0x03d: /* VIS I fpackfix */ - case 0x03e: /* VIS I pdist */ - // XXX goto illegal_insn; + case 0x03e: /* VIS I pdist */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_ne_fop_DDDD(dc, rd, rs1, rs2, gen_helper_pdist); + break; case 0x048: /* VIS I faligndata */ CHECK_FPU_FEATURE(dc, VIS1); cpu_src1_64 = gen_load_fpr_D(dc, rs1); diff --git a/target-sparc/vis_helper.c b/target-sparc/vis_helper.c index 39c8d9a66e..cd5d4a7ff3 100644 --- a/target-sparc/vis_helper.c +++ b/target-sparc/vis_helper.c @@ -396,3 +396,24 @@ VIS_CMPHELPER(helper_fcmpgt, FCMPGT) VIS_CMPHELPER(helper_fcmpeq, FCMPEQ) VIS_CMPHELPER(helper_fcmple, FCMPLE) VIS_CMPHELPER(helper_fcmpne, FCMPNE) + +uint64_t helper_pdist(uint64_t sum, uint64_t src1, uint64_t src2) +{ + int i; + for (i = 0; i < 8; i++) { + int s1, s2; + + s1 = (src1 >> (56 - (i * 8))) & 0xff; + s2 = (src2 >> (56 - (i * 8))) & 0xff; + + /* Absolute value of difference. */ + s1 -= s2; + if (s1 < 0) { + s1 = -s1; + } + + sum += s1; + } + + return sum; +} |