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>
This commit is contained in:
parent
b99c1bbddd
commit
b3c934dd34
@ -122,19 +122,19 @@ DEF_HELPER_FLAGS_2(fchksm16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fmean16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fslas16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fslas32, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
#define VIS_CMPHELPER(name) \
|
||||
#define VIS_CMPHELPER(name) \
|
||||
DEF_HELPER_FLAGS_2(f##name##8, TCG_CALL_NO_RWG_SE, \
|
||||
i64, i64, i64) \
|
||||
DEF_HELPER_FLAGS_2(f##name##16, TCG_CALL_NO_RWG_SE, \
|
||||
i64, i64, i64) \
|
||||
i64, i64, i64) \
|
||||
DEF_HELPER_FLAGS_2(f##name##32, TCG_CALL_NO_RWG_SE, \
|
||||
i64, i64, i64)
|
||||
VIS_CMPHELPER(cmpgt)
|
||||
VIS_CMPHELPER(cmpeq)
|
||||
VIS_CMPHELPER(cmple)
|
||||
VIS_CMPHELPER(cmpne)
|
||||
DEF_HELPER_FLAGS_2(fcmpeq8, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fcmpne8, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fcmpule8, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fcmpugt8, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
VIS_CMPHELPER(cmpugt)
|
||||
VIS_CMPHELPER(cmpule)
|
||||
DEF_HELPER_FLAGS_2(xmulx, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(xmulxhi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
#endif
|
||||
|
@ -425,6 +425,12 @@ FCMPEq 10 000 cc:2 110101 ..... 0 0101 0111 ..... \
|
||||
FPCMPUGT8 10 ..... 110110 ..... 1 0010 1000 ..... @r_d_d
|
||||
FPCMPNE8 10 ..... 110110 ..... 1 0010 0010 ..... @r_d_d
|
||||
FPCMPEQ8 10 ..... 110110 ..... 1 0010 1010 ..... @r_d_d
|
||||
FPCMPLE8 10 ..... 110110 ..... 0 0011 0100 ..... @r_d_d
|
||||
FPCMPGT8 10 ..... 110110 ..... 0 0011 1100 ..... @r_d_d
|
||||
FPCMPULE16 10 ..... 110110 ..... 1 0010 1110 ..... @r_d_d
|
||||
FPCMPUGT16 10 ..... 110110 ..... 1 0010 1011 ..... @r_d_d
|
||||
FPCMPULE32 10 ..... 110110 ..... 1 0010 1111 ..... @r_d_d
|
||||
FPCMPUGT32 10 ..... 110110 ..... 1 0010 1100 ..... @r_d_d
|
||||
|
||||
FMUL8x16 10 ..... 110110 ..... 0 0011 0001 ..... @d_r_d
|
||||
FMUL8x16AU 10 ..... 110110 ..... 0 0011 0011 ..... @d_r_r
|
||||
|
@ -67,15 +67,21 @@
|
||||
# define gen_helper_fcmpeq8 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpeq16 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpeq32 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpgt8 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpgt16 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpgt32 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmple8 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmple16 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmple32 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpne8 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpne16 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpne32 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpule8 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpule16 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpule32 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpugt8 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpugt16 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fcmpugt32 ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fdtox ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fexpand ({ qemu_build_not_reached(); NULL; })
|
||||
# define gen_helper_fmul8sux16 ({ qemu_build_not_reached(); NULL; })
|
||||
@ -5119,16 +5125,22 @@ TRANS(FPCMPLE16, VIS1, do_rdd, a, gen_helper_fcmple16)
|
||||
TRANS(FPCMPNE16, VIS1, do_rdd, a, gen_helper_fcmpne16)
|
||||
TRANS(FPCMPGT16, VIS1, do_rdd, a, gen_helper_fcmpgt16)
|
||||
TRANS(FPCMPEQ16, VIS1, do_rdd, a, gen_helper_fcmpeq16)
|
||||
TRANS(FPCMPULE16, VIS4, do_rdd, a, gen_helper_fcmpule16)
|
||||
TRANS(FPCMPUGT16, VIS4, do_rdd, a, gen_helper_fcmpugt16)
|
||||
|
||||
TRANS(FPCMPLE32, VIS1, do_rdd, a, gen_helper_fcmple32)
|
||||
TRANS(FPCMPNE32, VIS1, do_rdd, a, gen_helper_fcmpne32)
|
||||
TRANS(FPCMPGT32, VIS1, do_rdd, a, gen_helper_fcmpgt32)
|
||||
TRANS(FPCMPEQ32, VIS1, do_rdd, a, gen_helper_fcmpeq32)
|
||||
TRANS(FPCMPULE32, VIS4, do_rdd, a, gen_helper_fcmpule32)
|
||||
TRANS(FPCMPUGT32, VIS4, do_rdd, a, gen_helper_fcmpugt32)
|
||||
|
||||
TRANS(FPCMPEQ8, VIS3B, do_rdd, a, gen_helper_fcmpeq8)
|
||||
TRANS(FPCMPNE8, VIS3B, do_rdd, a, gen_helper_fcmpne8)
|
||||
TRANS(FPCMPULE8, VIS3B, do_rdd, a, gen_helper_fcmpule8)
|
||||
TRANS(FPCMPUGT8, VIS3B, do_rdd, a, gen_helper_fcmpugt8)
|
||||
TRANS(FPCMPLE8, VIS4, do_rdd, a, gen_helper_fcmple8)
|
||||
TRANS(FPCMPGT8, VIS4, do_rdd, a, gen_helper_fcmpgt8)
|
||||
|
||||
TRANS(PDISTN, VIS3, do_rdd, a, gen_op_pdistn)
|
||||
TRANS(XMULX, VIS3, do_rrr, a, gen_helper_xmulx)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user