f61321eaaf
Mon Apr 20 18:36:50 1998 Frank Ch. Eigler <fche@cygnus.com> * t-cop2b.c (test01): Additional COP2 tests (QMFC2/QMTC2/LQ/SQ). Don't use $1 ($at) register in inline assembly.
190 lines
3.4 KiB
C
190 lines
3.4 KiB
C
/* Copyright (C) 1998 Cygnus Solutions */
|
|
/* COP2 function test, with non-expert inline assembly */
|
|
|
|
|
|
|
|
/* globals */
|
|
|
|
int num_ok = 0;
|
|
int num_errors = 0;
|
|
float data_array[128] __attribute__((aligned(16)));
|
|
|
|
|
|
|
|
/* macros */
|
|
|
|
#define TEST(x) do_test(x, #x, __LINE__)
|
|
|
|
|
|
|
|
/* prototypes */
|
|
|
|
|
|
void enable_cop2();
|
|
void test00();
|
|
void do_test(int ok, const char* test, int line);
|
|
|
|
|
|
|
|
/* Utility functions */
|
|
|
|
void
|
|
enable_cop2()
|
|
{
|
|
asm volatile ("mfc0 $3,$12; dli $2,0x40000000; or $3,$2,$2; mtc0 $3,$12"
|
|
: /* no outputs */
|
|
: /* no inputs */
|
|
: "$3", "$2" /* clobbered */);
|
|
}
|
|
|
|
|
|
void
|
|
do_test(int ok, const char* test, int line)
|
|
{
|
|
static int test_num = 0;
|
|
|
|
printf("[%3d @ %3d] (%s): ", ++test_num, line, test);
|
|
if(ok)
|
|
{
|
|
num_ok ++;
|
|
printf("ok\n");
|
|
}
|
|
else
|
|
{
|
|
num_errors ++;
|
|
printf("ko\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Tests */
|
|
|
|
|
|
/* test00: test LQC2/SQC2 data non-corruption */
|
|
void test00()
|
|
{
|
|
volatile float* data = & data_array[0];
|
|
volatile float* data2 = & data_array[4];
|
|
|
|
/* stuff some initial values */
|
|
data[0] = -10.0;
|
|
data[1] = +10.0;
|
|
data[2] = -20.0;
|
|
data[3] = +20.0;
|
|
|
|
/* save values */
|
|
asm volatile ("lqc2 vf01,%0"
|
|
: /* no output */
|
|
: "m" (data[0]) /* input */
|
|
: "memory" /* clobbered */);
|
|
|
|
/* test no clobbering */
|
|
TEST(data[0] == -10.0f);
|
|
TEST(data[1] == +10.0f);
|
|
TEST(data[2] == -20.0f);
|
|
TEST(data[3] == +20.0f);
|
|
|
|
/* overwrite with VU constants */
|
|
asm volatile ("sqc2 vf00,%0"
|
|
: /* no outputs */
|
|
: "m" (data[0]) /* input */
|
|
: "memory" /* clobbered */);
|
|
|
|
/* test proper values */
|
|
TEST(data[0] == 0.0f);
|
|
TEST(data[1] == 0.5f);
|
|
TEST(data[2] == -1.0f);
|
|
TEST(data[3] == +1.0f);
|
|
|
|
/* read back original array values */
|
|
asm volatile ("sqc2 vf01,%0"
|
|
: /* no outputs */
|
|
: "m" (data2[0]) /* input */
|
|
: "memory" /* clobbered */);
|
|
|
|
/* printf("%f,%f,%f,%f\n", data2[0], data2[1], data2[2], data2[3]); */
|
|
|
|
/* test proper values */
|
|
TEST(data2[0] == -10.0f);
|
|
TEST(data2[1] == +10.0f);
|
|
TEST(data2[2] == -20.0f);
|
|
TEST(data2[3] == +20.0f);
|
|
}
|
|
|
|
|
|
|
|
/* test01: test QMFC2/QMTC2 data non-corruption */
|
|
void test01()
|
|
{
|
|
volatile float* data = & data_array[0];
|
|
volatile float* data2 = & data_array[4];
|
|
|
|
/* stuff some initial values */
|
|
data[0] = -10.0;
|
|
data[1] = +10.0;
|
|
data[2] = -20.0;
|
|
data[3] = +20.0;
|
|
|
|
/* save values */
|
|
asm volatile ("lq $4,%0; qmtc2 $4,vf01"
|
|
: /* no output */
|
|
: "m" (data[0]) /* input */
|
|
: "$4", "memory" /* clobbered */);
|
|
|
|
/* test no clobbering */
|
|
TEST(data[0] == -10.0f);
|
|
TEST(data[1] == +10.0f);
|
|
TEST(data[2] == -20.0f);
|
|
TEST(data[3] == +20.0f);
|
|
|
|
/* overwrite with VU constants */
|
|
asm volatile ("qmfc2 $4,vf00; sq $4,%0"
|
|
: /* no outputs */
|
|
: "m" (data[0]) /* input */
|
|
: "$4", "memory" /* clobbered */);
|
|
|
|
/* test proper values */
|
|
TEST(data[0] == 0.0f);
|
|
TEST(data[1] == 0.5f);
|
|
TEST(data[2] == -1.0f);
|
|
TEST(data[3] == +1.0f);
|
|
|
|
/* read back original array values */
|
|
asm volatile ("qmfc2 $4,vf01; sq $4,%0"
|
|
: /* no outputs */
|
|
: "m" (data2[0]) /* input */
|
|
: "$4", "memory" /* clobbered */);
|
|
|
|
/* printf("%f,%f,%f,%f\n", data2[0], data2[1], data2[2], data2[3]); */
|
|
|
|
/* test proper values */
|
|
TEST(data2[0] == -10.0f);
|
|
TEST(data2[1] == +10.0f);
|
|
TEST(data2[2] == -20.0f);
|
|
TEST(data2[3] == +20.0f);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Mainline */
|
|
|
|
|
|
int main()
|
|
{
|
|
enable_cop2();
|
|
|
|
/* tests */
|
|
test00();
|
|
test01();
|
|
|
|
|
|
/* summarize */
|
|
printf("%d ok, %d bad\n", num_ok, num_errors);
|
|
if(num_errors > 0)
|
|
exit(47);
|
|
else
|
|
exit(0);
|
|
}
|