aboutsummaryrefslogtreecommitdiff
path: root/target/sparc/vis_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-11-04 21:31:54 -0700
committerRichard Henderson <richard.henderson@linaro.org>2024-06-05 09:09:36 -0700
commitb3c934dd3457810b5c0810b0d85cf58dda53d8cd (patch)
tree3b92fcfd2abbbe3b6d9c9004d5dd79e56243ac06 /target/sparc/vis_helper.c
parentb99c1bbddd86d170029c3e7ad45bec55d603b927 (diff)
target/sparc: Implement VIS4 comparisons
VIS4 completes the set, adding missing signed 8-bit ops and missing unsigned 16 and 32-bit ops. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/sparc/vis_helper.c')
-rw-r--r--target/sparc/vis_helper.c170
1 files changed, 129 insertions, 41 deletions
diff --git a/target/sparc/vis_helper.c b/target/sparc/vis_helper.c
index c927a054b8..371f5445a1 100644
--- a/target/sparc/vis_helper.c
+++ b/target/sparc/vis_helper.c
@@ -66,6 +66,7 @@ target_ulong helper_array8(target_ulong rs1, target_ulong rs2)
#define VIS_W64(n) w[3 - (n)]
#define VIS_SW64(n) sw[3 - (n)]
#define VIS_L64(n) l[1 - (n)]
+#define VIS_SL64(n) sl[1 - (n)]
#define VIS_B32(n) b[3 - (n)]
#define VIS_W32(n) w[1 - (n)]
#else
@@ -74,6 +75,7 @@ target_ulong helper_array8(target_ulong rs1, target_ulong rs2)
#define VIS_W64(n) w[n]
#define VIS_SW64(n) sw[n]
#define VIS_L64(n) l[n]
+#define VIS_SL64(n) sl[n]
#define VIS_B32(n) b[n]
#define VIS_W32(n) w[n]
#endif
@@ -84,6 +86,7 @@ typedef union {
uint16_t w[4];
int16_t sw[4];
uint32_t l[2];
+ int32_t sl[2];
uint64_t ll;
float64 d;
} VIS64;
@@ -198,47 +201,6 @@ uint64_t helper_fexpand(uint32_t src2)
return d.ll;
}
-#define VIS_CMPHELPER(name, F) \
- uint64_t name##16(uint64_t src1, uint64_t src2) \
- { \
- VIS64 s, d; \
- \
- 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; \
- d.VIS_W64(0) |= F(s.VIS_W64(2), d.VIS_W64(2)) ? 4 : 0; \
- d.VIS_W64(0) |= F(s.VIS_W64(3), d.VIS_W64(3)) ? 8 : 0; \
- d.VIS_W64(1) = d.VIS_W64(2) = d.VIS_W64(3) = 0; \
- \
- return d.ll; \
- } \
- \
- uint64_t name##32(uint64_t src1, uint64_t src2) \
- { \
- VIS64 s, d; \
- \
- 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; \
- d.VIS_L64(1) = 0; \
- \
- return d.ll; \
- }
-
-#define FCMPGT(a, b) ((a) > (b))
-#define FCMPEQ(a, b) ((a) == (b))
-#define FCMPLE(a, b) ((a) <= (b))
-#define FCMPNE(a, b) ((a) != (b))
-
-VIS_CMPHELPER(helper_fcmpgt, FCMPGT)
-VIS_CMPHELPER(helper_fcmpeq, FCMPEQ)
-VIS_CMPHELPER(helper_fcmple, FCMPLE)
-VIS_CMPHELPER(helper_fcmpne, FCMPNE)
-
uint64_t helper_fcmpeq8(uint64_t src1, uint64_t src2)
{
uint64_t a = src1 ^ src2;
@@ -260,6 +222,25 @@ uint64_t helper_fcmpne8(uint64_t src1, uint64_t src2)
return helper_fcmpeq8(src1, src2) ^ 0xff;
}
+uint64_t helper_fcmple8(uint64_t src1, uint64_t src2)
+{
+ VIS64 s1, s2;
+ uint64_t r = 0;
+
+ s1.ll = src1;
+ s2.ll = src2;
+
+ for (int i = 0; i < 8; ++i) {
+ r |= (s1.VIS_SB64(i) <= s2.VIS_SB64(i)) << i;
+ }
+ return r;
+}
+
+uint64_t helper_fcmpgt8(uint64_t src1, uint64_t src2)
+{
+ return helper_fcmple8(src1, src2) ^ 0xff;
+}
+
uint64_t helper_fcmpule8(uint64_t src1, uint64_t src2)
{
VIS64 s1, s2;
@@ -279,6 +260,113 @@ uint64_t helper_fcmpugt8(uint64_t src1, uint64_t src2)
return helper_fcmpule8(src1, src2) ^ 0xff;
}
+uint64_t helper_fcmpeq16(uint64_t src1, uint64_t src2)
+{
+ uint64_t a = src1 ^ src2;
+ uint64_t m = 0x7fff7fff7fff7fffULL;
+ uint64_t c = ~(((a & m) + m) | a | m);
+
+ /* a...............b...............c...............d............... */
+ c |= c << 15;
+ /* ab..............bc..............cd..............d............... */
+ c |= c << 30;
+ /* abcd............bcd.............cd..............d............... */
+ return c >> 60;
+}
+
+uint64_t helper_fcmpne16(uint64_t src1, uint64_t src2)
+{
+ return helper_fcmpeq16(src1, src2) ^ 0xf;
+}
+
+uint64_t helper_fcmple16(uint64_t src1, uint64_t src2)
+{
+ VIS64 s1, s2;
+ uint64_t r = 0;
+
+ s1.ll = src1;
+ s2.ll = src2;
+
+ for (int i = 0; i < 4; ++i) {
+ r |= (s1.VIS_SW64(i) <= s2.VIS_SW64(i)) << i;
+ }
+ return r;
+}
+
+uint64_t helper_fcmpgt16(uint64_t src1, uint64_t src2)
+{
+ return helper_fcmple16(src1, src2) ^ 0xf;
+}
+
+uint64_t helper_fcmpule16(uint64_t src1, uint64_t src2)
+{
+ VIS64 s1, s2;
+ uint64_t r = 0;
+
+ s1.ll = src1;
+ s2.ll = src2;
+
+ for (int i = 0; i < 4; ++i) {
+ r |= (s1.VIS_W64(i) <= s2.VIS_W64(i)) << i;
+ }
+ return r;
+}
+
+uint64_t helper_fcmpugt16(uint64_t src1, uint64_t src2)
+{
+ return helper_fcmpule16(src1, src2) ^ 0xf;
+}
+
+uint64_t helper_fcmpeq32(uint64_t src1, uint64_t src2)
+{
+ uint64_t a = src1 ^ src2;
+ return ((uint32_t)a == 0) | (a >> 32 ? 0 : 2);
+}
+
+uint64_t helper_fcmpne32(uint64_t src1, uint64_t src2)
+{
+ uint64_t a = src1 ^ src2;
+ return ((uint32_t)a != 0) | (a >> 32 ? 2 : 0);
+}
+
+uint64_t helper_fcmple32(uint64_t src1, uint64_t src2)
+{
+ VIS64 s1, s2;
+ uint64_t r = 0;
+
+ s1.ll = src1;
+ s2.ll = src2;
+
+ for (int i = 0; i < 2; ++i) {
+ r |= (s1.VIS_SL64(i) <= s2.VIS_SL64(i)) << i;
+ }
+ return r;
+}
+
+uint64_t helper_fcmpgt32(uint64_t src1, uint64_t src2)
+{
+ return helper_fcmple32(src1, src2) ^ 3;
+}
+
+uint64_t helper_fcmpule32(uint64_t src1, uint64_t src2)
+{
+ VIS64 s1, s2;
+ uint64_t r = 0;
+
+ s1.ll = src1;
+ s2.ll = src2;
+
+ for (int i = 0; i < 2; ++i) {
+ r |= (s1.VIS_L64(i) <= s2.VIS_L64(i)) << i;
+ }
+ return r;
+}
+
+uint64_t helper_fcmpugt32(uint64_t src1, uint64_t src2)
+{
+ return helper_fcmpule32(src1, src2) ^ 3;
+}
+
uint64_t helper_pdist(uint64_t sum, uint64_t src1, uint64_t src2)
{
int i;