mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
(Maynard Johnson, maynardj@us.ibm.com and Pete Eberlein, eberlein@us.ibm.com) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11338
208 lines
4.8 KiB
C
208 lines
4.8 KiB
C
#include <stdio.h>
|
|
|
|
double foo = -1.0;
|
|
double FRT1;
|
|
double FRT2;
|
|
int base256(int val)
|
|
{
|
|
/* interpret the bitstream representing val as a base 256 number for testing
|
|
* the parity instrs
|
|
*/
|
|
int sum = 0;
|
|
int scale = 1;
|
|
int i;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
int bit = val & 1;
|
|
sum = sum + bit * scale;
|
|
val <<= 1;
|
|
scale *= 256;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
void test_parity_instrs()
|
|
{
|
|
unsigned long long_word;
|
|
unsigned int word;
|
|
int i, parity;
|
|
|
|
for (i = 0; i < 50; i++) {
|
|
word = base256(i);
|
|
long_word = word;
|
|
__asm__ volatile ("prtyd %0, %1":"=r" (parity):"r"(long_word));
|
|
printf("prtyd (%x) => parity=%x\n", i, parity);
|
|
__asm__ volatile ("prtyw %0, %1":"=r" (parity):"r"(word));
|
|
printf("prtyw (%x) => parity=%x\n", i, parity);
|
|
}
|
|
}
|
|
|
|
void test_lfiwax()
|
|
{
|
|
unsigned long base;
|
|
unsigned long offset;
|
|
|
|
typedef struct {
|
|
unsigned int hi;
|
|
unsigned int lo;
|
|
} int_pair_t;
|
|
|
|
int_pair_t *ip;
|
|
foo = -1024.0;
|
|
base = (unsigned long) &foo;
|
|
offset = 0;
|
|
__asm__ volatile ("lfiwax %0, %1, %2":"=f" (FRT1):"r"(base),
|
|
"r"(offset));
|
|
ip = (int_pair_t *) & FRT1;
|
|
printf("lfiwax (%f) => FRT=(%x, %x)\n", foo, ip->hi, ip->lo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* lfdp FPp, DS(RA) : load float double pair
|
|
** FPp = leftmost 64 bits stored at DS(RA)
|
|
** FPp+1= rightmost 64 bits stored at DS(RA)
|
|
** FPp must be an even float register
|
|
*/
|
|
int test_double_pair_instrs()
|
|
{
|
|
typedef struct {
|
|
double hi;
|
|
double lo;
|
|
} dbl_pair_t;
|
|
|
|
/* the following decls are for alignment */
|
|
int i;
|
|
int j;
|
|
int k;
|
|
int l;
|
|
#ifdef __powerpc64__
|
|
int m;
|
|
int n;
|
|
int o;
|
|
#endif
|
|
dbl_pair_t dbl_pair[3]; /* must be quad word aligned */
|
|
unsigned long base;
|
|
unsigned long offset;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
dbl_pair[i].hi = -1024.0 + i;
|
|
dbl_pair[i].lo = 1024.0 + i + 1;
|
|
}
|
|
|
|
__asm__ volatile ("lfdp 10, %0"::"m" (dbl_pair[0]));
|
|
__asm__ volatile ("fmr %0, 10":"=f" (FRT1));
|
|
__asm__ volatile ("fmr %0, 11":"=f" (FRT2));
|
|
printf("lfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
|
|
dbl_pair[0].hi, dbl_pair[0].lo, FRT1, FRT2);
|
|
|
|
|
|
FRT1 = 2.2048;
|
|
FRT2 = -4.1024;
|
|
__asm__ volatile ("fmr 10, %0"::"f" (FRT1));
|
|
__asm__ volatile ("fmr 11, %0"::"f" (FRT2));
|
|
__asm__ volatile ("stfdp 10, %0"::"m" (dbl_pair[1]));
|
|
printf("stfdp (%f, %f) => F_hi=%f, F_lo=%f\n",
|
|
FRT1, FRT2, dbl_pair[1].hi, dbl_pair[1].lo);
|
|
|
|
FRT1 = 0.0;
|
|
FRT2 = -1.0;
|
|
base = (unsigned long) &dbl_pair;
|
|
offset = (unsigned long) &dbl_pair[1] - base;
|
|
__asm__ volatile ("or 20, 0, %0"::"r" (base));
|
|
__asm__ volatile ("or 21, 0, %0"::"r" (offset));
|
|
__asm__ volatile ("lfdpx 10, 20, 21");
|
|
__asm__ volatile ("fmr %0, 10":"=f" (FRT1));
|
|
__asm__ volatile ("fmr %0, 11":"=f" (FRT2));
|
|
printf("lfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
|
|
dbl_pair[1].hi, dbl_pair[1].lo, FRT1, FRT2);
|
|
|
|
FRT1 = 8.2048;
|
|
FRT2 = -16.1024;
|
|
base = (unsigned long) &dbl_pair;
|
|
offset = (unsigned long) &dbl_pair[2] - base;
|
|
__asm__ volatile ("or 20, 0, %0"::"r" (base));
|
|
__asm__ volatile ("or 21, 0, %0"::"r" (offset));
|
|
__asm__ volatile ("fmr %0, 10":"=f" (FRT1));
|
|
__asm__ volatile ("fmr %0, 11":"=f" (FRT2));
|
|
__asm__ volatile ("stfdpx 10, 20, 21");
|
|
printf("stfdpx (%f, %f) => F_hi=%f, F_lo=%f\n",
|
|
FRT1, FRT2, dbl_pair[2].hi, dbl_pair[2].lo);
|
|
#ifdef __powerpc64__
|
|
return i + j + k + l + m + n + o;
|
|
#else
|
|
return i + j + k + l;
|
|
#endif
|
|
}
|
|
|
|
|
|
/* The contents of FRB with bit set 0 set to bit 0 of FRA copied into FRT */
|
|
void test_fcpsgn()
|
|
{
|
|
double A[] = {
|
|
10.101010,
|
|
-0.0,
|
|
0.0,
|
|
-10.101010
|
|
};
|
|
|
|
double B[] = {
|
|
11.111111,
|
|
-0.0,
|
|
0.0,
|
|
-11.111111
|
|
};
|
|
|
|
double FRT, FRA, FRB;
|
|
int i, j;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
FRA = A[i];
|
|
for (j = 0; j < 4; j++) {
|
|
FRB = B[j];
|
|
__asm__ volatile ("fcpsgn %0, %1, %2":"=f" (FRT):"f"(FRA),
|
|
"f"(FRB));
|
|
printf("fcpsgn sign=%f, base=%f => %f\n", FRA, FRB, FRT);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* b0 may be non-zero in lwarx/ldarx Power6 instrs */
|
|
int test_reservation()
|
|
{
|
|
|
|
int RT;
|
|
int i, j;
|
|
unsigned long base;
|
|
unsigned long offset;
|
|
long arr[4] = { 0xdeadbeef, 0xbad0beef, 0xbeefdead, 0xbeef0bad };
|
|
|
|
|
|
base = (unsigned long) &arr;
|
|
offset = (unsigned long) &arr[1] - base;
|
|
__asm__ volatile ("or 20, 0, %0"::"r" (base));
|
|
__asm__ volatile ("or 21, 0, %0"::"r" (offset));
|
|
__asm__ volatile ("lwarx %0, 20, 21, 1":"=r" (RT));
|
|
printf("lwarx => %x\n", RT);
|
|
|
|
#ifdef __powerpc64__
|
|
offset = (unsigned long) &arr[1] - base;
|
|
__asm__ volatile ("or 21, 0, %0"::"r" (offset));
|
|
__asm__ volatile ("ldarx %0, 20, 21, 1":"=r" (RT));
|
|
printf("ldarx => %x\n", RT);
|
|
#endif
|
|
return i + j;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
(void) test_reservation();
|
|
test_fcpsgn();
|
|
(void) test_double_pair_instrs();
|
|
test_lfiwax();
|
|
test_parity_instrs();
|
|
return 0;
|
|
}
|