Hexagon (target/hexagon) add A5_ACS (vacsh)
Rxx32,Pe4 = vacsh(Rss32, Rtt32) Add compare and select elements of two vectors Test cases in tests/tcg/hexagon/multi_result.c Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1617930474-31979-20-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
dd8705bdf5
commit
da74cd2dce
@ -199,6 +199,11 @@
|
||||
* Mathematical operations with more than one definition require
|
||||
* special handling
|
||||
*/
|
||||
#define fGEN_TCG_A5_ACS(SHORTCODE) \
|
||||
do { \
|
||||
gen_helper_vacsh_pred(PeV, cpu_env, RxxV, RssV, RttV); \
|
||||
gen_helper_vacsh_val(RxxV, cpu_env, RxxV, RssV, RttV); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Approximate reciprocal
|
||||
|
@ -26,6 +26,8 @@ DEF_HELPER_2(commit_store, void, env, int)
|
||||
DEF_HELPER_FLAGS_4(fcircadd, TCG_CALL_NO_RWG_SE, s32, s32, s32, s32, s32)
|
||||
DEF_HELPER_3(sfrecipa, i64, env, f32, f32)
|
||||
DEF_HELPER_2(sfinvsqrta, i64, env, f32)
|
||||
DEF_HELPER_4(vacsh_val, s64, env, s64, s64, s64)
|
||||
DEF_HELPER_FLAGS_4(vacsh_pred, TCG_CALL_NO_RWG_SE, s32, env, s64, s64, s64)
|
||||
|
||||
/* Floating point */
|
||||
DEF_HELPER_2(conv_sf2df, f64, env, f32)
|
||||
|
@ -1240,6 +1240,25 @@ MINMAX(uw,WORD,UWORD,2)
|
||||
#undef VMINORMAX3
|
||||
|
||||
|
||||
Q6INSN(A5_ACS,"Rxx32,Pe4=vacsh(Rss32,Rtt32)",ATTRIBS(),
|
||||
"Add Compare and Select elements of two vectors, record the maximums and the decisions ",
|
||||
{
|
||||
fHIDE(int i;)
|
||||
fHIDE(int xv;)
|
||||
fHIDE(int sv;)
|
||||
fHIDE(int tv;)
|
||||
for (i = 0; i < 4; i++) {
|
||||
xv = (int) fGETHALF(i,RxxV);
|
||||
sv = (int) fGETHALF(i,RssV);
|
||||
tv = (int) fGETHALF(i,RttV);
|
||||
xv = xv + tv; //assumes 17bit datapath
|
||||
sv = sv - tv; //assumes 17bit datapath
|
||||
fSETBIT(i*2, PeV, (xv > sv));
|
||||
fSETBIT(i*2+1,PeV, (xv > sv));
|
||||
fSETHALF(i, RxxV, fSATH(fMAX(xv,sv)));
|
||||
}
|
||||
})
|
||||
|
||||
/**********************************************/
|
||||
/* Vector Min/Max */
|
||||
/**********************************************/
|
||||
|
@ -1017,6 +1017,7 @@ MPY_ENC(M7_dcmpyiwc_acc, "1010","xxxxx","1","0","1","0","10")
|
||||
|
||||
|
||||
|
||||
MPY_ENC(A5_ACS, "1010","xxxxx","0","1","0","1","ee")
|
||||
/*
|
||||
*/
|
||||
|
||||
|
@ -347,6 +347,39 @@ uint64_t HELPER(sfinvsqrta)(CPUHexagonState *env, float32 RsV)
|
||||
return ((uint64_t)RdV << 32) | PeV;
|
||||
}
|
||||
|
||||
int64_t HELPER(vacsh_val)(CPUHexagonState *env,
|
||||
int64_t RxxV, int64_t RssV, int64_t RttV)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int xv = sextract64(RxxV, i * 16, 16);
|
||||
int sv = sextract64(RssV, i * 16, 16);
|
||||
int tv = sextract64(RttV, i * 16, 16);
|
||||
int max;
|
||||
xv = xv + tv;
|
||||
sv = sv - tv;
|
||||
max = xv > sv ? xv : sv;
|
||||
/* Note that fSATH can set the OVF bit in usr */
|
||||
RxxV = deposit64(RxxV, i * 16, 16, fSATH(max));
|
||||
}
|
||||
return RxxV;
|
||||
}
|
||||
|
||||
int32_t HELPER(vacsh_pred)(CPUHexagonState *env,
|
||||
int64_t RxxV, int64_t RssV, int64_t RttV)
|
||||
{
|
||||
int32_t PeV = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int xv = sextract64(RxxV, i * 16, 16);
|
||||
int sv = sextract64(RssV, i * 16, 16);
|
||||
int tv = sextract64(RttV, i * 16, 16);
|
||||
xv = xv + tv;
|
||||
sv = sv - tv;
|
||||
PeV = deposit32(PeV, i * 2, 1, (xv > sv));
|
||||
PeV = deposit32(PeV, i * 2 + 1, 1, (xv > sv));
|
||||
}
|
||||
return PeV;
|
||||
}
|
||||
|
||||
/*
|
||||
* mem_noshuf
|
||||
* Section 5.5 of the Hexagon V67 Programmer's Reference Manual
|
||||
|
@ -45,8 +45,41 @@ static int sfinvsqrta(int Rs, int *pred_result)
|
||||
return result;
|
||||
}
|
||||
|
||||
static long long vacsh(long long Rxx, long long Rss, long long Rtt,
|
||||
int *pred_result, int *ovf_result)
|
||||
{
|
||||
long long result = Rxx;
|
||||
int predval;
|
||||
int usr;
|
||||
|
||||
/*
|
||||
* This instruction can set bit 0 (OVF/overflow) in usr
|
||||
* Clear the bit first, then return that bit to the caller
|
||||
*/
|
||||
asm volatile("r2 = usr\n\t"
|
||||
"r2 = clrbit(r2, #0)\n\t" /* clear overflow bit */
|
||||
"usr = r2\n\t"
|
||||
"%0,p0 = vacsh(%3, %4)\n\t"
|
||||
"%1 = p0\n\t"
|
||||
"%2 = usr\n\t"
|
||||
: "+r"(result), "=r"(predval), "=r"(usr)
|
||||
: "r"(Rss), "r"(Rtt)
|
||||
: "r2", "p0", "usr");
|
||||
*pred_result = predval;
|
||||
*ovf_result = (usr & 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
int err;
|
||||
|
||||
static void check_ll(long long val, long long expect)
|
||||
{
|
||||
if (val != expect) {
|
||||
printf("ERROR: 0x%016llx != 0x%016llx\n", val, expect);
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
static void check(int val, int expect)
|
||||
{
|
||||
if (val != expect) {
|
||||
@ -87,10 +120,46 @@ static void test_sfinvsqrta()
|
||||
check_p(pred_result, 0x0);
|
||||
}
|
||||
|
||||
static void test_vacsh()
|
||||
{
|
||||
long long res64;
|
||||
int pred_result;
|
||||
int ovf_result;
|
||||
|
||||
res64 = vacsh(0x0004000300020001LL,
|
||||
0x0001000200030004LL,
|
||||
0x0000000000000000LL, &pred_result, &ovf_result);
|
||||
check_ll(res64, 0x0004000300030004LL);
|
||||
check_p(pred_result, 0xf0);
|
||||
check(ovf_result, 0);
|
||||
|
||||
res64 = vacsh(0x0004000300020001LL,
|
||||
0x0001000200030004LL,
|
||||
0x000affff000d0000LL, &pred_result, &ovf_result);
|
||||
check_ll(res64, 0x000e0003000f0004LL);
|
||||
check_p(pred_result, 0xcc);
|
||||
check(ovf_result, 0);
|
||||
|
||||
res64 = vacsh(0x00047fff00020001LL,
|
||||
0x00017fff00030004LL,
|
||||
0x000a0fff000d0000LL, &pred_result, &ovf_result);
|
||||
check_ll(res64, 0x000e7fff000f0004LL);
|
||||
check_p(pred_result, 0xfc);
|
||||
check(ovf_result, 1);
|
||||
|
||||
res64 = vacsh(0x0004000300020001LL,
|
||||
0x0001000200030009LL,
|
||||
0x000affff000d0001LL, &pred_result, &ovf_result);
|
||||
check_ll(res64, 0x000e0003000f0008LL);
|
||||
check_p(pred_result, 0xcc);
|
||||
check(ovf_result, 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_sfrecipa();
|
||||
test_sfinvsqrta();
|
||||
test_vacsh();
|
||||
|
||||
puts(err ? "FAIL" : "PASS");
|
||||
return err;
|
||||
|
Loading…
Reference in New Issue
Block a user