diff options
Diffstat (limited to 'target-sparc/vis_helper.c')
-rw-r--r-- | target-sparc/vis_helper.c | 251 |
1 files changed, 167 insertions, 84 deletions
diff --git a/target-sparc/vis_helper.c b/target-sparc/vis_helper.c index a22c10bb43..a992c293af 100644 --- a/target-sparc/vis_helper.c +++ b/target-sparc/vis_helper.c @@ -20,11 +20,6 @@ #include "cpu.h" #include "helper.h" -#define DT0 (env->dt0) -#define DT1 (env->dt1) -#define QT0 (env->qt0) -#define QT1 (env->qt1) - /* This function uses non-native bit order */ #define GET_FIELD(X, FROM, TO) \ ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1)) @@ -33,8 +28,7 @@ #define GET_FIELD_SP(X, FROM, TO) \ GET_FIELD(X, 63 - (TO), 63 - (FROM)) -target_ulong helper_array8(CPUState *env, target_ulong pixel_addr, - target_ulong cubesize) +target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize) { return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) | (GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) | @@ -47,29 +41,6 @@ target_ulong helper_array8(CPUState *env, target_ulong pixel_addr, GET_FIELD_SP(pixel_addr, 11, 12); } -target_ulong helper_alignaddr(CPUState *env, target_ulong addr, - target_ulong offset) -{ - uint64_t tmp; - - tmp = addr + offset; - env->gsr &= ~7ULL; - env->gsr |= tmp & 7ULL; - return tmp & ~7ULL; -} - -void helper_faligndata(CPUState *env) -{ - uint64_t tmp; - - tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8); - /* on many architectures a shift of 64 does nothing */ - if ((env->gsr & 7) != 0) { - tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8); - } - *((uint64_t *)&DT0) = tmp; -} - #ifdef HOST_WORDS_BIGENDIAN #define VIS_B64(n) b[7 - (n)] #define VIS_W64(n) w[3 - (n)] @@ -102,12 +73,12 @@ typedef union { float32 f; } VIS32; -void helper_fpmerge(CPUState *env) +uint64_t helper_fpmerge(uint64_t src1, uint64_t src2) { VIS64 s, d; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; /* Reverse calculation order to handle overlap */ d.VIS_B64(7) = s.VIS_B64(3); @@ -119,16 +90,16 @@ void helper_fpmerge(CPUState *env) d.VIS_B64(1) = s.VIS_B64(0); /* d.VIS_B64(0) = d.VIS_B64(0); */ - DT0 = d.d; + return d.ll; } -void helper_fmul8x16(CPUState *env) +uint64_t helper_fmul8x16(uint64_t src1, uint64_t src2) { VIS64 s, d; uint32_t tmp; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; #define PMUL(r) \ tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \ @@ -143,16 +114,16 @@ void helper_fmul8x16(CPUState *env) PMUL(3); #undef PMUL - DT0 = d.d; + return d.ll; } -void helper_fmul8x16al(CPUState *env) +uint64_t helper_fmul8x16al(uint64_t src1, uint64_t src2) { VIS64 s, d; uint32_t tmp; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; #define PMUL(r) \ tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \ @@ -167,16 +138,16 @@ void helper_fmul8x16al(CPUState *env) PMUL(3); #undef PMUL - DT0 = d.d; + return d.ll; } -void helper_fmul8x16au(CPUState *env) +uint64_t helper_fmul8x16au(uint64_t src1, uint64_t src2) { VIS64 s, d; uint32_t tmp; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; #define PMUL(r) \ tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \ @@ -191,16 +162,16 @@ void helper_fmul8x16au(CPUState *env) PMUL(3); #undef PMUL - DT0 = d.d; + return d.ll; } -void helper_fmul8sux16(CPUState *env) +uint64_t helper_fmul8sux16(uint64_t src1, uint64_t src2) { VIS64 s, d; uint32_t tmp; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; #define PMUL(r) \ tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \ @@ -215,16 +186,16 @@ void helper_fmul8sux16(CPUState *env) PMUL(3); #undef PMUL - DT0 = d.d; + return d.ll; } -void helper_fmul8ulx16(CPUState *env) +uint64_t helper_fmul8ulx16(uint64_t src1, uint64_t src2) { VIS64 s, d; uint32_t tmp; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; #define PMUL(r) \ tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \ @@ -239,16 +210,16 @@ void helper_fmul8ulx16(CPUState *env) PMUL(3); #undef PMUL - DT0 = d.d; + return d.ll; } -void helper_fmuld8sux16(CPUState *env) +uint64_t helper_fmuld8sux16(uint64_t src1, uint64_t src2) { VIS64 s, d; uint32_t tmp; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; #define PMUL(r) \ tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \ @@ -262,16 +233,16 @@ void helper_fmuld8sux16(CPUState *env) PMUL(0); #undef PMUL - DT0 = d.d; + return d.ll; } -void helper_fmuld8ulx16(CPUState *env) +uint64_t helper_fmuld8ulx16(uint64_t src1, uint64_t src2) { VIS64 s, d; uint32_t tmp; - s.d = DT0; - d.d = DT1; + s.ll = src1; + d.ll = src2; #define PMUL(r) \ tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \ @@ -285,42 +256,41 @@ void helper_fmuld8ulx16(CPUState *env) PMUL(0); #undef PMUL - DT0 = d.d; + return d.ll; } -void helper_fexpand(CPUState *env) +uint64_t helper_fexpand(uint64_t src1, uint64_t src2) { VIS32 s; VIS64 d; - s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff); - d.d = DT1; + s.l = (uint32_t)src1; + d.ll = src2; d.VIS_W64(0) = s.VIS_B32(0) << 4; d.VIS_W64(1) = s.VIS_B32(1) << 4; d.VIS_W64(2) = s.VIS_B32(2) << 4; d.VIS_W64(3) = s.VIS_B32(3) << 4; - DT0 = d.d; + return d.ll; } #define VIS_HELPER(name, F) \ - void name##16(CPUState *env) \ + uint64_t name##16(uint64_t src1, uint64_t src2) \ { \ VIS64 s, d; \ \ - s.d = DT0; \ - d.d = DT1; \ + s.ll = src1; \ + d.ll = src2; \ \ d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0)); \ d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1)); \ d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2)); \ d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3)); \ \ - DT0 = d.d; \ + return d.ll; \ } \ \ - uint32_t name##16s(CPUState *env, uint32_t src1, \ - uint32_t src2) \ + uint32_t name##16s(uint32_t src1, uint32_t src2) \ { \ VIS32 s, d; \ \ @@ -333,21 +303,20 @@ void helper_fexpand(CPUState *env) return d.l; \ } \ \ - void name##32(CPUState *env) \ + uint64_t name##32(uint64_t src1, uint64_t src2) \ { \ VIS64 s, d; \ \ - s.d = DT0; \ - d.d = DT1; \ + s.ll = src1; \ + d.ll = src2; \ \ d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0)); \ d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1)); \ \ - DT0 = d.d; \ + return d.ll; \ } \ \ - uint32_t name##32s(CPUState *env, uint32_t src1, \ - uint32_t src2) \ + uint32_t name##32s(uint32_t src1, uint32_t src2) \ { \ VIS32 s, d; \ \ @@ -365,12 +334,12 @@ VIS_HELPER(helper_fpadd, FADD) VIS_HELPER(helper_fpsub, FSUB) #define VIS_CMPHELPER(name, F) \ - uint64_t name##16(CPUState *env) \ + uint64_t name##16(uint64_t src1, uint64_t src2) \ { \ VIS64 s, d; \ \ - s.d = DT0; \ - d.d = DT1; \ + s.ll = src1; \ + d.ll = src2; \ \ d.VIS_W64(0) = F(s.VIS_W64(0), d.VIS_W64(0)) ? 1 : 0; \ d.VIS_W64(0) |= F(s.VIS_W64(1), d.VIS_W64(1)) ? 2 : 0; \ @@ -381,12 +350,12 @@ VIS_HELPER(helper_fpsub, FSUB) return d.ll; \ } \ \ - uint64_t name##32(CPUState *env) \ + uint64_t name##32(uint64_t src1, uint64_t src2) \ { \ VIS64 s, d; \ \ - s.d = DT0; \ - d.d = DT1; \ + s.ll = src1; \ + d.ll = src2; \ \ d.VIS_L64(0) = F(s.VIS_L64(0), d.VIS_L64(0)) ? 1 : 0; \ d.VIS_L64(0) |= F(s.VIS_L64(1), d.VIS_L64(1)) ? 2 : 0; \ @@ -404,3 +373,117 @@ 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; +} + +uint32_t helper_fpack16(uint64_t gsr, uint64_t rs2) +{ + int scale = (gsr >> 3) & 0xf; + uint32_t ret = 0; + int byte; + + for (byte = 0; byte < 4; byte++) { + uint32_t val; + int16_t src = rs2 >> (byte * 16); + int32_t scaled = src << scale; + int32_t from_fixed = scaled >> 7; + + val = (from_fixed < 0 ? 0 : + from_fixed > 255 ? 255 : from_fixed); + + ret |= val << (8 * byte); + } + + return ret; +} + +uint64_t helper_fpack32(uint64_t gsr, uint64_t rs1, uint64_t rs2) +{ + int scale = (gsr >> 3) & 0x1f; + uint64_t ret = 0; + int word; + + ret = (rs1 << 8) & ~(0x000000ff000000ffULL); + for (word = 0; word < 2; word++) { + uint64_t val; + int32_t src = rs2 >> (word * 32); + int64_t scaled = (int64_t)src << scale; + int64_t from_fixed = scaled >> 23; + + val = (from_fixed < 0 ? 0 : + (from_fixed > 255) ? 255 : from_fixed); + + ret |= val << (32 * word); + } + + return ret; +} + +uint32_t helper_fpackfix(uint64_t gsr, uint64_t rs2) +{ + int scale = (gsr >> 3) & 0x1f; + uint32_t ret = 0; + int word; + + for (word = 0; word < 2; word++) { + uint32_t val; + int32_t src = rs2 >> (word * 32); + int64_t scaled = src << scale; + int64_t from_fixed = scaled >> 16; + + val = (from_fixed < -32768 ? -32768 : + from_fixed > 32767 ? 32767 : from_fixed); + + ret |= (val & 0xffff) << (word * 16); + } + + return ret; +} + +uint64 helper_bshuffle(uint64_t gsr, uint64_t src1, uint64_t src2) +{ + union { + uint64_t ll[2]; + uint8_t b[16]; + } s; + VIS64 r; + uint32_t i, mask, host; + + /* Set up S such that we can index across all of the bytes. */ +#ifdef HOST_WORDS_BIGENDIAN + s.ll[0] = src1; + s.ll[1] = src2; + host = 0; +#else + s.ll[1] = src1; + s.ll[0] = src2; + host = 15; +#endif + mask = gsr >> 32; + + for (i = 0; i < 8; ++i) { + unsigned e = (mask >> (28 - i*4)) & 0xf; + r.VIS_B64(i) = s.b[e ^ host]; + } + + return r.ll; +} |