You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
microwatt/tests/prefix/prefix.c

215 lines
4.0 KiB
C

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "console.h"
#define MSR_LE 0x1
#define MSR_DR 0x10
#define MSR_IR 0x20
#define MSR_SF 0x8000000000000000ul
#define DSISR 18
#define DAR 19
#define SRR0 26
#define SRR1 27
#define PID 48
#define PTCR 464
extern long trapit(long arg, long (*func)(long));
extern long test_paddi(long arg);
extern long test_paddi_r(long arg);
extern long test_paddi_neg(long arg);
extern long test_paddi_mis(long arg);
extern long test_plbz(long arg);
extern long test_pld(long arg);
extern long test_plha(long arg);
extern long test_plhz(long arg);
extern long test_plwa(long arg);
extern long test_plwz(long arg);
extern long test_pstb(long arg);
extern long test_pstd(long arg);
extern long test_psth(long arg);
extern long test_pstw(long arg);
extern long test_plfd(long arg);
static inline unsigned long mfspr(int sprnum)
{
long val;
__asm__ volatile("mfspr %0,%1" : "=r" (val) : "i" (sprnum));
return val;
}
static inline void mtspr(int sprnum, unsigned long val)
{
__asm__ volatile("mtspr %0,%1" : : "i" (sprnum), "r" (val));
}
void print_string(const char *str)
{
for (; *str; ++str)
putchar(*str);
}
void print_hex(unsigned long val, int ndigits, const char *str)
{
int i, x;
for (i = (ndigits - 1) * 4; i >= 0; i -= 4) {
x = (val >> i) & 0xf;
if (x >= 10)
putchar(x + 'a' - 10);
else
putchar(x + '0');
}
print_string(str);
}
// i < 100
void print_test_number(int i)
{
print_string("test ");
putchar(48 + i/10);
putchar(48 + i%10);
putchar(':');
}
long int prefix_test_1(void)
{
long int ret;
ret = trapit(0x321, test_paddi);
if (ret != 0x123456789 + 0x321)
return ret;
ret = trapit(0x322, test_paddi_r);
if (ret != 0x123456789)
return ret;
ret = trapit(0x323, test_paddi_neg);
if (ret != 0x323 - 0x123456789)
return ret;
return 0;
}
double fpvar = 123.456;
long int prefix_test_2(void)
{
long int ret;
double x;
ret = trapit(0x123, test_paddi_mis);
if (ret != 0x600)
return 1;
if (mfspr(SRR0) != (unsigned long)&test_paddi_mis + 8)
return 2;
if (mfspr(SRR1) != (MSR_SF | MSR_LE | (1ul << (63 - 35)) | (1ul << (63 - 34))))
return 3;
ret = trapit((long)&x, test_plfd);
if (ret != 0x800)
return ret;
if (mfspr(SRR0) != (unsigned long)&test_plfd + 8)
return 6;
if (mfspr(SRR1) != (MSR_SF | MSR_LE | (1ul << (63 - 34))))
return 7;
return 0;
}
unsigned char bvar = 0x63;
long lvar = 0xfedcba987654;
unsigned short hvar = 0xffee;
unsigned int wvar = 0x80457788;
long int prefix_test_3(void)
{
long int ret;
long int x;
ret = trapit((long)&x, test_pld);
if (ret)
return ret | 1;
if (x != lvar)
return 2;
ret = trapit(1234, test_pstd);
if (ret)
return ret | 2;
if (lvar != 1234)
return 3;
ret = trapit((long)&x, test_plbz);
if (ret)
return ret | 0x10;
if (x != bvar)
return 0x11;
ret = trapit(0xaa, test_pstb);
if (ret)
return ret | 0x12;
if (bvar != 0xaa)
return 0x13;
ret = trapit((long)&x, test_plhz);
if (ret)
return ret | 0x20;
if (x != hvar)
return 0x21;
ret = trapit((long)&x, test_plha);
if (ret)
return ret | 0x22;
if (x != (signed short)hvar)
return 0x23;
ret = trapit(0x23aa, test_psth);
if (ret)
return ret | 0x24;
if (hvar != 0x23aa)
return 0x25;
ret = trapit((long)&x, test_plwz);
if (ret)
return ret | 0x30;
if (x != wvar)
return 0x31;
ret = trapit((long)&x, test_plwa);
if (ret)
return ret | 0x32;
if (x != (signed int)wvar)
return 0x33;
ret = trapit(0x23aaf44f, test_pstw);
if (ret)
return ret | 0x34;
if (wvar != 0x23aaf44f)
return 0x35;
return 0;
}
int fail = 0;
void do_test(int num, long int (*test)(void))
{
long int ret;
print_test_number(num);
ret = test();
if (ret == 0) {
print_string("PASS\r\n");
} else {
fail = 1;
print_string("FAIL ");
print_hex(ret, 16, " SRR0=");
print_hex(mfspr(SRR0), 16, " SRR1=");
print_hex(mfspr(SRR1), 16, "\r\n");
}
}
int main(void)
{
console_init();
//init_mmu();
do_test(1, prefix_test_1);
do_test(2, prefix_test_2);
do_test(3, prefix_test_3);
return fail;
}