old-cross-binutils/sim/testsuite/sky/rw-vureg.c

155 lines
3.7 KiB
C

#include <stdio.h>
#include <string.h>
extern void* memcpy( void*, const void*, size_t n );
/* Register offsets within memory-mapped window */
enum
{
VU_REG_VF = 0, /* Start of VF registers */
VU_REG_VI = 0x200, /* Start of VI registers */
VU_REG_MST = 0x300, /* Start of misc registers */
VU_REG_MMC = 0x310,
VU_REG_MCP = 0x320,
VU_REG_MR = 0x330,
VU_REG_MI = 0x340,
VU_REG_MQ = 0x350,
VU_REG_MP = 0x360,
VU_REG_MTPC = 0x3a0,
VU_REG_STAT = 0x3d0, /* Start of special registers */
VU_REG_CIA = 0x3e0,
VU_REG_END = 0x3f0
};
#define VU0_REGISTER_WINDOW_START 0x10000C00
#define VU1_REGISTER_WINDOW_START 0x11007000
struct sreg {
short reg;
char filler[14];
};
struct wreg {
int reg;
char filler[12];
};
struct vuregs {
float f[32][4];
struct sreg i[16];
struct wreg m[16];
} vu[2];
struct vuregs buf;
int main() {
volatile char *vu0, *vu1;
int i, j;
float f;
short s;
int v;
long long int lli;
int error = 0;
vu0 = (char *) VU0_REGISTER_WINDOW_START;
vu1 = (char *) VU1_REGISTER_WINDOW_START;
/* Write VU1 registers using friendly alignments and sizes (common case?).
* At the same time, initialize local (reference) copy of VU0 registers.
*/
printf( "Initialize VU1 registers...\n" );
for( i=0; i<32; i++ )
for( j=0; j<4; j++ ) {
vu[0].f[i][j] = i + j/10.0;
vu[1].f[i][j] = 100.0 + i + j/10.0;
((struct vuregs *) vu1)->f[i][j] = vu[1].f[i][j];
}
for( i=0; i<16; i++ ) {
vu[0].i[i].reg = i;
vu[1].i[i].reg = 100 + i;
((struct vuregs *) vu1)->i[i].reg = 100 + i;
}
for( i=0; i<12; i++ ) {
vu[0].m[i].reg = i;
vu[1].m[i].reg = 100 + i;
((struct vuregs *) vu1)->m[i].reg = 100 + i;
}
/* Blast VU0 registers across using memcpy */
printf( "Initialize VU0 registers...\n" );
memcpy( vu0, &(vu[0]), VU_REG_END );
/* Check VU0 registers using friendly alignment and sizes */
printf( "Check VU0 initial register values...\n" );
for( i=0; i<32; i++ )
for( j=0; j<4; j++ ) {
f = ((struct vuregs *) vu0)->f[i][j];
if( f != vu[0].f[i][j] ) {
printf( "vu0_vf%02d%d: got %f (%x) != %f (%x)\n", i, j,
f, *((int *) &f), vu[0].f[i][j], *((int *) &(vu[0].f[i][j])));
error++;
}
}
for( i=0; i<16; i++ ) {
s = ((struct vuregs *) vu0)->i[i].reg;
if( s != vu[0].i[i].reg ) {
printf( "vu0_vi%02d: got %d (%x) != %d (%x)\n", i,
s, s, vu[0].i[i].reg, vu[0].i[i].reg );
error++;
}
}
for( i=0; i<7; i++ ) {
v = ((struct vuregs *) vu0)->m[i].reg;
if( v != vu[0].m[i].reg ) {
printf( "vu0_misc %2d: got %d (%x) != %d (%x)\n", i,
v, v, vu[0].m[i].reg, vu[0].m[i].reg );
error++;
}
}
/* Load buf from VU1 reg window a double word at a time */
for( i=0; i<VU_REG_END; i+=8 )
*((long long int *) (((char *) &buf) + i))
= *(( long long int *) (vu1 + i));
printf( "Check VU1 initial register values...\n" );
for( i=0; i<32; i++ )
for( j=0; j<4; j++ ) {
if( buf.f[i][j] != vu[1].f[i][j] ) {
printf( "vu1_vf%02d%d: got %f (%x) != %f (%x)\n", i, j,
buf.f[i][j], *((int *) &(buf.f[i][j])),
vu[1].f[i][j], *((int *) &(vu[1].f[i][j])) );
error++;
}
}
for( i=0; i<16; i++ ) {
if( buf.i[i].reg != vu[1].i[i].reg ) {
printf( "vu1_vi%02d: got %d (%x) != %d (%x)\n", i,
buf.i[i].reg, buf.i[i].reg, vu[1].i[i].reg, vu[1].i[i].reg );
error++;
}
}
for( i=0; i<7; i++ ) {
if( buf.m[i].reg != vu[1].m[i].reg ) {
printf( "vu1_misc %d: got %d (%x) != %d (%x)\n", i,
buf.m[i].reg, buf.m[i].reg, vu[1].m[i].reg, vu[1].m[i].reg );
error++;
}
}
if( error ) {
printf( "%d errors detected\n", error );
error = 1;
}
exit( error );
}