mirror of
git://sourceware.org/git/valgrind.git
synced 2026-01-12 00:19:31 +08:00
s390: Remove S390_NUM_FACILITY_DW; fix testcase stfle.c (BZ 509562)
Now that the stfle insn is available we can use it to tell uas how
many double words are needed to store all facility bits. Hence,
S390_NUM_FACILITY_DW can go.
none/tests/s390x/stfle.c: The bug is here
if (bit_to_test < 64)
return (hoststfle[0] & (1ULL << (63 - bit_to_test)));
else if (bit_to_test < 128)
return (hoststfle[1] & (1ULL << (63 - bit_to_test)));
else if (bit_to_test < 192)
return (hoststfle[2] & (1ULL << (63 - bit_to_test)));
when bit_to_test >= 64. Now fixed and test added.
Part of fixing https://bugs.kde.org/show_bug.cgi?id=509562
This commit is contained in:
@@ -99,9 +99,6 @@
|
||||
/* Number of arguments that can be passed in registers */
|
||||
#define S390_NUM_GPRPARMS 5
|
||||
|
||||
/* Number of double words needed to store all facility bits. */
|
||||
#define S390_NUM_FACILITY_DW 4
|
||||
|
||||
#endif /* __LIBVEX_PUB_S390X_H */
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
@@ -1541,15 +1541,24 @@ Bool VG_(machine_get_hwcaps)( void )
|
||||
VG_(exit)(1);
|
||||
}
|
||||
|
||||
ULong hoststfle[S390_NUM_FACILITY_DW];
|
||||
/* Get number of double words to store all facilities */
|
||||
unsigned long long dummy[1];
|
||||
|
||||
for (i = 0; i < S390_NUM_FACILITY_DW; ++i)
|
||||
register ULong r0 asm("0") = 0;
|
||||
asm volatile(".insn s,0xb2b00000,%0\n" /* stfle */
|
||||
: "=Q" (dummy), "+d"(r0)
|
||||
:
|
||||
: "cc", "memory");
|
||||
UInt num_dw = r0 + 1;
|
||||
|
||||
/* Get the facility bits */
|
||||
ULong hoststfle[num_dw];
|
||||
|
||||
for (i = 0; i < num_dw; ++i)
|
||||
hoststfle[i] = 0;
|
||||
|
||||
register ULong reg0 asm("0") = S390_NUM_FACILITY_DW - 1;
|
||||
|
||||
__asm__(".insn s,0xb2b00000,%0" /* stfle */
|
||||
: "=Q"(hoststfle), "+d"(reg0)
|
||||
: "=Q"(hoststfle), "+d"(r0)
|
||||
:
|
||||
: "cc");
|
||||
|
||||
@@ -1582,7 +1591,6 @@ Bool VG_(machine_get_hwcaps)( void )
|
||||
UChar dw_number = 0;
|
||||
UChar fac_bit = 0;
|
||||
for (i=0; i < sizeof fac_hwcaps / sizeof fac_hwcaps[0]; ++i) {
|
||||
vg_assert(fac_hwcaps[i].facility_bit <= 191); // for now
|
||||
dw_number = fac_hwcaps[i].facility_bit / 64;
|
||||
fac_bit = fac_hwcaps[i].facility_bit % 64;
|
||||
if (hoststfle[dw_number] & (1ULL << (63 - fac_bit))) {
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Number of double words needed to store all facility bits. */
|
||||
#define S390_NUM_FACILITY_DW 4
|
||||
/* Return the number of double words needed to store all facility bits */
|
||||
static unsigned get_num_facility_dw(void)
|
||||
{
|
||||
unsigned long long dummy[1];
|
||||
|
||||
register unsigned long long r0 asm("0") = 0;
|
||||
asm volatile(".insn s,0xb2b00000,%0\n" /* stfle */
|
||||
: "=Q" (dummy), "+d"(r0)
|
||||
:
|
||||
: "cc", "memory");
|
||||
return r0 + 1;
|
||||
}
|
||||
|
||||
unsigned long long stfle(unsigned long dw, unsigned bit_to_test)
|
||||
{
|
||||
unsigned long long hoststfle[S390_NUM_FACILITY_DW];
|
||||
unsigned long long hoststfle[dw];
|
||||
register unsigned long long __nr asm("0") = dw - 1;
|
||||
int cc;
|
||||
|
||||
@@ -16,20 +26,19 @@ unsigned long long stfle(unsigned long dw, unsigned bit_to_test)
|
||||
: "=Q" (*hoststfle), "+d" (__nr), "=d" (cc) : : "cc", "memory");
|
||||
|
||||
printf("the value of cc is %d and #double words is %llu\n", cc, __nr + 1);
|
||||
if (bit_to_test < 64)
|
||||
return (hoststfle[0] & (1ULL << (63 - bit_to_test)));
|
||||
else if (bit_to_test < 128)
|
||||
return (hoststfle[1] & (1ULL << (63 - bit_to_test)));
|
||||
else if (bit_to_test < 192)
|
||||
return (hoststfle[2] & (1ULL << (63 - bit_to_test)));
|
||||
|
||||
printf("code needs to be updated\n");
|
||||
return 0;
|
||||
for (unsigned i = 0; i < dw; ++i) {
|
||||
if (bit_to_test < (i + 1) * 64) {
|
||||
bit_to_test -= i * 64;
|
||||
return (hoststfle[i] & (1ULL << (63 - bit_to_test)));
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
int dw = S390_NUM_FACILITY_DW;
|
||||
int dw = get_num_facility_dw();
|
||||
|
||||
/* Test #1: Make sure STFLE returns sensible values. z/Arch facilities
|
||||
must be present. */
|
||||
@@ -44,6 +53,12 @@ int main()
|
||||
else
|
||||
printf("STFLE facility is not installed\n");
|
||||
|
||||
/* Test #2.1: Test facility 77 which is installed for z196 and later */
|
||||
if (stfle(dw, 77))
|
||||
printf("Facility 77 is installed\n");
|
||||
else
|
||||
printf("Facility 77 is not installed\n");
|
||||
|
||||
/* Test #3: Tell STFLE to only write 1 DW of facility bits. Expected condition
|
||||
code should be 3 because this test is run on those machines only
|
||||
that need 3 do double words to store facility bits. */
|
||||
|
||||
@@ -3,6 +3,8 @@ the value of cc is 0 and #double words is 3
|
||||
The z/Architecture architectural mode is installed and active
|
||||
the value of cc is 0 and #double words is 3
|
||||
STFLE facility is installed
|
||||
the value of cc is 0 and #double words is 3
|
||||
Facility 77 is installed
|
||||
the value of cc is 3 and #double words is 3
|
||||
the value of cc is 3 and #double words is 3
|
||||
The z/Architecture architectural mode is installed and active
|
||||
|
||||
@@ -3,6 +3,8 @@ the value of cc is 0 and #double words is 4
|
||||
The z/Architecture architectural mode is installed and active
|
||||
the value of cc is 0 and #double words is 4
|
||||
STFLE facility is installed
|
||||
the value of cc is 0 and #double words is 4
|
||||
Facility 77 is installed
|
||||
the value of cc is 3 and #double words is 4
|
||||
the value of cc is 3 and #double words is 4
|
||||
The z/Architecture architectural mode is installed and active
|
||||
|
||||
@@ -51,23 +51,33 @@
|
||||
#define GET_HWCAP() 0UL
|
||||
#endif
|
||||
|
||||
/* Number of double words needed to store all facility bits. */
|
||||
#define S390_NUM_FACILITY_DW 3
|
||||
/* Return the number of double words needed to store all facility bits */
|
||||
static unsigned get_num_facility_dw(void)
|
||||
{
|
||||
unsigned long long facilities[1];
|
||||
|
||||
static void clear_facilities(unsigned long long *ret)
|
||||
register unsigned long long r0 asm("0") = 0;
|
||||
asm volatile(".insn s,0xb2b00000,%0\n" /* stfle */
|
||||
: "=Q" (facilities), "+d"(r0)
|
||||
:
|
||||
: "cc", "memory");
|
||||
return r0 + 1;
|
||||
}
|
||||
|
||||
static void clear_facilities(unsigned long long *ret, unsigned num_dw)
|
||||
{
|
||||
unsigned int index;
|
||||
for(index = 0; index < S390_NUM_FACILITY_DW; index++)
|
||||
for(index = 0; index < num_dw; index++)
|
||||
{
|
||||
ret[index] = 0ULL;
|
||||
}
|
||||
}
|
||||
|
||||
void stfle(unsigned long long *ret)
|
||||
void stfle(unsigned long long *ret, unsigned num_dw)
|
||||
{
|
||||
register unsigned long long r0 asm("0") = S390_NUM_FACILITY_DW - 1;
|
||||
register unsigned long long r0 asm("0") = num_dw - 1;
|
||||
asm volatile(".insn s,0xb2b00000,%0\n" /* stfle */
|
||||
: "=m" (*ret), "+d"(r0) :: "cc", "memory");
|
||||
: "=Q" (*ret), "+d"(r0) :: "cc", "memory");
|
||||
}
|
||||
|
||||
|
||||
@@ -217,13 +227,15 @@ static model_info *get_host(void)
|
||||
|
||||
static int go(char *feature, char *cpu)
|
||||
{
|
||||
unsigned long long facilities[S390_NUM_FACILITY_DW];
|
||||
unsigned long long match;
|
||||
model_info *host, *from, *to, *p;
|
||||
char *colon;
|
||||
|
||||
clear_facilities(facilities);
|
||||
stfle(facilities);
|
||||
unsigned num_dw = get_num_facility_dw();
|
||||
unsigned long long facilities[num_dw];
|
||||
|
||||
clear_facilities(facilities, num_dw);
|
||||
stfle(facilities, num_dw);
|
||||
|
||||
if (strcmp(feature, "s390x-vx") == 0 ) {
|
||||
/* VX needs kernel support; thus check the appropriate HWCAP bit. */
|
||||
|
||||
Reference in New Issue
Block a user