diff --git a/lib/CPUs/MIPS/bsp/examples/Bessel.c b/lib/CPUs/MIPS/bsp/examples/Bessel.c new file mode 100644 index 0000000..080fe17 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/Bessel.c @@ -0,0 +1,87 @@ +/************************************************************************/ +/* Ein Programm zur Berechnung der Bessel-Koeffizienten Jn +/* Dateiname : Bessel.cpp +/* Autoren : T. Burr, J. Ahrensfeld +/* Datum : 28.10.1999 +/* letzte Änderung : 28.01.2000 +/* Version : 1.0 +/************************************************************************/ + +#include "stdio.h" +#include "math.h" +#include "stdlib.h" + + +#define MAX_SUM 25 +#define VERSION "1.0" + +/************************************************************************/ +/* Funktionsdeklarationen */ +/************************************************************************/ +// Fakultätsberechnung +double fak (int N) +{ + int index; + double erg=1; + + for (index = 1; index <= N; index++) + erg = erg * index; + + return erg; +} + +// Bessel() +// Berechnung von Jn von mfm +double bessel(int n, double mfm) +{ + int m; + double Jn=0; + + for (m=0; m < MAX_SUM; m++) + { + Jn = Jn + (pow(-1.0,m)/(fak(m)*fak(m+n))*pow(mfm/2.0,(2*m+n))); + } + return Jn; +} + + +/************************************************************************/ +/* Das Hauptprogramm +/************************************************************************/ +void main() +{ + + int N, Nmax; + double erg; + float mfm; + + printf("\n\t Besselfunktion Version %s",VERSION); + printf("\n\t ~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); + printf("\n\tCopyright by J. Ahrensfeld & T. Burr\n\n"); + +// --------------------------------------------------------------------------------- + // Benutzereingaben + printf("\nBerechnungen fuer J = 0..."); + if(scanf("%d",&Nmax)==0) + exit (-1); + + printf("Bitte Modulationsindex eingeben : "); + if(scanf("%f",&mfm)==0) + exit(-1); + + printf("\n"); + +// --------------------------------------------------------------------------------- + // Berechnung + for (N=0; N <= Nmax; N++) + { + erg = bessel(N,(double)mfm); + printf("J(%d) = %10.8f\n",N,erg); + } + + printf("FERTIG.\n"); + + } + +/************************************************************************/ + diff --git a/lib/CPUs/MIPS/bsp/examples/Makefile b/lib/CPUs/MIPS/bsp/examples/Makefile new file mode 100644 index 0000000..25e78fc --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/Makefile @@ -0,0 +1,112 @@ +TOOLS_DIR=../../tools + +CFLAGS=-G 0 -msoft-float -O2 -march=r3000 -I. +LFLAGS=-G0 -M -T link.ld +LIB_DIRS=-L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/4.3.0 +LIBS=-lc -lm -lgcc + +CC=mipsel-elf-gcc +LD=mipsel-elf-ld + +PROG = hello testbench test_irq dhry queens stanford paranoia rmd160_test Bessel whet phrasen + +all: $(PROG) + +libsys: startup.S init.S kernel.S libsys.c xcpt.c irq.o + $(CC) $(CFLAGS) -c startup.S -o startup.o + $(CC) $(CFLAGS) -c init.S -o init.o + $(CC) $(CFLAGS) -c kernel.S -o kernel.o + $(CC) $(CFLAGS) -c libsys.c -o libsys.o + $(CC) $(CFLAGS) -c xcpt.c -o xcpt.o + $(CC) $(CFLAGS) -c irq.c -o irq.o + +hello: libsys hello.c + $(CC) $(CFLAGS) -Os -g -c hello.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o hello.o -o hello.elf $(LIBS) >hello.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +testbench: libsys testbench.c + $(CC) $(CFLAGS) -Os -g -c testbench.c paranoia.c -DNOSIGNAL -DBATCHMODE -DNOMAIN + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o paranoia.o testbench.o -o testbench.elf $(LIBS) >testbench.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +test_irq: libsys test_irq.c + $(CC) $(CFLAGS) -Os -g -c test_irq.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o test_irq.o -o test_irq.elf $(LIBS) >test_irq.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +dhry: libsys dhry_1.c dhry_2.c dhry.h + $(CC) $(CFLAGS) -g -DHZ=1000 -c dhry_1.c dhry_2.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o dhry_1.o dhry_2.o -o dhry.elf $(LIBS) >dhry.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +queens: libsys queens.c + $(CC) $(CFLAGS) -DUNIX_Old -DHZ=1000 -g -c queens.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o queens.o -o queens.elf $(LIBS) >queens.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +stanford: libsys stanford.c + $(CC) $(CFLAGS) -g -DHZ=1000 -c stanford.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o stanford.o -o stanford.elf $(LIBS) >stanford.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +paranoia: libsys paranoia.c + $(CC) $(CFLAGS) -DNOSIGNAL -DBATCHMODE -g -c paranoia.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o paranoia.o -o paranoia.elf $(LIBS) >paranoia.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +rmd160_test: libsys rmd160_test.c rmd160.c rmd160.h + $(CC) $(CFLAGS) -DNOSIGNAL -DBATCHMODE -g -c rmd160.c rmd160_test.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o rmd160.o rmd160_test.o -o rmd160_test.elf $(LIBS) >rmd160.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +Bessel: libsys Bessel.c + $(CC) $(CFLAGS) -g -c Bessel.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o Bessel.o -o Bessel.elf $(LIBS) >Bessel.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +whet: libsys whet.c + $(CC) $(CFLAGS) -g -c whet.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o whet.o -o whet.elf $(LIBS) >whet.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +phrasen: libsys phrasen.c + $(CC) $(CFLAGS) -g -c phrasen.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o xcpt.o irq.o libsys.o phrasen.o -o phrasen.elf $(LIBS) >phrasen.map + mipsel-elf-objdump -d $@.elf > $@.dis + mipsel-elf-objcopy $@.elf -O binary $@.bin + mipsel-elf-objcopy -O srec $@.elf $@.srec + $(TOOLS_DIR)/flashgen $@.bin + +clean: + rm -rf *.a *.o *.bin *.map *.dis *.srec *.elf $(PROG) > /dev/null diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader.c b/lib/CPUs/MIPS/bsp/examples/bootloader.c new file mode 100644 index 0000000..525d8b0 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader.c @@ -0,0 +1,403 @@ +#include "libsys.h" +#include "cfiflash.h" + +typedef struct _ssrec_t +{ + UINT32 addr; + UINT32 size; + UINT32 type; + UINT8 *data; + +} srec_t; + +enum srec_type +{ + srec_err, srec_sob, srec_data, srec_rec, srec_eob +}; + +UINT8 h2i(UINT8 *c) +{ + int i; + UINT8 t, b = 0; + + for (i=0; i < 2; i++) + { + t = c[i]; + if (t >= 'A') + t = t - 'A' + 10; + else + t -= '0'; + + b = (b << 4) | t; + } + return b; +} + +int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen) +{ + UINT8 chksum, byte; + int alen, i; + + if (!buflen) + return srec_err; + + pRec->type = srec_rec; + alen = 0; + if ((pBuf[1] > '0') && (pBuf[1] < '4')) + { + alen = pBuf[1] - '0' + 1; + pRec->type = srec_data; + } + else if ((pBuf[1] >= '7') && (pBuf[1] <= '9')) + { + alen = 11 - (pBuf[1] - '0'); + pRec->type = srec_eob; + } + else if (pBuf[1] == '0') + { + alen = 2; + pRec->type = srec_sob; + } + + byte = h2i(&pBuf[2]); + pRec->size = byte; + chksum = byte; + + pRec->addr = 0; + for (i=0; i < alen; i++) + { + byte = h2i(&pBuf[4+2*i]); + pRec->addr = pRec->addr << 8 | byte; + chksum += byte; + } + pRec->size -= (alen+1); + + pRec->data = (UINT8*) &pBuf[4 + 2*alen]; + for (i=0; i < (int)pRec->size; i++) + { + byte = h2i(&pRec->data[2*i]); + pRec->data[i] = byte; + chksum += byte; + } + chksum = ~chksum; + byte = h2i(&pRec->data[2*i]); + if (chksum != byte) + return 0; + + return pRec->type; +} + +int srec_getline(UINT8 *pLine) +{ + char c; + int i = 0; + + do + { + c = readchar(); + + } while ((c != 's') && (c != 'S')); + + while(((c != 0x0D) && (c != 0x0A))) + { + pLine[i++] = c; + c = readchar(); + }; + + return i; +} + +void Exec_at(void *pEntry) +{ + __asm + ( + ".set noreorder\n" + "mfc0 $26, $12\n" // change exception vector + "li $27, 0xFFBFFFFF\n" + "and $26, $27\n" + "mtc0 $26, $12\n" + "jr $4\n" // jump entry + "rfe\n" + ".set reorder\n" + + ); +} + +void PrintCPUinfo(void) +{ + int result, rev_id; + + char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"}; + + // Print Status register + result = CP0_SR_read(); + + sputs("Status : "); + print_word(result); + sputs("\n"); + + // Print Revision + result = CP0_PRID_read(); + rev_id = (result >> 8) & 0xFF; + sputs("CPU type: "); + if ((rev_id > 0) && (rev_id < 0x07)) + { + sputs(cpu_type_str[rev_id]); + sputs(" Rev."); + rev_id = result & 0xFF; + print_byte((char)rev_id); + } + else + sputs("Unknown"); + + sputs("\n"); + +} + + +#define TEST_SIZE (1024*1024) // bytes +//#define TEST_SIZE (1024) // bytes +#define SDRAM_BASE 0x40000000 +#define IMAGE_OFFSET 0x01000000 +#define FLASH_OFFSET 0x00700000 + +int main(int argc, char *argv[]) +{ + UINT8 buf[256]; + srec_t srec; + int result, i; + UINT32 haddr, addr; + flash_t flash; + + volatile UINT32 *pReg = (UINT32*)sys_led_port; + volatile UINT32 *pBtn = (UINT32*)sys_gpio0; + volatile UINT8 *pMem; + volatile UINT32 *pROM32; + volatile UINT32 *pMem32; + volatile UINT32 *pFlash = (UINT32*)sys_flash_io; + volatile UINT32 *pUSB = (UINT32*)sys_usb_data; + + volatile UINT8 *ram8 = (UINT8*)SDRAM_BASE; + volatile UINT16 *ram16 = (UINT16*)SDRAM_BASE; + volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE; + + *pReg = 0; + haddr = 0; +/* + __asm __volatile + ( + ".set noreorder\n" + "li $a0, 0xA0020000\n" + "li $t0, 0x12345678\n" + "li $t1, 0x5555AAAA\n" + "sw $t0, 0($a0)\n" +// "nop\n" + "sw $t1, 4($a0)\n" +// "nop\n" + "lw $v0, 0($a0)\n" +// "nop\n" + "lw $v0, 4($a0)\n" +// "nop\n" + "sw $t0, 0($a0)\n" +// "nop\n" + "lw $v0, 4($a0)\n" +// "nop\n" + "sw $t1, 4($a0)\n" +// "nop\n" + "lw $v0, 0($a0)\n" + ".set reorder\n" + ); + __asm __volatile + ( + ".set noreorder\n" + "lui $v1, 0xA002\n" + "lui $v0,0x70\n" + "ori $v0,$v0,0x70\n" + "sw $v0,0($v1)\n" + "lui $a0,0x4002\n" + "lw $a1,0($v1)\n" + "lw $ra,12($sp)\n" + "lw $s1,8($sp)\n" + "lw $s0,4($sp)\n" + ".set reorder\n" + ); + +*/ +// PrintCPUinfo(); +/* + *(pFlash+0) = 0x12345678; + *(pFlash+1) = 0xAAAA5555; + *(pFlash+2) = 0xFFFF0000; + *(pFlash+3) = 0x0000FFFF; + + *pReg = *(pFlash+0); + *pReg = *(pFlash+1); + *pReg = *(pFlash+2); + *pReg = *(pFlash+3); + + *(pUSB+0) = 0x12345678; + *(pUSB+1) = 0xAAAA5555; + *(pUSB+2) = 0xFFFF0000; + *(pUSB+3) = 0x0000FFFF; + + *pReg = *(pUSB+0); + *pReg = *(pUSB+1); + *pReg = *(pUSB+2); + *pReg = *(pUSB+3); + sputs("BOOT "); + + pMem32 = (UINT32*)0x40000000; + pROM32 = (UINT32*)0x00000000; + for (i=0; i < 0x3500; i+=4) + *pMem32++ = *pROM32++; + + Exec_at((void*)0x40000000); + + + // Memtest BEGIN + sputs("SDRAM Memory Test\r\n"); + sputs("Write (8-Bit access)..."); + for (i=0; i < TEST_SIZE; i++) + ram8[i] = (UINT8)i; + + sputs("done\r\n"); + + sputs("Verify (8-Bit access)..."); + for (i=TEST_SIZE-1; i >= 0; i--) + if (ram8[i] != (UINT8)i) + break; + i++; + if (i) + sputs("failed\r\n"); + else + sputs("passed\r\n"); + + + sputs("Write (16-Bit access)..."); + for (i=0; i < TEST_SIZE/2; i++) + ram16[i] = (UINT16)i; + + sputs("done\r\n"); + + sputs("Verify (16-Bit access)..."); + for (i=TEST_SIZE/2-1; i >= 0; i--) + if (ram16[i] != (UINT16)i) + break; + i++; + if (i) + sputs("failed\r\n"); + else + sputs("passed\r\n"); + + + sputs("Write (32-Bit access)..."); + for (i=0; i < TEST_SIZE/4; i++) + ram32[i] = (UINT32)i; + + sputs("done\r\n"); + + sputs("Verify (32-Bit access)..."); + for (i=TEST_SIZE/4-1; i >= 0; i--) + if (ram32[i] != (UINT32)i) + break; + i++; + if (i) + sputs("failed\r\n"); + else + sputs("passed\r\n"); + + for (i=0; i < TEST_SIZE/4; i++) + ram32[i] = 0; + + // Memtest END + // ---------------------------------------------------------- +*/ + ram32 = (UINT32*)(SDRAM_BASE + IMAGE_OFFSET); + pFlash = (UINT32*)(sys_flash_io + FLASH_OFFSET); + print_word((UINT32)*pBtn); + if (!*pBtn) + { + sputs("Booting from flash.."); + for (i=0; i < TEST_SIZE/4; i++) + ram32[i] = pFlash[i]; + + sputs("done"); + + Exec_at((void*)ram32); + } + else + { + + sputs("SDRAM erase at : "); + print_word((UINT32)ram32); + sputs("\n"); + for (i=0; i < TEST_SIZE/4; i++) + ram32[i] = 0; + + cfi_init(&flash, sys_flash_io); + if (cfi_find(&flash) < 0) + return 1; + + sputs("Found Flash at "); + print_word((UINT32)flash.pBase); + sputs("\n"); + + addr = FLASH_OFFSET; + sputs("Flash erase at : "); + print_word(addr); + sputs("\n"); + cfi_block_erase(&flash, addr/4); + + while(1) + { + sputs("BOOT "); + + while(1) + { + result = srec_getline(buf); + result = decode_srec(&srec, buf, result); + *pReg = 0; + srec.addr += IMAGE_OFFSET; + switch (result) + { + case srec_data: + if ((srec.addr + srec.size) > haddr) + haddr = srec.addr + srec.size; + + pMem = (UINT8*)srec.addr; + for (i=0; i < srec.size; i++) + *pMem++ = srec.data[i]; + + break; + + case srec_eob: + *pReg = 1; + print_word(srec.addr); + sputs(" to "); + print_word(haddr-4); + sputs("\n"); + + addr = FLASH_OFFSET; + sputs("Program Flash at : "); + print_word(addr); + sputs("\n"); + cfi_program_multi(&flash, addr/4, (UINT32*)ram32, TEST_SIZE/4); + + // Exec_at((void*)srec.addr); + break; + + default: + break; + } + if (result == srec_err) + { + *pReg = 0x40000000; + break; + } + + }; + } + } + return 0; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/Makefile b/lib/CPUs/MIPS/bsp/examples/bootloader/Makefile new file mode 100644 index 0000000..7c0ced3 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/Makefile @@ -0,0 +1,30 @@ +ROM_WORDADDR_WIDTH=11 +TOOLS_DIR=../../../tools + +CFLAGS=-G 0 -O2 -I. -I../ -msoft-float -march=r3000 +LFLAGS=-G0 -M -T bootloader.ld +LIB_DIRS=-L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/4.3.0 +LIBS=-lc -lm -lgcc + +CC=mipsel-elf-gcc +LD=mipsel-elf-ld + +all: bootloader + +libsys: startup_boot.S init_boot.S kernel_boot.S libsys_boot.c + $(CC) $(CFLAGS) -c startup_boot.S -o startup.o + $(CC) $(CFLAGS) -c init_boot.S -o init.o + $(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o + $(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o + +bootloader: libsys bootloader.c + $(CC) $(CFLAGS) -g -c bootloader.c + $(CC) $(CFLAGS) -g -c ../cfiflash.c + $(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o cfiflash.o bootloader.o -o bootloader.elf $(LIBS) >bootloader.map + mipsel-elf-objdump -d bootloader.elf > bootloader.dis + mipsel-elf-objcopy bootloader.elf -O binary bootloader.ROM.bin + mipsel-elf-objcopy -O srec bootloader.elf bootloader.srec + $(TOOLS_DIR)/romgen bootloader.ROM.bin $(ROM_WORDADDR_WIDTH) + +clean: + rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.c b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.c new file mode 100644 index 0000000..07c36ed --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.c @@ -0,0 +1,360 @@ +#include "libsys_boot.h" +#include "cfiflash.h" + +typedef struct _ssrec_t +{ + UINT32 addr; + UINT32 size; + UINT32 type; + UINT8 *data; + +} srec_t; + +typedef struct _sflash_img_hdr_t +{ + UINT8 magic[4]; + UINT32 target_addr; + UINT32 img_offset; + UINT32 img_size; + UINT32 hdr_next; + UINT8 img_name[128]; + UINT8 res[108]; + +} flash_img_hdr_t; + +enum srec_type +{ + srec_err, srec_sob, srec_data, srec_rec, srec_eob +}; + +UINT8 h2i(UINT8 *c) +{ + int i; + UINT8 t, b = 0; + + for (i=0; i < 2; i++) + { + t = c[i]; + if (t >= 'A') + t = t - 'A' + 10; + else + t -= '0'; + + b = (b << 4) | t; + } + return b; +} + +int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen) +{ + UINT8 chksum, byte; + int alen, i; + + if (!buflen) + return srec_err; + + pRec->type = srec_rec; + alen = 0; + if ((pBuf[1] > '0') && (pBuf[1] < '4')) + { + alen = pBuf[1] - '0' + 1; + pRec->type = srec_data; + } + else if ((pBuf[1] >= '7') && (pBuf[1] <= '9')) + { + alen = 11 - (pBuf[1] - '0'); + pRec->type = srec_eob; + } + else if (pBuf[1] == '0') + { + alen = 2; + pRec->type = srec_sob; + } + + byte = h2i(&pBuf[2]); + pRec->size = byte; + chksum = byte; + + pRec->addr = 0; + for (i=0; i < alen; i++) + { + byte = h2i(&pBuf[4+2*i]); + pRec->addr = pRec->addr << 8 | byte; + chksum += byte; + } + pRec->size -= (alen+1); + + pRec->data = (UINT8*) &pBuf[4 + 2*alen]; + for (i=0; i < (int)pRec->size; i++) + { + byte = h2i(&pRec->data[2*i]); + pRec->data[i] = byte; + chksum += byte; + } + chksum = ~chksum; + byte = h2i(&pRec->data[2*i]); + if (chksum != byte) + return 0; + + return pRec->type; +} + +int srec_getline(UINT8 *pLine) +{ + char c; + int i = 0; + + do + { + c = readchar(); + + } while ((c != 's') && (c != 'S')); + + while(((c != 0x0D) && (c != 0x0A))) + { + pLine[i++] = c; + c = readchar(); + }; + + return i; +} + +void Jump_to(void *pEntry) +{ + __asm + ( + ".set noreorder\n" + ); + __asm + ( + "jr %[pEntry]\n" // jump entry + : + : [pEntry] "r" (pEntry) + ); + __asm + ( + "nop\n" + ); + __asm + ( + ".set reorder\n" + ); +} + +void Exec_at(void *pEntry) +{ + __asm + ( + ".set noreorder\n" + ); + + __asm + ( + "mfc0 $26, $12\n" // change exception vector + "li $27, 0xFFBFFFFF\n" + "and $26, $27\n" + "mtc0 $26, $12\n" + ); + + __asm + ( + "jr %[pEntry]\n" // jump entry + : + : [pEntry] "r" (pEntry) + ); + + __asm + ( + "rfe\n" + ); + + __asm + ( + ".set reorder\n" + ); +} + +void PrintCPUinfo(void) +{ + int result, rev_id; + + char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"}; + + // Print Status register + result = CP0_SR_read(); + + sputs("Status : "); + print_word(result); + sputs("\n"); + + // Print Revision + result = CP0_PRID_read(); + rev_id = (result >> 8) & 0xFF; + sputs("CPU type: "); + if ((rev_id > 0) && (rev_id < 0x07)) + { + sputs(cpu_type_str[rev_id]); + sputs(" Rev."); + rev_id = result & 0xFF; + print_byte((char)rev_id); + } + else + sputs("Unknown"); + + sputs("\n"); + +} + +#define MAX_IMG_SIZE (1024*1024) // bytes +#define SDRAM_BASE 0x40000000 +#define FLASH_OFFSET 0x00000000 + +int main(int argc, char *argv[]) +{ + UINT8 buf[256]; + srec_t srec; + int result, srec_state, i; + UINT32 haddr; + flash_t flash; + flash_img_hdr_t img_hdr = {0}; + flash_img_hdr_t *pImg_hdr; + UINT32 img_size; + + volatile UINT32 *pReg = (UINT32*)sys_led_port; + volatile UINT32 *pBtn = (UINT32*)sys_gpio0; + volatile UINT8 *pMem; + volatile UINT32 *pROM32; + volatile UINT32 *pMem32; + volatile UINT32 *pFlash = (UINT32*)sys_flash_io; + volatile UINT32 *pUSB = (UINT32*)sys_usb_data; + + volatile UINT8 *ram8 = (UINT8*)SDRAM_BASE; + volatile UINT16 *ram16 = (UINT16*)SDRAM_BASE; + volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE; + + *pReg = 0; + haddr = 0; + + // ---------------------------------------------------------- + ram32 = (UINT32*)(SDRAM_BASE); + pFlash = (UINT32*)(sys_flash_io + FLASH_OFFSET); + + if (!*pBtn) + { + sputs("\n\n"); + sputs("Booting from flash..."); + + pImg_hdr = (flash_img_hdr_t*)pFlash; + ram32 = (UINT32*)pImg_hdr->target_addr; + pFlash = (UINT32*)(sys_flash_io + pImg_hdr->img_offset); + img_size = pImg_hdr->img_size; + + for (i=0; i < img_size/4; i++) + ram32[i] = pFlash[i]; + + sputs("done\n\n"); + + Exec_at((void*)ram32); + } + else + { + + if (flash_find(&flash, sys_flash_io) < 0) + { + sputs("Cannot find flash device. Exit now!\n\n"); + return 1; + } + + // Erase SDRAM + for (i=0; i < MAX_IMG_SIZE/4; i++) + ram32[i] = 0; + + sputs("\n\n"); + sputs("Booting from UART.."); + + while(1) + { + sputs("."); + while(1) + { + result = srec_getline(buf); + srec_state = decode_srec(&srec, buf, result); + *pReg = 0; + switch (srec_state) + { + case srec_data: + if ((srec.addr + srec.size) > haddr) + haddr = srec.addr + srec.size; + + pMem = (UINT8*)srec.addr; + for (i=0; i < srec.size; i++) + *pMem++ = srec.data[i]; + + break; + + case srec_eob: + sputs("done\n\n"); + + img_hdr.magic[0] = 'J'; + img_hdr.magic[1] = 'F'; + img_hdr.magic[2] = 'I'; + img_hdr.magic[3] = '1'; + img_hdr.target_addr = srec.addr; + img_hdr.img_size = haddr - srec.addr; + img_hdr.img_offset = FLASH_OFFSET + sizeof(flash_img_hdr_t); + img_hdr.hdr_next = FLASH_OFFSET; + + sputs("Flash erase..."); + result = flash_erase(&flash, FLASH_OFFSET, img_hdr.img_size + sizeof(flash_img_hdr_t)); + if (result < 0) + { + sputs("failed!\n"); + break; + } + sputs("done\n"); + + sputs("Flash write..."); + result = flash_program(&flash, FLASH_OFFSET, (UINT8*)&img_hdr, sizeof(flash_img_hdr_t)); + if (result < 0) + { + sputs("failed!\n"); + break; + } + result = flash_program(&flash, img_hdr.img_offset, (UINT8*)ram32, img_hdr.img_size); + if (result < 0) + { + sputs("failed!\n"); + break; + } + sputs("done\n"); + + sputs("Flash verify..."); + result = flash_verify(&flash, img_hdr.img_offset, (UINT8*)ram32, img_hdr.img_size); + if (result < 0) + { + sputs("failed!\n"); + break; + } + sputs("passed\n"); + Jump_to((void*)0xBFC00000); +// sputs("\nPush reset button to boot!\n"); +// *pReg = 1; + + break; + + default: + result = -1; + break; + } + if (result < 0) + { + *pReg = 0x40000000; + break; + } + + }; + } + } + return 0; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.ld b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.ld new file mode 100644 index 0000000..8b2872a --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.ld @@ -0,0 +1,47 @@ +MEMORY +{ + rom : ORIGIN = 0xBFC00000, LENGTH = 0x00002000 /* 8K */ + sram : ORIGIN = 0x40000000, LENGTH = 0x02000000 /* 32M */ +} + +stack_ptr = 0x7FFFFFF0; +baudrate = 0x0D; +sys_led_port = 0xA0000000; +sys_uart_data = 0xA0010000; +sys_uart_stat = 0xA0010004; +sys_uart_baud = 0xA0010008; +sys_timer_usec = 0xA000008; +sys_timer_sec = 0xA000000C; + + +SECTIONS +{ + .stext ORIGIN(rom) : + { + start = ALIGN(4); + entry = ALIGN(4); + _entry = ALIGN(4); + __entry = ALIGN(4); + *(.stext) + } > rom + + .ktext ORIGIN(rom) + 0x180 : + { + *(.ktext) + } > rom + + .text . : + { + *(.text) + } > rom + + .rodata . : + { + *(.rodata*) + } > rom + + .data ORIGIN(rom) : + { + *(.data) + } > rom +} diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/init_boot.S b/lib/CPUs/MIPS/bsp/examples/bootloader/init_boot.S new file mode 100644 index 0000000..c8e3019 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/init_boot.S @@ -0,0 +1,208 @@ + .file "init.S" + + .text + .align 2 + .globl _init + .extern end + +_init: + .set noreorder + + # set uart + la $26, sys_uart_baud + addiu $27, $0, baudrate + sb $27, 0($26) + + # set stack pointer + la $sp, stack_ptr +# j $jmain + + # TEST + li $26, +5 + beqz $26, _terminate + li $26, -5 + beqz $26, _terminate + li $26, 0 + beqz $26, $_L11 + nop + j _terminate + nop +$_L11: + li $26, +5 + li $27, +6 + beq $26, $27, _terminate + li $26, -5 + beq $26, $27, _terminate + li $26, 0 + beq $26, $27, _terminate + li $26, +6 + beq $26, $27, $_L12 + nop + j _terminate + nop +$_L12: + li $26, -5 + bgez $26, _terminate + li $26, +5 + bgez $26, $_L13 + nop + j _terminate +$_L13: li $26, 0 + bgez $26, $_L14 + nop + j _terminate +$_L14: + li $26, -5 + bgtz $26, _terminate + li $26, 0 + bgtz $26, _terminate + li $26, +5 + bgtz $26, $_L15 + nop + j _terminate + +$_L15: + li $26, +5 + blez $26, _terminate + li $26, 0 + blez $26, $_L16 + nop + j _terminate +$_L16: li $26, -5 + blez $26, $_L17 + nop + j _terminate + +$_L17: + li $26, +5 + bltz $26, _terminate + li $26, 0 + bltz $26, _terminate + li $26, -5 + bltz $26, $_L18 + nop + j _terminate +$_L18: + li $26, +5 + li $27, +6 + bne $26, $27, $_L19 + nop + j _terminate +$_L19: li $26, -5 + bne $26, $27, $_L20 + nop + j _terminate +$_L20: li $26, -6 + bne $26, $27, $_L21 + nop + j _terminate +$_L21: li $26, 0 + bne $26, $27, $_L22 + nop + j _terminate +$_L22: li $26, +6 + bne $26, $27, _terminate + li $26, +5 + bnez $26, $_L23 + nop + j _terminate +$_L23: li $26, -5 + bnez $26, $_L24 + nop + j _terminate +$_L24: li $26, 0 + bnez $26, _terminate + +$_L25: + li $27, +5 + sltiu $26,$27,+6 + sltiu $26,$27,-6 + li $27, -5 + sltiu $26,$27,+6 + sltiu $26,$27,-6 + li $27, +6 + sltiu $26,$27,+5 + sltiu $26,$27,-5 + li $27, -6 + sltiu $26,$27,+5 + sltiu $26,$27,-5 + + li $27, +5 + slti $26,$27,+6 + slti $26,$27,-6 + li $27, -5 + slti $26,$27,+6 + slti $26,$27,-6 + li $27, +6 + slti $26,$27,+5 + slti $26,$27,-5 + li $27, -6 + slti $26,$27,+5 + slti $26,$27,-5 + + + li $26, +5 + li $27, +6 + sltu $26,$26,$27 + li $26, +5 + li $27, -6 + sltu $26,$26,$27 + li $26, -5 + li $27, +6 + sltu $26,$26,$27 + li $26, -5 + li $27, -6 + sltu $26,$26,$27 + + li $26, +6 + li $27, +5 + sltu $26,$26,$27 + li $26, +6 + li $27, -5 + sltu $26,$26,$27 + li $26, -6 + li $27, +5 + sltu $26,$26,$27 + li $26, -6 + li $27, -5 + sltu $26,$26,$27 + + li $26, +5 + li $27, +6 + slt $26,$26,$27 + li $26, +5 + li $27, -6 + slt $26,$26,$27 + li $26, -5 + li $27, +6 + slt $26,$26,$27 + li $26, -5 + li $27, -6 + slt $26,$26,$27 + + li $26, +6 + li $27, +5 + slt $26,$26,$27 + li $26, +6 + li $27, -5 + slt $26,$26,$27 + li $26, -6 + li $27, +5 + slt $26,$26,$27 + li $26, -6 + li $27, -5 + slt $26,$26,$27 + + # TEST + + + # jump main +$jmain: la $26, main + jalr $26 + +_terminate: + nop + j _terminate + nop + + .set reorder diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/kernel_boot.S b/lib/CPUs/MIPS/bsp/examples/bootloader/kernel_boot.S new file mode 100644 index 0000000..4829036 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/kernel_boot.S @@ -0,0 +1,45 @@ + .file "kernel.S" + + .section .ktext,"ax" + .align 2 + + .macro kpush reg + addiu $sp, 4 + sw \reg, 0($sp) + .endm + + .macro kpop reg + lw \reg, 0($sp) + addiu $sp, -4 + .endm + +_exc_handler: + + .set noreorder + + # Set Error LED and ExcCode LEDs + # Get Cause + mfc0 $26, $13 + la $27, sys_led_port + srl $26, 2 + andi $26, 0x000F + or $26, $27 + sw $26, 0($27) + + # wait for all interrupts = 0 +$w4x: mfc0 $26, $13 + nop + srl $26, 8 + andi $26, 0xFF + bnez $26, $w4x + nop + + # Get return address + mfc0 $26, $14 + + # Return + nop + jr $26 + rfe + .set reorder + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.c b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.c new file mode 100644 index 0000000..91a99ea --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include +#include "libsys_boot.h" + +// --------------------------------------------------------------------------------- +// MIPS specific +UINT32 CP0_SR_read(void) +{ + UINT32 result; + + __asm + ( + "mfc0 %[val], $12\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_SR_write(UINT32 val) +{ + __asm + ( + "mtc0 %[val], $12\n" + : /* no output */ + : [val] "r" (val) + ); +} + +UINT32 CP0_CR_read(void) +{ + UINT32 result; + + __asm + ( + "mfc0 %[val], $13\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_CR_write(UINT32 val) +{ + __asm + ( + "mtc0 %[val], $13\n" + : + : [val] "r" (val) + ); +} + +UINT32 CP0_PRID_read(void) +{ + UINT32 result; + + __asm + ( + "mfc0 %[val], $15\n" + : [val] "=r" (result) + ); + + return result; +} + +// --------------------------------------------------------------------------------- +char readchar(void) +{ + volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat; + volatile UINT32 *pUART_data = (UINT32*)sys_uart_data; + + while(!(0x10 & *pUART_stat)); + + return (char)*pUART_data; +} + +void writechar(char c) +{ + volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat; + volatile UINT32 *pUART_data = (UINT32*)sys_uart_data; + + while((0x02 & *pUART_stat) != 0); + + *pUART_data = (UINT32)c; +} + +void _putchar(char c) +{ + if (c == 0x0A) + { + writechar(0x0D); + } + writechar(c); +} + +int sputs(char *pStr) +{ + char *start; + start = pStr; + + while(*pStr) + _putchar(*(pStr++)); + + return pStr - start; +} + +void print_byte(char byte) +{ + int i; + unsigned char c, nibble; + + for (i=0; i < 2; i++) + { + nibble = (char)((byte >> 4) & 0xF); + byte <<= 4; + + if (nibble < 10) + c = nibble + '0'; + else + c = nibble + 'A' - 10; + + _putchar(c); + } +} + +void print_word(int word) +{ + int i; + unsigned char c, nibble; + + for (i=0; i < 4; i++) + { + c = (char) (word >> 24); + print_byte(c); + word <<= 8; + } +} + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.h b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.h new file mode 100644 index 0000000..31ab047 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.h @@ -0,0 +1,50 @@ +#ifndef LIBSYS_H +#define LIBSYS_H + +// --------------------------------------------------------- +// Types +// --------------------------------------------------------- +#define INT8 char +#define INT16 short +#define INT32 long +#define UINT8 unsigned char +#define UINT16 unsigned short +#define UINT32 unsigned long +#define INT int +#define UINT unsigned int +#define FLOAT32 float +#define FLOAT64 double + + +#define sys_gpio0 0xA0000000 +#define sys_gpio1 0xA0000004 +#define sys_led_port sys_gpio0 +#define sys_usb_ctrl sys_gpio1 +#define sys_timer_usec 0xA0000008 +#define sys_timer_sec 0xA000000C +#define sys_uart_data 0xA0010000 +#define sys_uart_stat 0xA0010004 +#define sys_uart_baud 0xA0010008 +#define sys_usb_data 0xA0020000 +#define sys_usb_mbx 0xA0020004 +#define sys_usb_addr 0xA0020008 +#define sys_usb_status 0xA002000C +#define sys_flash_io 0xA4000000 + +// MIPS specific +UINT32 CP0_SR_read(void); +void CP0_SR_write(UINT32 val); +UINT32 CP0_CR_read(void); +void CP0_CR_write(UINT32 val); +UINT32 CP0_PRID_read(void); + +// General +char readchar(void); +void writechar(char c); +int write(int file, char *ptr, int len); +int sputs(char *pStr); +void print_byte(char byte); +void print_word(int word); + +#endif // LIBSYS_H + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/startup_boot.S b/lib/CPUs/MIPS/bsp/examples/bootloader/startup_boot.S new file mode 100644 index 0000000..fa88df4 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/startup_boot.S @@ -0,0 +1,25 @@ + .file "startup.S" + + .section .stext,"ax" + .extern _init + .align 2 + +_start: + .set noreorder + + # Set Kernel mode + li $26, 0x1040000C + mtc0 $26, $12 + li $26, 0x00000000 + mtc0 $26, $13 + + mfc0 $26, $15 + nop + mtc0 $26, $31 + + # jump init + la $26, _init + jr $26 + nop + + .set reorder diff --git a/lib/CPUs/MIPS/bsp/examples/cfiflash.c b/lib/CPUs/MIPS/bsp/examples/cfiflash.c new file mode 100644 index 0000000..e022561 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/cfiflash.c @@ -0,0 +1,253 @@ +#include +#include +#include "libsys.h" +#include "cfiflash.h" + +UINT32 cfi_get_status(flash_t *pObj) +{ + volatile UINT32 *pF; + UINT32 status; + + pF = (UINT32*)pObj->pBase; + + *pF = 0x00700070; + + status = *pF; + + *pF = 0x00FF00FF; + + return status; + +} + +void cfi_init(flash_t *pObj, UINT32 base_addr) +{ + int i; + UINT8 *pInfo; + + pObj->pBase = (void*)base_addr; + + pInfo = (UINT8*)&pObj->info; + for (i=0; i < sizeof(flash_info_t); i++) + { + pInfo[i] = 0; + } +} + +UINT32 cfi_find(flash_t *pObj) +{ + int i; + volatile UINT32 *pF; + volatile UINT16 *pF16; + UINT8 qry_ref[12] = {0x51, 0x00, 0x51, 0x00, 0x52, 0x00, 0x52, 0x00, 0x59, 0x00, 0x59, 0x00}; + UINT32 size; + + pF = (UINT32*)pObj->pBase; + pF16 = (UINT16*)pObj->pBase; + + // Look for flash + *pF = 0x00980098; + for (i=0; i < sizeof(qry_ref); i++) + if (((UINT8*)(&pF[0x10]))[i] != qry_ref[i]) + return (UINT32)-1; + + *pF = 0x00FF00FF; + *pF = 0x00900090; + +/* + printf("ManID : %8.8X\n", (UINT32)pF[0]); + printf("Device code : %8.8X\n", (UINT32)pF[1]); + printf("Block info : %8.8X\n", (UINT32)pF[2]); + + printf("VCC(min) : %8.8X\n", (UINT32)pF[0x1B]); + printf("VCC(max) : %8.8X\n", (UINT32)pF[0x1C]); + printf("VPP(min) : %8.8X\n", (UINT32)pF[0x1D]); + printf("VPP(max) : %8.8X\n", (UINT32)pF[0x1E]); + printf("Device Layout : %8.8X\n", (UINT32)pF[0x27]); + printf("Interface type : %8.8X %8.8X\n", (UINT32)pF[0x28], (UINT32)pF[0x29]); + printf("Write buffer size : %8.8X %8.8X\n", (UINT32)pF[0x2A], (UINT32)pF[0x2B]); + printf("Num. erase blocks : %8.8X\n", (UINT32)pF[0x2C]); + printf("Erase block info : %8.8X %8.8X %8.8X %8.8X\n", (UINT32)pF[0x2D], (UINT32)pF[0x2E], (UINT32)pF[0x2F], (UINT32)pF[0x30]); +*/ + pObj->info.num_flash = 2; + pObj->info.if_width = 32; + size = (UINT32)pF16[2*0x27]; + pObj->info.flashsize = pObj->info.num_flash; + for (i=0; i < size; i++) + pObj->info.flashsize *= 2; + + size = (UINT32)(pF16[2*0x2B] << 8 | pF16[2*0x2A]); + pObj->info.wbuf_size = pObj->info.num_flash; + for (i=0; i < size; i++) + pObj->info.wbuf_size *= 2; + + pObj->info.nblocks = pObj->info.num_flash * ((UINT32)(pF16[2*0x2E] << 8 | pF16[2*0x2D]) + 1); + pObj->info.blocksize = pObj->info.num_flash * ((UINT32)(pF16[2*0x30] << 8 | pF16[2*0x2F]) * 256); + + *pF = 0x00FF00FF; + + return 0; +} + +UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index) +{ + volatile UINT32 *pF; + UINT32 status, block_index, block_mask; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return -1; + + block_mask = ((pObj->info.nblocks-1) << 16); + block_index = word_index & block_mask; + + pF[block_index] = 0x00200020; + pF[block_index] = 0x00D000D0; + + do + { + status = pF[block_index]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + pF[block_index] = 0x00FF00FF; + + return 0; +} + +UINT32 cfi_program_single(flash_t *pObj, UINT32 word_index, UINT32 word) +{ + volatile UINT32 *pF; + UINT32 status; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return -1; + + pF[word_index] = 0x00400040; + pF[word_index] = word; + + do + { + status = pF[word_index]; + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + pF[word_index] = 0x00FF00FF; + + return 0; + +} + +UINT32 cfi_program_multi(flash_t *pObj, UINT32 word_index, UINT32 *pWords, UINT32 num_words) +{ + int i, j, k; + volatile UINT32 *pF; + UINT32 status, bcurr, bnext, block_mask, nblock_write, nbuf_write; + + pF = (UINT32*)pObj->pBase; + + if (word_index >= (pObj->info.flashsize/4)) + return -1; + + block_mask = ((pObj->info.nblocks-1) << 16); + + k = 0; + while(num_words) + { + + bcurr = word_index & block_mask; + bnext = bcurr + (1 << 16); + nblock_write = bnext - word_index; + if (nblock_write > num_words) + nblock_write = num_words; + +// printf("bcurr : %8.8X\n", bcurr); +// printf("bnext : %8.8X\n", bnext); +// printf("windex : %8.8X\n", word_index); +// printf("num_words : %d\n", num_words); +// printf("nblock_write : %d\n", nblock_write); + + while(nblock_write) + { + pF[bcurr] = 0x00E800E8; + do + { + status = pF[bcurr]; +// printf("status : %8.8X\n", status); + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + nbuf_write = nblock_write; + if (nblock_write > pObj->info.wbuf_size/4) + nbuf_write = pObj->info.wbuf_size/4; + +// printf("nbuf_write : %d\n", nbuf_write); + + pF[bcurr] = (nbuf_write-1) << 16 | (nbuf_write-1); + + for (j=0; j < nbuf_write; j++) + pF[word_index+j] = pWords[k++]; + + word_index += j; + nblock_write -= j; + num_words -= j; + + pF[bcurr] = 0x00D000D0; + do + { + status = pF[bcurr]; +// printf("status : %8.8X\n", status); + + } while((status & SR_BIT_ISMS) != SR_BIT_ISMS); + + pF[bcurr] = 0x00FF00FF; + } + bcurr = bnext; + } + + return 0; + +} + +UINT32 flash_find(flash_t *pObj, UINT32 base_addr) +{ + cfi_init(pObj, base_addr); + return cfi_find(pObj); +} + +UINT32 flash_erase(flash_t *pObj, UINT32 offset, UINT32 size) +{ + int i; + UINT32 offset_end; + + offset_end = offset + size; + + for (i=offset; i < offset_end; i += pObj->info.blocksize) + if (cfi_block_erase(pObj, i/4) < 0) + return -1; + + return 0; + +} + +UINT32 flash_program(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size) +{ + return cfi_program_multi(pObj, offset/4, (UINT32*)pData, size/4); +} + +UINT32 flash_verify(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size) +{ + int i; + UINT8 *pF; + + pF = (UINT8*)(pObj->pBase + offset); + + for (i=0; i < size; i++) + if (pF[i] != pData[i]) + return -1; + + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/cfiflash.h b/lib/CPUs/MIPS/bsp/examples/cfiflash.h new file mode 100644 index 0000000..1c5a079 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/cfiflash.h @@ -0,0 +1,44 @@ +/************************************************************************/ +#ifndef CFIFLASH_H +#define CFIFLASH_H + +#include "libsys.h" + +#define SR_BIT_DPS 0x00020002 +#define SR_BIT_PSS 0x00040004 +#define SR_BIT_VPENS 0x00080008 +#define SR_BIT_PSLBS 0x00100010 +#define SR_BIT_ECLBS 0x00200020 +#define SR_BIT_ESS 0x00400040 +#define SR_BIT_ISMS 0x00800080 + +typedef struct _sflash_info_t +{ + UINT32 flashsize; + UINT32 blocksize; + UINT32 nblocks; + UINT32 wbuf_size; + UINT32 if_width; + UINT32 num_flash; + +} flash_info_t; + +typedef struct _sflash_t +{ + void *pBase; + flash_info_t info; + +} flash_t; + +void cfi_init(flash_t *pObj, UINT32 base_addr); +UINT32 cfi_find(flash_t *pObj); +UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index); +UINT32 cfi_program_single(flash_t *pObj, UINT32 word_index, UINT32 word); +UINT32 cfi_program_multi(flash_t *pObj, UINT32 word_index, UINT32 *pWords, UINT32 num_words); + +UINT32 flash_find(flash_t *pObj, UINT32 base_addr); +UINT32 flash_erase(flash_t *pObj, UINT32 offset, UINT32 size); +UINT32 flash_program(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size); +UINT32 flash_verify(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size); + +#endif // CFIFLASH_H diff --git a/lib/CPUs/MIPS/bsp/examples/dhry.h b/lib/CPUs/MIPS/bsp/examples/dhry.h new file mode 100644 index 0000000..c8d8f0a --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/dhry.h @@ -0,0 +1,430 @@ +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry.h (part 1 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * Siemens AG, E STE 35 + * Postfach 3240 + * 8520 Erlangen + * Germany (West) + * Phone: [xxx-49]-9131-7-20330 + * (8-17 Central European Time) + * Usenet: ..!mcvax!unido!estevax!weicker + * + * Original Version (in Ada) published in + * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), + * pp. 1013 - 1030, together with the statistics + * on which the distribution of statements etc. is based. + * + * In this C version, the following C library functions are used: + * - strcpy, strcmp (inside the measurement loop) + * - printf, scanf (outside the measurement loop) + * In addition, Berkeley UNIX system calls "times ()" or "time ()" + * are used for execution time measurement. For measurements + * on other systems, these calls have to be changed. + * + * Collection of Results: + * Reinhold Weicker (address see above) and + * + * Rick Richardson + * PC Research. Inc. + * 94 Apple Orchard Drive + * Tinton Falls, NJ 07724 + * Phone: (201) 389-8963 (9-17 EST) + * Usenet: ...!uunet!pcrat!rick + * + * Please send results to Rick Richardson and/or Reinhold Weicker. + * Complete information should be given on hardware and software used. + * Hardware information includes: Machine type, CPU, type and size + * of caches; for microprocessors: clock frequency, memory speed + * (number of wait states). + * Software information includes: Compiler (and runtime library) + * manufacturer and version, compilation switches, OS version. + * The Operating System version may give an indication about the + * compiler; Dhrystone itself performs no OS calls in the measurement loop. + * + * The complete output generated by the program should be mailed + * such that at least some checks for correctness can be made. + * + *************************************************************************** + * + * History: This version C/2.1 has been made for two reasons: + * + * 1) There is an obvious need for a common C version of + * Dhrystone, since C is at present the most popular system + * programming language for the class of processors + * (microcomputers, minicomputers) where Dhrystone is used most. + * There should be, as far as possible, only one C version of + * Dhrystone such that results can be compared without + * restrictions. In the past, the C versions distributed + * by Rick Richardson (Version 1.1) and by Reinhold Weicker + * had small (though not significant) differences. + * + * 2) As far as it is possible without changes to the Dhrystone + * statistics, optimizing compilers should be prevented from + * removing significant statements. + * + * This C version has been developed in cooperation with + * Rick Richardson (Tinton Falls, NJ), it incorporates many + * ideas from the "Version 1.1" distributed previously by + * him over the UNIX network Usenet. + * I also thank Chaim Benedelac (National Semiconductor), + * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), + * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) + * for their help with comments on earlier versions of the + * benchmark. + * + * Changes: In the initialization part, this version follows mostly + * Rick Richardson's version distributed via Usenet, not the + * version distributed earlier via floppy disk by Reinhold Weicker. + * As a concession to older compilers, names have been made + * unique within the first 8 characters. + * Inside the measurement loop, this version follows the + * version previously distributed by Reinhold Weicker. + * + * At several places in the benchmark, code has been added, + * but within the measurement loop only in branches that + * are not executed. The intention is that optimizing compilers + * should be prevented from moving code out of the measurement + * loop, or from removing code altogether. Since the statements + * that are executed within the measurement loop have NOT been + * changed, the numbers defining the "Dhrystone distribution" + * (distribution of statements, operand types and locality) + * still hold. Except for sophisticated optimizing compilers, + * execution times for this version should be the same as + * for previous versions. + * + * Since it has proven difficult to subtract the time for the + * measurement loop overhead in a correct way, the loop check + * has been made a part of the benchmark. This does have + * an impact - though a very minor one - on the distribution + * statistics which have been updated for this version. + * + * All changes within the measurement loop are described + * and discussed in the companion paper "Rationale for + * Dhrystone version 2". + * + * Because of the self-imposed limitation that the order and + * distribution of the executed statements should not be + * changed, there are still cases where optimizing compilers + * may not generate code for some statements. To a certain + * degree, this is unavoidable for small synthetic benchmarks. + * Users of the benchmark are advised to check code listings + * whether code is generated for all statements of Dhrystone. + * + * Version 2.1 is identical to version 2.0 distributed via + * the UNIX network Usenet in March 1988 except that it corrects + * some minor deficiencies that were found by users of version 2.0. + * The only change within the measurement loop is that a + * non-executed "else" part was added to the "if" statement in + * Func_3, and a non-executed "else" part removed from Proc_3. + * + *************************************************************************** + * + * Defines: The following "Defines" are possible: + * -DREG=register (default: Not defined) + * As an approximation to what an average C programmer + * might do, the "register" storage class is applied + * (if enabled by -DREG=register) + * - for local variables, if they are used (dynamically) + * five or more times + * - for parameters if they are used (dynamically) + * six or more times + * Note that an optimal "register" strategy is + * compiler-dependent, and that "register" declarations + * do not necessarily lead to faster execution. + * -DNOSTRUCTASSIGN (default: Not defined) + * Define if the C compiler does not support + * assignment of structures. + * -DNOENUMS (default: Not defined) + * Define if the C compiler does not support + * enumeration types. + * -DTIMES (default) + * -DTIME + * The "times" function of UNIX (returning process times) + * or the "time" function (returning wallclock time) + * is used for measurement. + * For single user machines, "time ()" is adequate. For + * multi-user machines where you cannot get single-user + * access, use the "times ()" function. If you have + * neither, use a stopwatch in the dead of night. + * "printf"s are provided marking the points "Start Timer" + * and "Stop Timer". DO NOT use the UNIX "time(1)" + * command, as this will measure the total time to + * run this program, which will (erroneously) include + * the time to allocate storage (malloc) and to perform + * the initialization. + * -DHZ=nnn + * In Berkeley UNIX, the function "times" returns process + * time in 1/HZ seconds, with HZ = 60 for most systems. + * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY + * A VALUE. + * + *************************************************************************** + * + * Compilation model and measurement (IMPORTANT): + * + * This C version of Dhrystone consists of three files: + * - dhry.h (this file, containing global definitions and comments) + * - dhry_1.c (containing the code corresponding to Ada package Pack_1) + * - dhry_2.c (containing the code corresponding to Ada package Pack_2) + * + * The following "ground rules" apply for measurements: + * - Separate compilation + * - No procedure merging + * - Otherwise, compiler optimizations are allowed but should be indicated + * - Default results are those without register declarations + * See the companion paper "Rationale for Dhrystone Version 2" for a more + * detailed discussion of these ground rules. + * + * For 16-Bit processors (e.g. 80186, 80286), times for all compilation + * models ("small", "medium", "large" etc.) should be given if possible, + * together with a definition of these models for the compiler system used. + * + ************************************************************************** + * + * Dhrystone (C version) statistics: + * + * [Comment from the first distribution, updated for version 2. + * Note that because of language differences, the numbers are slightly + * different from the Ada version.] + * + * The following program contains statements of a high level programming + * language (here: C) in a distribution considered representative: + * + * assignments 52 (51.0 %) + * control statements 33 (32.4 %) + * procedure, function calls 17 (16.7 %) + * + * 103 statements are dynamically executed. The program is balanced with + * respect to the three aspects: + * + * - statement type + * - operand type + * - operand locality + * operand global, local, parameter, or constant. + * + * The combination of these three aspects is balanced only approximately. + * + * 1. Statement Type: + * ----------------- number + * + * V1 = V2 9 + * (incl. V1 = F(..) + * V = Constant 12 + * Assignment, 7 + * with array element + * Assignment, 6 + * with record component + * -- + * 34 34 + * + * X = Y +|-|"&&"|"|" Z 5 + * X = Y +|-|"==" Constant 6 + * X = X +|- 1 3 + * X = Y *|/ Z 2 + * X = Expression, 1 + * two operators + * X = Expression, 1 + * three operators + * -- + * 18 18 + * + * if .... 14 + * with "else" 7 + * without "else" 7 + * executed 3 + * not executed 4 + * for ... 7 | counted every time + * while ... 4 | the loop condition + * do ... while 1 | is evaluated + * switch ... 1 + * break 1 + * declaration with 1 + * initialization + * -- + * 34 34 + * + * P (...) procedure call 11 + * user procedure 10 + * library procedure 1 + * X = F (...) + * function call 6 + * user function 5 + * library function 1 + * -- + * 17 17 + * --- + * 103 + * + * The average number of parameters in procedure or function calls + * is 1.82 (not counting the function values aX * + * + * 2. Operators + * ------------ + * number approximate + * percentage + * + * Arithmetic 32 50.8 + * + * + 21 33.3 + * - 7 11.1 + * * 3 4.8 + * / (int div) 1 1.6 + * + * Comparison 27 42.8 + * + * == 9 14.3 + * /= 4 6.3 + * > 1 1.6 + * < 3 4.8 + * >= 1 1.6 + * <= 9 14.3 + * + * Logic 4 6.3 + * + * && (AND-THEN) 1 1.6 + * | (OR) 1 1.6 + * ! (NOT) 2 3.2 + * + * -- ----- + * 63 100.1 + * + * + * 3. Operand Type (counted once per operand reference): + * --------------- + * number approximate + * percentage + * + * Integer 175 72.3 % + * Character 45 18.6 % + * Pointer 12 5.0 % + * String30 6 2.5 % + * Array 2 0.8 % + * Record 2 0.8 % + * --- ------- + * 242 100.0 % + * + * When there is an access path leading to the final operand (e.g. a record + * component), only the final data type on the access path is counted. + * + * + * 4. Operand Locality: + * ------------------- + * number approximate + * percentage + * + * local variable 114 47.1 % + * global variable 22 9.1 % + * parameter 45 18.6 % + * value 23 9.5 % + * reference 22 9.1 % + * function result 6 2.5 % + * constant 55 22.7 % + * --- ------- + * 242 100.0 % + * + * + * The program does not compute anything meaningful, but it is syntactically + * and semantically correct. All variables have a value assigned to them + * before they are used as a source operand. + * + * There has been no explicit effort to account for the effects of a + * cache, or to balance the use of long or short displacements for code or + * data. + * + *************************************************************************** + */ + +/* Compiler and system dependent definitions: */ + +#ifndef TIME +#undef TIMES +#define TIMES +#endif + /* Use times(2) time function unless */ + /* explicitly defined otherwise */ +#ifdef MSC_CLOCK +#undef HZ +#undef TIMES +#include +#define HZ CLK_TCK +#endif + /* Use Microsoft C hi-res clock */ + +#ifdef TIMES +#include +#include + /* for "times" */ +#endif + +#define Mic_secs_Per_Second 1000000.0 + /* Berkeley UNIX C returns process times in seconds/HZ */ + +#ifdef NOSTRUCTASSIGN +#define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) +#else +#define structassign(d, s) d = s +#endif + +#ifdef NOENUM +#define Ident_1 0 +#define Ident_2 1 +#define Ident_3 2 +#define Ident_4 3 +#define Ident_5 4 + typedef int Enumeration; +#else + typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} + Enumeration; +#endif + /* for boolean and enumeration types in Ada, Pascal */ + +/* General definitions: */ + +#include + /* for strcpy, strcmp */ + +#define Null 0 + /* Value of a Null pointer */ +#define true 1 +#define false 0 + +typedef int One_Thirty; +typedef int One_Fifty; +typedef char Capital_Letter; +typedef int Boolean; +typedef char Str_30 [31]; +typedef int Arr_1_Dim [50]; +typedef int Arr_2_Dim [50] [50]; + +typedef struct record + { + struct record *Ptr_Comp; + Enumeration Discr; + union { + struct { + Enumeration Enum_Comp; + int Int_Comp; + char Str_Comp [31]; + } var_1; + struct { + Enumeration E_Comp_2; + char Str_2_Comp [31]; + } var_2; + struct { + char Ch_1_Comp; + char Ch_2_Comp; + } var_3; + } variant; + } Rec_Type, *Rec_Pointer; + + diff --git a/lib/CPUs/MIPS/bsp/examples/dhry_1.c b/lib/CPUs/MIPS/bsp/examples/dhry_1.c new file mode 100644 index 0000000..f7b8373 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/dhry_1.c @@ -0,0 +1,402 @@ +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry_1.c (part 2 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * + **************************************************************************** + */ + +#include "dhry.h" + +/* Global Variables: */ + +Rec_Pointer Ptr_Glob, + Next_Ptr_Glob; +int Int_Glob; +Boolean Bool_Glob; +char Ch_1_Glob, + Ch_2_Glob; +int Arr_1_Glob [50]; +int Arr_2_Glob [50] [50]; + +extern char *malloc (); +Enumeration Func_1 (); + /* forward declaration necessary since Enumeration may not simply be int */ + +#ifndef REG + Boolean Reg = false; +#define REG + /* REG becomes defined as empty */ + /* i.e. no register variables */ +#else + Boolean Reg = true; +#endif + +/* variables for time measurement: */ + +#ifdef TIMES +struct tms time_info; + /* see library function "times" */ +#define Too_Small_Time (2*HZ) + /* Measurements should last at least about 2 seconds */ +#endif +#ifdef TIME +extern long time(); + /* see library function "time" */ +#define Too_Small_Time 2 + /* Measurements should last at least 2 seconds */ +#endif +#ifdef MSC_CLOCK +extern clock_t clock(); +#define Too_Small_Time (2*HZ) +#endif + +long Begin_Time, + End_Time, + User_Time; +float Microseconds, + Dhrystones_Per_Second; + +/* end of variables for time measurement */ + + +main () +/*****/ + + /* main program, corresponds to procedures */ + /* Main and Proc_0 in the Ada version */ +{ + One_Fifty Int_1_Loc; + REG One_Fifty Int_2_Loc; + One_Fifty Int_3_Loc; + REG char Ch_Index; + Enumeration Enum_Loc; + Str_30 Str_1_Loc; + Str_30 Str_2_Loc; + REG int Run_Index; + REG int Number_Of_Runs; + + /* Initializations */ + + Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + + Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; + Ptr_Glob->Discr = Ident_1; + Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; + Ptr_Glob->variant.var_1.Int_Comp = 40; + strcpy (Ptr_Glob->variant.var_1.Str_Comp, + "DHRYSTONE PROGRAM, SOME STRING"); + strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + + Arr_2_Glob [8][7] = 10; + /* Was missing in published program. Without this statement, */ + /* Arr_2_Glob [8][7] would have an undefined value. */ + /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ + /* overflow may occur for this array element. */ + + /* + printf ("\n"); + printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); + printf ("\n"); + if (Reg) + { + printf ("Program compiled with 'register' attribute\n"); + printf ("\n"); + } + else + { + printf ("Program compiled without 'register' attribute\n"); + printf ("\n"); + } + printf ("Please give the number of runs through the benchmark: "); + { + int n; + scanf ("%d", &n); + Number_Of_Runs = n; + } + printf ("\n"); + */ +#ifdef NRUNS + Number_Of_Runs = NRUNS; +#else + Number_Of_Runs = 2000000; +#endif + printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); + + /***************/ + /* Start timer */ + /***************/ + +#ifdef TIMES + times (&time_info); + Begin_Time = (long) time_info.tms_utime; +#endif +#ifdef TIME + Begin_Time = time ( (long *) 0); +#endif +#ifdef MSC_CLOCK + Begin_Time = clock(); +#endif + + for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) + { + + Proc_5(); + Proc_4(); + /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ + Int_1_Loc = 2; + Int_2_Loc = 3; + strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); + Enum_Loc = Ident_2; + Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); + /* Bool_Glob == 1 */ + while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ + { + Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; + /* Int_3_Loc == 7 */ + Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); + /* Int_3_Loc == 7 */ + Int_1_Loc += 1; + } /* while */ + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); + /* Int_Glob == 5 */ + Proc_1 (Ptr_Glob); + for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) + /* loop body executed twice */ + { + if (Enum_Loc == Func_1 (Ch_Index, 'C')) + /* then, not executed */ + { + Proc_6 (Ident_1, &Enum_Loc); + strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING"); + Int_2_Loc = Run_Index; + Int_Glob = Run_Index; + } + } + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Int_2_Loc = Int_2_Loc * Int_1_Loc; + Int_1_Loc = Int_2_Loc / Int_3_Loc; + Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; + /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ + Proc_2 (&Int_1_Loc); + /* Int_1_Loc == 5 */ + + } /* loop "for Run_Index" */ + + /**************/ + /* Stop timer */ + /**************/ + +#ifdef TIMES + times (&time_info); + End_Time = (long) time_info.tms_utime; +#endif +#ifdef TIME + End_Time = time ( (long *) 0); +#endif +#ifdef MSC_CLOCK + End_Time = clock(); +#endif + /* + printf ("Execution ends\n"); + printf ("\n"); + printf ("Final values of the variables used in the benchmark:\n"); + printf ("\n"); + printf ("Int_Glob: %d\n", Int_Glob); + printf (" should be: %d\n", 5); + printf ("Bool_Glob: %d\n", Bool_Glob); + printf (" should be: %d\n", 1); + printf ("Ch_1_Glob: %c\n", Ch_1_Glob); + printf (" should be: %c\n", 'A'); + printf ("Ch_2_Glob: %c\n", Ch_2_Glob); + printf (" should be: %c\n", 'B'); + printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); + printf (" should be: %d\n", 7); + printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); + printf (" should be: Number_Of_Runs + 10\n"); + printf ("Ptr_Glob->\n"); + printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp); + printf (" should be: (implementation-dependent)\n"); + printf (" Discr: %d\n", Ptr_Glob->Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp); + printf (" should be: %d\n", 2); + printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp); + printf (" should be: %d\n", 17); + printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Next_Ptr_Glob->\n"); + printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp); + printf (" should be: (implementation-dependent), same as above\n"); + printf (" Discr: %d\n", Next_Ptr_Glob->Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp); + printf (" should be: %d\n", 1); + printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp); + printf (" should be: %d\n", 18); + printf (" Str_Comp: %s\n", + Next_Ptr_Glob->variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Int_1_Loc: %d\n", Int_1_Loc); + printf (" should be: %d\n", 5); + printf ("Int_2_Loc: %d\n", Int_2_Loc); + printf (" should be: %d\n", 13); + printf ("Int_3_Loc: %d\n", Int_3_Loc); + printf (" should be: %d\n", 7); + printf ("Enum_Loc: %d\n", Enum_Loc); + printf (" should be: %d\n", 1); + printf ("Str_1_Loc: %s\n", Str_1_Loc); + printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); + printf ("Str_2_Loc: %s\n", Str_2_Loc); + printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); + printf ("\n"); + +*/ + User_Time = End_Time - Begin_Time; + + if (User_Time < Too_Small_Time) + { + printf ("Measured time too small to obtain meaningful results\n"); + printf ("Please increase number of runs\n"); + printf ("\n"); + } + else + { +#ifdef TIME + Microseconds = (float) User_Time * Mic_secs_Per_Second + / (float) Number_Of_Runs; + Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; +#else + Microseconds = (float) User_Time * Mic_secs_Per_Second + / ((float) HZ * ((float) Number_Of_Runs)); + Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs) + / (float) User_Time; +#endif + printf ("Microseconds for one run through Dhrystone: "); + printf ("%6.1f \n", Microseconds); + printf ("Dhrystones per Second: "); + printf ("%6.1f \n", Dhrystones_Per_Second); + printf ("\n"); + printf ("This equals to %6.1f DMIPS\n", Dhrystones_Per_Second/1757); + } + +} + + +Proc_1 (Ptr_Val_Par) +/******************/ + +REG Rec_Pointer Ptr_Val_Par; + /* executed once */ +{ + REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; + /* == Ptr_Glob_Next */ + /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */ + /* corresponds to "rename" in Ada, "with" in Pascal */ + + structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); + Ptr_Val_Par->variant.var_1.Int_Comp = 5; + Next_Record->variant.var_1.Int_Comp + = Ptr_Val_Par->variant.var_1.Int_Comp; + Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; + Proc_3 (&Next_Record->Ptr_Comp); + /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp + == Ptr_Glob->Ptr_Comp */ + if (Next_Record->Discr == Ident_1) + /* then, executed */ + { + Next_Record->variant.var_1.Int_Comp = 6; + Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, + &Next_Record->variant.var_1.Enum_Comp); + Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; + Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, + &Next_Record->variant.var_1.Int_Comp); + } + else /* not executed */ + structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); +} /* Proc_1 */ + + +Proc_2 (Int_Par_Ref) +/******************/ + /* executed once */ + /* *Int_Par_Ref == 1, becomes 4 */ + +One_Fifty *Int_Par_Ref; +{ + One_Fifty Int_Loc; + Enumeration Enum_Loc; + + Int_Loc = *Int_Par_Ref + 10; + do /* executed once */ + if (Ch_1_Glob == 'A') + /* then, executed */ + { + Int_Loc -= 1; + *Int_Par_Ref = Int_Loc - Int_Glob; + Enum_Loc = Ident_1; + } /* if */ + while (Enum_Loc != Ident_1); /* true */ +} /* Proc_2 */ + + +Proc_3 (Ptr_Ref_Par) +/******************/ + /* executed once */ + /* Ptr_Ref_Par becomes Ptr_Glob */ + +Rec_Pointer *Ptr_Ref_Par; + +{ + if (Ptr_Glob != Null) + /* then, executed */ + *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp; + Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); +} /* Proc_3 */ + + +Proc_4 () /* without parameters */ +/*******/ + /* executed once */ +{ + Boolean Bool_Loc; + + Bool_Loc = Ch_1_Glob == 'A'; + Bool_Glob = Bool_Loc | Bool_Glob; + Ch_2_Glob = 'B'; +} /* Proc_4 */ + + +Proc_5 () /* without parameters */ +/*******/ + /* executed once */ +{ + Ch_1_Glob = 'A'; + Bool_Glob = false; +} /* Proc_5 */ + + + /* Procedure for the assignment of structures, */ + /* if the C compiler doesn't support this feature */ +#ifdef NOSTRUCTASSIGN +memcpy (d, s, l) +register char *d; +register char *s; +register int l; +{ + while (l--) *d++ = *s++; +} +#endif + + diff --git a/lib/CPUs/MIPS/bsp/examples/dhry_2.c b/lib/CPUs/MIPS/bsp/examples/dhry_2.c new file mode 100644 index 0000000..63a3d3e --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/dhry_2.c @@ -0,0 +1,192 @@ +/* + **************************************************************************** + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry_2.c (part 3 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * + **************************************************************************** + */ + +#include "dhry.h" + +#ifndef REG +#define REG + /* REG becomes defined as empty */ + /* i.e. no register variables */ +#endif + +extern int Int_Glob; +extern char Ch_1_Glob; + + +Proc_6 (Enum_Val_Par, Enum_Ref_Par) +/*********************************/ + /* executed once */ + /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */ + +Enumeration Enum_Val_Par; +Enumeration *Enum_Ref_Par; +{ + *Enum_Ref_Par = Enum_Val_Par; + if (! Func_3 (Enum_Val_Par)) + /* then, not executed */ + *Enum_Ref_Par = Ident_4; + switch (Enum_Val_Par) + { + case Ident_1: + *Enum_Ref_Par = Ident_1; + break; + case Ident_2: + if (Int_Glob > 100) + /* then */ + *Enum_Ref_Par = Ident_1; + else *Enum_Ref_Par = Ident_4; + break; + case Ident_3: /* executed */ + *Enum_Ref_Par = Ident_2; + break; + case Ident_4: break; + case Ident_5: + *Enum_Ref_Par = Ident_3; + break; + } /* switch */ +} /* Proc_6 */ + + +Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref) +/**********************************************/ + /* executed three times */ + /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */ + /* Int_Par_Ref becomes 7 */ + /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */ + /* Int_Par_Ref becomes 17 */ + /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */ + /* Int_Par_Ref becomes 18 */ +One_Fifty Int_1_Par_Val; +One_Fifty Int_2_Par_Val; +One_Fifty *Int_Par_Ref; +{ + One_Fifty Int_Loc; + + Int_Loc = Int_1_Par_Val + 2; + *Int_Par_Ref = Int_2_Par_Val + Int_Loc; +} /* Proc_7 */ + + +Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val) +/*********************************************************************/ + /* executed once */ + /* Int_Par_Val_1 == 3 */ + /* Int_Par_Val_2 == 7 */ +Arr_1_Dim Arr_1_Par_Ref; +Arr_2_Dim Arr_2_Par_Ref; +int Int_1_Par_Val; +int Int_2_Par_Val; +{ + REG One_Fifty Int_Index; + REG One_Fifty Int_Loc; + + Int_Loc = Int_1_Par_Val + 5; + Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val; + Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc]; + Arr_1_Par_Ref [Int_Loc+30] = Int_Loc; + for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index) + Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc; + Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1; + Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc]; + Int_Glob = 5; +} /* Proc_8 */ + + +Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val) +/*************************************************/ + /* executed three times */ + /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */ + /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */ + /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */ + +Capital_Letter Ch_1_Par_Val; +Capital_Letter Ch_2_Par_Val; +{ + Capital_Letter Ch_1_Loc; + Capital_Letter Ch_2_Loc; + + Ch_1_Loc = Ch_1_Par_Val; + Ch_2_Loc = Ch_1_Loc; + if (Ch_2_Loc != Ch_2_Par_Val) + /* then, executed */ + return (Ident_1); + else /* not executed */ + { + Ch_1_Glob = Ch_1_Loc; + return (Ident_2); + } +} /* Func_1 */ + + +Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref) +/*************************************************/ + /* executed once */ + /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */ + /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */ + +Str_30 Str_1_Par_Ref; +Str_30 Str_2_Par_Ref; +{ + REG One_Thirty Int_Loc; + Capital_Letter Ch_Loc; + + Int_Loc = 2; + while (Int_Loc <= 2) /* loop body executed once */ + if (Func_1 (Str_1_Par_Ref[Int_Loc], + Str_2_Par_Ref[Int_Loc+1]) == Ident_1) + /* then, executed */ + { + Ch_Loc = 'A'; + Int_Loc += 1; + } /* if, while */ + if (Ch_Loc >= 'W' && Ch_Loc < 'Z') + /* then, not executed */ + Int_Loc = 7; + if (Ch_Loc == 'R') + /* then, not executed */ + return (true); + else /* executed */ + { + if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0) + /* then, not executed */ + { + Int_Loc += 7; + Int_Glob = Int_Loc; + return (true); + } + else /* executed */ + return (false); + } /* if Ch_Loc */ +} /* Func_2 */ + + +Boolean Func_3 (Enum_Par_Val) +/***************************/ + /* executed once */ + /* Enum_Par_Val == Ident_3 */ +Enumeration Enum_Par_Val; +{ + Enumeration Enum_Loc; + + Enum_Loc = Enum_Par_Val; + if (Enum_Loc == Ident_3) + /* then, executed */ + return (true); + else /* not executed */ + return (false); +} /* Func_3 */ + diff --git a/lib/CPUs/MIPS/bsp/examples/hello.c b/lib/CPUs/MIPS/bsp/examples/hello.c new file mode 100644 index 0000000..666e985 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/hello.c @@ -0,0 +1,18 @@ +#include "libsys.h" + + +int main (void) +{ + UINT32 *pGPIO0 = (UINT32*)sys_gpio0; + UINT32 *pGPIO1 = (UINT32*)sys_gpio1; + + *pGPIO0 = 0x55555555; + *pGPIO1 = 0x55555555; + + sputs("Hello world!"); + + *pGPIO0 = 0xAAAAAAAA; + *pGPIO1 = 0xAAAAAAAA; + return 0; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/init.S b/lib/CPUs/MIPS/bsp/examples/init.S new file mode 100644 index 0000000..e01bbed --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/init.S @@ -0,0 +1,44 @@ + .file "init.S" + + .text + .align 2 + .globl _init + .extern end + +_init: + .set noreorder + + # set uart + la $8, sys_uart_baud + addiu $9, $0, baudrate + sb $9, 0($8) + + # set stack pointer + la $sp, stack_ptr + + # zero bss + la $8, __bss_start + la $9, __bss_end +$zeroise: + sw $0, 0($8) + bne $8, $9, $zeroise + addiu $8, 4 + + # zero sbss +# la $8, __sbss_start +# la $9, __sbss_end +#$szeroise: +# sw $0, 0($8) +# bne $8, $9, $szeroise +# addiu $8, 4 + + # jump main + la $8, main + jalr $8 + +_terminate: + nop + j _terminate + nop + + .set reorder diff --git a/lib/CPUs/MIPS/bsp/examples/irq.c b/lib/CPUs/MIPS/bsp/examples/irq.c new file mode 100644 index 0000000..a051f58 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/irq.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include "libsys.h" +#include "regdef.h" +#include "xcpt.h" +#include "irq.h" + +static fp_t g_irq_handler[MAX_NUM_IRQ] = {NULL}; + +int _irq_dispatch(struct xcptcontext * xcp) +{ + int i, ip; + + ip = (xcp->cr >> 8) & 0xFF; + + for (i=0; i < MAX_NUM_IRQ; i++) + { + if (ip & 1) + if (g_irq_handler[i]) + (g_irq_handler[i])(); + + ip >>= 1; + } + + return 0; +} + +void interrupt_register(int irq_num, fp_t fp) +{ + if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ)) + g_irq_handler[irq_num] = fp; + +} + +void interrupt_enable(int irq_num) +{ + reg_t reg, im; + + if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ)) + { + im = 1 << irq_num; + reg = CP0_SR_read(); + reg |= (SR_MASK_IM & (im << 8)); + CP0_SR_write(reg); + } + +} + +void interrupt_disable(int irq_num) +{ + reg_t reg, im; + + if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ)) + { + im = 1 << irq_num; + reg = CP0_SR_read(); + reg &= ~(SR_MASK_IM & (im << 8)); + CP0_SR_write(reg); + } +} + +void interrupt_set(int irq_num) +{ + reg_t reg, ip; + + if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ)) + { + ip = 1 << irq_num; + reg = CP0_CR_read(); + reg |= (CR_MASK_IP & (ip << 8)); + CP0_CR_write(reg); + } +} + +void interrupt_clr(int irq_num) +{ + reg_t reg, ip; + + if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ)) + { + ip = 1 << irq_num; + reg = CP0_CR_read(); + reg &= ~(CR_MASK_IP & (ip << 8)); + CP0_CR_write(reg); + } +} + + diff --git a/lib/CPUs/MIPS/bsp/examples/irq.h b/lib/CPUs/MIPS/bsp/examples/irq.h new file mode 100644 index 0000000..73b207d --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/irq.h @@ -0,0 +1,15 @@ +#ifndef IRQ_H +#define IRQ_H + +#include "xcpt.h" + +#define MAX_NUM_IRQ 8 + +typedef void (*fp_t)(void); + +int _irq_dispatch(struct xcptcontext * xcp); +void interrupt_register(int irq_num, fp_t fp); +void interrupt_enable(int irq_num); +void interrupt_disable(int irq_num); + +#endif // IRQ_H diff --git a/lib/CPUs/MIPS/bsp/examples/kernel.S b/lib/CPUs/MIPS/bsp/examples/kernel.S new file mode 100644 index 0000000..bcffffb --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/kernel.S @@ -0,0 +1,180 @@ +#include +#include + + .section .ktext,"ax" + +LEAF(xcptlow_handler) + .set noreorder + .set noat + /* Note: exceptions do not save and restore registers k0 and k1. + * on entry, k1 = exception class. + */ + + /* allocate exception stack frame (on 8-byte boundary) */ + subu k1, sp, XCP_SIZE + srl k1, 3 /* shift right/left -> alligned on boundary */ + sll k1, 3 + + /* save enough registers to get by */ + sw AT, XCP_AT(k1) + sw v0, XCP_V0(k1) + sw v1, XCP_V1(k1) + sw a0, XCP_A0(k1) + sw a1, XCP_A1(k1) + sw a2, XCP_A2(k1) + sw a3, XCP_A3(k1) + sw sp, XCP_SP(k1) + sw ra, XCP_RA(k1) + + /* get coprocessor 0 exception state */ + mfc0 a0, CP0_CR + mfc0 a1, CP0_SR + mfc0 a2, CP0_BADDR + mfc0 a3, CP0_EPC + + /* we can safely use AT now */ + .set at + + /* switch to using sp to point at exception frame */ + move sp, k1 + + /* nothing sensible to store for k0/k1, store zero */ + sw zero, XCP_K0(sp) + sw zero, XCP_K1(sp) + + /* we are now interruptible: dump all remaining state + * into the exception stack frame. + */ + /* coprocessor exception state */ + sw a0, XCP_CR(sp) + sw a1, XCP_SR(sp) + sw a2, XCP_BADDR(sp) + sw a3, XCP_EPC(sp) + + /* mdhi and mdlo */ + mfhi v0 + mflo v1 + sw v0, XCP_MDHI(sp) + sw v1, XCP_MDLO(sp) + + /* Save all the other general registers. + * We save zero, s0-s7 and s8 as well, as instruction emulators (e.g. FP + * operations) and debuggers rely on all registers stored together in + * well-defined structure. + */ + sw zero, XCP_ZERO(sp) + sw t0, XCP_T0(sp) + sw t1, XCP_T1(sp) + sw t2, XCP_T2(sp) + sw t3, XCP_T3(sp) + sw t4, XCP_T4(sp) + sw t5, XCP_T5(sp) + sw t6, XCP_T6(sp) + sw t7, XCP_T7(sp) + sw s0, XCP_S0(sp) + sw s1, XCP_S1(sp) + sw s2, XCP_S2(sp) + sw s3, XCP_S3(sp) + sw s4, XCP_S4(sp) + sw s5, XCP_S5(sp) + sw s6, XCP_S6(sp) + sw s7, XCP_S7(sp) + sw t8, XCP_T8(sp) + sw t9, XCP_T9(sp) + sw gp, XCP_GP(sp) + sw s8, XCP_S8(sp) + + /* I don't know what the following does. [rb] */ + /* load our _gp pointer */ +# la gp, _gp + + /* and call the C exception handler */ + move a0, sp # arg1 = &xcp + subu sp, 16 # (arg save area) + j _xcptcall + move ra, zero # fake return address + + /* This strange call to _xcptcall with zero return address is to + * help exception-aware debuggers to trace back over the exception event. + * We are basically interposing a bogus stackframe (with a zero return + * address) between the C exception handler and the actual machine + * exception. + */ +xcptrest: + .set noat + add AT, sp, 16 + + /* at points to exception frame */ +xcptrestother: + /* restore all state */ + /* restore most general registers */ + lw t0, XCP_T0(AT) + lw t1, XCP_T1(AT) + lw t2, XCP_T2(AT) + lw t3, XCP_T3(AT) + lw t4, XCP_T4(AT) + lw t5, XCP_T5(AT) + lw t6, XCP_T6(AT) + lw t7, XCP_T7(AT) + lw s0, XCP_S0(AT) + lw s1, XCP_S1(AT) + lw s2, XCP_S2(AT) + lw s3, XCP_S3(AT) + lw s4, XCP_S4(AT) + lw s5, XCP_S5(AT) + lw s6, XCP_S6(AT) + lw s7, XCP_S7(AT) + lw t8, XCP_T8(AT) + lw t9, XCP_T9(AT) + lw gp, XCP_GP(AT) + lw s8, XCP_S8(AT) + + /* mdhi and mdlo */ + lw v0, XCP_MDHI(AT) + lw v1, XCP_MDLO(AT) + mthi v0 + mtlo v1 + + /* remaining general registers */ + lw a0, XCP_A0(AT) + lw a1, XCP_A1(AT) + lw a2, XCP_A2(AT) + lw a3, XCP_A3(AT) + lw ra, XCP_RA(AT) + + /* restore the exception-time status register */ + .set noreorder + lw v0, XCP_SR(AT) + nop + mtc0 v0, CP0_SR + lw v1, XCP_V1(AT) + lw v0, XCP_V0(AT) + lw sp, XCP_SP(AT) + + /* we are not uninterruptible and can use k1 safely */ + lw k1, XCP_EPC(AT) + lw AT, XCP_AT(AT) + mtc0 k1, CP0_EPC + j k1 + rfe + + .set reorder + .set at +END(xcptlow_handler) + + +LEAF(_xcptcall) + /* on entry: a0 == &xcp */ + subu sp, 24 + sw ra, 16(sp) + + /* punt out to _xcpt_deliver */ + jal _xcpt_deliver + nop + lw ra, 16(sp) + addu sp, 24 + beqz ra, xcptrest + nop + j ra + nop +END(_xcptcall) diff --git a/lib/CPUs/MIPS/bsp/examples/kernel_sim.S b/lib/CPUs/MIPS/bsp/examples/kernel_sim.S new file mode 100644 index 0000000..4231004 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/kernel_sim.S @@ -0,0 +1,260 @@ + .file "kernel.s" + + .equ stack_ptr, 0x7FFFEFFC + .equ baudrate, 0x0D + .equ sys_led_port, 0xA0000000 + .equ sys_uart_baud, 0xA0000009 + .equ sys_uart_stat, 0xA0000008 + .equ sys_uart_data, 0xA0000004 + .equ sys_timer_sec, 0xA0000014 + .equ sys_timer_usec, 0xA0000010 + + .section .kdata,"a" + .align 2 +_k_stack: .space 256, 0 +_k_msg1: .asciiz "Exception at " +_k_msg2: .asciiz "EPC : " +_k_msg3: .asciiz "Cause : " +_k_msg4: .asciiz "Status : " +_k_msg5: .asciiz "BadVAddr : " +_k_crlf: .asciiz "\r\n" +_k_hextbl: .ascii "0123456789ABCDEF" + + .section .ktext,"ax" + .align 2 + .globl _kputs + + .macro kpush reg + addiu $sp, 4 + sw \reg, 0($sp) + .endm + + .macro kpop reg + lw \reg, 0($sp) + addiu $sp, -4 + .endm + +_exc_handler: + + sw $sp, _k_stack + la $sp, _k_stack + kpush $8 + kpush $9 + kpush $10 + kpush $11 + kpush $12 + kpush $31 + + .set noreorder +# # Get BadVAddr +# mfc0 $10, $8 +# kpush $10 +# # Get Status +# mfc0 $10, $12 +# kpush $10 +# # Get Cause +# mfc0 $10, $13 +# kpush $10 +# srl $10, 29 +# andi $11, $10, 4 +# # Get EPC +# mfc0 $10, $14 +# kpush $10 +# +# # Get real EPC +# addu $10, $11 +# kpush $10 +# +# # set uart +# la $26, sys_uart_baud +# addiu $27, $0, baudrate +# sb $27, 0($26) +# +# # Print CRLF +# la $11, _k_crlf +# jal _kputs +# nop +# +# # Print real EPC +# la $11, _k_msg1 +# jal _kputs +# nop +# kpop $10 +# jal _kprint_word +# nop +# la $11, _k_crlf +# jal _kputs +# nop +# +# # Print EPC +# la $11, _k_msg2 +# jal _kputs +# nop +# kpop $10 +# jal _kprint_word +# nop +# la $11, _k_crlf +# jal _kputs +# nop +# +# # Print Cause +# la $11, _k_msg3 +# jal _kputs +# nop +# kpop $10 +# jal _kprint_word +# nop +# la $11, _k_crlf +# jal _kputs +# nop +# +# # Print Status +# la $11, _k_msg4 +# jal _kputs +# nop +# kpop $10 +# jal _kprint_word +# nop +# la $11, _k_crlf +# jal _kputs +# nop +# +# # Print BadVAddr +# la $11, _k_msg5 +# jal _kputs +# nop +# kpop $10 +# jal _kprint_word +# nop +# la $11, _k_crlf +# jal _kputs +# nop +# + # Set Error LED and ExcCode LEDs + # Get Cause +# mfc0 $26, $13 +# la $27, sys_led_port +# srl $26, 2 +# andi $26, 0x000F +# or $26, $27 +# sw $26, 0($27) + + # wait for all interrupts = 0 +#$w4x: mfc0 $26, $13 +# mfc0 $27, $12 +# srl $26, 8 +# srl $27, 8 +# and $26, $27 +# bnez $26, $w4x + + # Get return address + mfc0 $26, $14 + +$no_int: kpop $31 + kpop $12 + kpop $11 + kpop $10 + kpop $9 + kpop $8 + lw $sp, _k_stack + + # Return + jr $26 + rfe + .set reorder + +# word = $10 +_kprint_word: + .set noreorder + kpush $31 + kpush $10 + srl $10, 16 + jal _kprint_halfword + nop + kpop $10 + jal _kprint_halfword + nop + kpop $31 + jr $31 + nop + .set noreorder + +# halfword = $10 +_kprint_halfword: + .set noreorder + kpush $31 + kpush $10 + srl $10, 8 + jal _kprint_byte + nop + kpop $10 + jal _kprint_byte + nop + kpop $31 + jr $31 + nop + .set noreorder + +# byte = $10 +_kprint_byte: + .set noreorder + kpush $31 + kpush $10 + srl $10, 4 + jal _kprint_nibble + nop + kpop $10 + jal _kprint_nibble + nop + kpop $31 + jr $31 + nop + .set noreorder + +_kprint_nibble: + .set noreorder + kpush $31 + kpush $10 + la $12, _k_hextbl + andi $10, 0xF + addu $12, $10 + lbu $10, 0($12) + jal _ksaus + nop + kpop $10 + kpop $31 + jr $31 + nop + .set noreorder + +# char = $10 +_ksaus: + .set noreorder + la $8, sys_uart_stat + lbu $8, 0($8) + la $9, sys_uart_data + andi $8, 0x02 + bnez $8, _ksaus + nop + j $31 + sb $10, 0($9) + .set reorder + +_kputs: + .set noreorder + kpush $11 + kpush $31 +$kpl: lbu $10, 0($11) + addiu $11, 1 + blez $10, $kpex + nop + jal _ksaus + nop + j $kpl + nop +$kpex: kpop $31 + kpop $11 + jr $31 + nop + .set reorder + diff --git a/lib/CPUs/MIPS/bsp/examples/libsys.c b/lib/CPUs/MIPS/bsp/examples/libsys.c new file mode 100644 index 0000000..a6d706e --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/libsys.c @@ -0,0 +1,440 @@ +#include +#include +#include +#include +#include +#include +#include "libsys.h" + +// --------------------------------------------------------------------------------- +// MIPS specific +UINT32 CP0_SR_read(void) +{ + UINT32 result; + + __asm + ( + "mfc0 %[val], $12\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_SR_write(UINT32 val) +{ + __asm + ( + "mtc0 %[val], $12\n" + : /* no output */ + : [val] "r" (val) + ); +} + +UINT32 CP0_CR_read(void) +{ + UINT32 result; + + __asm + ( + "mfc0 %[val], $13\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_CR_write(UINT32 val) +{ + __asm + ( + "mtc0 %[val], $13\n" + : + : [val] "r" (val) + ); +} + +UINT32 CP0_TR_read(void) +{ + UINT32 result; + + __asm + ( + "mfc0 %[val], $31\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_TR_write(UINT32 val) +{ + __asm + ( + "mtc0 %[val], $31\n" + : + : [val] "r" (val) + ); +} + +UINT32 CP0_PRID_read(void) +{ + UINT32 result; + + __asm + ( + "mfc0 %[val], $15\n" + : [val] "=r" (result) + ); + + return result; +} + +// --------------------------------------------------------------------------------- +char readchar(void) +{ + volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat; + volatile UINT32 *pUART_data = (UINT32*)sys_uart_data; + + while(!(0x10 & *pUART_stat)); + + return (char)*pUART_data; +} + +void writechar(char c) +{ + volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat; + volatile UINT32 *pUART_data = (UINT32*)sys_uart_data; + + while((0x01 & *pUART_stat) != 0); + + *pUART_data = (UINT32)c; +} + +void _putchar(char c) +{ + if (c == 0x0A) + { + writechar(0x0D); + } + writechar(c); +} + +void cg_writechar(char c) +{ + volatile UINT32 *pCG_data = (UINT32*)sys_vga_data; + + while (!(*pCG_data & 1)); + *pCG_data = (UINT32)c; +} + +void cg_clr_line(void) +{ + volatile UINT32 *pCG_clrline = (UINT32*)sys_vga_clrline; + + while (!(*pCG_clrline & 1)); + *pCG_clrline = 1; +} + +void _cg_putchar(char c) +{ + if (c == 0x0A) + { + cg_writechar(0x0D); + } + cg_writechar(c); + if (c == 0x0A) + cg_clr_line(); + +} + +void _exit (int exitcode) +{ + sputs("_exit("); + print_word(exitcode); + sputs(")\n"); + while(1); +} + +void sleep(unsigned ms) +{ + unsigned stop; + struct tms t; + + times(&t); + stop = t.tms_utime + ms; + + do + { + times(&t); + } while (t.tms_utime < stop); + +} + + +int getrusage(int who, struct rusage *usage) +{ + volatile long *pReg_usec = (long*)sys_timer_usec; + volatile long *pReg_sec = (long*)sys_timer_sec; + + // who: RUSAGE_SELF or RUSAGE_CHILDREN + usage->ru_utime.tv_usec = *pReg_usec; + usage->ru_utime.tv_sec = *pReg_sec; + usage->ru_stime.tv_usec = *pReg_usec; + usage->ru_stime.tv_sec = *pReg_sec; +} + +clock_t times(struct tms *buffer) +{ + volatile long *pReg_usec = (long*)sys_timer_usec; + volatile long *pReg_sec = (long*)sys_timer_sec; + long sec; + long usec; + + sec = *pReg_sec; + usec = *pReg_usec; + + if (buffer) + { + buffer->tms_utime = sec*1000 + usec/1000; + buffer->tms_stime = 0; + buffer->tms_cutime = 0; + buffer->tms_cstime = 0; + } + + return (clock_t)sec; +} + +int gettimeofday(struct timeval *tp, void *tzp) +{ + volatile long *pReg_usec = (long*)sys_timer_usec; + volatile long *pReg_sec = (long*)sys_timer_sec; + + if (tp) + { + tp->tv_sec = *pReg_sec; + tp->tv_usec = *pReg_usec; + } + + return 0; +} + +int settimeofday(const struct timeval *tp, const struct timezone *tzp) +{ + volatile long *pReg_usec = (long*)sys_timer_usec; + volatile long *pReg_sec = (long*)sys_timer_sec; + div_t res; + + res = div(tp->tv_usec, 1E6); + + if (tp) + { + *pReg_usec = res.rem; + *pReg_sec = tp->tv_sec + res.quot; + } + + return 0; +} + +caddr_t sbrk(int incr) +{ + extern char end; + static char *heap_end; + char *prev_heap_end; + + if (heap_end == 0) + heap_end = &end; + + prev_heap_end = heap_end; +// if (heap_end + incr > stack_ptr) +// { +// sputs("Heap and stack collision\r\n"); +// abort(); +// } + +// sputs("\n"); +// print_word((int)prev_heap_end); +// sputs("\n"); + heap_end += incr; + return (caddr_t) prev_heap_end; +} + +int fstat(int file, struct stat *st) +{ +// sputs("Fstat()\n"); + st->st_mode = S_IFCHR; + st->st_blksize = 0; + return 0; +} + +int lseek(int file, int ptr, int dir) +{ + sputs("Lseek()\n"); + + errno = ESPIPE; + return -1; +} + +int open(const char *name, int flags, int mode) +{ + sputs("Open()\n"); + errno = EIO; + return -1; +} + +int close(int file) +{ + sputs("Close()\n"); + return 0; +} + +int read(int file, char *ptr, int len) +{ + int i; + +// sputs("Read()\n"); + for (i = 0; i < len; i++) + { + ptr[i] = readchar(); + if ((ptr[i] == '\n') || (ptr[i] == '\r')) + { + i++; + writechar(0x0D); + writechar(0x0A); + break; + } + writechar(ptr[i]); + } + return i; +} + +int write(int file, char *ptr, int len) +{ + int i; + + if (file == 1) + { + for (i=0; i < len; i++) + STDOUT_FUNCTION(*ptr++); + } + if (file == 2) + { + for (i=0; i < len; i++) + STDERR_FUNCTION(*ptr++); + } + return i; +} + +int isatty(int file) +{ +// sputs("Isatty()\n"); + return 1; +} + +int sputs(char *pStr) +{ + char *start; + start = pStr; + + while(*pStr) + _putchar(*(pStr++)); + + return pStr - start; +} + +void print_byte(char byte) +{ + int i; + unsigned char c, nibble; + + for (i=0; i < 2; i++) + { + nibble = (char)((byte >> 4) & 0xF); + byte <<= 4; + + if (nibble < 10) + c = nibble + '0'; + else + c = nibble + 'A' - 10; + + _putchar(c); + } +} + +void print_word(int word) +{ + int i; + unsigned char c, nibble; + + for (i=0; i < 4; i++) + { + c = (char) (word >> 24); + print_byte(c); + word <<= 8; + } +} + +// --------------------------------------------------------------------------------- +// PrintBuffer8() +// Prints byte buffer as hex and ascii interpretation +// --------------------------------------------------------------------------------- +// _Parameters : +// pBuf: : IN: Buffer to display +// nbpr : Number of bytes per row to display +// len : Length of input buffer +// _Return: none +// +// --------------------------------------------------------------------------- +void PrintBuffer8(UINT8 *pBuf, int nbpr, int len) +{ + int i, j, cnt_hex, cnt_asc; + unsigned char c; + + i = j = 0; + cnt_hex = len; + cnt_asc = len; + + do + { + print_word(i); + sputs(": "); + for (j=0; j < nbpr; j++) + { + if (cnt_hex) + { + print_byte(pBuf[i+j]); + sputs(" "); + cnt_hex--; + } + else + { + sputs(" "); + break; + } + + } + + sputs(" "); + for (j=0; j < nbpr; j++) + { + if (cnt_asc) + { + c = pBuf[i+j]; + if((c < 0x20) || (c > 0x7F)) + c = '.'; + + _putchar(c); + cnt_asc--; + } + else + { + sputs(" "); + break; + } + } + sputs("\n"); + i += nbpr; + + } while (cnt_hex); +} + diff --git a/lib/CPUs/MIPS/bsp/examples/libsys.h b/lib/CPUs/MIPS/bsp/examples/libsys.h new file mode 100644 index 0000000..d73b602 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/libsys.h @@ -0,0 +1,77 @@ +#ifndef LIBSYS_H +#define LIBSYS_H + +// --------------------------------------------------------- +// Types +// --------------------------------------------------------- +#define INT8 signed char +#define INT16 signed short +#define INT32 signed int +#define INT64 signed long long +#define UINT8 unsigned char +#define UINT16 unsigned short +#define UINT32 unsigned int +#define UINT64 unsigned long long +#define INT INT32 +#define UINT UINT32 +#define FLOAT32 float +#define FLOAT64 double + + +#define sys_gpio0 0xA0000000 +#define sys_gpio1 0xA0000004 +#define sys_led_port sys_gpio0 +#define sys_usb_ctrl sys_gpio1 +#define sys_timer_usec 0xA0000008 +#define sys_timer_sec 0xA000000C +#define sys_uart_data 0xA0010000 +#define sys_uart_stat 0xA0010004 +#define sys_uart_baud 0xA0010008 +#define sys_usb_data 0xA0020000 +#define sys_usb_mbx 0xA0020004 +#define sys_usb_addr 0xA0020008 +#define sys_usb_status 0xA002000C +#define sys_vga_data 0xA0030004 +#define sys_vga_posx 0xA0030008 +#define sys_vga_posy 0xA0030010 +#define sys_vga_clrscr 0xA0030020 +#define sys_vga_clrline 0xA0030040 +#define sys_vga_mctrl 0xA0030100 +#define sys_vga_moffs 0xA0030200 +#define sys_ac97_stat 0xA0040000 +#define sys_ac97_ctrl 0xA0040000 +#define sys_ac97_acstat 0xA0040400 +#define sys_ac97_acctrl 0xA0040600 +#define sys_ac97_pcm 0xA0040800 +#define sys_ac97_wavin sys_ac97_pcm +#define sys_ac97_wavout sys_ac97_pcm +#define sys_flash_io 0xA4000000 +#define sys_ssram_io 0xA8000000 + +//#define STDOUT_FUNCTION _cg_putchar // Video character +//#define STDERR_FUNCTION _putchar // Serial output + +#define STDOUT_FUNCTION _putchar // Serial output +#define STDERR_FUNCTION _putchar // Serial output + +UINT32 CP0_SR_read(void); +void CP0_SR_write(UINT32 val); +UINT32 CP0_CR_read(void); +void CP0_CR_write(UINT32 val); +UINT32 CP0_PRID_read(void); +UINT32 CP0_TR_read(void); +void CP0_TR_write(UINT32 val); + +char readchar(void); +void writechar(char c); +int write(int file, char *ptr, int len); +int sputs(char *pStr); +void print_byte(char byte); +void print_word(int word); +void _exit (int exitcode); +void sleep(unsigned ms); + +void PrintBuffer8(UINT8 *pBuf, int nbpr, int len); + +#endif // LIBSYS_H + diff --git a/lib/CPUs/MIPS/bsp/examples/link.ld b/lib/CPUs/MIPS/bsp/examples/link.ld new file mode 100644 index 0000000..a1486c1 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/link.ld @@ -0,0 +1,64 @@ +MEMORY +{ + reg : ORIGIN = 0xA0000000, LENGTH = 0x04000000 /* 64M */ + flash_io : ORIGIN = 0xA4000000, LENGTH = 0x00800000 /* 8M */ + ssram_io : ORIGIN = 0xA8000000, LENGTH = 0x00800000 /* 8M */ + sdram : ORIGIN = 0x40000000, LENGTH = 0x04000000 /* 64M */ +} + +stack_ptr = 0x7FFFEFF0; +baudrate = 0x0D; +sys_led_port = 0xA0000000; +sys_uart_data = 0xA0010000; +sys_uart_stat = 0xA0010004; +sys_uart_baud = 0xA0010008; +sys_timer_usec = 0xA000008; +sys_timer_sec = 0xA000000C; + +SECTIONS +{ + .etext ORIGIN(sdram) : + { + start = ALIGN(2); + entry = ALIGN(2); + _entry = ALIGN(2); + __entry = ALIGN(2); + *(.etext) + } > sdram + + .ktext ORIGIN(sdram) + 0x180 : + { + *(.ktext) + } > sdram + + .text . : ALIGN(2) + { + *(.text*) + } > sdram + + .data . : ALIGN(2) + { + *(.rodata*) *(.data*) *(.kdata) *(.sdata*) *(COMMON) *(.gcc*) + } > sdram + + .ctors . : ALIGN(2) + { + *(.ctor*) + } > sdram + + .eh_frame . : ALIGN(2) + { + *(.eh_frame) + } > sdram + + .bss . : ALIGN(2) + { + __bss_start = ALIGN(2); + *(.*bss*) + __bss_end = ALIGN(2); + end = ALIGN(2); + _end = ALIGN(2); + + } > sdram + +} diff --git a/lib/CPUs/MIPS/bsp/examples/paranoia.c b/lib/CPUs/MIPS/bsp/examples/paranoia.c new file mode 100644 index 0000000..38f08e1 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/paranoia.c @@ -0,0 +1,2302 @@ +/* + * paranoia.c,v 1.4 1995/08/23 19:26:32 joel Exp + * + * A C version of Kahan's Floating Point Test "Paranoia" + * + * Thos Sumner, UCSF, Feb. 1985 + * David Gay, BTL, Jan. 1986 + * + * This is a rewrite from the Pascal version by + * + * B. A. Wichmann, 18 Jan. 1985 + * + * (and does NOT exhibit good C programming style). + * + * Sun May 16 18:21:51 MDT 1993 Jeffrey Wheat (cassidy@cygnus.com) + * Removed KR_headers defines, removed ANSI prototyping + * Cleaned up and reformated code. Added special CYGNUS + * "verbose" mode type messages (-DCYGNUS). + * Note: This code is VERY NASTY. + * + * Adjusted to use Standard C headers 19 Jan. 1992 (dmg); + * compile with -DKR_headers or insert + * #define KR_headers + * at the beginning if you have an old-style C compiler. + * + * (C) Apr 19 1983 in BASIC version by: + * Professor W. M. Kahan, + * 567 Evans Hall + * Electrical Engineering & Computer Science Dept. + * University of California + * Berkeley, California 94720 + * USA + * + * converted to Pascal by: + * B. A. Wichmann + * National Physical Laboratory + * Teddington Middx + * TW11 OLW + * UK + * + * converted to C by: + * + * David M. Gay and Thos Sumner + * AT&T Bell Labs Computer Center, Rm. U-76 + * 600 Mountain Avenue University of California + * Murray Hill, NJ 07974 San Francisco, CA 94143 + * USA USA + * + * with simultaneous corrections to the Pascal source (reflected + * in the Pascal source available over netlib). + * [A couple of bug fixes from dgh = sun!dhough incorporated 31 July 1986.] + * + * Reports of results on various systems from all the versions + * of Paranoia are being collected by Richard Karpinski at the + * same address as Thos Sumner. This includes sample outputs, + * bug reports, and criticisms. + * + * You may copy this program freely if you acknowledge its source. + * Comments on the Pascal version to NPL, please. + * + * + * The C version catches signals from floating-point exceptions. + * If signal(SIGFPE,...) is unavailable in your environment, you may + * #define NOSIGNAL to comment out the invocations of signal. + * + * This source file is too big for some C compilers, but may be split + * into pieces. Comments containing "SPLIT" suggest convenient places + * for this splitting. At the end of these comments is an "ed script" + * (for the UNIX(tm) editor ed) that will do this splitting. + * + * By #defining SINGLE_PRECISION when you compile this source, you may + * obtain a single-precision C version of Paranoia. + * + * The following is from the introductory commentary from Wichmann's work: + * + * The BASIC program of Kahan is written in Microsoft BASIC using many + * facilities which have no exact analogy in Pascal. The Pascal + * version below cannot therefore be exactly the same. Rather than be + * a minimal transcription of the BASIC program, the Pascal coding + * follows the conventional style of block-structured languages. Hence + * the Pascal version could be useful in producing versions in other + * structured languages. + * + * Rather than use identifiers of minimal length (which therefore have + * little mnemonic significance), the Pascal version uses meaningful + * identifiers as follows [Note: A few changes have been made for C]: + * + * + * BASIC C BASIC C BASIC C + * + * A J S StickyBit + * A1 AInverse J0 NoErrors T + * B Radix [Failure] T0 Underflow + * B1 BInverse J1 NoErrors T2 ThirtyTwo + * B2 RadixD2 [SeriousDefect] T5 OneAndHalf + * B9 BMinusU2 J2 NoErrors T7 TwentySeven + * C [Defect] T8 TwoForty + * C1 CInverse J3 NoErrors U OneUlp + * D [Flaw] U0 UnderflowThreshold + * D4 FourD K PageNo U1 + * E0 L Milestone U2 + * E1 M V + * E2 Exp2 N V0 + * E3 N1 V8 + * E5 MinSqEr O Zero V9 + * E6 SqEr O1 One W + * E7 MaxSqEr O2 Two X + * E8 O3 Three X1 + * E9 O4 Four X8 + * F1 MinusOne O5 Five X9 Random1 + * F2 Half O8 Eight Y + * F3 Third O9 Nine Y1 + * F6 P Precision Y2 + * F9 Q Y9 Random2 + * G1 GMult Q8 Z + * G2 GDiv Q9 Z0 PseudoZero + * G3 GAddSub R Z1 + * H R1 RMult Z2 + * H1 HInverse R2 RDiv Z9 + * I R3 RAddSub + * IO NoTrials R4 RSqrt + * I3 IEEE R9 Random9 + * + * SqRWrng + * + * All the variables in BASIC are true variables and in consequence, + * the program is more difficult to follow since the "constants" must + * be determined (the glossary is very helpful). The Pascal version + * uses Real constants, but checks are added to ensure that the values + * are correctly converted by the compiler. + * + * The major textual change to the Pascal version apart from the + * identifiersis that named procedures are used, inserting parameters + * wherehelpful. New procedures are also introduced. The + * correspondence is as follows: + * + * + * BASIC Pascal + * lines + * + * 90- 140 Pause + * 170- 250 Instructions + * 380- 460 Heading + * 480- 670 Characteristics + * 690- 870 History + * 2940-2950 Random + * 3710-3740 NewD + * 4040-4080 DoesYequalX + * 4090-4110 PrintIfNPositive + * 4640-4850 TestPartialUnderflow + * +*/ + +#include +#include + +/* + * To compile this on host using only libm from newlib (and using host libc) + * do: + * gcc -g -DNEED_REENT -DCYGNUS paranoia.c .../newlib-1.6/newlib/libm.a + */ + +#ifdef NEED_REENT +#include +struct _reent libm_reent = _REENT_INIT(libm_reent); +struct _reent *_impure_ptr = &libm_reent; +#endif + +#ifndef NOSIGNAL +#include +#include +#else /* NOSIGNAL */ +#define longjmp(e,v) +#define setjmp(e) 0 +#define jmp_buf int +#endif /* NOSIGNAL */ + +#ifdef SINGLE_PRECISION +#define FLOAT float +#define FABS(x) (float)fabs((double)(x)) +#define FLOOR(x) (float)floor((double)(x)) +#define LOG(x) (float)log((double)(x)) +#define POW(x,y) (float)pow((double)(x),(double)(y)) +#define SQRT(x) (float)sqrt((double)(x)) +#else /* !SINGLE_PRECISION */ +#define FLOAT double +#define FABS(x) fabs(x) +#define FLOOR(x) floor(x) +#define LOG(x) log(x) +#define POW(x,y) pow(x,y) +#define SQRT(x) sqrt(x) +#endif /* SINGLE_PRECISION */ + +jmp_buf ovfl_buf; +extern double fabs (), floor (), log (), pow (), sqrt (); +extern void exit (); +typedef void (*Sig_type) (); +FLOAT Sign (), Random (); +extern void BadCond (); +extern void SqXMinX (); +extern void TstCond (); +extern void notify (); +extern int read (); +extern void Characteristics (); +extern void Heading (); +extern void History (); +extern void Instructions (); +extern void IsYeqX (); +extern void NewD (); +extern void Pause (); +extern void PrintIfNPositive (); +extern void SR3750 (); +extern void SR3980 (); +extern void TstPtUf (); + +Sig_type sigsave; + +#define KEYBOARD 0 + +FLOAT Radix, BInvrse, RadixD2, BMinusU2; + +/*Small floating point constants.*/ +FLOAT Zero = 0.0; +FLOAT Half = 0.5; +FLOAT One = 1.0; +FLOAT Two = 2.0; +FLOAT Three = 3.0; +FLOAT Four = 4.0; +FLOAT Five = 5.0; +FLOAT Eight = 8.0; +FLOAT Nine = 9.0; +FLOAT TwentySeven = 27.0; +FLOAT ThirtyTwo = 32.0; +FLOAT TwoForty = 240.0; +FLOAT MinusOne = -1.0; +FLOAT OneAndHalf = 1.5; + +/*Integer constants*/ +int NoTrials = 20; /*Number of tests for commutativity. */ +#define False 0 +#define True 1 + +/* + * Definitions for declared types + * Guard == (Yes, No); + * Rounding == (Chopped, Rounded, Other); + * Message == packed array [1..40] of char; + * Class == (Flaw, Defect, Serious, Failure); + */ +#define Yes 1 +#define No 0 +#define Chopped 2 +#define Rounded 1 +#define Other 0 +#define Flaw 3 +#define Defect 2 +#define Serious 1 +#define Failure 0 +typedef int Guard, Rounding, Class; +typedef char Message; + +/* Declarations of Variables */ +int Indx; +char ch[8]; +FLOAT AInvrse, A1; +FLOAT C, CInvrse; +FLOAT D, FourD; +FLOAT E0, E1, Exp2, E3, MinSqEr; +FLOAT SqEr, MaxSqEr, E9; +FLOAT Third; +FLOAT F6, F9; +FLOAT H, HInvrse; +int I; +FLOAT StickyBit, J; +FLOAT MyZero; +FLOAT Precision; +FLOAT Q, Q9; +FLOAT R, Random9; +FLOAT T, Underflow, S; +FLOAT OneUlp, UfThold, U1, U2; +FLOAT V, V0, V9; +FLOAT W; +FLOAT X, X1, X2, X8, Random1; +FLOAT Y, Y1, Y2, Random2; +FLOAT Z, PseudoZero, Z1, Z2, Z9; +int ErrCnt[4]; +int fpecount; +int Milestone; +int PageNo; +int M, N, N1; +Guard GMult, GDiv, GAddSub; +Rounding RMult, RDiv, RAddSub, RSqrt; +int Break, Done, NotMonot, Monot, Anomaly, IEEE, SqRWrng, UfNGrad; + +/* Computed constants. + * U1 gap below 1.0, i.e, 1.0 - U1 is next number below 1.0 + * U2 gap above 1.0, i.e, 1.0 + U2 is next number above 1.0 + */ + +int batchmode; /* global batchmode test */ + +/* program name and version variables and macro */ +char *temp; +char *program_name; +char *program_vers; + +#ifndef VERSION +#define VERSION "1.1 [cygnus]" +#endif /* VERSION */ + +#define basename(cp) ((temp=(char *)strrchr((cp), '/')) ? temp+1 : (cp)) + +#ifndef BATCHMODE +# ifdef CYGNUS +# define BATCHMODE +# endif +#endif + +/* floating point exception receiver */ +void +_sigfpe (x) +int x; +{ + fpecount++; + printf ("\n* * * FLOATING-POINT ERROR %d * * *\n", x); + fflush (stdout); + if (sigsave) { +#ifndef NOSIGNAL + signal (SIGFPE, sigsave); +#endif /* NOSIGNAL */ + sigsave = 0; + longjmp (ovfl_buf, 1); + } + exit (1); +} + +#ifdef NOMAIN +#define main paranoia +#endif + +int +main (argc, argv) +int argc; +char **argv; +{ + /* First two assignments use integer right-hand sides. */ + Zero = 0; + One = 1; + Two = One + One; + Three = Two + One; + Four = Three + One; + Five = Four + One; + Eight = Four + Four; + Nine = Three * Three; + TwentySeven = Nine * Three; + ThirtyTwo = Four * Eight; + TwoForty = Four * Five * Three * Four; + MinusOne = -One; + Half = One / Two; + OneAndHalf = One + Half; + ErrCnt[Failure] = 0; + ErrCnt[Serious] = 0; + ErrCnt[Defect] = 0; + ErrCnt[Flaw] = 0; + PageNo = 1; + +#ifdef BATCHMODE + batchmode = 1; /* run test in batchmode? */ +#else /* !BATCHMODE */ + batchmode = 0; /* run test interactively */ +#endif /* BATCHMODE */ + +/* + program_name = basename (argv[0]); +*/ + program_vers = VERSION; + + printf ("%s version %s\n", "Paranoia", program_vers); + + /*=============================================*/ + Milestone = 0; + /*=============================================*/ +#ifndef NOSIGNAL + signal (SIGFPE, _sigfpe); +#endif + + if (!batchmode) { + Instructions (); + Pause (); + Heading (); + Instructions (); + Pause (); + Heading (); + Pause (); + Characteristics (); + Pause (); + History (); + Pause (); + } + + /*=============================================*/ + Milestone = 7; + /*=============================================*/ + printf ("Program is now RUNNING tests on small integers:\n"); + TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero) + && (One > Zero) && (One + One == Two), + "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2"); + Z = -Zero; + if (Z != 0.0) { + ErrCnt[Failure] = ErrCnt[Failure] + 1; + printf ("Comparison alleges that -0.0 is Non-zero!\n"); + U1 = 0.001; + Radix = 1; + TstPtUf (); + } + TstCond (Failure, (Three == Two + One) && (Four == Three + One) + && (Four + Two * (-Two) == Zero) + && (Four - Three - One == Zero), + "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0"); + TstCond (Failure, (MinusOne == (0 - One)) + && (MinusOne + One == Zero) && (One + MinusOne == Zero) + && (MinusOne + FABS (One) == Zero) + && (MinusOne + MinusOne * MinusOne == Zero), + "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0"); + TstCond (Failure, Half + MinusOne + Half == Zero, + "1/2 + (-1) + 1/2 != 0"); + /*=============================================*/ + Milestone = 10; + /*=============================================*/ + TstCond (Failure, (Nine == Three * Three) + && (TwentySeven == Nine * Three) && (Eight == Four + Four) + && (ThirtyTwo == Eight * Four) + && (ThirtyTwo - TwentySeven - Four - One == Zero), + "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0"); + TstCond (Failure, (Five == Four + One) && + (TwoForty == Four * Five * Three * Four) + && (TwoForty / Three - Four * Four * Five == Zero) + && (TwoForty / Four - Five * Three * Four == Zero) + && (TwoForty / Five - Four * Three * Four == Zero), + "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48"); + if (ErrCnt[Failure] == 0) { + printf ("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n"); + printf ("\n"); + } + printf ("Searching for Radix and Precision.\n"); + W = One; + do { + W = W + W; + Y = W + One; + Z = Y - W; + Y = Z - One; + } + while (MinusOne + FABS (Y) < Zero); + /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/ + Precision = Zero; + Y = One; + do { + Radix = W + Y; + Y = Y + Y; + Radix = Radix - W; + } + while (Radix == Zero); + if (Radix < Two) + Radix = One; + printf ("Radix = %f .\n", Radix); + if (Radix != 1) { + W = One; + do { + Precision = Precision + One; + W = W * Radix; + Y = W + One; + } + while ((Y - W) == One); + } + /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1 + ...*/ + U1 = One / W; + U2 = Radix * U1; + printf ("Closest relative separation found is U1 = %.7e .\n\n", U1); + printf ("Recalculating radix and precision\n "); + + /*save old values*/ + E0 = Radix; + E1 = U1; + E9 = U2; + E3 = Precision; + + X = Four / Three; + Third = X - One; + F6 = Half - Third; + X = F6 + F6; + X = FABS (X - Third); + if (X < U2) + X = U2; + + /*... now X = (unknown no.) ulps of 1+...*/ + do { + U2 = X; + Y = Half * U2 + ThirtyTwo * U2 * U2; + Y = One + Y; + X = Y - One; + } + while (!((U2 <= X) || (X <= Zero))); + + /*... now U2 == 1 ulp of 1 + ... */ + X = Two / Three; + F6 = X - Half; + Third = F6 + F6; + X = Third - Half; + X = FABS (X + F6); + if (X < U1) + X = U1; + + /*... now X == (unknown no.) ulps of 1 -... */ + do { + U1 = X; + Y = Half * U1 + ThirtyTwo * U1 * U1; + Y = Half - Y; + X = Half + Y; + Y = Half - X; + X = Half + Y; + } + while (!((U1 <= X) || (X <= Zero))); + /*... now U1 == 1 ulp of 1 - ... */ + if (U1 == E1) + printf ("confirms closest relative separation U1 .\n"); + else + printf ("gets better closest relative separation U1 = %.7e .\n", U1); + W = One / U1; + F9 = (Half - U1) + Half; + Radix = FLOOR (0.01 + U2 / U1); + if (Radix == E0) + printf ("Radix confirmed.\n"); + else + printf ("MYSTERY: recalculated Radix = %.7e .\n", Radix); + TstCond (Defect, Radix <= Eight + Eight, + "Radix is too big: roundoff problems"); + TstCond (Flaw, (Radix == Two) || (Radix == 10) + || (Radix == One), "Radix is not as good as 2 or 10"); + /*=============================================*/ + Milestone = 20; + /*=============================================*/ + TstCond (Failure, F9 - Half < Half, + "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?"); + X = F9; + I = 1; + Y = X - Half; + Z = Y - Half; + TstCond (Failure, (X != One) + || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0"); + X = One + U2; + I = 0; + /*=============================================*/ + Milestone = 25; + /*=============================================*/ + /*... BMinusU2 = nextafter(Radix, 0) */ + BMinusU2 = Radix - One; + BMinusU2 = (BMinusU2 - U2) + One; + /* Purify Integers */ + if (Radix != One) { + X = -TwoForty * LOG (U1) / LOG (Radix); + Y = FLOOR (Half + X); + if (FABS (X - Y) * Four < One) + X = Y; + Precision = X / TwoForty; + Y = FLOOR (Half + Precision); + if (FABS (Precision - Y) * TwoForty < Half) + Precision = Y; + } + if ((Precision != FLOOR (Precision)) || (Radix == One)) { + printf ("Precision cannot be characterized by an Integer number\n"); + printf ("of significant digits but, by itself, this is a minor flaw.\n"); + } + if (Radix == One) + printf ("logarithmic encoding has precision characterized solely by U1.\n"); + else + printf ("The number of significant digits of the Radix is %f .\n", + Precision); + TstCond (Serious, U2 * Nine * Nine * TwoForty < One, + "Precision worse than 5 decimal figures "); + /*=============================================*/ + Milestone = 30; + /*=============================================*/ + /* Test for extra-precise subepressions */ + X = FABS (((Four / Three - One) - One / Four) * Three - One / Four); + do { + Z2 = X; + X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One; + } + while (!((Z2 <= X) || (X <= Zero))); + X = Y = Z = FABS ((Three / Four - Two / Three) * Three - One / Four); + do { + Z1 = Z; + Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1)) + + One / Two)) + One / Two; + } + while (!((Z1 <= Z) || (Z <= Zero))); + do { + do { + Y1 = Y; + Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half + )) + Half; + } + while (!((Y1 <= Y) || (Y <= Zero))); + X1 = X; + X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9; + } + while (!((X1 <= X) || (X <= Zero))); + if ((X1 != Y1) || (X1 != Z1)) { + BadCond (Serious, "Disagreements among the values X1, Y1, Z1,\n"); + printf ("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1); + printf ("are symptoms of inconsistencies introduced\n"); + printf ("by extra-precise evaluation of arithmetic subexpressions.\n"); + notify ("Possibly some part of this"); + if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) + printf ( + "That feature is not tested further by this program.\n"); + } else { + if ((Z1 != U1) || (Z2 != U2)) { + if ((Z1 >= U1) || (Z2 >= U2)) { + BadCond (Failure, ""); + notify ("Precision"); + printf ("\tU1 = %.7e, Z1 - U1 = %.7e\n", U1, Z1 - U1); + printf ("\tU2 = %.7e, Z2 - U2 = %.7e\n", U2, Z2 - U2); + } else { + if ((Z1 <= Zero) || (Z2 <= Zero)) { + printf ("Because of unusual Radix = %f", Radix); + printf (", or exact rational arithmetic a result\n"); + printf ("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2); + notify ("of an\nextra-precision"); + } + if (Z1 != Z2 || Z1 > Zero) { + X = Z1 / U1; + Y = Z2 / U2; + if (Y > X) + X = Y; + Q = -LOG (X); + printf ("Some subexpressions appear to be calculated extra\n"); + printf ("precisely with about %g extra B-digits, i.e.\n", + (Q / LOG (Radix))); + printf ("roughly %g extra significant decimals.\n", + Q / LOG (10.)); + } + printf ("That feature is not tested further by this program.\n"); + } + } + } + Pause (); + /*=============================================*/ + Milestone = 35; + /*=============================================*/ + if (Radix >= Two) { + X = W / (Radix * Radix); + Y = X + One; + Z = Y - X; + T = Z + U2; + X = T - Z; + TstCond (Failure, X == U2, + "Subtraction is not normalized X=Y,X+Z != Y+Z!"); + if (X == U2) + printf ( + "Subtraction appears to be normalized, as it should be."); + } + printf ("\nChecking for guard digit in *, /, and -.\n"); + Y = F9 * One; + Z = One * F9; + X = F9 - Half; + Y = (Y - Half) - X; + Z = (Z - Half) - X; + X = One + U2; + T = X * Radix; + R = Radix * X; + X = T - Radix; + X = X - Radix * U2; + T = R - Radix; + T = T - Radix * U2; + X = X * (Radix - One); + T = T * (Radix - One); + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) + GMult = Yes; + else { + GMult = No; + TstCond (Serious, False, + "* lacks a Guard Digit, so 1*X != X"); + } + Z = Radix * U2; + X = One + Z; + Y = FABS ((X + Z) - X * X) - U2; + X = One - U2; + Z = FABS ((X - U2) - X * X) - U1; + TstCond (Failure, (Y <= Zero) + && (Z <= Zero), "* gets too many final digits wrong.\n"); + Y = One - U2; + X = One + U2; + Z = One / Y; + Y = Z - X; + X = One / Three; + Z = Three / Nine; + X = X - Z; + T = Nine / TwentySeven; + Z = Z - T; + TstCond (Defect, X == Zero && Y == Zero && Z == Zero, + "Division lacks a Guard Digit, so error can exceed 1 ulp\n\ +or 1/3 and 3/9 and 9/27 may disagree"); + Y = F9 / One; + X = F9 - Half; + Y = (Y - Half) - X; + X = One + U2; + T = X / One; + X = T - X; + if ((X == Zero) && (Y == Zero) && (Z == Zero)) + GDiv = Yes; + else { + GDiv = No; + TstCond (Serious, False, + "Division lacks a Guard Digit, so X/1 != X"); + } + X = One / (One + U2); + Y = X - Half - Half; + TstCond (Serious, Y < Zero, + "Computed value of 1/1.000..1 >= 1"); + X = One - U2; + Y = One + Radix * U2; + Z = X * Radix; + T = Y * Radix; + R = Z / Radix; + StickyBit = T / Radix; + X = R - X; + Y = StickyBit - Y; + TstCond (Failure, X == Zero && Y == Zero, + "* and/or / gets too many last digits wrong"); + Y = One - U1; + X = One - F9; + Y = One - Y; + T = Radix - U2; + Z = Radix - BMinusU2; + T = Radix - T; + if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) + GAddSub = Yes; + else { + GAddSub = No; + TstCond (Serious, False, + "- lacks Guard Digit, so cancellation is obscured"); + } + if (F9 != One && F9 - One >= Zero) { + BadCond (Serious, "comparison alleges (1-U1) < 1 although\n"); + printf (" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n"); + printf (" such precautions against division by zero as\n"); + printf (" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n"); + } + if (GMult == Yes && GDiv == Yes && GAddSub == Yes) + printf ( + " *, /, and - appear to have guard digits, as they should.\n"); + /*=============================================*/ + Milestone = 40; + /*=============================================*/ + Pause (); + printf ("Checking rounding on multiply, divide and add/subtract.\n"); + RMult = Other; + RDiv = Other; + RAddSub = Other; + RadixD2 = Radix / Two; + A1 = Two; + Done = False; + do { + AInvrse = Radix; + do { + X = AInvrse; + AInvrse = AInvrse / A1; + } + while (!(FLOOR (AInvrse) != AInvrse)); + Done = (X == One) || (A1 > Three); + if (!Done) + A1 = Nine + One; + } + while (!(Done)); + if (X == One) + A1 = Radix; + AInvrse = One / A1; + X = A1; + Y = AInvrse; + Done = False; + do { + Z = X * Y - Half; + TstCond (Failure, Z == Half, + "X * (1/X) differs from 1"); + Done = X == Radix; + X = Radix; + Y = One / X; + } + while (!(Done)); + Y2 = One + U2; + Y1 = One - U2; + X = OneAndHalf - U2; + Y = OneAndHalf + U2; + Z = (X - U2) * Y2; + T = Y * Y1; + Z = Z - X; + T = T - X; + X = X * Y2; + Y = (Y + U2) * Y1; + X = X - OneAndHalf; + Y = Y - OneAndHalf; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) { + X = (OneAndHalf + U2) * Y2; + Y = OneAndHalf - U2 - U2; + Z = OneAndHalf + U2 + U2; + T = (OneAndHalf - U2) * Y1; + X = X - (Z + U2); + StickyBit = Y * Y1; + S = Z * Y2; + T = T - Y; + Y = (U2 - Y) + StickyBit; + Z = S - (Z + U2 + U2); + StickyBit = (Y2 + U2) * Y1; + Y1 = Y2 * Y1; + StickyBit = StickyBit - Y2; + Y1 = Y1 - Half; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && (StickyBit == Zero) && (Y1 == Half)) { + RMult = Rounded; + printf ("Multiplication appears to round correctly.\n"); + } else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero) + && (T < Zero) && (StickyBit + U2 == Zero) + && (Y1 < Half)) { + RMult = Chopped; + printf ("Multiplication appears to chop.\n"); + } else + printf ("* is neither chopped nor correctly rounded.\n"); + if ((RMult == Rounded) && (GMult == No)) + notify ("Multiplication"); + } else + printf ("* is neither chopped nor correctly rounded.\n"); + /*=============================================*/ + Milestone = 45; + /*=============================================*/ + Y2 = One + U2; + Y1 = One - U2; + Z = OneAndHalf + U2 + U2; + X = Z / Y2; + T = OneAndHalf - U2 - U2; + Y = (T - U2) / Y1; + Z = (Z + U2) / Y2; + X = X - OneAndHalf; + Y = Y - T; + T = T / Y1; + Z = Z - (OneAndHalf + U2); + T = (U2 - OneAndHalf) + T; + if (!((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) { + X = OneAndHalf / Y2; + Y = OneAndHalf - U2; + Z = OneAndHalf + U2; + X = X - Y; + T = OneAndHalf / Y1; + Y = Y / Y1; + T = T - (Z + U2); + Y = Y - Z; + Z = Z / Y2; + Y1 = (Y2 + U2) / Y2; + Z = Z - OneAndHalf; + Y2 = Y1 - Y2; + Y1 = (F9 - U1) / F9; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && (Y2 == Zero) && (Y2 == Zero) + && (Y1 - Half == F9 - Half)) { + RDiv = Rounded; + printf ("Division appears to round correctly.\n"); + if (GDiv == No) + notify ("Division"); + } else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero) + && (Y2 < Zero) && (Y1 - Half < F9 - Half)) { + RDiv = Chopped; + printf ("Division appears to chop.\n"); + } + } + if (RDiv == Other) + printf ("/ is neither chopped nor correctly rounded.\n"); + BInvrse = One / Radix; + TstCond (Failure, (BInvrse * Radix - Half == Half), + "Radix * ( 1 / Radix ) differs from 1"); + /*=============================================*/ + Milestone = 50; + /*=============================================*/ + TstCond (Failure, ((F9 + U1) - Half == Half) + && ((BMinusU2 + U2) - One == Radix - One), + "Incomplete carry-propagation in Addition"); + X = One - U1 * U1; + Y = One + U2 * (One - U2); + Z = F9 - Half; + X = (X - Half) - Z; + Y = Y - One; + if ((X == Zero) && (Y == Zero)) { + RAddSub = Chopped; + printf ("Add/Subtract appears to be chopped.\n"); + } + if (GAddSub == Yes) { + X = (Half + U2) * U2; + Y = (Half - U2) * U2; + X = One + X; + Y = One + Y; + X = (One + U2) - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) { + X = (Half + U2) * U1; + Y = (Half - U2) * U1; + X = One - X; + Y = One - Y; + X = F9 - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) { + RAddSub = Rounded; + printf ("Addition/Subtraction appears to round correctly.\n"); + if (GAddSub == No) + notify ("Add/Subtract"); + } else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + } else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + } else + printf ("Addition/Subtraction neither rounds nor chops.\n"); + S = One; + X = One + Half * (One + Half); + Y = (One + U2) * Half; + Z = X - Y; + T = Y - X; + StickyBit = Z + T; + if (StickyBit != Zero) { + S = Zero; + BadCond (Flaw, "(X - Y) + (Y - X) is non zero!\n"); + } + StickyBit = Zero; + if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes) + && (RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (FLOOR (RadixD2) == RadixD2)) { + printf ("Checking for sticky bit.\n"); + X = (Half + U1) * U2; + Y = Half * U2; + Z = One + Y; + T = One + X; + if ((Z - One <= Zero) && (T - One >= U2)) { + Z = T + Y; + Y = Z - X; + if ((Z - T >= U2) && (Y - T == Zero)) { + X = (Half + U1) * U1; + Y = Half * U1; + Z = One - Y; + T = One - X; + if ((Z - One == Zero) && (T - F9 == Zero)) { + Z = (Half - U1) * U1; + T = F9 - Z; + Q = F9 - Y; + if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) { + Z = (One + U2) * OneAndHalf; + T = (OneAndHalf + U2) - Z + U2; + X = One + Half / Radix; + Y = One + Radix * U2; + Z = X * Y; + if (T == Zero && X + Radix * U2 - Z == Zero) { + if (Radix != Two) { + X = Two + U2; + Y = X / Two; + if ((Y - One == Zero)) + StickyBit = S; + } else + StickyBit = S; + } + } + } + } + } + } + if (StickyBit == One) + printf ("Sticky bit apparently used correctly.\n"); + else + printf ("Sticky bit used incorrectly or not at all.\n"); + TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No || + RMult == Other || RDiv == Other || RAddSub == Other), + "lack(s) of guard digits or failure(s) to correctly round or chop\n\ +(noted above) count as one flaw in the final tally below"); + /*=============================================*/ + Milestone = 60; + /*=============================================*/ + printf ("\n"); + printf ("Does Multiplication commute? "); + printf ("Testing on %d random pairs.\n", NoTrials); + Random9 = SQRT (3.0); + Random1 = Third; + I = 1; + do { + X = Random (); + Y = Random (); + Z9 = Y * X; + Z = X * Y; + Z9 = Z - Z9; + I = I + 1; + } + while (!((I > NoTrials) || (Z9 != Zero))); + if (I == NoTrials) { + Random1 = One + Half / Three; + Random2 = (U2 + U1) + One; + Z = Random1 * Random2; + Y = Random2 * Random1; + Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half / + Three) * ((U2 + U1) + One); + } + if (!((I == NoTrials) || (Z9 == Zero))) + BadCond (Defect, "X * Y == Y * X trial fails.\n"); + else + printf (" No failures found in %d integer pairs.\n", NoTrials); + /*=============================================*/ + Milestone = 70; + /*=============================================*/ + printf ("\nRunning test of square root(x).\n"); + TstCond (Failure, (Zero == SQRT (Zero)) + && (-Zero == SQRT (-Zero)) + && (One == SQRT (One)), "Square root of 0.0, -0.0 or 1.0 wrong"); + MinSqEr = Zero; + MaxSqEr = Zero; + J = Zero; + X = Radix; + OneUlp = U2; + SqXMinX (Serious); + X = BInvrse; + OneUlp = BInvrse * U1; + SqXMinX (Serious); + X = U1; + OneUlp = U1 * U1; + SqXMinX (Serious); + if (J != Zero) + Pause (); + printf ("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials); + J = Zero; + X = Two; + Y = Radix; + if ((Radix != One)) + do { + X = Y; + Y = Radix * Y; + } + while (!((Y - X >= NoTrials))); + OneUlp = X * U2; + I = 1; + while (I <= NoTrials) { + X = X + One; + SqXMinX (Defect); + if (J > Zero) + break; + I = I + 1; + } + printf ("Test for sqrt monotonicity.\n"); + I = -1; + X = BMinusU2; + Y = Radix; + Z = Radix + Radix * U2; + NotMonot = False; + Monot = False; + while (!(NotMonot || Monot)) { + I = I + 1; + X = SQRT (X); + Q = SQRT (Y); + Z = SQRT (Z); + if ((X > Q) || (Q > Z)) + NotMonot = True; + else { + Q = FLOOR (Q + Half); + if ((I > 0) || (Radix == Q * Q)) + Monot = True; + else if (I > 0) { + if (I > 1) + Monot = True; + else { + Y = Y * BInvrse; + X = Y - U1; + Z = Y + U1; + } + } else { + Y = Q; + X = Y - U2; + Z = Y + U2; + } + } + } + if (Monot) + printf ("sqrt has passed a test for Monotonicity.\n"); + else { + BadCond (Defect, ""); + printf ("sqrt(X) is non-monotonic for X near %.7e .\n", Y); + } + /*=============================================*/ + Milestone = 80; + /*=============================================*/ + MinSqEr = MinSqEr + Half; + MaxSqEr = MaxSqEr - Half; + Y = (SQRT (One + U2) - One) / U2; + SqEr = (Y - One) + U2 / Eight; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + SqEr = Y + U2 / Eight; + if (SqEr < MinSqEr) + MinSqEr = SqEr; + Y = ((SQRT (F9) - U2) - (One - U2)) / U1; + SqEr = Y + U1 / Eight; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + SqEr = (Y + One) + U1 / Eight; + if (SqEr < MinSqEr) + MinSqEr = SqEr; + OneUlp = U2; + X = OneUlp; + for (Indx = 1; Indx <= 3; ++Indx) { + Y = SQRT ((X + U1 + X) + F9); + Y = ((Y - U2) - ((One - U2) + X)) / OneUlp; + Z = ((U1 - X) + F9) * Half * X * X / OneUlp; + SqEr = (Y + Half) + Z; + if (SqEr < MinSqEr) + MinSqEr = SqEr; + SqEr = (Y - Half) + Z; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + if (((Indx == 1) || (Indx == 3))) + X = OneUlp * Sign (X) * FLOOR (Eight / (Nine * SQRT (OneUlp))); + else { + OneUlp = U1; + X = -OneUlp; + } + } + /*=============================================*/ + Milestone = 85; + /*=============================================*/ + SqRWrng = False; + Anomaly = False; + RSqrt = Other; /* ~dgh */ + if (Radix != One) { + printf ("Testing whether sqrt is rounded or chopped.\n"); + D = FLOOR (Half + POW (Radix, One + Precision - FLOOR (Precision))); + /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */ + X = D / Radix; + Y = D / A1; + if ((X != FLOOR (X)) || (Y != FLOOR (Y))) { + Anomaly = True; + } else { + X = Zero; + Z2 = X; + Y = One; + Y2 = Y; + Z1 = Radix - One; + FourD = Four * D; + do { + if (Y2 > Z2) { + Q = Radix; + Y1 = Y; + do { + X1 = FABS (Q + FLOOR (Half - Q / Y1) * Y1); + Q = Y1; + Y1 = X1; + } + while (!(X1 <= Zero)); + if (Q <= One) { + Z2 = Y2; + Z = Y; + } + } + Y = Y + Two; + X = X + Eight; + Y2 = Y2 + X; + if (Y2 >= FourD) + Y2 = Y2 - FourD; + } + while (!(Y >= D)); + X8 = FourD - Z2; + Q = (X8 + Z * Z) / FourD; + X8 = X8 / Eight; + if (Q != FLOOR (Q)) + Anomaly = True; + else { + Break = False; + do { + X = Z1 * Z; + X = X - FLOOR (X / Radix) * Radix; + if (X == One) + Break = True; + else + Z1 = Z1 - One; + } + while (!(Break || (Z1 <= Zero))); + if ((Z1 <= Zero) && (!Break)) + Anomaly = True; + else { + if (Z1 > RadixD2) + Z1 = Z1 - Radix; + do { + NewD (); + } + while (!(U2 * D >= F9)); + if (D * Radix - D != W - D) + Anomaly = True; + else { + Z2 = D; + I = 0; + Y = D + (One + Z) * Half; + X = D + Z + Q; + SR3750 (); + Y = D + (One - Z) * Half + D; + X = D - Z + D; + X = X + Q + X; + SR3750 (); + NewD (); + if (D - Z2 != W - Z2) + Anomaly = True; + else { + Y = (D - Z2) + (Z2 + (One - Z) * Half); + X = (D - Z2) + (Z2 - Z + Q); + SR3750 (); + Y = (One + Z) * Half; + X = Q; + SR3750 (); + if (I == 0) + Anomaly = True; + } + } + } + } + } + if ((I == 0) || Anomaly) { + BadCond (Failure, "Anomalous arithmetic with Integer < "); + printf ("Radix^Precision = %.7e\n", W); + printf (" fails test whether sqrt rounds or chops.\n"); + SqRWrng = True; + } + } + if (!Anomaly) { + if (!((MinSqEr < Zero) || (MaxSqEr > Zero))) { + RSqrt = Rounded; + printf ("Square root appears to be correctly rounded.\n"); + } else { + if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half) + || (MinSqEr + Radix < Half)) + SqRWrng = True; + else { + RSqrt = Chopped; + printf ("Square root appears to be chopped.\n"); + } + } + } + if (SqRWrng) { + printf ("Square root is neither chopped nor correctly rounded.\n"); + printf ("Observed errors run from %.7e ", MinSqEr - Half); + printf ("to %.7e ulps.\n", Half + MaxSqEr); + TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix, + "sqrt gets too many last digits wrong"); + } + /*=============================================*/ + Milestone = 90; + /*=============================================*/ + Pause (); + printf ("Testing powers Z^i for small Integers Z and i.\n"); + N = 0; + /* ... test powers of zero. */ + I = 0; + Z = -Zero; + M = 3; + Break = False; + do { + X = One; + SR3980 (); + if (I <= 10) { + I = 1023; + SR3980 (); + } + if (Z == MinusOne) + Break = True; + else { + Z = MinusOne; + /* .. if(-1)^N is invalid, replace MinusOne by One. */ + I = -4; + } + } + while (!Break); + PrintIfNPositive (); + N1 = N; + N = 0; + Z = A1; + M = (int) FLOOR (Two * LOG (W) / LOG (A1)); + Break = False; + do { + X = Z; + I = 1; + SR3980 (); + if (Z == AInvrse) + Break = True; + else + Z = AInvrse; + } + while (!(Break)); + /*=============================================*/ + Milestone = 100; + /*=============================================*/ + /* Powers of Radix have been tested, */ + /* next try a few primes */ + M = NoTrials; + Z = Three; + do { + X = Z; + I = 1; + SR3980 (); + do { + Z = Z + Two; + } + while (Three * FLOOR (Z / Three) == Z); + } + while (Z < Eight * Three); + if (N > 0) { + printf ("Errors like this may invalidate financial calculations\n"); + printf ("\tinvolving interest rates.\n"); + } + PrintIfNPositive (); + N += N1; + if (N == 0) + printf ("... no discrepancies found.\n"); + if (N > 0) + Pause (); + else + printf ("\n"); + /*=============================================*/ + Milestone = 110; + /*=============================================*/ + printf ("Seeking Underflow thresholds UfThold and E0.\n"); + D = U1; + if (Precision != FLOOR (Precision)) { + D = BInvrse; + X = Precision; + do { + D = D * BInvrse; + X = X - One; + } + while (X > Zero); + } + Y = One; + Z = D; + /* ... D is power of 1/Radix < 1. */ + do { + C = Y; + Y = Z; + Z = Y * Y; + } + while ((Y > Z) && (Z + Z > Z)); + Y = C; + Z = Y * D; + do { + C = Y; + Y = Z; + Z = Y * D; + } + while ((Y > Z) && (Z + Z > Z)); + if (Radix < Two) + HInvrse = Two; + else + HInvrse = Radix; + H = One / HInvrse; + /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */ + CInvrse = One / C; + E0 = C; + Z = E0 * H; + /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */ + do { + Y = E0; + E0 = Z; + Z = E0 * H; + } + while ((E0 > Z) && (Z + Z > Z)); + UfThold = E0; + E1 = Zero; + Q = Zero; + E9 = U2; + S = One + E9; + D = C * S; + if (D <= C) { + E9 = Radix * U2; + S = One + E9; + D = C * S; + if (D <= C) { + BadCond (Failure, "multiplication gets too many last digits wrong.\n"); + Underflow = E0; + Y1 = Zero; + PseudoZero = Z; + Pause (); + } + } else { + Underflow = D; + PseudoZero = Underflow * H; + UfThold = Zero; + do { + Y1 = Underflow; + Underflow = PseudoZero; + if (E1 + E1 <= E1) { + Y2 = Underflow * HInvrse; + E1 = FABS (Y1 - Y2); + Q = Y1; + if ((UfThold == Zero) && (Y1 != Y2)) + UfThold = Y1; + } + PseudoZero = PseudoZero * H; + } + while ((Underflow > PseudoZero) + && (PseudoZero + PseudoZero > PseudoZero)); + } + /* Comment line 4530 .. 4560 */ + if (PseudoZero != Zero) { + printf ("\n"); + Z = PseudoZero; + /* ... Test PseudoZero for "phoney- zero" violates */ + /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero + ... */ + if (PseudoZero <= Zero) { + BadCond (Failure, "Positive expressions can underflow to an\n"); + printf ("allegedly negative value\n"); + printf ("PseudoZero that prints out as: %g .\n", PseudoZero); + X = -PseudoZero; + if (X <= Zero) { + printf ("But -PseudoZero, which should be\n"); + printf ("positive, isn't; it prints out as %g .\n", X); + } + } else { + BadCond (Flaw, "Underflow can stick at an allegedly positive\n"); + printf ("value PseudoZero that prints out as %g .\n", PseudoZero); + } + TstPtUf (); + } + /*=============================================*/ + Milestone = 120; + /*=============================================*/ + if (CInvrse * Y > CInvrse * Y1) { + S = H * S; + E0 = Underflow; + } + if (!((E1 == Zero) || (E1 == E0))) { + BadCond (Defect, ""); + if (E1 < E0) { + printf ("Products underflow at a higher"); + printf (" threshold than differences.\n"); + if (PseudoZero == Zero) + E0 = E1; + } else { + printf ("Difference underflows at a higher"); + printf (" threshold than products.\n"); + } + } + printf ("Smallest strictly positive number found is E0 = %g .\n", E0); + Z = E0; + TstPtUf (); + Underflow = E0; + if (N == 1) + Underflow = Y; + I = 4; + if (E1 == Zero) + I = 3; + if (UfThold == Zero) + I = I - 2; + UfNGrad = True; + switch (I) { + case 1: + UfThold = Underflow; + if ((CInvrse * Q) != ((CInvrse * Y) * S)) { + UfThold = Y; + BadCond (Failure, "Either accuracy deteriorates as numbers\n"); + printf ("approach a threshold = %.17e\n", UfThold);; + printf (" coming down from %.17e\n", C); + printf (" or else multiplication gets too many last digits wrong.\n"); + } + Pause (); + break; + + case 2: + BadCond (Failure, "Underflow confuses Comparison, which alleges that\n"); + printf ("Q == Y while denying that |Q - Y| == 0; these values\n"); + printf ("print out as Q = %.17e, Y = %.17e .\n", Q, Y2); + printf ("|Q - Y| = %.17e .\n", FABS (Q - Y2)); + UfThold = Q; + break; + + case 3: + X = X; + break; + + case 4: + if ((Q == UfThold) && (E1 == E0) + && (FABS (UfThold - E1 / E9) <= E1)) { + UfNGrad = False; + printf ("Underflow is gradual; it incurs Absolute Error =\n"); + printf ("(roundoff in UfThold) < E0.\n"); + Y = E0 * CInvrse; + Y = Y * (OneAndHalf + U2); + X = CInvrse * (One + U2); + Y = Y / X; + IEEE = (Y == E0); + } + } + if (UfNGrad) { + printf ("\n"); + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) { + printf ("Underflow / UfThold failed!\n"); + R = H + H; + } else + R = SQRT (Underflow / UfThold); + sigsave = 0; + if (R <= H) { + Z = R * UfThold; + X = Z * (One + R * H * (One + H)); + } else { + Z = UfThold; + X = Z * (One + H * H * (One + H)); + } + if (!((X == Z) || (X - Z != Zero))) { + BadCond (Flaw, ""); + printf ("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z); + Z9 = X - Z; + printf ("yet X - Z yields %.17e .\n", Z9); + printf (" Should this NOT signal Underflow, "); + printf ("this is a SERIOUS DEFECT\nthat causes "); + printf ("confusion when innocent statements like\n");; + printf (" if (X == Z) ... else"); + printf (" ... (f(X) - f(Z)) / (X - Z) ...\n"); + printf ("encounter Division by Zero although actually\n"); + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) + printf ("X / Z fails!\n"); + else + printf ("X / Z = 1 + %g .\n", (X / Z - Half) - Half); + sigsave = 0; + } + } + printf ("The Underflow threshold is %.17e, %s\n", UfThold, + " below which"); + printf ("calculation may suffer larger Relative error than "); + printf ("merely roundoff.\n"); + Y2 = U1 * U1; + Y = Y2 * Y2; + Y2 = Y * U1; + if (Y2 <= UfThold) { + if (Y > E0) { + BadCond (Defect, ""); + I = 5; + } else { + BadCond (Serious, ""); + I = 4; + } + printf ("Range is too narrow; U1^%d Underflows.\n", I); + } + /*=============================================*/ + Milestone = 130; + /*=============================================*/ + Y = -FLOOR (Half - TwoForty * LOG (UfThold) / LOG (HInvrse)) / TwoForty; + Y2 = Y + Y; + printf ("Since underflow occurs below the threshold\n"); + printf ("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y); + printf ("should afflict the expression\n\t(%.17e) ^ (%.17e);\n", + HInvrse, Y2); + printf ("actually calculating yields:"); + if (setjmp (ovfl_buf)) { + sigsave = 0; + BadCond (Serious, "trap on underflow.\n"); + } else { + sigsave = _sigfpe; + V9 = POW (HInvrse, Y2); + sigsave = 0; + printf (" %.17e .\n", V9); + if (!((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) { + BadCond (Serious, "this is not between 0 and underflow\n"); + printf (" threshold = %.17e .\n", UfThold); + } else if (!(V9 > UfThold * (One + E9))) + printf ("This computed value is O.K.\n"); + else { + BadCond (Defect, "this is not between 0 and underflow\n"); + printf (" threshold = %.17e .\n", UfThold); + } + } + /*=============================================*/ + Milestone = 140; + /*=============================================*/ + printf ("\n"); + /* ...calculate Exp2 == exp(2) == 7.389056099... */ + X = Zero; + I = 2; + Y = Two * Three; + Q = Zero; + N = 0; + do { + Z = X; + I = I + 1; + Y = Y / (I + I); + R = Y + Q; + X = Z + R; + Q = (Z - X) + R; + } + while (X > Z); + Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo); + X = Z * Z; + Exp2 = X * X; + X = F9; + Y = X - U1; + printf ("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n", + Exp2); + for (I = 1;;) { + Z = X - BInvrse; + Z = (X + One) / (Z - (One - BInvrse)); + Q = POW (X, Z) - Exp2; + if (FABS (Q) > TwoForty * U2) { + N = 1; + V9 = (X - BInvrse) - (One - BInvrse); + BadCond (Defect, "Calculated"); + printf (" %.17e for\n", POW (X, Z)); + printf ("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z); + printf ("\tdiffers from correct value by %.17e .\n", Q); + printf ("\tThis much error may spoil financial\n"); + printf ("\tcalculations involving tiny interest rates.\n"); + break; + } else { + Z = (Y - X) * Two + Y; + X = Y; + Y = Z; + Z = One + (X - F9) * (X - F9); + if (Z > One && I < NoTrials) + I++; + else { + if (X > One) { + if (N == 0) + printf ("Accuracy seems adequate.\n"); + break; + } else { + X = One + U2; + Y = U2 + U2; + Y += X; + I = 1; + } + } + } + } + /*=============================================*/ + Milestone = 150; + /*=============================================*/ + printf ("Testing powers Z^Q at four nearly extreme values.\n"); + N = 0; + Z = A1; + Q = FLOOR (Half - LOG (C) / LOG (A1)); + Break = False; + do { + X = CInvrse; + Y = POW (Z, Q); + IsYeqX (); + Q = -Q; + X = C; + Y = POW (Z, Q); + IsYeqX (); + if (Z < One) + Break = True; + else + Z = AInvrse; + } + while (!(Break)); + PrintIfNPositive (); + if (N == 0) + printf (" ... no discrepancies found.\n"); + printf ("\n"); + + /*=============================================*/ + Milestone = 160; + /*=============================================*/ + Pause (); + printf ("Searching for Overflow threshold:\n"); + printf ("This may generate an error.\n"); + Y = -CInvrse; + V9 = HInvrse * Y; + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) { + I = 0; + V9 = Y; + goto overflow; + } + do { + V = Y; + Y = V9; + V9 = HInvrse * Y; + } + while (V9 < Y); + I = 1; + overflow: + sigsave = 0; + Z = V9; + printf ("Can `Z = -Y' overflow?\n"); + printf ("Trying it on Y = %.17e .\n", Y); + V9 = -Y; + V0 = V9; + if (V - Y == V + V0) + printf ("Seems O.K.\n"); + else { + printf ("finds a "); + BadCond (Flaw, "-(-Y) differs from Y.\n"); + } + if (Z != Y) { + BadCond (Serious, ""); + printf ("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z); + } + if (I) { + Y = V * (HInvrse * U2 - HInvrse); + Z = Y + ((One - HInvrse) * U2) * V; + if (Z < V0) + Y = Z; + if (Y < V0) + V = Y; + if (V0 - V < V0) + V = V0; + } else { + V = Y * (HInvrse * U2 - HInvrse); + V = V + ((One - HInvrse) * U2) * Y; + } + printf ("Overflow threshold is V = %.17e .\n", V); + if (I) + printf ("Overflow saturates at V0 = %.17e .\n", V0); + else + printf ("There is no saturation value because \ +the system traps on overflow.\n"); + V9 = V * One; + printf ("No Overflow should be signaled for V * 1 = %.17e\n", V9); + V9 = V / One; + printf (" nor for V / 1 = %.17e .\n", V9); + printf ("Any overflow signal separating this * from the one\n"); + printf ("above is a DEFECT.\n"); + /*=============================================*/ + Milestone = 170; + /*=============================================*/ + if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) { + BadCond (Failure, "Comparisons involving "); + printf ("+-%g, +-%g\nand +-%g are confused by Overflow.", + V, V0, UfThold); + } + /*=============================================*/ + Milestone = 175; + /*=============================================*/ + printf ("\n"); + for (Indx = 1; Indx <= 3; ++Indx) { + switch (Indx) { + case 1: + Z = UfThold; + break; + case 2: + Z = E0; + break; + case 3: + Z = PseudoZero; + break; + } + if (Z != Zero) { + V9 = SQRT (Z); + Y = V9 * V9; + if (Y / (One - Radix * E9) < Z + || Y > (One + Radix * E9) * Z) { /* dgh: + E9 --> * E9 */ + if (V9 > U1) + BadCond (Serious, ""); + else + BadCond (Defect, ""); + printf ("Comparison alleges that what prints as Z = %.17e\n", Z); + printf (" is too far from sqrt(Z) ^ 2 = %.17e .\n", Y); + } + } + } + /*=============================================*/ + Milestone = 180; + /*=============================================*/ + for (Indx = 1; Indx <= 2; ++Indx) { + if (Indx == 1) + Z = V; + else + Z = V0; + V9 = SQRT (Z); + X = (One - Radix * E9) * V9; + V9 = V9 * X; + if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) { + Y = V9; + if (X < W) + BadCond (Serious, ""); + else + BadCond (Defect, ""); + printf ("Comparison alleges that Z = %17e\n", Z); + printf (" is too far from sqrt(Z) ^ 2 (%.17e) .\n", Y); + } + } + /*=============================================*/ + Milestone = 190; + /*=============================================*/ + Pause (); + X = UfThold * V; + Y = Radix * Radix; + if (X * Y < One || X > Y) { + if (X * Y < U1 || X > Y / U1) + BadCond (Defect, "Badly"); + else + BadCond (Flaw, ""); + + printf (" unbalanced range; UfThold * V = %.17e\n\t%s\n", + X, "is too far from 1.\n"); + } + /*=============================================*/ + Milestone = 200; + /*=============================================*/ + for (Indx = 1; Indx <= 5; ++Indx) { + X = F9; + switch (Indx) { + case 2: + X = One + U2; + break; + case 3: + X = V; + break; + case 4: + X = UfThold; + break; + case 5: + X = Radix; + } + Y = X; + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) + printf (" X / X traps when X = %g\n", X); + else { + V9 = (Y / X - Half) - Half; + if (V9 == Zero) + continue; + if (V9 == -U1 && Indx < 5) + BadCond (Flaw, ""); + else + BadCond (Serious, ""); + printf (" X / X differs from 1 when X = %.17e\n", X); + printf (" instead, X / X - 1/2 - 1/2 = %.17e .\n", V9); + } + sigsave = 0; + } + /*=============================================*/ + Milestone = 210; + /*=============================================*/ + MyZero = Zero; + printf ("\n"); + printf ("What message and/or values does Division by Zero produce?\n"); +#ifndef BATCHMODE + printf ("This can interupt your program. You can "); + printf ("skip this part if you wish.\n"); + printf ("Do you wish to compute 1 / 0? "); + fflush (stdout); + read (KEYBOARD, ch, 8); + if ((ch[0] == 'Y') || (ch[0] == 'y')) { +#endif /* !BATCHMODE */ + sigsave = _sigfpe; + printf (" Trying to compute 1 / 0 produces ..."); + if (!setjmp (ovfl_buf)) + printf (" %.7e .\n", One / MyZero); + sigsave = 0; +#ifndef BATCHMODE + } else + printf ("O.K.\n"); + printf ("\nDo you wish to compute 0 / 0? "); + fflush (stdout); + read (KEYBOARD, ch, 80); + if ((ch[0] == 'Y') || (ch[0] == 'y')) { +#endif /* !BATCHMODE */ + sigsave = _sigfpe; + printf ("\n Trying to compute 0 / 0 produces ..."); + if (!setjmp (ovfl_buf)) + printf (" %.7e .\n", Zero / MyZero); + sigsave = 0; +#ifndef BATCHMODE + } else + printf ("O.K.\n"); +#endif /* !BATCHMODE */ + /*=============================================*/ + Milestone = 220; + /*=============================================*/ + + Pause (); + printf ("\n"); + { + static char *msg[] = + { + "FAILUREs encountered =", + "SERIOUS DEFECTs discovered =", + "DEFECTs discovered =", + "FLAWs discovered ="}; + int i; + for (i = 0; i < 4; i++) + if (ErrCnt[i]) + printf ("The number of %-29s %d.\n", + msg[i], ErrCnt[i]); + } + + printf ("\n"); + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] + + ErrCnt[Flaw]) > 0) { + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[ + Defect] == 0) && (ErrCnt[Flaw] > 0)) { + printf ("The arithmetic diagnosed seems "); + printf ("Satisfactory though flawed.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) + && (ErrCnt[Defect] > 0)) { + printf ("The arithmetic diagnosed may be Acceptable\n"); + printf ("despite inconvenient Defects.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) { + printf ("The arithmetic diagnosed has "); + printf ("unacceptable Serious Defects.\n"); + } + if (ErrCnt[Failure] > 0) { + printf ("Potentially fatal FAILURE may have spoiled this"); + printf (" program's subsequent diagnoses.\n"); + } + } else { + + printf ("No failures, defects nor flaws have been discovered.\n"); + if (!((RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (RSqrt == Rounded))) + printf ("The arithmetic diagnosed seems Satisfactory.\n"); + else { + if (StickyBit >= One && + (Radix - Two) * (Radix - Nine - One) == Zero) { + printf ("Rounding appears to conform to "); + printf ("the proposed IEEE standard P"); + if ((Radix == Two) && + ((Precision - Four * Three * Two) * + (Precision - TwentySeven - + TwentySeven + One) == Zero)) + printf ("754"); + else + printf ("854"); + if (IEEE) + printf (".\n"); + else { + printf (",\nexcept for possibly Double Rounding"); + printf (" during Gradual Underflow.\n"); + } + } + printf ("The arithmetic diagnosed appears to be Excellent!\n"); + } + } + + if (fpecount) + printf ("\nA total of %d floating point exceptions were registered.\n", + fpecount); + printf ("END OF TEST.\n"); + return 0; +} + +FLOAT +Sign (X) + FLOAT X; +{ + return X >= 0. ? 1.0 : -1.0; +} + +void +Pause () +{ +#ifndef BATCHMODE + char ch[8]; + + printf ("\nTo continue, press RETURN"); + fflush (stdout); + read (KEYBOARD, ch, 8); +#endif /* !BATCHMODE */ +#ifndef CYGNUS + printf ("\nDiagnosis resumes after milestone Number %d", Milestone); + printf (" Page: %d\n\n", PageNo); + ++Milestone; + ++PageNo; +#endif /* !CYGNUS */ +} + +void +TstCond (K, Valid, T) + int K, Valid; + char *T; +{ +#ifdef CYGNUS + printf ("TEST: %s\n", T); +#endif /* CYGNUS */ + if (!Valid) { + BadCond (K, T); + printf (".\n"); + } +#ifdef CYGNUS + printf ("PASS: %s\n", T); +#endif /* CYGNUS */ +} + +void +BadCond (K, T) + int K; + char *T; +{ + static char *msg[] = + {"FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW"}; + + ErrCnt[K] = ErrCnt[K] + 1; +#ifndef CYGNUS + printf ("%s: %s", msg[K], T); +#else + printf ("ERROR: Severity: %s: %s", msg[K], T); +#endif /* CYGNUS */ +} + +/* + * Random computes + * X = (Random1 + Random9)^5 + * Random1 = X - FLOOR(X) + 0.000005 * X; + * and returns the new value of Random1 +*/ +FLOAT +Random () +{ + FLOAT X, Y; + + X = Random1 + Random9; + Y = X * X; + Y = Y * Y; + X = X * Y; + Y = X - FLOOR (X); + Random1 = Y + X * 0.000005; + return (Random1); +} + +void +SqXMinX (ErrKind) + int ErrKind; +{ + FLOAT XA, XB; + + XB = X * BInvrse; + XA = X - XB; + SqEr = ((SQRT (X * X) - XB) - XA) / OneUlp; + if (SqEr != Zero) { + if (SqEr < MinSqEr) + MinSqEr = SqEr; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + J = J + 1.0; + BadCond (ErrKind, "\n"); + printf ("sqrt( %.17e) - %.17e = %.17e\n", X * X, X, OneUlp * SqEr); + printf ("\tinstead of correct value 0 .\n"); + } +} + +void +NewD () +{ + X = Z1 * Q; + X = FLOOR (Half - X / Radix) * Radix + X; + Q = (Q - X * Z) / Radix + X * X * (D / Radix); + Z = Z - Two * X * D; + if (Z <= Zero) { + Z = -Z; + Z1 = -Z1; + } + D = Radix * D; +} + +void +SR3750 () +{ + if (!((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) { + I = I + 1; + X2 = SQRT (X * D); + Y2 = (X2 - Z2) - (Y - Z2); + X2 = X8 / (Y - Half); + X2 = X2 - Half * X2 * X2; + SqEr = (Y2 + Half) + (Half - X2); + if (SqEr < MinSqEr) + MinSqEr = SqEr; + SqEr = Y2 - X2; + if (SqEr > MaxSqEr) + MaxSqEr = SqEr; + } +} + +void +IsYeqX () +{ + if (Y != X) { + if (N <= 0) { + if (Z == Zero && Q <= Zero) + printf ("WARNING: computing\n"); + else + BadCond (Defect, "computing\n"); + printf ("\t(%.17e) ^ (%.17e)\n", Z, Q); + printf ("\tyielded %.17e;\n", Y); + printf ("\twhich compared unequal to correct %.17e ;\n", + X); + printf ("\t\tthey differ by %.17e .\n", Y - X); + } + N = N + 1; /* ... count discrepancies. */ + } +} + +void +SR3980 () +{ + do { + Q = (FLOAT) I; + Y = POW (Z, Q); + IsYeqX (); + if (++I > M) + break; + X = Z * X; + } + while (X < W); +} + +void +PrintIfNPositive () +{ + if (N > 0) + printf ("Similar discrepancies have occurred %d times.\n", N); +} + +void +TstPtUf () +{ + N = 0; + if (Z != Zero) { + printf ("Since comparison denies Z = 0, evaluating "); + printf ("(Z + Z) / Z should be safe.\n"); + sigsave = _sigfpe; + if (setjmp (ovfl_buf)) + goto very_serious; + Q9 = (Z + Z) / Z; + printf ("What the machine gets for (Z + Z) / Z is %.17e .\n", + Q9); + if (FABS (Q9 - Two) < Radix * U2) { + printf ("This is O.K., provided Over/Underflow"); + printf (" has NOT just been signaled.\n"); + } else { + if ((Q9 < One) || (Q9 > Two)) { + very_serious: + N = 1; + ErrCnt[Serious] = ErrCnt[Serious] + 1; + printf ("This is a VERY SERIOUS DEFECT!\n"); + } else { + N = 1; + ErrCnt[Defect] = ErrCnt[Defect] + 1; + printf ("This is a DEFECT!\n"); + } + } + sigsave = 0; + V9 = Z * One; + Random1 = V9; + V9 = One * Z; + Random2 = V9; + V9 = Z / One; + if ((Z == Random1) && (Z == Random2) && (Z == V9)) { + if (N > 0) + Pause (); + } else { + N = 1; + BadCond (Defect, "What prints as Z = "); + printf ("%.17e\n\tcompares different from ", Z); + if (Z != Random1) + printf ("Z * 1 = %.17e ", Random1); + if (!((Z == Random2) + || (Random2 == Random1))) + printf ("1 * Z == %g\n", Random2); + if (!(Z == V9)) + printf ("Z / 1 = %.17e\n", V9); + if (Random2 != Random1) { + ErrCnt[Defect] = ErrCnt[Defect] + 1; + BadCond (Defect, "Multiplication does not commute!\n"); + printf ("\tComparison alleges that 1 * Z = %.17e\n", + Random2); + printf ("\tdiffers from Z * 1 = %.17e\n", Random1); + } + Pause (); + } + } +} + +void +notify (s) + char *s; +{ + printf ("%s test appears to be inconsistent...\n", s); + printf (" PLEASE NOTIFY KARPINKSI!\n"); +} + +void +msglist (s) + char **s; +{ + while (*s) + printf ("%s\n", *s++); +} + +void +Instructions () +{ + static char *instr[] = + { + "Lest this program stop prematurely, i.e. before displaying\n", + " `END OF TEST',\n", + "try to persuade the computer NOT to terminate execution when an", + "error like Over/Underflow or Division by Zero occurs, but rather", + "to persevere with a surrogate value after, perhaps, displaying some", + "warning. If persuasion avails naught, don't despair but run this", + "program anyway to see how many milestones it passes, and then", + "amend it to make further progress.\n", + "Answer questions with Y, y, N or n (unless otherwise indicated).\n", + 0}; + + msglist (instr); +} + +void +Heading () +{ + static char *head[] = + { + "Users are invited to help debug and augment this program so it will", + "cope with unanticipated and newly uncovered arithmetic pathologies.\n", + "Please send suggestions and interesting results to", + "\tRichard Karpinski", + "\tComputer Center U-76", + "\tUniversity of California", + "\tSan Francisco, CA 94143-0704, USA\n", + "In doing so, please include the following information:", +#ifdef SINGLE_PRECISION + "\tPrecision:\tsingle;", +#else /* !SINGLE_PRECISION */ + "\tPrecision:\tdouble;", +#endif /* SINGLE_PRECISION */ + "\tVersion:\t10 February 1989;", + "\tComputer:\n", + "\tCompiler:\n", + "\tOptimization level:\n", + "\tOther relevant compiler options:", + 0}; + + msglist (head); +} + +void +Characteristics () +{ + static char *chars[] = + { + "Running this program should reveal these characteristics:", + " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...", + " Precision = number of significant digits carried.", + " U2 = Radix/Radix^Precision = One Ulp", + "\t(OneUlpnit in the Last Place) of 1.000xxx .", + " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .", + " Adequacy of guard digits for Mult., Div. and Subt.", + " Whether arithmetic is chopped, correctly rounded, or something else", + "\tfor Mult., Div., Add/Subt. and Sqrt.", + " Whether a Sticky Bit used correctly for rounding.", + " UnderflowThreshold = an underflow threshold.", + " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.", + " V = an overflow threshold, roughly.", + " V0 tells, roughly, whether Infinity is represented.", + " Comparisions are checked for consistency with subtraction", + "\tand for contamination with pseudo-zeros.", + " Sqrt is tested. Y^X is not tested.", + " Extra-precise subexpressions are revealed but NOT YET tested.", + " Decimal-Binary conversion is NOT YET tested for accuracy.", + 0}; + + msglist (chars); +} + +void +History () +{ /* History */ + /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner, + with further massaging by David M. Gay. */ + + static char *hist[] = + { + "The program attempts to discriminate among", + " FLAWs, like lack of a sticky bit,", + " Serious DEFECTs, like lack of a guard digit, and", + " FAILUREs, like 2+2 == 5 .", + "Failures may confound subsequent diagnoses.\n", + "The diagnostic capabilities of this program go beyond an earlier", + "program called `MACHAR', which can be found at the end of the", + "book `Software Manual for the Elementary Functions' (1980) by", + "W. J. Cody and W. Waite. Although both programs try to discover", + "the Radix, Precision and range (over/underflow thresholds)", + "of the arithmetic, this program tries to cope with a wider variety", + "of pathologies, and to say how well the arithmetic is implemented.", + "\nThe program is based upon a conventional radix representation for", + "floating-point numbers, but also allows logarithmic encoding", + "as used by certain early WANG machines.\n", + "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;", + "see source comments for more history.", + 0}; + + msglist (hist); +} diff --git a/lib/CPUs/MIPS/bsp/examples/phrasen.c b/lib/CPUs/MIPS/bsp/examples/phrasen.c new file mode 100644 index 0000000..8066ebd --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/phrasen.c @@ -0,0 +1,298 @@ +#include +#include +#include "libsys.h" + +struct substantive +{ + char *subst; + int sex; +}; + +struct verben +{ + char *verb_k; + char *verb_gr; + int art; +}; + +struct adjektive +{ + char *adj; +}; + + char *art[4]={"er","ie","as","en"}; + +char getch(void) +{ + return readchar(); +} + +void randomize(void) +{ + srand(clock()); +} + +struct substantive namen[]= +{ + {"Gerhard Schröder",1},{"Helmut Kohl",1},{"Rudolf Scharping",1}, + {"Claudia Nolte",2}, {"Johannes Rau",1},{"Wolfgang Schäuble",1}, + {"Joschka Fischer",1},{"Toni Blair",1},{"Kleopatra",2}, + {"Claudia Schiffer",2},{"Hannelore Kohl",2},{"Konrad Adenauer",1}, + {"Michael Jackson",1},{"Karl Marx",1}, {"Helmut Kohl",1},{"Heino",1}, + {"Gerhard Schröder",1},{"Donald Duck",1},{"Madonna",2},{"Jesus",1}, + {"Gott",1},{"Sheryl Crow",2},{"Verona Feldbusch",2},{"Pipi Langstrumpf",2}, + {"Bill Gates",1},{"Bill Clinton",1},{"Cleopatra",2},{"Winnetou",1}, + {"Käpt'n Blaubär",1},{"Rita Süssmuth",2},{"Boris Becker",1}, + {"Lilo Wanders",2},{"Queen Elizabeth",2},{"Lady Di",2},{"Steffi Graf",2}, + {"Frank Zappa",1},{"Dolly Buster",2},{"Mao Tse Tung",1},{"Ghandi",1}, + {"Dalai Lama",1},{"Teufel",1},{"Lenin",1},{"Edmund Stoiber",1}, + {"Ludwig van Beethoven",1},{"Wolfgang Amadeus Mozart",1}, + {"Richard Wagner",1},{"Erich Honecker",1},{"Adam Riese",1}, + {"Bill Clinton",1},{"Josef Stalin",1},{"Willy Brandt",1}, + {"John F. Kennedy",1},{"E.T.",1},{"Donald Duck",1},{"Lothar Matthäus",1}, + {"Hans Dietrich Genscher",1},{"Franz Josef Strauss",1},{"Sting",1}, + {"Hermann Hesse",1},{"Albert Einstein",1},{"Max Planck",1}, + {"Tom Jones",1},{"Heidi Kabel",2},{"Homer Simpson",1},{"Zeus",1}, + {"Helmut Schmidt",1},{"Antje Vollmer",2},{"Politiker",1},{"Papst",1}, + {"Bundeskanzler",1},{"Arzt",1},{"Friseuse",2},{"Teufel",1}, + {"Sandmännchen",3},{"Mutter",2},{"Vater",1},{"Säufer",1},{"Student",1}, + {"Bauer",1},{"Leiche",2},{"Polizist",1},{"Patientin",2},{"Bäcker",1}, + {"Wirt",1}, {"Schlachter",1},{"Baby",3},{"Reporter",1},{"Politiker",1}, + {"Beamtin",2},{"Oma",2},{"Putzfrau",2},{"Blinde",2},{"Wahnsinnige",2}, + {"Mörder",1},{"Psychiater",1},{"Prinz Charles",1},{"Onkel",1},{"Tante",2} +}; + +struct substantive sachen[]= +{ + {"Haus",3},{"Buch",3},{"Fahrrad",3},{"Schule",2},{"Auto",3},{"Nase",2}, + {"Mund",1},{"Kopf",1},{"Kaffee",1},{"Telephon",3},{"Tasse",2},{"Katze",2}, + {"Hund",1},{"Maus",2},{"Stuhl",1},{"Mann",1},{"Frau",2},{"Kind",3}, + {"Idiotin",2},{"Lampe",2},{"Panzer",1},{"Klavier",3},{"Gitarre",2}, + {"Straße",2},{"Wasser",3},{"Luft",2},{"Feuer",3},{"Erde",2},{"Mond",1}, + {"Sonne",2},{"Bild",3},{"Stadt",2},{"Land",3},{"Fluss",1}, + {"Bundeskanzler",1},{"Ball",1},{"Hut",1},{"Hose",2},{"Hemd",3},{"Tod",1}, + {"Geld",3},{"Tisch",1},{"Hand",2},{"Baum",1},{"Bier",3},{"Ratte",2}, + {"Esel",1},{"Musik",2},{"Blech",3},{"Dose",2},{"Zahn",1},{"Humor",1}, + {"Unterhose",2},{"Gift",3},{"Gesicht",3},{"Fuß",1},{"Auge",3},{"Warze",2}, + {"Ohr",3},{"Kanone",2},{"Milch",2},{"Messer",3},{"Papier",3},{"Haar",3}, + {"Welt",2},{"Motor",1},{"Langeweile",2},{"Grab",3},{"Schnaps",1}, + {"Vogel",1},{"Fisch",1},{"Meer",3},{"Banane",2},{"Brot",3}, + {"Sitzung",2},{"Labor",3},{"Kurzschluß",1},{"Lüge",2},{"Axt",2}, + {"Abstimmung",2},{"Toilette",2},{"Zigarette",2},{"Winter",1}, + {"Torte",2},{"Bahnhof",1},{"Sarg",1},{"Imbiss",1},{"Mund",1},{"Seife",2}, + {"Fernseher",1},{"Flasche",2},{"Eimer",1},{"Uhr",2},{"Irrenhaus",3}, + {"Wüste",2},{"Klumpen",1},{"Glück",3},{"Schiff",3},{"Käse",1},{"Quark",1}, + {"Sommer",1},{"Witz",1},{"Idee",2},{"Nacht",2},{"Dreck",1},{"Meer",3}, + {"Blut",3},{"Herz",3},{"Apfel",1},{"Banane",2},{"Mist",1},{"Atom",3}, + {"Note",2},{"Gehirn",3},{"Gefühl",3},{"Bombe",2},{"Vakuum",3}, + {"Zahl",2},{"Wort",3},{"Programm",3},{"Computer",1},{"Orient",1}, + {"Gabelstapler",1} +}; + +struct adjektive ad[]= +{ + {"schön"},{"doof"},{"gut"},{"schlecht"},{"gelb"},{"grün"},{"rot"}, + {"blau"},{"schnell"},{"lang"},{"kurz"},{"hell"},{"düster"},{"sanft"}, + {"hart"},{"langsam"},{"bitter"},{"süß"},{"kaputt"},{"nett"},{"groß"}, + {"klein"},{"leicht"},{"schwer"},{"dick"},{"dünn"},{"rund"},{"eckig"}, + {"heiß"},{"kalt"},{"schlau"},{"elektrisch"},{"nass"},{"trocken"},{"ratlos"}, + {"abartig"},{"genial"},{"bestechlich"},{"irr"},{"steif"},{"angespannt"}, + {"laut"},{"leis"},{"warm"},{"wütend"},{"sauber"},{"schmutzig"},{"arm"}, + {"ätzend"},{"langweilig"},{"interessant"},{"erfahren"},{"abgewählt"}, + {"durchgeknallt"},{"angenehm"},{"widerwärtig"},{"willig"},{"mutig"}, + {"schwach"},{"stark"},{"nervend"},{"spießig"},{"alt"},{"neu"},{"spitz"}, + {"stumpf"},{"teuflisch"},{"scharf"},{"lecker"},{"übelriechend"},{"halb"}, + {"ganz"},{"bleich"},{"peinlich"},{"taktlos"},{"gewieft"},{"windig"}, + {"größenwahnsinnig"},{"verrückt"},{"uralt"},{"aalglatt"},{"korrekt"}, + {"kompetent"},{"einfühlsam"},{"tot"},{"schleimig"},{"gestört"},{"hohl"}, + {"beknackt"},{"nackt"},{"barfüßig"},{"schwitzend"},{"laufend"},{"knackig"}, + {"unverschämt"},{"schläfrig"},{"wohlgeformt"},{"kugelförmig"},{"rauh"}, + {"degeneriert"},{"ekelhaft"},{"brutal"},{"gemein"},{"aggressiv"}, + {"aufdringlich"},{"betroffen"},{"geliebt"},{"gehasst"},{"beharrlich"}, + {"unmenschlich"},{"verblödet"},{"wichtig"},{"gigantisch"},{"winzig"}, + {"witzig"},{"komisch"},{"pervers"},{"fett"},{"stinkend"},{"lausig"}, + {"wendig"},{"breit"},{"locker"},{"einzigartig"},{"sterbend"},{"munter"}, + {"ungepflegt"},{"eisern"},{"echt"},{"besser"},{"wild"},{"ächzend"}, + {"frohlockend"},{"unscheinbar"},{"nebulös"},{"skandalös"},{"obzön"}, + {"beschränkt"},{"genervt"},{"hilflos"},{"unwürdig"},{"geleckt"}, + {"betrunken"},{"unwürdig"},{"bissig"},{"verkalkt"},{"senil"}, + {"jungfräulich"},{"ausgeleiert"},{"beleibt"},{"nachtragend"},{"errötend"}, + {"kahl"},{"würgend"},{"abwesend"},{"ruhig"},{"albern"},{"trostlos"}, + {"salzig"},{"lachend"},{"merkwürdig"},{"behaart"},{"leblos"},{"aufgeblasen"}, + {"frech"},{"kopflos"},{"schmierig"} +}; + +struct verben verb[]= +{ + {"geht","gehen",6},{"steht","stehen",2},{"sitzt","sitzen",2}, + {"spielt","spielen",7},{"singt","singen",2},{"trinkt","trinken",3}, + {"redet","reden",2}, {"liebt","lieben",7},{"schläft","schlafen",2}, + {"ißt","essen",3},{"lacht","lachen",2},{"tötet","töten",7}, + {"lügt","lügen",2},{"fliegt","fliegen",2},{"überfährt","überfahren",7}, + {"sieht","sehen",3},{"hört","hören",3},{"spricht","sprechen",2}, + {"berechnet","rechnen",3},{"schwimmt","schwimmen",2}, + {"zerschneidet","zerschnitten werden",3},{"raucht","rauchen",3}, + {"spaltet","spalten",3},{"verbrennt","verbrennen",2},{"ist","sein",2}, + {"hat","haben",1},{"zerbricht","zerbrechen",3},{"muss","müssen",4}, + {"kann","können",4},{"darf","dürfen",4},{"will","wollen",5}, + {"klaut","klauen",1},{"soll","sollen",4},{"studiert","studieren",3}, + {"reibt","reiben",3},{"liest","lesen",2},{"irrt","irren",2}, + {"spendiert","spendieren",1},{"schlägt","schlagen",3},{"fragt","fragen",7}, + {"zerstört","zerstören",1},{"erschießt","sich erschießen",1}, + {"überlegt","überlegen",2},{"trifft","treffen",7},{"leckt","lecken",1}, + {"wirft","werfen",1},{"vergiftet","vergiftet werden",1}, + {"öffnet","öffnen",1},{"schreit","schreien",2},{"sprengt","explodieren",3}, + {"erwürgt","würgen",7},{"arbeitet","arbeiten",2},{"erlegt","erlegen",1}, + {"putzt","putzen",1},{"stirbt","sterben",2}, {"kauft","kaufen",1}, + {"brüllt","brüllen",2},{"versteht","es verstehen",7}, + {"zertritt","zertreten werden",1},{"verendet","verenden",2}, + {"labert","labern",2},{"kratzt","kratzen",1},{"wird","nichts werden",2}, + {"entkleidet","sich entkleiden",7},{"verbiegt","sich verbiegen",1}, + {"verschenkt","es verschenken",7},{"vergisst","es vergessen",1}, + {"ergreift","greifen",1},{"baut","bauen",1},{"betet","beten",}, + {"rollt","rollen",3},{"bleibt","bleiben",2},{"wäscht","sich waschen",1}, + {"heiratet","heiraten",7},{"hebt","heben",1},{"denkt","nachdenken",2} +}; + +void end_sach_aus(void); +void nam_aus(void); +void end_nam_aus(void); +void adj_aus(void); +int verb_aus_k(void); +int verb_aus_gr(void); +int zufall(int); + +int main() +{ + int vindx; + int rem=0; + char end; + + setbuf(stdout, NULL); + randomize(); + printf("\n\t\t************************"); + printf("\n\t\t* DER ELEKTRISCHE POET *"); + printf("\n\t\t************************\n"); + printf("\n\tCopyright by J. Ahrensfeld & T. Burr"); + printf("\n\n\tFür die Texte ist Ihr Computer verantwortlich :-)\n"); + printf("\n\tZum beenden des Programmes 'x' eingeben!\n"); + printf("\n\tWeiter mit beliebiger Taste!\n"); + end = getch(); + + while(end != 'x') + { + if(rem >= 10) + { + printf("\n\n\tZum beenden des Programmes 'x' eingeben!\n"); + rem = 0; + if(getch() == 'x') + break; + } + printf("\n\n"); + nam_aus(); + + vindx=verb_aus_k(); + + switch (vindx) + { + case 1: end_sach_aus(); break; + + case 2: adj_aus(); break; + + case 3: end_sach_aus(); break; + + case 4: verb_aus_gr(); break; + + case 5: verb_aus_gr(); break; + + case 6: adj_aus(); break; + + case 7: end_nam_aus(); break; + } + + printf("."); + end = getch(); + rem++; + + } + printf("\n\n\tDas ist das Ende!"); + return 0; +} + +int zufall(int max) +{ + + return (rand()%max); +} + +void adj_aus(void) +{ + printf("%s", ad[zufall((sizeof(ad)/sizeof(*ad)))].adj); + return; +} + +void end_sach_aus(void) +{ + int index; + + index = zufall(sizeof(sachen)/sizeof(*sachen)); + if (sachen[index].sex==1) + printf("d%s", art[3]); + else + printf("d%s", art[(sachen[index].sex)-1]); + printf(" "); + adj_aus(); + if (sachen[index].sex==1) + printf("en %s", sachen[index].subst); + else + printf("e %s", sachen[index].subst); + return; +} + +void nam_aus(void) +{ + int index; + + index = zufall(sizeof(namen)/sizeof(*namen)); + printf("D%s", art[(namen[index].sex)-1]); + printf(" "); + adj_aus(); + printf("e %s " ,namen[index].subst); + return; +} + +void end_nam_aus(void) +{ + int index; + + index = zufall(sizeof(namen)/sizeof(*namen)); + if (namen[index].sex==1) + printf("d%s", art[3]); + else + printf("d%s", art[(namen[index].sex)-1]); + printf(" "); + adj_aus(); + if (namen[index].sex==1) + printf("en %s", namen[index].subst); + else + printf("e %s", namen[index].subst); + return; +} + +int verb_aus_k(void) +{ + int index; + + index = zufall(sizeof(verb)/sizeof(*verb)); + printf("%s ", verb[index].verb_k); + return (verb[index].art); +} + +int verb_aus_gr(void) +{ + int index; + + index = zufall(sizeof(verb)/sizeof(*verb)); + printf("%s", verb[index].verb_gr); + return index; +} diff --git a/lib/CPUs/MIPS/bsp/examples/queens.c b/lib/CPUs/MIPS/bsp/examples/queens.c new file mode 100644 index 0000000..f9735e6 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/queens.c @@ -0,0 +1,856 @@ +/* +** Queens.c -- Find solutions to the Eight-Queens chess problem. +** Roberto Sierra 7/25/93 Version 1.1 +** 3/19/84 Version 1.0 +** +** Description: +** This program finds all the possible ways that N queens can +** be placed on an NxN chessboard so that the queens cannot +** capture one another -- that is, so that no rank, file or +** diagonal is occupied by more than one queen. By default, +** the program prints the first solution it finds. You can +** use the -a option to print all solutions, or the -c option +** just to count them. The program allows the chess board +** to be from 1x1 (trivial case) to 100x100. Warning: the +** larger the chess board, the longer it typically takes to +** find each solution, even though there may be more of them. +** +** This is a terrific example of the utility of recursion. The +** algorithm uses recursion to drastically limit the number +** of board positions that are tested. The program is able +** to find all 8x8 queen solutions in a fraction of a second +** (not counting print time). The code makes no attempt to +** eliminate symmetrical solutions, so the number of solutions +** reported will always be higher than the actual number of +** distinct solutions. +** +** +** Usage: +** Queens [-ac] n +** +** n number of queens (rows and columns). +** An integer from 1 to 100. +** -a Find (and print) all solutions. +** -c Count all solutions, but do not print them. +** +** The output is sent to stdout. All errors messages are +** sent to stderr. If a problem arises, the return code is -1. +** +** +** Examples: +** +** Queens 8 ## Show an 8x8 solution +** 8 queens on a 8x8 board... +** Q - - - - - - - +** - - - - Q - - - +** - - - - - - - Q +** - - - - - Q - - +** - - Q - - - - - +** - - - - - - Q - +** - Q - - - - - - +** - - - Q - - - - +** +** Queens -c 8 ## Count all 8x8 solutions +** 8 queens on a 8x8 board... +** ...there are 92 solutions. +** +** Queens -a 4 ## Show all 4x4 solutions +** 4 queens on a 4x4 board... +** +** Solution #1: +** - Q - - +** - - - Q +** Q - - - +** - - Q - +** +** Solution #2: +** - - Q - +** Q - - - +** - - - Q +** - Q - - +** +** ...there are 2 solutions. +** +** +** Build Instructions: +** You'll need an ANSI C compiler (or the willingness to edit +** the program a bit). If you've got Gnu C, then you can +** compile and load the program as follows: +** +** gcc Queens.c -ansi -o Queens +** +** [If you're using MPW on the Mac, define '-d MPW' on the +** compile line so that background processing will occur.] +** +** +** Algorithm: +** In a 1984 Byte article, I ran across an interesting letter +** from a high school student who was attempting to solve the +** Eight Queens problem using a BASIC interpreter. He had +** developed a program which placed eight queens successively +** on all sixty-four squares, testing for conflicts at each +** iteration. Of course, such a program would require 64^8 +** iterations (about 2.8x10^14 iterations). Even in C on a, +** fast CPU, this could take months or years. Byte's answer was +** to alter the loops so that the queens resided on separate +** ranks, thereby reducing the number of iterations required +** to find all solutions to 8^8 iterations (about 16 million). +** More reasonable, but still requiring a chunk of CPU time. +** +** I puzzled about this problem a bit, and came to realize that +** this was still wasting a lot of CPU cycles. Though I'm sure +** others have come up with good algorithms, I decided to come +** up with my own, with a particular eye on efficiency. The +** resulting algorithm finds all 8x8 solutions in a fraction +** of a second (there are 92 solutions, including rotations). +** On a Sun 4, it'll find all 365,596 solutions on a 14x14 board +** in a bit over 2 minutes (printing them out requires extra +** time, of course). Even Byte's solution would require 14^14 +** iterations (about 10^16) which would take aeons. +** +** My algorithm works as follows: +** (1) Place a queen in the top left corner. +** (2) Place another queen immediately below. +** (3) Test for conflicts. If the second queen conflicts (it +** does at first), then move it one square to the right. +** (4) Loop step 3 until there are no conflicts. Place +** the next queen on the board and recurse. +** (5) If any queen reaches the right edge of the board, +** remove it and 'pop' to the previous recursion level. +** (6) Now repeat these steps recursively until all eight +** queens (or however many) have been placed without +** conflict -- the result is a solution to the problem, +** which is counted and optionally printed. +** +** Because conflicts are tested as the recursion proceeds, +** this has the effect of 'pruning' the recursion so that +** a large number of board positions are not even attempted. +** The result is that the algorithm runs in reasonable time. +** +** I used a few tricks to make the test-for-conflict code +** extremely efficient -- there is no 'inner' loop to search +** along ranks, files, or diagonals. A series of arrays are +** maintained instead which indicate which queen currently +** 'owns' each rank, file or diagonal. This makes the +** algorithm really fly, though the code is a little hard to +** read. Lastly, pointer arithmetic is used to reduce the +** number of implicit multiplications used in array addressing. +** +** +** Contact: +** For queries regarding this program, contact Roberto Sierra +** at any of the following addresses: +** +** Roberto Sierra +** bert@netcom.com (preferred address) +** 73557.2101@compuserve.com +** +** Tempered MicroDesigns +** P.O. Box 170638 +** San Francisco, CA 94117 +** +** +** Fine Print: +** This program is in the public domain and can be used for +** any purpose whatsoever, including commercial application. +** [I'd like to hear what you do with it, though.] +** Absolutely no warranty or liability is implied or extended +** by the author. +** +** +** Modification History: +** PRS 3/19/84 v1.0 -- Original version. +** PRS 7/25/93 v1.1 -- ANSIfied the code. More efficient pointers. +** +*/ + +/***************************************************************/ +/* Timer options. You MUST uncomment one of the options below */ +/* or compile, for example, with the '-DUNIX' option. */ +/***************************************************************/ +/* #define Amiga */ +/* #define UNIX */ +/* #define UNIX_Old */ +/* #define VMS */ +/* #define BORLAND_C */ +/* #define MSC */ +/* #define MAC */ +/* #define IPSC */ +/* #define FORTRAN_SEC */ +/* #define GTODay */ +/* #define CTimer */ +/* #define UXPM */ +/* #define MAC_TMgr */ +/* #define PARIX */ +/* #define POSIX */ +/* #define WIN32 */ +/* #define POSIX1 */ +/***********************/ + +#include /* Need standard I/O functions */ +#include /* Need exit() routine interface */ +#include /* Need strcmp() interface */ +#ifdef MPW /* Macintosh MPW ONLY */ +#include /* Need cursor control interfaces */ +#endif + +#define MAXQUEENS 100 /* Maximum number of queens */ +#define MAXRANKS MAXQUEENS /* Maximum number of ranks (rows) */ +#define MAXFILES MAXQUEENS /* Maximum number of files (columns) */ +#define MAXDIAGS (MAXRANKS+MAXFILES-1) /* Maximum number of diagonals */ +#define EMPTY (MAXQUEENS+1) /* Marks unoccupied file or diagonal */ + +/* GLOBAL VARIABLES */ + +int queens; /* Number of queens to place */ +int ranks; /* Number of ranks (rows) */ +int files; /* Number of files (columns) */ +int printing = 1; /* TRUE if printing positions */ +int findall = 0; /* TRUE if finding all solutions */ + +unsigned long solutions = 0; /* Number of solutions found */ +int queen[MAXRANKS]; /* File on which each queen is located */ +int file[MAXFILES]; /* Which queen 'owns' each file */ +int fordiag[MAXDIAGS]; /* Which queen 'owns' forward diagonals */ +int bakdiag[MAXDIAGS]; /* Which queen 'owns' reverse diagonals */ +char *progname = 0; /* The name of this program */ + + + + + +/***********************/ +/**** ROUTINES ****/ +/***********************/ + +/* Internal prototypes */ +//void main(int argc,char **argv); /* Main program */ +void find(int level); /* Algorithm to find solutions */ +void pboard(void); /* Print a solution */ +void run_queens(int argc,char **argv); + + + + +/*---------------------- main() --------------------------- +** MAIN program. The main purpose of this routine is +** to deal with decoding the command line arguments, +** initializing the various arrays, and starting the +** recursive search routine. +*/ +int main(void) +{ + char *args[] = {"queens", "-c", "12"}; + run_queens(3, args); +} + +void run_queens(int argc,char **argv) +{ + register int i; /* Loop variable */ + register char *p; /* Pointer to argument */ + double starttime, benchtime, dtime(); + +#ifdef MPW /* Macintosh MPW ONLY */ + InitCursorCtl(0); /* Enable cursor control */ +#endif + + progname = argv[0]; /* The name of the program */ + + /**** DECODE COMMAND LINE ARGUMENTS ****/ + + for (i=1; i MAXQUEENS) { /* N can't be too large */ + fprintf(stderr,"%s: can't have more than %d queens\n", + progname, MAXQUEENS); + exit(-1); + } + } /* End of argument test */ + } /* End of argument scan loop */ + if (queens == 0) { + fprintf(stderr,"%s: missing queens argument\n",progname); + fprintf(stderr,"usage: %s [-ac] queens\n",progname); + exit(-1); + } + + + ranks = files = queens; /* NxN board for N queens */ + printf("%d queen%s on a %dx%d board...\n", + queens, queens>1? "s" : "", ranks, files); + fflush(stdout); + + starttime = dtime(); + + /* Initialization */ + solutions = 0; /* No solutions yet */ + for (i=0; i= level && /* No queen on the file? */ + *fdp >= level && *bdp >= level /* No queens on diagonals? */ + ) { + queen[level] = f; /* Note new position of queen */ + *fp = *fdp = *bdp = level; /* Place queen on file & diags */ + find(level+1); /* This level OK, recurse to next */ + *fp = *fdp = *bdp = EMPTY; /* Remove queen from file & diags */ + } /* End of conflict test */ + } /* End of file loop */ + } /* End if (level == queens) */ +} /* End of find() */ + + + + +/*------------------------- pboard() ----------------------- +** This routines prints the board for a particular solution. +** The output is sent to stdout. +*/ + +void pboard(void) +{ + register int i,j; /* Rank/File indices */ + + if (findall) { /* Only if searching for all */ + printf("\nSolution #%lu:\n",solutions); /* Print solution number */ + } + for (i=0; i +#define HZ 50 + +double dtime() +{ + double q; + + struct tt + { + long days; + long minutes; + long ticks; + } tt; + + DateStamp(&tt); + + q = ((double)(tt.ticks + (tt.minutes * 60L * 50L))) / (double)HZ; + + return q; +} +#endif + +/*****************************************************/ +/* UNIX dtime(). This is the preferred UNIX timer. */ +/* Provided by: Markku Kolkka, mk59200@cc.tut.fi */ +/* HP-UX Addition by: Bo Thide', bt@irfu.se */ +/*****************************************************/ +#ifdef UNIX +#include +#include + +#ifdef hpux +#include +#define getrusage(a,b) syscall(SYS_getrusage,a,b) +#endif + +struct rusage rusage; + +double dtime() +{ + double q; + + getrusage(RUSAGE_SELF,&rusage); + + q = (double)(rusage.ru_utime.tv_sec); + q = q + (double)(rusage.ru_utime.tv_usec) * 1.0e-06; + + return q; +} +#endif + +/***************************************************/ +/* UNIX_Old dtime(). This is the old UNIX timer. */ +/* Make sure HZ is properly defined in param.h !! */ +/***************************************************/ +#ifdef UNIX_Old +#include +#include +#include + +#ifndef HZ +#define HZ 60 +#endif + +struct tms tms; + +double dtime() +{ + double q; + + times(&tms); + + q = (double)(tms.tms_utime) / (double)HZ; + + return q; +} +#endif + +/*********************************************************/ +/* VMS dtime() for VMS systems. */ +/* Provided by: RAMO@uvphys.phys.UVic.CA */ +/* Some people have run into problems with this timer. */ +/*********************************************************/ +#ifdef VMS +#include time + +#ifndef HZ +#define HZ 100 +#endif + +struct tbuffer_t + { + int proc_user_time; + int proc_system_time; + int child_user_time; + int child_system_time; + }; + +struct tbuffer_t tms; + +double dtime() +{ + double q; + + times(&tms); + + q = (double)(tms.proc_user_time) / (double)HZ; + + return q; +} +#endif + +/******************************/ +/* BORLAND C dtime() for DOS */ +/******************************/ +#ifdef BORLAND_C +#include +#include +#include + +#define HZ 100 +struct time tnow; + +double dtime() +{ + double q; + + gettime(&tnow); + + q = 60.0 * (double)(tnow.ti_min); + q = q + (double)(tnow.ti_sec); + q = q + (double)(tnow.ti_hund)/(double)HZ; + + return q; +} +#endif + +/**************************************/ +/* Microsoft C (MSC) dtime() for DOS */ +/**************************************/ +#ifdef MSC +#include +#include + +#define HZ CLOCKS_PER_SEC +clock_t tnow; + +double dtime() +{ + double q; + + tnow = clock(); + + q = (double)tnow / (double)HZ; + + return q; +} +#endif + +/*************************************/ +/* Macintosh (MAC) Think C dtime() */ +/*************************************/ +#ifdef MAC +#include + +#define HZ 60 + +double dtime() +{ + double q; + + q = (double)clock() / (double)HZ; + + return q; +} +#endif + +/************************************************************/ +/* iPSC/860 (IPSC) dtime() for i860. */ +/* Provided by: Dan Yergeau, yergeau@gloworm.Stanford.EDU */ +/************************************************************/ +#ifdef IPSC +extern double dclock(); + +double dtime() +{ + double q; + + q = dclock(); + + return q; +} +#endif + +/**************************************************/ +/* FORTRAN dtime() for Cray type systems. */ +/* This is the preferred timer for Cray systems. */ +/**************************************************/ +#ifdef FORTRAN_SEC + +fortran double second(); + +double dtime() +{ + double q; + + second(&q); + + return q; +} +#endif + +/***********************************************************/ +/* UNICOS C dtime() for Cray UNICOS systems. Don't use */ +/* unless absolutely necessary as returned time includes */ +/* 'user+system' time. Provided by: R. Mike Dority, */ +/* dority@craysea.cray.com */ +/***********************************************************/ +#ifdef CTimer +#include + +double dtime() +{ + double q; + clock_t clock(void); + + q = (double)clock() / (double)CLOCKS_PER_SEC; + + return q; +} +#endif + +/********************************************/ +/* Another UNIX timer using gettimeofday(). */ +/* However, getrusage() is preferred. */ +/********************************************/ +#ifdef GTODay +#include + +struct timeval tnow; + +double dtime() +{ + double q; + + gettimeofday(&tnow,NULL); + q = (double)tnow.tv_sec + (double)tnow.tv_usec * 1.0e-6; + + return q; +} +#endif + +/*****************************************************/ +/* Fujitsu UXP/M timer. */ +/* Provided by: Mathew Lim, ANUSF, M.Lim@anu.edu.au */ +/*****************************************************/ +#ifdef UXPM +#include +#include +struct tmsu rusage; + +double dtime() +{ + double q; + + timesu(&rusage); + + q = (double)(rusage.tms_utime) * 1.0e-06; + + return q; +} +#endif + +/**********************************************/ +/* Macintosh (MAC_TMgr) Think C dtime() */ +/* requires Think C Language Extensions or */ +/* #include in the prefix */ +/* provided by Francis H Schiffer 3rd (fhs) */ +/* skipschiffer@genie.geis.com */ +/**********************************************/ +#ifdef MAC_TMgr +#include +#include + +static TMTask mgrTimer; +static Boolean mgrInited = false; +static double mgrClock; + +#define RMV_TIMER RmvTime( (QElemPtr)&mgrTimer ) +#define MAX_TIME 1800000000L +/* MAX_TIME limits time between calls to */ +/* dtime( ) to no more than 30 minutes */ +/* this limitation could be removed by */ +/* creating a completion routine to sum */ +/* 30 minute segments (fhs 1994 feb 9) */ + +static void Remove_timer( ) +{ + RMV_TIMER; + mgrInited = false; +} + +double dtime( ) +{ + if( mgrInited ) { + RMV_TIMER; + mgrClock += (MAX_TIME + mgrTimer.tmCount)*1.0e-6; + } else { + if( _atexit( &Remove_timer ) == 0 ) mgrInited = true; + mgrClock = 0.0; + } + + if ( mgrInited ) + { + mgrTimer.tmAddr = NULL; + mgrTimer.tmCount = 0; + mgrTimer.tmWakeUp = 0; + mgrTimer.tmReserved = 0; + InsTime( (QElemPtr)&mgrTimer ); + PrimeTime( (QElemPtr)&mgrTimer, -MAX_TIME ); + } + return( mgrClock ); +} +#endif + +/***********************************************************/ +/* Parsytec GCel timer. */ +/* Provided by: Georg Wambach, gw@informatik.uni-koeln.de */ +/***********************************************************/ +#ifdef PARIX +#include + +double dtime() +{ + double q; + + q = (double) (TimeNowHigh()) / (double) CLK_TCK_HIGH; + + return q; +} +#endif + +/************************************************/ +/* Sun Solaris POSIX dtime() routine */ +/* Provided by: Case Larsen, CTLarsen.lbl.gov */ +/************************************************/ +#ifdef POSIX +#include +#include +#include + +#ifdef __hpux +#include +#endif + +struct rusage rusage; + +double dtime() +{ + double q; + + getrusage(RUSAGE_SELF,&rusage); + + q = (double)(rusage.ru_utime.tv_sec); + q = q + (double)(rusage.ru_utime.tv_nsec) * 1.0e-09; + + return q; +} +#endif + + +/****************************************************/ +/* Windows NT (32 bit) dtime() routine */ +/* Provided by: Piers Haken, piersh@microsoft.com */ +/****************************************************/ +#ifdef WIN32 +#include + +double dtime(void) +{ + double q; + + q = (double)GetTickCount() * 1.0e-03; + + return q; +} +#endif + +/*****************************************************/ +/* Time according to POSIX.1 - */ +/* Ref: "POSIX Programmer's Guide" O'Reilly & Assoc.*/ +/*****************************************************/ +#ifdef POSIX1 +#define _POSIX_SOURCE 1 +#include +#include +#include + +struct tms tms; + +double dtime() +{ + double q; + times(&tms); + q = (double)tms.tms_utime / (double)CLK_TCK; + return q; +} +#endif + +/*-------- End of queens.c, Say goodnight Linda! --------*/ diff --git a/lib/CPUs/MIPS/bsp/examples/random.c b/lib/CPUs/MIPS/bsp/examples/random.c new file mode 100644 index 0000000..c5f6615 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/random.c @@ -0,0 +1,86 @@ +/* random.c + + Author: Numerical recipes (ran1, gaussian), Jon Hamkins (others) + Revised by: Jon Hamkins + Date: 4-16-98 +*/ + +#include + +#define IA 16807 +#define IM 2147483647 +#define AM (1.0/IM) +#define IQ 127773 +#define IR 2836 +#define NTAB 32 +#define NDIV (1+(IM-1)/NTAB) +#define EPS 1.2e-14 +#define RNMX (1.0-EPS) +/* From Numerical Recipes, p. 280, modified from float to double */ +/* returns a uniform deviate in (0,1) */ +double ran1(long *idum) +{ + int j; + long k; + static long iy=0; + static long iv[NTAB]; + double temp; + + if (*idum <=0 || !iy) { + if (-(*idum) < 1) *idum=1; + else *idum = -(*idum); + for (j=NTAB+7; j>=0; j--) { + k=(*idum)/IQ; + *idum=IA*(*idum-k*IQ)-IR*k; + if (*idum < 0) *idum += IM; + if (j < NTAB) iv[j] = *idum; + } + iy = iv[0]; + } + k=(*idum)/IQ; + *idum=IA*(*idum-k*IQ)-IR*k; + if (*idum < 0) *idum += IM; + j=iy/NDIV; + iy=iv[j]; + iv[j] = *idum; + if ((temp=AM*iy) > RNMX) return RNMX; + else return temp; +} +#undef IA +#undef IM +#undef AM +#undef IQ +#undef IR +#undef NTAB +#undef NDIV +#undef EPS +#undef RNMX + +/* Generate a N(0,1) r.v. */ +double gaussian(long *idum) +{ + static int iset=0; + static double gset; + double fac,r,v1,v2; + double ran1(); + if (iset == 0) { + do { + v1=2.0*ran1(idum)-1.0; + v2=2.0*ran1(idum)-1.0; + r=v1*v1+v2*v2; + } while (r >= 1.0 || r == 0.0); + fac=sqrt(-2.0*log(r)/r); + gset=v1*fac; + iset=1; + return v2*fac; + } else { + iset=0; + return gset; + } +} + +/* generate a random bit */ +int random_bit(long *idum) +{ + return((ran1(idum)<0.5) ? 0 : 1); +} diff --git a/lib/CPUs/MIPS/bsp/examples/random.h b/lib/CPUs/MIPS/bsp/examples/random.h new file mode 100644 index 0000000..673d6af --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/random.h @@ -0,0 +1,6 @@ +/* random.h */ + +/* functions provided by random.c */ +extern double ran1(long *idum); +extern double gaussian(long *idum); +extern int random_bit(long *idum); diff --git a/lib/CPUs/MIPS/bsp/examples/regdef.h b/lib/CPUs/MIPS/bsp/examples/regdef.h new file mode 100644 index 0000000..60c6c2a --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/regdef.h @@ -0,0 +1,81 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1985 MIPS Computer Systems, Inc. + * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle + * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. + */ +#ifndef _ASM_REGDEF_H +#define _ASM_REGDEF_H + +/* + * Symbolic register names for 32 bit ABI + */ +#define zero $0 /* wired zero */ +#define AT $1 /* assembler temp - uppercase because of ".set at" */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 /* caller saved */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 +#define jp $25 /* PIC jump register */ +#define k0 $26 /* kernel scratch */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define s8 $30 /* same like fp! */ +#define ra $31 /* return address */ + +/* CP0 registers */ +#define CP0_INDEX $0 /* R3000 available */ +#define CP0_RANDOM $1 /* R3000 available */ +#define CP0_ENTRYLO $2 /* R3000 available */ +#define CP0_CONTEXT $4 /* R3000 available */ +#define CP0_BADDR $8 /* R3000 available */ +#define CP0_ENTRYHI $10 /* R3000 available */ +#define CP0_SR $12 /* R3000 available */ +#define CP0_CR $13 /* R3000 available */ +#define CP0_EPC $14 /* R3000 available */ +#define CP0_PRID $15 /* R3000 available */ + +/* Status register masks */ +#define SR_MASK_IEC 0x00000001 +#define SR_MASK_KUC 0x00000002 +#define SR_MASK_IEP 0x00000004 +#define SR_MASK_KUP 0x00000008 +#define SR_MASK_IEO 0x00000010 +#define SR_MASK_KUO 0x00000020 +#define SR_MASK_IM 0x0000FF00 +#define SR_MASK_DS 0x00FF0000 +#define SR_MASK_RE 0x01000000 +#define SR_MASK_CU 0xF0000000 + +/* Cause register masks */ +#define CR_MASK_EXC 0x0000007C +#define CR_MASK_IP 0x0000FF00 +#define CR_MASK_CE 0x40000000 +#define CR_MASK_BD 0x80000000 + +#endif /* _ASM_REGDEF_H */ diff --git a/lib/CPUs/MIPS/bsp/examples/rmd160.c b/lib/CPUs/MIPS/bsp/examples/rmd160.c new file mode 100644 index 0000000..8b0f2c7 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/rmd160.c @@ -0,0 +1,294 @@ +/********************************************************************\ + * + * FILE: rmd160.c + * + * CONTENTS: A sample C-implementation of the RIPEMD-160 + * hash-function. + * TARGET: any computer with an ANSI C compiler + * + * AUTHOR: Antoon Bosselaers, ESAT-COSIC + * DATE: 1 March 1996 + * VERSION: 1.0 + * + * Copyright (c) Katholieke Universiteit Leuven + * 1996, All Rights Reserved + * + * Conditions for use of the RIPEMD-160 Software + * + * The RIPEMD-160 software is freely available for use under the terms and + * conditions described hereunder, which shall be deemed to be accepted by + * any user of the software and applicable on any use of the software: + * + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for + * all purposes be considered the owner of the RIPEMD-160 software and of + * all copyright, trade secret, patent or other intellectual property + * rights therein. + * 2. The RIPEMD-160 software is provided on an "as is" basis without + * warranty of any sort, express or implied. K.U.Leuven makes no + * representation that the use of the software will not infringe any + * patent or proprietary right of third parties. User will indemnify + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities + * which may arise as a result of its use of the software. In no + * circumstances K.U.Leuven R&D will be held liable for any deficiency, + * fault or other mishappening with regard to the use or performance of + * the software. + * 3. User agrees to give due credit to K.U.Leuven in scientific publications + * or communications in relation with the use of the RIPEMD-160 software + * as follows: RIPEMD-160 software written by Antoon Bosselaers, + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/. + * +\********************************************************************/ + +/* header files */ +#include +#include +#include +#include "rmd160.h" + +/********************************************************************/ + +void MDinit(dword *MDbuf) +{ + MDbuf[0] = 0x67452301UL; + MDbuf[1] = 0xefcdab89UL; + MDbuf[2] = 0x98badcfeUL; + MDbuf[3] = 0x10325476UL; + MDbuf[4] = 0xc3d2e1f0UL; + + return; +} + +/********************************************************************/ + +void compress(dword *MDbuf, dword *X) +{ + dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], + dd = MDbuf[3], ee = MDbuf[4]; + dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], + ddd = MDbuf[3], eee = MDbuf[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ + MDbuf[1] = MDbuf[2] + dd + eee; + MDbuf[2] = MDbuf[3] + ee + aaa; + MDbuf[3] = MDbuf[4] + aa + bbb; + MDbuf[4] = MDbuf[0] + bb + ccc; + MDbuf[0] = ddd; + + return; +} + +/********************************************************************/ + +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen) +{ + unsigned int i; /* counter */ + dword X[16]; /* message words */ + + memset(X, 0, 16*sizeof(dword)); + + /* put bytes from strptr into X */ + for (i=0; i<(lswlen&63); i++) { + /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ + X[i>>2] ^= (dword) *strptr++ << (8 * (i&3)); + } + + /* append the bit m_n == 1 */ + X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7); + + if ((lswlen & 63) > 55) { + /* length goes to next block */ + compress(MDbuf, X); + memset(X, 0, 16*sizeof(dword)); + } + + /* append length in bits*/ + X[14] = lswlen << 3; + X[15] = (lswlen >> 29) | (mswlen << 3); + compress(MDbuf, X); + + return; +} + +/************************ end of file rmd160.c **********************/ + diff --git a/lib/CPUs/MIPS/bsp/examples/rmd160.h b/lib/CPUs/MIPS/bsp/examples/rmd160.h new file mode 100644 index 0000000..70a33a6 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/rmd160.h @@ -0,0 +1,154 @@ +/********************************************************************\ + * + * FILE: rmd160.h + * + * CONTENTS: Header file for a sample C-implementation of the + * RIPEMD-160 hash-function. + * TARGET: any computer with an ANSI C compiler + * + * AUTHOR: Antoon Bosselaers, ESAT-COSIC + * DATE: 1 March 1996 + * VERSION: 1.0 + * + * Copyright (c) Katholieke Universiteit Leuven + * 1996, All Rights Reserved + * + * Conditions for use of the RIPEMD-160 Software + * + * The RIPEMD-160 software is freely available for use under the terms and + * conditions described hereunder, which shall be deemed to be accepted by + * any user of the software and applicable on any use of the software: + * + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for + * all purposes be considered the owner of the RIPEMD-160 software and of + * all copyright, trade secret, patent or other intellectual property + * rights therein. + * 2. The RIPEMD-160 software is provided on an "as is" basis without + * warranty of any sort, express or implied. K.U.Leuven makes no + * representation that the use of the software will not infringe any + * patent or proprietary right of third parties. User will indemnify + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities + * which may arise as a result of its use of the software. In no + * circumstances K.U.Leuven R&D will be held liable for any deficiency, + * fault or other mishappening with regard to the use or performance of + * the software. + * 3. User agrees to give due credit to K.U.Leuven in scientific publications + * or communications in relation with the use of the RIPEMD-160 software + * as follows: RIPEMD-160 software written by Antoon Bosselaers, + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/. + * +\********************************************************************/ + +#ifndef RMD160H /* make sure this file is read only once */ +#define RMD160H + +/********************************************************************/ + +/* typedef 8 and 32 bit types, resp. */ +/* adapt these, if necessary, + for your operating system and compiler */ +typedef unsigned char byte; +typedef unsigned long dword; + + +/********************************************************************/ + +/* macro definitions */ + +/* collect four bytes into one word: */ +#define BYTES_TO_DWORD(strptr) \ + (((dword) *((strptr)+3) << 24) | \ + ((dword) *((strptr)+2) << 16) | \ + ((dword) *((strptr)+1) << 8) | \ + ((dword) *(strptr))) + +/* ROL(x, n) cyclically rotates x over n bits to the left */ +/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ +#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) {\ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define GG(a, b, c, d, e, x, s) {\ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define HH(a, b, c, d, e, x, s) {\ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define II(a, b, c, d, e, x, s) {\ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define JJ(a, b, c, d, e, x, s) {\ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define FFF(a, b, c, d, e, x, s) {\ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define GGG(a, b, c, d, e, x, s) {\ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define HHH(a, b, c, d, e, x, s) {\ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define III(a, b, c, d, e, x, s) {\ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } +#define JJJ(a, b, c, d, e, x, s) {\ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10);\ + } + +/********************************************************************/ + +/* function prototypes */ + +void MDinit(dword *MDbuf); +/* + * initializes MDbuffer to "magic constants" + */ + +void compress(dword *MDbuf, dword *X); +/* + * the compression function. + * transforms MDbuf using message bytes X[0] through X[15] + */ + +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen); +/* + * puts bytes from strptr into X and pad out; appends length + * and finally, compresses the last block(s) + * note: length in bits == 8 * (lswlen + 2^32 mswlen). + * note: there are (lswlen mod 64) bytes left in strptr. + */ + +#endif /* RMD160H */ + +/*********************** end of file rmd160.h ***********************/ + diff --git a/lib/CPUs/MIPS/bsp/examples/rmd160_test.c b/lib/CPUs/MIPS/bsp/examples/rmd160_test.c new file mode 100644 index 0000000..d4d15ec --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/rmd160_test.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include "libsys.h" + +#include "rmd160.h" + +#ifndef RMDsize +#define RMDsize 160 +#endif + +byte *RMD(byte *message) +/* + * returns RMD(message) + * message should be a string terminated by '\0' + */ +{ + dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */ + static byte hashcode[RMDsize/8]; /* for final hash-value */ + dword X[16]; /* current 16-word chunk */ + unsigned int i; /* counter */ + dword length; /* length in bytes of message */ + dword nbytes; /* # of bytes not yet processed */ + + /* initialize */ + MDinit(MDbuf); + length = (dword)strlen((char *)message); + + /* process message in 16-word chunks */ + for (nbytes=length; nbytes > 63; nbytes-=64) { + for (i=0; i<16; i++) { + X[i] = BYTES_TO_DWORD(message); + message += 4; + } + compress(MDbuf, X); + } /* length mod 64 bytes left */ + + /* finish: */ + MDfinish(MDbuf, message, length, 0); + + for (i=0; i>2]; /* implicit cast to byte */ + hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */ + hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */ + hashcode[i+3] = (MDbuf[i>>2] >> 24); + } + + return (byte *)hashcode; +} + +#define MSG_SIZE 1024*1024 // Bit +int main (void) +{ + int result, i, j, cnt; + byte *hashcode; + byte hashref[] = {0xFC,0x20,0x7B,0x84,0x40,0x1C,0x49,0x0B,0x8D,0x69,0x88,0xD2,0x49,0x20,0x01,0x90,0x41,0x77,0x72,0x59}; + volatile int *pLED = (int*)sys_led_port; + char msg[MSG_SIZE/8]; + char crlf[] = "\n"; + UINT32 start, stop; + + for (i=0; i < MSG_SIZE/8; i++) + msg[i] = 0x55; + + msg[i] = 0; + + setbuf(stdout, NULL); + + cnt = 0; + start = clock(); + stop = start + 1000; + while(1) + { + hashcode = RMD((byte *)msg); + start = clock(); + if (memcmp(hashcode, hashref, sizeof(hashref))) + { + printf("Error RipeMD-160!\n"); + return 1; + } + if (start >= stop) + { + for (i=0; i %d Mbit/s\n\n", cnt, MSG_SIZE/(1024*1024), cnt*MSG_SIZE/(1024*1024)); + start = clock(); + stop = start + 1000; + cnt = 0; + } + cnt++; + } + + return 0; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/stanford.c b/lib/CPUs/MIPS/bsp/examples/stanford.c new file mode 100644 index 0000000..907477b --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/stanford.c @@ -0,0 +1,1117 @@ +/* stanford baby benchmark suite from john hennessy -- + +There are copies all around; the MIPS performance brief has up-to-date +numbers for a bunch of machines. BUT, these wouldn't be my first +choice. SPEC, the industry benchmark collection group, will probably +specify a new set of benchmarks shortly and release then right after +that. I imagine they will include espresso, gcc, and other large, but +public domain programs, for real things. + +here's bench.c + John Hennessy +*/ + + +/* This is a suite of benchmarks that are relatively short, both in program + size and execution time. It requires no input, and prints the execution + time for each program, using the system- dependent routine Getclock, + below, to find out the current CPU time. It does a rudimentary check to + make sure each program gets the right output. These programs were + gathered by John Hennessy and modified by Peter Nye. + +4.2 VERSION */ + +#include +#include +#include +#include + +#ifndef HZ +#define HZ 60 +#endif +#define nil 0 +#define false 0 +#define true 1 +#define bubblebase 1.61 +#define dnfbase 3.5 +#define permbase 1.75 +#define queensbase 1.83 +#define towersbase 2.39 +#define quickbase 1.92 +#define intmmbase 1.46 +#define treebase 2.5 +#define mmbase 0.0 +#define fpmmbase 2.92 +#define puzzlebase 0.5 +#define fftbase 0.0 +#define fpfftbase 4.44 + /* Towers */ +#define maxcells 18 + + /* Intmm, Mm */ +#define rowsize 40 + + /* Puzzle */ +#define size 511 +#define classmax 3 +#define typemax 12 +#define d 8 + + /* Bubble, Quick */ +#define sortelements 5000 +#define srtelements 500 + + /* fft */ +#define fftsize 256 +#define fftsize2 129 +/* +type */ + /* Perm */ +#define permrange 10 + + /* tree */ +struct node +{ + struct node *left, *right; + int val; +}; + +/* Towers *//* + discsizrange = 1..maxcells; */ +#define stackrange 3 +/* cellcursor = 0..maxcells; */ +struct element +{ + int discsize; + int next; +}; +/* emsgtype = packed array[1..15] of char; +*/ +/* Intmm, Mm *//* + index = 1 .. rowsize; + intmatrix = array [index,index] of integer; + realmatrix = array [index,index] of real; + */ +/* Puzzle *//* + piececlass = 0..classmax; + piecetype = 0..typemax; + position = 0..size; + */ +/* Bubble, Quick *//* + listsize = 0..sortelements; + sortarray = array [listsize] of integer; + */ + /* FFT */ +struct complex +{ + float rp, ip; +}; +/* + carray = array [1..fftsize] of complex ; + c2array = array [1..fftsize2] of complex ; +*/ + +float value; +float fixed, floated; + + /* global */ +int timer; +int xtimes[11]; +int seed; + + /* Perm */ +int permarray[permrange + 1]; +int pctr; + + /* tree */ +struct node *tree; + + /* Towers */ +int stack[stackrange + 1]; +struct element cellspace[maxcells + 1]; +int freelist, movesdone; + + /* Intmm, Mm */ +int ima[rowsize + 1][rowsize + 1], imb[rowsize + 1][rowsize + 1], + imr[rowsize + 1][rowsize + 1]; +float rma[rowsize + 1][rowsize + 1], rmb[rowsize + 1][rowsize + 1], + rmr[rowsize + 1][rowsize + 1]; + + /* Puzzle */ +int piececount[classmax + 1], + class[typemax + 1], + piecemax[typemax + 1], + puzzl[size + 1], p[typemax + 1][size + 1], n, kount; + + /* Bubble, Quick */ +int sortlist[sortelements + 1], biggest, littlest, top; + + /* FFT */ +struct complex z[fftsize + 1], w[fftsize + 1], e[fftsize2 + 1]; +float zr, zi; + +/* global procedures */ + +int +Getclock () +{ + struct tms rusage; + times (&rusage); + return ((60*rusage.tms_utime/HZ) * 50 / 3); +}; + +Initrand () +{ + seed = 74755; +}; + +int +Rand () +{ + seed = (seed * 1309 + 13849) & 65535; + return (seed); +}; + + + + /* Permutation program, heavily recursive, written by Denny Brown. */ + +Swap (a, b) + int *a, *b; +{ + int t; + t = *a; + *a = *b; + *b = t; +}; + +Initialize () +{ + int i; + for (i = 1; i <= 7; i++) + { + permarray[i] = i - 1; + }; +}; + +Permute (n) + int n; +{ /* permute */ + int k; + pctr = pctr + 1; + if (n != 1) + { + Permute (n - 1); + for (k = n - 1; k >= 1; k--) + { + Swap (&permarray[n], &permarray[k]); + Permute (n - 1); + Swap (&permarray[n], &permarray[k]); + }; + }; +} /* permute */ ; + +Perm () +{ /* Perm */ + int i; + pctr = 0; + for (i = 1; i <= 5; i++) + { + Initialize (); + Permute (7); + }; + if (pctr != 43300) + printf (" Error in Perm.\n"); +} /* Perm */ ; + + + + /* Program to Solve the Towers of Hanoi */ + +Error (emsg) + char *emsg; +{ + printf (" Error in Towers: %s\n", emsg); +}; + +Makenull (s) +{ + stack[s] = 0; +}; + +int +Getelement () +{ + int temp; + if (freelist > 0) + { + temp = freelist; + freelist = cellspace[freelist].next; + } + else + Error ("out of space "); + return (temp); +}; + +Push (i, s) + int i, s; +{ + int errorfound, localel; + errorfound = false; + if (stack[s] > 0) + if (cellspace[stack[s]].discsize <= i) + { + errorfound = true; + Error ("disc size error"); + }; + if (!errorfound) + { + localel = Getelement (); + cellspace[localel].next = stack[s]; + stack[s] = localel; + cellspace[localel].discsize = i; + } +}; + +Init (s, n) + int s, n; +{ + int discctr; + Makenull (s); + for (discctr = n; discctr >= 1; discctr--) + Push (discctr, s); +}; + +int +Pop (s) + int s; +{ + int temp, temp1; + if (stack[s] > 0) + { + temp1 = cellspace[stack[s]].discsize; + temp = cellspace[stack[s]].next; + cellspace[stack[s]].next = freelist; + freelist = stack[s]; + stack[s] = temp; + return (temp1); + } + else + Error ("nothing to pop "); +}; + +Move (s1, s2) + int s1, s2; +{ + Push (Pop (s1), s2); + movesdone = movesdone + 1; +}; + +tower (i, j, k) + int i, j, k; +{ + int other; + if (k == 1) + Move (i, j); + else + { + other = 6 - i - j; + tower (i, other, k - 1); + Move (i, j); + tower (other, j, k - 1); + } +}; + + +Towers () +{ /* Towers */ + int i; + for (i = 1; i <= maxcells; i++) + cellspace[i].next = i - 1; + freelist = maxcells; + Init (1, 14); + Makenull (2); + Makenull (3); + movesdone = 0; + tower (1, 2, 14); + if (movesdone != 16383) + printf (" Error in Towers.\n"); +}; /* Towers */ + + + /* The eight queens problem, solved 50 times. */ +/* + type + doubleboard = 2..16; + doublenorm = -7..7; + boardrange = 1..8; + aarray = array [boardrange] of boolean; + barray = array [doubleboard] of boolean; + carray = array [doublenorm] of boolean; + xarray = array [boardrange] of boardrange; +*/ + +Try (i, q, a, b, c, x) + int i, *q, a[], b[], c[], x[]; +{ + int j; + j = 0; + *q = false; + while ((!*q) && (j != 8)) + { + j = j + 1; + *q = false; + if (b[j] && a[i + j] && c[i - j + 7]) + { + x[i] = j; + b[j] = false; + a[i + j] = false; + c[i - j + 7] = false; + if (i < 8) + { + Try (i + 1, q, a, b, c, x); + if (!*q) + { + b[j] = true; + a[i + j] = true; + c[i - j + 7] = true; + } + } + else + *q = true; + } + } +}; + +Doit () +{ + int i, q; + int a[9], b[17], c[15], x[9]; + i = 0 - 7; + while (i <= 16) + { + if ((i >= 1) && (i <= 8)) + a[i] = true; + if (i >= 2) + b[i] = true; + if (i <= 7) + c[i + 7] = true; + i = i + 1; + }; + + Try (1, &q, b, a, c, x); + if (!q) + printf (" Error in Queens.\n"); +}; + +Queens () +{ + int i; + for (i = 1; i <= 50; i++) + Doit (); +}; + + /* Multiplies two integer matrices. */ + +Initmatrix (m) + int m[rowsize + 1][rowsize + 1]; +{ + int temp, i, j; + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + { + temp = Rand (); + m[i][j] = temp - (temp / 120) * 120 - 60; + } +}; + +Innerproduct (result, a, b, row, column) + int *result, a[rowsize + 1][rowsize + 1], b[rowsize + 1][rowsize + 1], + row, column; + /* computes the inner product of A[row,*] and B[*,column] */ +{ + int i; + *result = 0; + for (i = 1; i <= rowsize; i++) + *result = *result + a[row][i] * b[i][column]; +}; + +Intmm () +{ + int i, j; + Initrand (); + Initmatrix (ima); + Initmatrix (imb); + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + Innerproduct (&imr[i][j], ima, imb, i, j); +}; + + + /* Multiplies two real matrices. */ + +rInitmatrix (m) + float m[rowsize + 1][rowsize + 1]; +{ + int temp, i, j; + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + { + temp = Rand (); + m[i][j] = (temp - (temp / 120) * 120 - 60) / 3; + } +}; + +rInnerproduct (result, a, b, row, column) + float *result, a[rowsize + 1][rowsize + 1], b[rowsize + 1][rowsize + 1]; + int row, column; + /* computes the inner product of A[row,*] and B[*,column] */ +{ + int i; + *result = 0.0; + for (i = 1; i <= rowsize; i++) + *result = *result + a[row][i] * b[i][column]; +}; + +Mm () +{ + int i, j; + Initrand (); + rInitmatrix (rma); + rInitmatrix (rmb); + for (i = 1; i <= rowsize; i++) + for (j = 1; j <= rowsize; j++) + rInnerproduct (&rmr[i][j], rma, rmb, i, j); +}; + + + + + /* A compute-bound program from Forest Baskett. */ + +int +Fit (i, j) + int i, j; +{ + int k; + for (k = 0; k <= piecemax[i]; k++) + if (p[i][k]) + if (puzzl[j + k]) + return (false); + return (true); +}; + +int +Place (i, j) + int i, j; +{ + int k; + for (k = 0; k <= piecemax[i]; k++) + if (p[i][k]) + puzzl[j + k] = true; + piececount[class[i]] = piececount[class[i]] - 1; + for (k = j; k <= size; k++) + if (!puzzl[k]) + { + return (k); + }; + return (0); +}; + +Remove (i, j) + int i, j; +{ + int k; + for (k = 0; k <= piecemax[i]; k++) + if (p[i][k]) + puzzl[j + k] = false; + piececount[class[i]] = piececount[class[i]] + 1; +}; + +int +Trial (j) + int j; +{ + int i, k; + kount = kount + 1; + for (i = 0; i <= typemax; i++) + if (piececount[class[i]] != 0) + if (Fit (i, j)) + { + k = Place (i, j); + if (Trial (k) || (k == 0)) + { + return (true); + } + else + Remove (i, j); + }; + return (false); +}; + +Puzzle () +{ + int i, j, k, m; + for (m = 0; m <= size; m++) + puzzl[m] = true; + for (i = 1; i <= 5; i++) + for (j = 1; j <= 5; j++) + for (k = 1; k <= 5; k++) + puzzl[i + d * (j + d * k)] = false; + for (i = 0; i <= typemax; i++) + for (m = 0; m <= size; m++) + p[i][m] = false; + for (i = 0; i <= 3; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 0; k++) + p[0][i + d * (j + d * k)] = true; + class[0] = 0; + piecemax[0] = 3 + d * 1 + d * d * 0; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 3; k++) + p[1][i + d * (j + d * k)] = true; + class[1] = 0; + piecemax[1] = 1 + d * 0 + d * d * 3; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 3; j++) + for (k = 0; k <= 1; k++) + p[2][i + d * (j + d * k)] = true; + class[2] = 0; + piecemax[2] = 0 + d * 3 + d * d * 1; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 3; j++) + for (k = 0; k <= 0; k++) + p[3][i + d * (j + d * k)] = true; + class[3] = 0; + piecemax[3] = 1 + d * 3 + d * d * 0; + for (i = 0; i <= 3; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 1; k++) + p[4][i + d * (j + d * k)] = true; + class[4] = 0; + piecemax[4] = 3 + d * 0 + d * d * 1; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 3; k++) + p[5][i + d * (j + d * k)] = true; + class[5] = 0; + piecemax[5] = 0 + d * 1 + d * d * 3; + for (i = 0; i <= 2; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 0; k++) + p[6][i + d * (j + d * k)] = true; + class[6] = 1; + piecemax[6] = 2 + d * 0 + d * d * 0; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 2; j++) + for (k = 0; k <= 0; k++) + p[7][i + d * (j + d * k)] = true; + class[7] = 1; + piecemax[7] = 0 + d * 2 + d * d * 0; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 2; k++) + p[8][i + d * (j + d * k)] = true; + class[8] = 1; + piecemax[8] = 0 + d * 0 + d * d * 2; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 0; k++) + p[9][i + d * (j + d * k)] = true; + class[9] = 2; + piecemax[9] = 1 + d * 1 + d * d * 0; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 0; j++) + for (k = 0; k <= 1; k++) + p[10][i + d * (j + d * k)] = true; + class[10] = 2; + piecemax[10] = 1 + d * 0 + d * d * 1; + for (i = 0; i <= 0; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 1; k++) + p[11][i + d * (j + d * k)] = true; + class[11] = 2; + piecemax[11] = 0 + d * 1 + d * d * 1; + for (i = 0; i <= 1; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 1; k++) + p[12][i + d * (j + d * k)] = true; + class[12] = 3; + piecemax[12] = 1 + d * 1 + d * d * 1; + piececount[0] = 13; + piececount[1] = 3; + piececount[2] = 1; + piececount[3] = 1; + m = 1 + d * (1 + d * 1); + kount = 0; + if (Fit (0, m)) + n = Place (0, m); + else + printf ("Error1 in Puzzle\n"); + if (!Trial (n)) + printf ("Error2 in Puzzle.\n"); + else if (kount != 2005) + printf ("Error3 in Puzzle.\n"); +}; + + + + /* Sorts an array using quicksort */ + +Initarr () +{ + int i, temp; + Initrand (); + biggest = 0; + littlest = 0; + for (i = 1; i <= sortelements; i++) + { + temp = Rand (); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + + if (sortlist[i] > biggest) + biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; +}; + +Quicksort (a, l, r) + int a[], l, r; + /* quicksort the array A from start to finish */ +{ + int i, j, x, w; + + i = l; + j = r; + x = a[(l + r) / 2]; + do + { + while (a[i] < x) + i = i + 1; + while (x < a[j]) + j = j - 1; + if (i <= j) + { + w = a[i]; + a[i] = a[j]; + a[j] = w; + i = i + 1; + j = j - 1; + } + } + while (i <= j); + if (l < j) + Quicksort (a, l, j); + if (i < r) + Quicksort (a, i, r); +}; + + +Quick () +{ + Initarr (); + Quicksort (sortlist, 1, sortelements); + if ((sortlist[1] != littlest) || (sortlist[sortelements] != biggest)) + { + printf (" Error in Quick.\n"); + } + +}; + + + /* Sorts an array using treesort */ + +tInitarr () +{ + int i, temp; + Initrand (); + biggest = 0; + littlest = 0; + for (i = 1; i <= sortelements; i++) + { + temp = Rand (); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + if (sortlist[i] > biggest) + biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; + +}; + +CreateNode (t, n) + struct node **t; + int n; +{ + *t = (struct node *) malloc (sizeof (struct node)); + (*t)->left = nil; + (*t)->right = nil; + (*t)->val = n; +}; + +Insert (n, t) + int n; + struct node *t; + /* insert n into tree */ +{ + if (n > t->val) + if (t->left == nil) + CreateNode (&t->left, n); + else + Insert (n, t->left); + else if (n < t->val) + if (t->right == nil) + CreateNode (&t->right, n); + else + Insert (n, t->right); +}; + +int +Checktree (p) + struct node *p; + /* check by inorder traversal */ +{ + int result; + result = true; + if (p->left != nil) + if (p->left->val <= p->val) + result = false; + else + result = Checktree (p->left) && result; + if (p->right != nil) + if (p->right->val >= p->val) + result = false; + else + result = Checktree (p->right) && result; + return (result); +}; /* checktree */ + +Trees () +{ + int i; + tInitarr (); + tree = (struct node *) malloc (sizeof (struct node)); + tree->left = nil; + tree->right = nil; + tree->val = sortlist[1]; + for (i = 2; i <= sortelements; i++) + Insert (sortlist[i], tree); + if (!Checktree (tree)) + printf (" Error in Tree.\n"); +}; + + + /* Sorts an array using bubblesort */ + +bInitarr () +{ + int i, temp; + Initrand (); + biggest = 0; + littlest = 0; + for (i = 1; i <= srtelements; i++) + { + temp = Rand (); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + if (sortlist[i] > biggest) + biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; +}; + +Bubble () +{ + int i, j; + bInitarr (); + top = srtelements; + + while (top > 1) + { + + i = 1; + while (i < top) + { + + if (sortlist[i] > sortlist[i + 1]) + { + j = sortlist[i]; + sortlist[i] = sortlist[i + 1]; + sortlist[i + 1] = j; + }; + i = i + 1; + }; + + top = top - 1; + }; + if ((sortlist[1] != littlest) || (sortlist[srtelements] != biggest)) + printf ("Error3 in Bubble.\n"); +}; + + +float +Cos (x) + float x; +/* computes cos of x (x in radians) by an expansion */ +{ + int i, factor; + float result, power; + + result = 1.0; + factor = 1; + power = x; + for (i = 2; i <= 10; i++) + { + factor = factor * i; + power = power * x; + if ((i & 1) == 0) + { + if ((i & 3) == 0) + result = result + power / factor; + else + result = result - power / factor; + }; + }; + return (result); +}; + +int +Min0 (arg1, arg2) + int arg1, arg2; +{ + if (arg1 < arg2) + return (arg1); + else + return (arg2); +}; + +Printcomplex (arg1, arg2, zarray, start, finish, increment) + int arg1, arg2, start, finish, increment; + struct complex zarray[]; +{ + int i; + printf ("\n"); + + i = start; + do + { + printf (" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); + i = i + increment; + printf (" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); + printf ("\n"); + i = i + increment; + } + while (i <= finish); + +}; + +Uniform11 (iy, yfl) + int iy; + float yfl; +{ + iy = (4855 * iy + 1731) & 8191; + yfl = iy / 8192.0; +} /* uniform */ ; + +Exptab (n, e) + int n; + struct complex e[]; + +{ /* exptab */ + float theta, divisor, h[26]; + int i, j, k, l, m; + + theta = 3.1415926536; + divisor = 4.0; + for (i = 1; i <= 25; i++) + { + h[i] = 1 / (2 * Cos (theta / divisor)); + divisor = divisor + divisor; + }; + + m = n / 2; + l = m / 2; + j = 1; + e[1].rp = 1.0; + e[1].ip = 0.0; + e[l + 1].rp = 0.0; + e[l + 1].ip = 1.0; + e[m + 1].rp = -1.0; + e[m + 1].ip = 0.0; + + do + { + i = l / 2; + k = i; + + do + { + e[k + 1].rp = h[j] * (e[k + i + 1].rp + e[k - i + 1].rp); + e[k + 1].ip = h[j] * (e[k + i + 1].ip + e[k - i + 1].ip); + k = k + l; + } + while (k <= m); + + j = Min0 (j + 1, 25); + l = i; + } + while (l > 1); + +} /* exptab */ ; + +Fft (n, z, w, e, sqrinv) + int n; + struct complex z[], w[]; + struct complex e[]; + float sqrinv; +{ + int i, j, k, l, m, index; + m = n / 2; + l = 1; + + do + { + k = 0; + j = l; + i = 1; + + do + { + + do + { + w[i + k].rp = z[i].rp + z[m + i].rp; + w[i + k].ip = z[i].ip + z[m + i].ip; + w[i + j].rp = e[k + 1].rp * (z[i].rp - z[i + m].rp) + - e[k + 1].ip * (z[i].ip - z[i + m].ip); + w[i + j].ip = e[k + 1].rp * (z[i].ip - z[i + m].ip) + + e[k + 1].ip * (z[i].rp - z[i + m].rp); + i = i + 1; + } + while (i <= j); + + k = j; + j = k + l; + } + while (j <= m); + + /*z = w ; */ index = 1; + do + { + z[index] = w[index]; + index = index + 1; + } + while (index <= n); + l = l + l; + } + while (l <= m); + + for (i = 1; i <= n; i++) + { + z[i].rp = sqrinv * z[i].rp; + z[i].ip = -sqrinv * z[i].ip; + }; + +}; + +Oscar () +{ /* oscar */ + int i; + Exptab (fftsize, e); + seed = 5767; + for (i = 1; i <= fftsize; i++) + { + Uniform11 (seed, zr); + Uniform11 (seed, zi); + z[i].rp = 20.0 * zr - 10.0; + z[i].ip = 20.0 * zi - 10.0; + }; + + + for (i = 1; i <= 20; i++) + { + Fft (fftsize, z, w, e, 0.0625); +// Printcomplex( 6, 99, z, 1, 256, 17 ); + }; +} /* oscar */ ; + +main () +{ + int i; + fixed = 0.0; + floated = 0.0; + printf ("Starting \n"); +/* rewrite (output); */ + setbuf(stdout, nil); + printf (" Perm"); + timer = Getclock (); + Perm (); + xtimes[1] = Getclock () - timer; + fixed = fixed + permbase * xtimes[1]; + floated = floated + permbase * xtimes[1]; + printf (" Towers"); + timer = Getclock (); + Towers (); + xtimes[2] = Getclock () - timer; + fixed = fixed + towersbase * xtimes[2]; + floated = floated + towersbase * xtimes[2]; + printf (" Queens"); + timer = Getclock (); + Queens (); + xtimes[3] = Getclock () - timer; + fixed = fixed + queensbase * xtimes[3]; + floated = floated + queensbase * xtimes[3]; + printf (" Intmm"); + timer = Getclock (); + Intmm (); + xtimes[4] = Getclock () - timer; + fixed = fixed + intmmbase * xtimes[4]; + floated = floated + intmmbase * xtimes[4]; + printf (" Mm"); + timer = Getclock (); + Mm (); + xtimes[5] = Getclock () - timer; + fixed = fixed + mmbase * xtimes[5]; + floated = floated + fpmmbase * xtimes[5]; + printf (" Puzzle"); + timer = Getclock (); + Puzzle (); + xtimes[6] = Getclock () - timer; + fixed = fixed + puzzlebase * xtimes[6]; + floated = floated + puzzlebase * xtimes[6]; + printf (" Quick"); + timer = Getclock (); + Quick (); + xtimes[7] = Getclock () - timer; + fixed = fixed + quickbase * xtimes[7]; + floated = floated + quickbase * xtimes[7]; + printf (" Bubble"); + timer = Getclock (); + Bubble (); + xtimes[8] = Getclock () - timer; + fixed = fixed + bubblebase * xtimes[8]; + floated = floated + bubblebase * xtimes[8]; + printf (" Tree"); + timer = Getclock (); + Trees (); + xtimes[9] = Getclock () - timer; + fixed = fixed + treebase * xtimes[9]; + floated = floated + treebase * xtimes[9]; + printf (" FFT"); + timer = Getclock (); + Oscar (); + xtimes[10] = Getclock () - timer; + fixed = fixed + fftbase * xtimes[10]; + floated = floated + fpfftbase * xtimes[10]; + printf ("\n"); + for (i = 1; i <= 10; i++) + printf ("%8d", xtimes[i]); + printf ("\n"); + /* compute composites */ + printf ("\n"); + printf ("Nonfloating point composite is %10.0f\n", fixed / 10.0); + printf ("\n"); + printf ("Floating point composite is %10.0f\n", floated / 10.0); +} diff --git a/lib/CPUs/MIPS/bsp/examples/startup.S b/lib/CPUs/MIPS/bsp/examples/startup.S new file mode 100644 index 0000000..c7283a5 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/startup.S @@ -0,0 +1,15 @@ + .file "startup.S" + + .section .etext,"ax" + .extern _init + .align 2 + .globl _start +_start: + .set noreorder + + # jump init + la $8, _init + jr $8 + nop + + .set reorder diff --git a/lib/CPUs/MIPS/bsp/examples/test_flash.c b/lib/CPUs/MIPS/bsp/examples/test_flash.c new file mode 100644 index 0000000..7d40961 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_flash.c @@ -0,0 +1,94 @@ +/************************************************************************/ +/* */ +/* AMD CFI Enabled Flash Memory Drivers */ +/* File name: CFIDRIVE.C */ +/* Revision: 1.0 5/07/98 */ +/* */ +/* Copyright (c) 1998 ADVANCED MICRO DEVICES, INC. All Rights Reserved. */ +/* This software is unpublished and contains the trade secrets and */ +/* confidential proprietary information of AMD. Unless otherwise */ +/* provided in the Software Agreement associated herewith, it is */ +/* licensed in confidence "AS IS" and is not to be reproduced in whole */ +/* or part by any means except for backup. Use, duplication, or */ +/* disclosure by the Government is subject to the restrictions in */ +/* paragraph (b) (3) (B) of the Rights in Technical Data and Computer */ +/* Software clause in DFAR 52.227-7013 (a) (Oct 1988). */ +/* Software owned by */ +/* Advanced Micro Devices, Inc., */ +/* One AMD Place, */ +/* P.O. Box 3453 */ +/* Sunnyvale, CA 94088-3453. */ +/************************************************************************/ +/* This software constitutes a basic shell of source code for */ +/* programming all AMD Flash components. AMD */ +/* will not be responsible for misuse or illegal use of this */ +/* software for devices not supported herein. AMD is providing */ +/* this source code "AS IS" and will not be responsible for */ +/* issues arising from incorrect user implementation of the */ +/* source code herein. It is the user's responsibility to */ +/* properly design-in this source code. */ +/* */ +/************************************************************************/ + +#include +#include +#include "cfiflash.h" +#include "libsys.h" + +#define TEST_SIZE (1024*1024) +#define FLASH_OFFSET 0x700000 +int main(void) +{ + int i; + flash_t flash; + UINT8 *pFlash = (UINT8*)0xA4000000; + UINT32 result; + UINT8 *pBuf; + + setbuf(stdout, NULL); + result = flash_find(&flash, 0xA4000000); + + if (result < 0) + { + printf("flash_find() error!\n"); + return 1; + } + + printf("Found Flash at %8.8X\n", (UINT32)flash.pBase); + + pBuf = (UINT8*)malloc(TEST_SIZE); + + for (i=0; i < TEST_SIZE; i++) + pBuf[i] = i; + + printf("Flash erase from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE); + result = flash_erase(&flash, FLASH_OFFSET, TEST_SIZE); + if (result < 0) + { + printf("error!\n"); + return 1; + } + printf("OK\n"); + + printf("Flash program from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE); + result = flash_program(&flash, FLASH_OFFSET, pBuf, TEST_SIZE); + if (result < 0) + { + printf("error!\n"); + return 1; + } + printf("OK\n"); + + printf("Flash verify from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE); + result = flash_verify(&flash, FLASH_OFFSET, pBuf, TEST_SIZE); + if (result < 0) + { + printf("error!\n"); + return 1; + } + printf("OK\n"); + +// PrintBuffer8((UINT8*)pFlash, 16, TEST_SIZE); + + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/test_irq.c b/lib/CPUs/MIPS/bsp/examples/test_irq.c new file mode 100644 index 0000000..9a3a32a --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_irq.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include "irq.h" +#include "libsys.h" + +char buffer[16384]; +char * volatile pPtr_r; +char * volatile pPtr_w; + +void handler0(void) +{ + printf("Interrupt 0\n"); + interrupt_clr(0); +} + +void handler1(void) +{ + printf("Interrupt 1\n"); + interrupt_clr(1); +} + +void handler2(void) +{ + printf("Interrupt 2\n"); +} + +void handler3(void) +{ + volatile char *pUART_stat = (char*)sys_uart_stat; + volatile char *pUART_data = (char*)sys_uart_data; + + while((0x10 & *pUART_stat)) + { +// sputs("w: "); print_word((int)pPtr_w); sputs("\n"); + if (pPtr_w == &buffer[16383]) + pPtr_w = buffer; + *(pPtr_w++) = *pUART_data; + } + +} + +void handler4(void) +{ + printf("Interrupt 4\n"); +} + +void handler5(void) +{ + printf("Interrupt 5\n"); +} + +void handler6(void) +{ + printf("Interrupt 6\n"); +} + +void handler7(void) +{ + printf("Interrupt 7\n"); +} + +int main(void) +{ + + printf("Hello\n"); + memset(buffer, 0, sizeof(buffer)); + pPtr_r = buffer; + pPtr_w = buffer; + interrupt_register(0, handler0); + interrupt_enable(0); + + interrupt_register(1, handler1); + interrupt_enable(1); + + interrupt_register(2, handler2); + interrupt_enable(2); + + interrupt_register(3, handler3); + interrupt_enable(3); + + interrupt_register(4, handler4); +// interrupt_enable(4); + + interrupt_register(5, handler5); + interrupt_enable(5); + + interrupt_register(6, handler6); + interrupt_enable(6); + + interrupt_register(7, handler7); + interrupt_enable(7); + + printf("Start:\n"); + + interrupt_set(0); + interrupt_set(1); + interrupt_set(2); + interrupt_set(3); + interrupt_set(4); + interrupt_set(5); + interrupt_set(6); + interrupt_set(7); + + sputs("r: "); print_word((int)pPtr_r); sputs("\n"); + sputs("w: "); print_word((int)pPtr_w); sputs("\n"); + + // Print Status register + sputs("Status : "); + print_word(CP0_SR_read()); + sputs("\n"); + + while(1) + { + if(pPtr_w != pPtr_r) + { +// sputs("r: "); print_word((int)pPtr_r); sputs("\n"); + if (pPtr_r == &buffer[16383]) + pPtr_r = buffer; + writechar(*(pPtr_r++)); + } + } + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/testbench.c b/lib/CPUs/MIPS/bsp/examples/testbench.c new file mode 100644 index 0000000..a2e5ebd --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/testbench.c @@ -0,0 +1,551 @@ +#include +#include +#include +#include +#include +#include "libsys.h" + +#define NO_ERROR 0x00000000 +#define ERROR 0x80000000 +#define IS_ERROR(e) ((e & ERROR) == ERROR) + +#define TEST10_ERROR (ERROR | 0x10) +#define TEST11_ERROR (ERROR | 0x11) +#define TEST12_ERROR (ERROR | 0x12) + +char buffer[16384]; +int i; + +extern int paranoia(int argc, char **argv); + +void handler3(void) +{ + volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat; + volatile UINT32 *pUART_data = (UINT32*)sys_uart_data; + + while((0x10 & *pUART_stat)) + { + buffer[i] = (char)*pUART_data; + i = (i+1)%sizeof(buffer); + } + +} + +int fibonacci(int f0, int f1, int *pDst, int len) +{ + int i; + + i = 0; + + pDst[i++] = f0; + pDst[i++] = f1; + + for (; i < len; i++) + { + pDst[i] = pDst[i-2] + pDst[i-1]; + } + + return i; +} + +void PrintCPUinfo(void) +{ + int result, rev_id; + + char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"}; + + // Print Status register + result = CP0_SR_read(); + + printf("Status : %8.8X\n", result); + + // Print Revision + result = CP0_PRID_read(); + rev_id = (result >> 8) & 0xFF; + printf("CPU type: "); + if ((rev_id > 0) && (rev_id < 0x07)) + { + printf(cpu_type_str[rev_id]); + printf(" Rev."); + rev_id = result & 0xFF; + printf("%d", rev_id); + } + else + printf("Unknown"); + + printf("\n"); + +} + +int Test10_LoadStore() +{ + int *buf, i, result, data, err; + volatile int *pPtr; + + buf = (int*)malloc(32*sizeof(int)); +// sputs("buf = "); +// print_word((int)buf); +// sputs("\n"); + + while(1) + { + err = TEST10_ERROR; + // Basic Load/Store + pPtr = buf; + *pPtr++ = 0x00000000; + *pPtr++ = 0x55555555; + *pPtr++ = 0xAAAAAAAA; + *pPtr++ = 0xFFFFFFFF; + pPtr = buf; + if (*pPtr++ != 0x00000000) + break; + if (*pPtr++ != 0x55555555) + break; + if (*pPtr++ != 0xAAAAAAAA) + break; + if (*pPtr++ != 0xFFFFFFFF) + break; + + // Filling from left + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data >> 1 | 0x80000000; + + } + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data >> 1 | 0x80000000; + } + if (i != 32) + break; + + // Filling from right + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data << 1 | 1; + + } + pPtr = buf; + data = 0x00000000; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data << 1 | 1; + } + if (i != 32) + break; + + // Walking ones + pPtr = buf; + data = 0x00000001; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data << 1; + + } + pPtr = buf; + data = 0x00000001; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data << 1; + } + if (i != 32) + break; + + // Walking zeros + pPtr = buf; + data = 0xFFFFFFFE; + for (i=0; i < 32; i++) + { + *pPtr++ = data; + data = data << 1 | 1; + + } + pPtr = buf; + data = 0xFFFFFFFE; + for (i=0; i < 32; i++) + { + + if (*pPtr++ != data) + break; + + data = data << 1 | 1; + + } + if (i != 32) + break; + + err = NO_ERROR; + break; + } + free(buf); + return err; + +} + + +#define NUM_ELEMENTS 100000 +#define NUM_RUNS 3 +int Test11_AddSub() +{ + int buf[NUM_ELEMENTS], result, i, j, diff, fill, num_right_elements, num_right_runs; + + fill = 0xAAAAAAAA; + + num_right_runs = 0; + + for (i=0; i < NUM_RUNS; i++) + { + for (j=0; j < NUM_ELEMENTS; j++) + { + buf[j] = fill; + fill = ((fill ^ j) - 1) << 1; + } + num_right_elements = 2; + result = fibonacci(i, i+1, buf, NUM_ELEMENTS); + for (j=2; j < NUM_ELEMENTS; j++) + { + diff = buf[j] - buf[j-1]; + if (diff == buf[j-2]) + num_right_elements++; + } + if (num_right_elements == NUM_ELEMENTS) + num_right_runs++; + + } + + if (num_right_runs != NUM_RUNS) + return TEST11_ERROR; + + return NO_ERROR; +} + +int Test12_MulDiv() +{ + int mix, i, j; + int s1, s2, sp, st; + div_t div_res; + + srand(0x19701031); + for (i=0; i < 100; i++) + { + for (j=1; j < 100; j++) + { + mix = (int)rand(); + mix = (mix << 8) ^ (mix << 16); + s1 = (int)rand() ^ mix; + mix = (int)rand(); + mix = (mix << 8) ^ (mix << 16); + s2 = (int)rand() ^ mix; + + div_res = div(s1, s2); + + sp = s2*div_res.quot; + st = div_res.rem + sp; + if (st != s1) + return TEST12_ERROR; + } + } + return NO_ERROR; +} + +#define PI_SCALE 10000 +#define PI_MAXARR 2800 +#define PI_ARRINIT 2000 + +int pi_calc() +{ + int i, j; + int carry = 0; + int arr[PI_MAXARR+1]; + +// setbuf(stdout, NULL); + + for (i = 0; i <= PI_MAXARR; ++i) + arr[i] = PI_ARRINIT; + for (i = PI_MAXARR; i; i -= 14) + { + int sum = 0; + for (j = i; j > 0; --j) + { + sum = sum*j + PI_SCALE*arr[j]; + arr[j] = sum % (j*2-1); + sum /= (j*2-1); + } + printf("%04d", carry + sum/PI_SCALE); + carry = sum % PI_SCALE; + } + printf("\n"); + return 0; +} + +#define TEST_SIZE (32*1024*1024) // Bytes +#define SMALL_TEST_SIZE (8192) // Bytes +int main (void) +{ + int result, i, j, cnt; + volatile UINT32 *pUART_baud = (UINT32*)sys_uart_baud; + volatile UINT32 *pReg = (UINT32*)sys_led_port; + volatile UINT32 *pReg_usec = (UINT32*)sys_timer_usec; + volatile UINT32 *pReg_sec = (UINT32*)sys_timer_sec; + volatile UINT32 *pSSRAM = (UINT32*)sys_ssram_io; + time_t curr_date; + struct tm *pDate, date; + UINT32 start, end; + char sel; + + UINT8 *ram8 = NULL; + UINT16 *ram16 = NULL; + UINT32 *ram32 = NULL; + + UINT32 *pSrc32, *pDst32; + +// *pUART_baud = 1; + + setbuf(stdout, NULL); + PrintCPUinfo(); + + i = 0; + memset(buffer, 0, sizeof(buffer)); + interrupt_register(3, handler3); + + // ---------------------------------------------------------- + // Memtest BEGIN +/* printf("SSRAM Memory Test\r\n"); + printf("Small data test\r\n"); + printf("Write (32-Bit access)..."); + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=0; i < SMALL_TEST_SIZE/4; i++) + pSSRAM[i] = (UINT32)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + PrintBuffer8((UINT8*)pSSRAM, 16, 256); + + printf("Verify (32-Bit access)..."); + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=SMALL_TEST_SIZE/4-1; i >= 0; i--) + if (pSSRAM[i] != (UINT32)i) + break; + + end = clock(); + i++; + if (i) + printf("failed\r\n"); + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); +*/ + // ---------------------------------------------------------- + // Memtest BEGIN + printf("SDRAM Memory Test\n"); + printf("Test size %d kByte\n\n", TEST_SIZE/1024); + ram8 = (UINT8*)calloc(TEST_SIZE,sizeof(UINT8)); + printf("Write (8-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE; i++) + ram8[i] = (UINT8)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + printf("Verify (8-Bit access)..."); + start = clock(); + for (i=TEST_SIZE-1; i >= 0; i--) + if (ram8[i] != (UINT8)i) + break; + + end = clock(); + i++; + if (i) + printf("failed\r\n"); + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + free(ram8); + + ram16 = (UINT16*)calloc(TEST_SIZE/2,sizeof(UINT16)); + printf("Write (16-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE/2; i++) + ram16[i] = (UINT16)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + printf("Verify (16-Bit access)..."); + start = clock(); + for (i=TEST_SIZE/2-1; i >= 0; i--) + if (ram16[i] != (UINT16)i) + break; + + end = clock(); + i++; + if (i) + printf("failed\r\n"); + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + free(ram16); + + ram32 = (UINT32*)calloc(TEST_SIZE/4,sizeof(UINT32)); + printf("Write (32-Bit access)..."); + start = clock(); + for (i=0; i < TEST_SIZE/4; i++) + ram32[i] = (UINT32)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + printf("Verify (32-Bit access)..."); + start = clock(); + for (i=TEST_SIZE/4-1; i >= 0; i--) + if (ram32[i] != (UINT32)i) + break; + + end = clock(); + i++; + if (i) + printf("failed\r\n"); + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + free(ram32); + + printf("Small data test\r\n"); + printf("Test size %d kByte\n\n", SMALL_TEST_SIZE/1024); + printf("Write (32-Bit access)..."); + ram32 = (UINT32*)calloc(SMALL_TEST_SIZE/4,sizeof(UINT32)); + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=0; i < SMALL_TEST_SIZE/4; i++) + ram32[i] = (UINT32)i; + + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + printf("Verify (32-Bit access)..."); + start = clock(); + for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++) + for (i=SMALL_TEST_SIZE/4-1; i >= 0; i--) + if (ram32[i] != (UINT32)i) + break; + + end = clock(); + i++; + if (i) + printf("failed\r\n"); + else + printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start))); + + free(ram32); + + printf("Memcpy() Test \n"); + pSrc32 = (UINT32*)calloc(TEST_SIZE/8,sizeof(UINT32)); + pDst32 = (UINT32*)calloc(TEST_SIZE/8,sizeof(UINT32)); + printf("Copying %d kBytes...", TEST_SIZE/(2*1024)); + start = clock(); + memcpy(pDst32, pSrc32, TEST_SIZE/2); + end = clock(); + printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(2*1000*(end-start))); + + free(pSrc32); + free(pDst32); + + // Memtest END + // ---------------------------------------------------------- + sputs("\r\n"); + + printf("Datum und Uhrzeit setzen? [j/N]: "); + scanf("%c", &sel); + if (toupper(sel) == 'J') + { + printf("Jahr : "); + scanf("%d", &date.tm_year); + printf("Monat : "); + scanf("%d", &date.tm_mon); + printf("Tag : "); + scanf("%d", &date.tm_mday); + + printf("Wir haben heute den %d. %d. %d\n", date.tm_mday, date.tm_mon, date.tm_year); + } + + interrupt_enable(3); + cnt = 0; + while (1) + { + *pReg = cnt & 0x3FFFFFFF; + + printf("-------------------------------------------\n"); + printf("-- LoadStore ------------------------------\n"); + printf("-------------------------------------------\n"); + result = Test10_LoadStore(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- AddSub ---------------------------------\n"); + printf("-------------------------------------------\n"); + result = Test11_AddSub(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- MulDiv ---------------------------------\n"); + printf("-------------------------------------------\n"); + result = Test12_MulDiv(); + if (IS_ERROR(result)) + break; + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- Paranoia -------------------------------\n"); + printf("-------------------------------------------\n"); + paranoia(1, NULL); + printf("passed\n\n"); + + printf("-------------------------------------------\n"); + printf("-- PI calc --------------------------------\n"); + printf("-------------------------------------------\n"); + pi_calc(); + printf("passed\n\n"); + + printf("Iteration %d: Passed\n", cnt); + curr_date = time(NULL); + pDate = gmtime(&curr_date); + puts(asctime(pDate)); + cnt++; + +// printf("V=%.17e\n", pow((double)cnt-1, (double)cnt)); + } + *pReg = 0x40000000 | cnt; + printf("Failed with error %8.8X\n", result); + + return 1; + +} + diff --git a/lib/CPUs/MIPS/bsp/examples/whet.c b/lib/CPUs/MIPS/bsp/examples/whet.c new file mode 100644 index 0000000..d939910 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/whet.c @@ -0,0 +1,265 @@ +/* + * @(#)whet.c 1.1 + */ + +/* + * Whetstone benchmark in C. This program is a translation of the + * original Algol version in "A Synthetic Benchmark" by H.J. Curnow + * and B.A. Wichman in Computer Journal, Vol 19 #1, February 1976. + * + * Used to test compiler optimization and floating point performance. + */ + +/* + * Compile with -DMEASURE_TIME for time measurement. + * + * Compile with -DPOUT to print intermediate results. + * Running this benchmark without printing the intermediate results is + * contrary to the authors' intentions! But using serial I/O can draw back + * the performance extremely when low baud rate communication is used. + */ +#define MEASURE_TIME 1 +//#define POUT 1 + +#define ITERATIONS 10 /* 10 Million Whetstone instructions */ + +#include +#include + +#ifdef MEASURE_TIME +#include +unsigned long Begin_Time,End_Time,Total_Time; +double whetstones; +#endif + +#define Pout(n, j, k, x1, x2, x3, x4) pout(n, j, k, x1, x2, x3, x4); + +double xx1, xx2, xx3, xx4, x, y, z, t, t1, t2; +double e1[4]; +unsigned int i, j, k, l, n1, n2, n3, n4, n6, n7, n8, n9, n10, n11; + +main() +{ + printf("\nWhetstone Benchmark\n\n"); + + printf( "%d iterations\n", ITERATIONS ); + +#ifdef MEASURE_TIME + Begin_Time = clock(); +#endif + + /* initialize constants */ + + t = 0.499975; + t1 = 0.50025; + t2 = 2.0; + + /* set values of module weights */ + + n1 = 0 * ITERATIONS; + n2 = 12 * ITERATIONS; + n3 = 14 * ITERATIONS; + n4 = 345 * ITERATIONS; + n6 = 210 * ITERATIONS; + n7 = 32 * ITERATIONS; + n8 = 899 * ITERATIONS; + n9 = 616 * ITERATIONS; + n10 = 0 * ITERATIONS; + n11 = 93 * ITERATIONS; + +/* MODULE 1: simple identifiers */ + + xx1 = 1.0; + xx2 = xx3 = xx4 = -1.0; + + for(i = 1; i <= n1; i += 1) { + xx1 = ( xx1 + xx2 + xx3 - xx4 ) * t; + xx2 = ( xx1 + xx2 - xx3 + xx4 ) * t; + xx3 = ( xx1 - xx2 + xx3 + xx4 ) * t; + xx4 = (-xx1 + xx2 + xx3 + xx4 ) * t; + } +#ifdef POUT + Pout(n1, n1, n1, xx1, xx2, xx3, xx4); +#endif + + +/* MODULE 2: array elements */ + + e1[0] = 1.0; + e1[1] = e1[2] = e1[3] = -1.0; + + for (i = 1; i <= n2; i +=1) { + e1[0] = ( e1[0] + e1[1] + e1[2] - e1[3] ) * t; + e1[1] = ( e1[0] + e1[1] - e1[2] + e1[3] ) * t; + e1[2] = ( e1[0] - e1[1] + e1[2] + e1[3] ) * t; + e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3] ) * t; + } +#ifdef POUT + Pout(n2, n3, n2, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE 3: array as parameter */ + + for (i = 1; i <= n3; i += 1) + pa(e1); +#ifdef POUT + Pout(n3, n2, n2, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE 4: conditional jumps */ + + j = 1; + for (i = 1; i <= n4; i += 1) { + if (j == 1) + j = 2; + else + j = 3; + + if (j > 2) + j = 0; + else + j = 1; + + if (j < 1 ) + j = 1; + else + j = 0; + } +#ifdef POUT + Pout(n4, j, j, xx1, xx2, xx3, xx4); +#endif + +/* MODULE 5: omitted */ + +/* MODULE 6: integer arithmetic */ + + j = 1; + k = 2; + l = 3; + + for (i = 1; i <= n6; i += 1) { + j = j * (k - j) * (l -k); + k = l * k - (l - j) * k; + l = (l - k) * (k + j); + + e1[l - 2] = j + k + l; /* C arrays are zero based */ + e1[k - 2] = j * k * l; + } +#ifdef POUT + Pout(n6, j, k, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE 7: trig. functions */ + + x = y = 0.5; + + for(i = 1; i <= n7; i +=1) { + x = t * atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0)); + y = t * atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0)); + } +#ifdef POUT + Pout(n7, j, k, x, x, y, y); +#endif + +/* MODULE 8: procedure calls */ + + x = y = z = 1.0; + + for (i = 1; i <= n8; i +=1) + p3(x, y, &z); +#ifdef POUT + Pout(n8, j, k, x, y, z, z); +#endif + +/* MODULE9: array references */ + + j = 1; + k = 2; + l = 3; + + e1[0] = 1.0; + e1[1] = 2.0; + e1[2] = 3.0; + + for(i = 1; i <= n9; i += 1) + p0(); +#ifdef POUT + Pout(n9, j, k, e1[0], e1[1], e1[2], e1[3]); +#endif + +/* MODULE10: integer arithmetic */ + + j = 2; + k = 3; + + for(i = 1; i <= n10; i +=1) { + j = j + k; + k = j + k; + j = k - j; + k = k - j - j; + } +#ifdef POUT + Pout(n10, j, k, xx1, xx2, xx3, xx4); +#endif + +/* MODULE11: standard functions */ + + x = 0.75; + for(i = 1; i <= n11; i +=1) + x = sqrt( exp( log(x) / t1)); + +#ifdef POUT + Pout(n11, j, k, x, x, x, x); +#endif + +#ifdef MEASURE_TIME + End_Time = clock(); + + Total_Time = End_Time - Begin_Time; /* in 1/ seconds */ + + whetstones = (1e5 * ITERATIONS * CLOCKS_PER_SEC) / Total_Time; + printf("\nWhetstone runs in %ld clock ticks (%d). %ld Kwhets/second\n", + Total_Time, CLOCKS_PER_SEC, (long) whetstones / 1000 ); +#endif +} + +pa(e) +double e[4]; +{ + register int j; + + j = 0; + lab: + e[0] = ( e[0] + e[1] + e[2] - e[3] ) * t; + e[1] = ( e[0] + e[1] - e[2] + e[3] ) * t; + e[2] = ( e[0] - e[1] + e[2] + e[3] ) * t; + e[3] = ( -e[0] + e[1] + e[2] + e[3] ) / t2; + j += 1; + if (j < 6) + goto lab; +} + +p3(x, y, z) +double x, y, *z; +{ + x = t * (x + y); + y = t * (x + y); + *z = (x + y) /t2; +} + +p0() +{ + e1[j] = e1[k]; + e1[k] = e1[l]; + e1[l] = e1[j]; +} + +#ifdef POUT +pout(n, j, k, x1, x2, x3, x4) +unsigned int n, j, k; +double x1, x2, x3, x4; +{ + printf("%5u %5u %5u %11.3e %11.3e %11.3e %11.3e\n", + n, j, k, x1, x2, x3, x4); +} +#endif diff --git a/lib/CPUs/MIPS/bsp/examples/xcpt.c b/lib/CPUs/MIPS/bsp/examples/xcpt.c new file mode 100644 index 0000000..b56f52f --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/xcpt.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include "libsys.h" +#include "xcpt.h" +#include "irq.h" + +char *_xcpt_code_str[32] = +{ + "Int", "Mod", "TLBL", "TLBS", "AdEL", "AdES", "IBE", "DBE", + "Sys", "Bp", "RI", "CpU", "Ov", "Tr", "NCD/VCEI", "MC/FPE", + "Res(16)", "Res(17)", "Res(18)", "Res(19)", "Res(20)", "Res(21)", "Res(22)", "WATCH", + "Res(24)", "Res(25)", "Res(26)", "Res(27)", "Res(28)", "Res(29)", "Res(30)", "VCED" + }; + +#define PRINT_REG(tag_str, reg) \ + sputs(tag_str); \ + print_word(reg); \ + sputs("\n"); + +int _xcpt_default_dispatch(struct xcptcontext * xcp) +{ + return 1; +} + +int _xcpt_dispatch(struct xcptcontext * xcp) +{ + int xcpt_code, result; + + xcpt_code = ((0xFF & xcp->cr) >> 2); + + switch(xcpt_code) + { + case Int: + result = _irq_dispatch(xcp); + break; + + default: + result = _xcpt_default_dispatch(xcp); + break; + } + + return result; +} + +int _xcpt_deliver(struct xcptcontext * _xcp) +{ + + int exc_code; + volatile int *pInstr; + + /* This function gets called by the low-level exception handler. */ + if (_xcpt_dispatch(_xcp)) + { + sputs("\n"); + PRINT_REG("Status : ", _xcp->sr); + PRINT_REG("Cause : ", _xcp->cr); + PRINT_REG("EPC : ", _xcp->epc); + PRINT_REG("BadAddr : ", _xcp->baddr); + PRINT_REG("MDLO : ", _xcp->mdlo); + PRINT_REG("MDHI : ", _xcp->mdhi); + + sputs("\n"); + + sputs("Registers:\n"); + PRINT_REG(" 0 (zero) : ", _xcp->regs[0]); + PRINT_REG(" 1 (at) : ", _xcp->regs[1]); + PRINT_REG(" 2 (v0) : ", _xcp->regs[2]); + PRINT_REG(" 3 (v1) : ", _xcp->regs[3]); + PRINT_REG(" 4 (a0) : ", _xcp->regs[4]); + PRINT_REG(" 5 (a1) : ", _xcp->regs[5]); + PRINT_REG(" 6 (a2) : ", _xcp->regs[6]); + PRINT_REG(" 7 (a3) : ", _xcp->regs[7]); + PRINT_REG(" 8 (t0) : ", _xcp->regs[8]); + PRINT_REG(" 9 (t1) : ", _xcp->regs[9]); + PRINT_REG("10 (t2) : ", _xcp->regs[10]); + PRINT_REG("11 (t3) : ", _xcp->regs[11]); + PRINT_REG("12 (t4) : ", _xcp->regs[12]); + PRINT_REG("13 (t5) : ", _xcp->regs[13]); + PRINT_REG("14 (t6) : ", _xcp->regs[14]); + PRINT_REG("15 (t7) : ", _xcp->regs[15]); + PRINT_REG("16 (s0) : ", _xcp->regs[16]); + PRINT_REG("17 (s1) : ", _xcp->regs[17]); + PRINT_REG("18 (s2) : ", _xcp->regs[18]); + PRINT_REG("19 (s3) : ", _xcp->regs[19]); + PRINT_REG("20 (s4) : ", _xcp->regs[20]); + PRINT_REG("21 (s5) : ", _xcp->regs[21]); + PRINT_REG("22 (s6) : ", _xcp->regs[22]); + PRINT_REG("23 (s7) : ", _xcp->regs[23]); + PRINT_REG("24 (t8) : ", _xcp->regs[24]); + PRINT_REG("25 (t9) : ", _xcp->regs[25]); + PRINT_REG("26 (k0) : ", _xcp->regs[26]); + PRINT_REG("27 (k1) : ", _xcp->regs[27]); + PRINT_REG("28 (gp) : ", _xcp->regs[28]); + PRINT_REG("29 (sp) : ", _xcp->regs[29]); + PRINT_REG("30 (fp) : ", _xcp->regs[30]); + PRINT_REG("31 (ra) : ", _xcp->regs[31]); + sputs("\n"); + + exc_code = (_xcp->cr >> 2) & 0x1F; + + sputs("Unhandled exception <"); + sputs(_xcpt_code_str[exc_code]); + sputs("> at PC : "); + print_word(_xcp->epc); + sputs("\n"); + + if (_xcp->cr & 0x80000000) + { + pInstr = (int*)(_xcp->epc + 4); + } + else + { + pInstr = (int*)(_xcp->epc); + } + + sputs("Instruction at exception address : "); + print_word(*pInstr); + sputs("\n"); + + sputs("Terminate.\n"); + _exit(exc_code); + } + + return 0; +} diff --git a/lib/CPUs/MIPS/bsp/examples/xcpt.h b/lib/CPUs/MIPS/bsp/examples/xcpt.h new file mode 100644 index 0000000..8b42ace --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/xcpt.h @@ -0,0 +1,34 @@ +#ifndef XCPT_H +#define XCPT_H + +typedef enum +{ + Int = 0, Mod = 1, TLBL = 2, TLBS = 3, AdEL = 4, AdES = 5, + IBE = 6, DBE = 7, Syscall = 8, Bp = 9, RI = 10, CpU = 11, + Ov = 12, TRAP = 13, VCEI = 14, FPE = 15, C2E = 16, Watch = 23, VCED = 31 + +} EXCEPTION_CODE; + +typedef unsigned int reg_t; + +typedef struct xcptcontext +{ + /* This is the exception context frame that is passed to the exception + handlers. It gets filled in by the low-level exception handler in + "machine.S". An assembler version of this structure can be found at the + bottom of "machine.H".*/ + reg_t sr; /* Status Register */ + reg_t cr; /* Cause Register */ + reg_t epc; /* PC at time of exception. */ + reg_t baddr; + reg_t regs[32]; /* Copy of all general purpose registers */ + reg_t mdlo; /* HI/LO registers (used for memory management) */ + reg_t mdhi; + reg_t count; /* Timer registers */ + reg_t compare; + struct xcptcontext * prev; /* To link exceptions. (unused for now) */ + unsigned xclass; /* Priority class of this exception. (unused for now). */ + +} EXCEPTION_CONTEXT; + +#endif // XCPT_H diff --git a/lib/CPUs/MIPS/bsp/examples/xcpt_asm.h b/lib/CPUs/MIPS/bsp/examples/xcpt_asm.h new file mode 100644 index 0000000..76f0bab --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/xcpt_asm.h @@ -0,0 +1,67 @@ +#ifndef XCPT_ASM_H +#define XCPT_ASM_H + +/* LEAF - declare leaf routine */ +#define LEAF(symbol) \ + .globl symbol; \ + .align 2; \ + .type symbol, @function; \ + .ent symbol, 0; \ +symbol: .frame sp, 0, ra + +/* END - mark end of function */ +#define END(function) \ + .end function; \ + .size function, .-function + +/* Exception stack size */ +#define XCP_SIZE 1024 + +/* save location for registers */ +#define XCP_SR 0 +#define XCP_CR 4 +#define XCP_EPC 8 +#define XCP_BADDR 12 +#define XCP_ZERO 16 +#define XCP_AT 20 +#define XCP_V0 24 +#define XCP_V1 28 +#define XCP_A0 32 +#define XCP_A1 36 +#define XCP_A2 40 +#define XCP_A3 44 +#define XCP_T0 48 +#define XCP_T1 52 +#define XCP_T2 56 +#define XCP_T3 60 +#define XCP_T4 64 +#define XCP_T5 68 +#define XCP_T6 72 +#define XCP_T7 76 +#define XCP_S0 80 +#define XCP_S1 84 +#define XCP_S2 88 +#define XCP_S3 92 +#define XCP_S4 96 +#define XCP_S5 100 +#define XCP_S6 104 +#define XCP_S7 108 +#define XCP_T8 112 +#define XCP_T9 116 +#define XCP_JP 116 +#define XCP_K0 120 +#define XCP_K1 124 +#define XCP_GP 128 +#define XCP_SP 132 +#define XCP_S8 136 +#define XCP_FP 136 +#define XCP_RA 140 +#define XCP_MDLO 144 +#define XCP_MDHI 148 +#define XCP_COUNT 152 +#define XCP_COMPARE 156 +#define XCP_PREV 160 +#define XCP_CLASS 164 + + +#endif /* XCPT_ASM_H */ diff --git a/lib/CPUs/MIPS/bsp/toolchain/howto_build.txt b/lib/CPUs/MIPS/bsp/toolchain/howto_build.txt new file mode 100644 index 0000000..0540d1e --- /dev/null +++ b/lib/CPUs/MIPS/bsp/toolchain/howto_build.txt @@ -0,0 +1,37 @@ +# --------------------------------------------------------------- +# 1. Binutils bauen und installieren +# --------------------------------------------------------------- +> tar -xzf binutils-2.18.tar.gz +> mkdir binutils-2.18_build +> cd binutils-2.18_build + +> ../binutils-2.18/configure --target=mipsel-elf --prefix=/usr/local +> make +> make install + +# --------------------------------------------------------------- +# 2. GCC bauen und installieren +# --------------------------------------------------------------- +> tar -xzf gcc-4.3.0.tar.gz +> tar -xzf gcc-core-4.3.0.tar.gz +> mkdir gcc-4.3.0_build +> cd gcc-4.3.0_build +> ../gcc-4.3.0/configure --target=mipsel-elf --prefix=/usr/local --enable-languages=c,c++ --disable-shared --with-newlib --with-float=soft --disable-multilib --with-abi=eabi +> CFLAGS_FOR_TARGET="-G 0 -g -O2" make LANGUAGES="c c++" +> make install LANGUAGES="c c++" + +# --------------------------------------------------------------- +# 3. Newlib bauen und installieren +# --------------------------------------------------------------- +> tar -xzf newlib-1.16.0.tar.gz +! Bug in newlib-1.16.0/newlib/libc/machine/mips/strlen.c. + Newlib von Hand patchen (32-bit MIPS targets): + "lbu $3,0($4)\n" + "nop\n" <= nop einfügen + "bnez $3,1b\n" + +> mkdir newlib-1.16.0_build +> cd newlib-1.16.0_build +> ../newlib-1.16.0/configure --target=mipsel-elf --prefix=/usr/local --disable-multilib --with-float=soft --with-abi=eabi +> TARGET_CFLAGS="-G 0 -g -O2" make +> make install diff --git a/lib/CPUs/MIPS/dist/files.dist b/lib/CPUs/MIPS/dist/files.dist new file mode 100644 index 0000000..8e53719 --- /dev/null +++ b/lib/CPUs/MIPS/dist/files.dist @@ -0,0 +1,37 @@ +../../../misc/dpram_2w2r.vhd +../../../misc/dpram_1w1r.vhd +../../../misc/dpram_1w1r_dist.vhd +../../../FIFO/src/fifo_ctrl_pkg.vhd +../../../FIFO/src/sync_fifo_ctrl.vhd +../../../FIFO/src/fifo_sync_dist.vhd + +../../../uart/bbfifo_16x8.vhd +../../../uart/kcuart_rx.vhd +../../../uart/kcuart_tx.vhd +../../../uart/uart_rx.vhd +../../../uart/uart_tx.vhd +../../../uart/uart_wb.vhd + +../../../misc/gpio_wb.vhd +../../../misc/async_types.vhd +../../../misc/async_port_wb.vhd +../src/async_defs.vhd + +../src/bootloader.ROM.vhd +../../../misc/rom_wb.vhd + +../src/core/mips_types.vhd +../src/core/mips_instr.vhd +../src/core/mips_idecode_rom.vhd +../src/core/mips_reg.vhd +../src/core/mips_shifter.vhd +../src/core/mips_alu.vhd +../src/core/mips_muldiv.vhd +../src/core/mips_cop.vhd +../src/core/mips_icache.vhd +../src/core/mips_dcache.vhd +../src/core/mips_biu.vhd +../src/core/mips_bcu.vhd +../src/core/mips_pipeline.vhd +../src/core/mips_top.vhd +../src/tb_mips_top.vhd diff --git a/lib/CPUs/MIPS/dist/mdist b/lib/CPUs/MIPS/dist/mdist new file mode 100644 index 0000000..e58668e --- /dev/null +++ b/lib/CPUs/MIPS/dist/mdist @@ -0,0 +1,45 @@ +#!/bin/sh + +PROJECT="mips_top" +DIST_FILE="./files.dist" +DIST_DIR="./release/mips.r9" + +# --------------------------------------------------------------- +mkdir -p $DIST_DIR/src +mkdir -p $DIST_DIR/sim +mkdir -p $DIST_DIR/doc +mkdir -p $DIST_DIR/bsp +mkdir -p $DIST_DIR/tools + +cp -a ../bsp/* $DIST_DIR/bsp/ +cp -a ../doc/*.pdf $DIST_DIR/doc/ +cp -a ../tools/* $DIST_DIR/tools/ + +cp -a ./tmpl/gpl-3.0.txt $DIST_DIR/ +cp -a ./tmpl/tb_mips_top.wdo $DIST_DIR/sim/ +cp -a ./tmpl/hello.flash.bin $DIST_DIR/sim/ + +for i in $(cat -s $DIST_FILE); do + echo $i; + cp -a $i $DIST_DIR/src/ +done; + +# Delete CVS directories +rm -r $(find release/ -name CVS) + +# --------------------------------------------------------------- +# Generate testbench do-file +echo "vlib work" > $DIST_DIR/sim/tb_$PROJECT.fdo + +for i in $(cat -s $DIST_FILE); do + echo "vcom -explicit -93 \"../src/$(basename $i)\"" >> $DIST_DIR/sim/tb_$PROJECT.fdo +done; +echo "vsim -t 1ps -lib work tb_$PROJECT" >> $DIST_DIR/sim/tb_$PROJECT.fdo + +echo "do {tb_mips_top.wdo}" >> $DIST_DIR/sim/tb_$PROJECT.fdo +echo "view wave" >> $DIST_DIR/sim/tb_$PROJECT.fdo +echo "view structure" >> $DIST_DIR/sim/tb_$PROJECT.fdo +echo "view signals" >> $DIST_DIR/sim/tb_$PROJECT.fdo +echo "run 1600us" >> $DIST_DIR/sim/tb_$PROJECT.fdo + +# --------------------------------------------------------------- diff --git a/lib/CPUs/MIPS/dist/tmpl/gpl-3.0.txt b/lib/CPUs/MIPS/dist/tmpl/gpl-3.0.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/lib/CPUs/MIPS/dist/tmpl/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/lib/CPUs/MIPS/dist/tmpl/hello.flash.bin b/lib/CPUs/MIPS/dist/tmpl/hello.flash.bin new file mode 100644 index 0000000..cd652ef Binary files /dev/null and b/lib/CPUs/MIPS/dist/tmpl/hello.flash.bin differ diff --git a/lib/CPUs/MIPS/dist/tmpl/tb_mips_top.wdo b/lib/CPUs/MIPS/dist/tmpl/tb_mips_top.wdo new file mode 100644 index 0000000..93f1ed5 --- /dev/null +++ b/lib/CPUs/MIPS/dist/tmpl/tb_mips_top.wdo @@ -0,0 +1,60 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider {MIPS top} +add wave -noupdate -format Literal /tb_mips_top/debug +add wave -noupdate -format Logic /tb_mips_top/rst +add wave -noupdate -format Logic /tb_mips_top/clk +add wave -noupdate -format Logic /tb_mips_top/mrdy_o +add wave -noupdate -format Logic /tb_mips_top/cyc_o +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o +add wave -noupdate -format Literal /tb_mips_top/sel_o +add wave -noupdate -format Logic /tb_mips_top/we_o +add wave -noupdate -format Logic /tb_mips_top/stb_o +add wave -noupdate -format Logic /tb_mips_top/srdy_i +add wave -noupdate -format Logic /tb_mips_top/ack_i +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o +add wave -noupdate -format Literal /tb_mips_top/int +add wave -noupdate -divider Flash +add wave -noupdate -format Logic /tb_mips_top/clk +add wave -noupdate -format Logic /tb_mips_top/flash_cs_n +add wave -noupdate -format Logic /tb_mips_top/flash_oe_n +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d +add wave -noupdate -divider SRAM +add wave -noupdate -format Logic /tb_mips_top/clk +add wave -noupdate -format Logic /tb_mips_top/sram_cs_n +add wave -noupdate -format Literal /tb_mips_top/sram_wr_n +add wave -noupdate -format Logic /tb_mips_top/sram_oe_n +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d +add wave -noupdate -divider GPIO +add wave -noupdate -format Logic /tb_mips_top/clk +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0 +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1 +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi0 +add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi1 +add wave -noupdate -divider UART +add wave -noupdate -format Logic /tb_mips_top/clk +add wave -noupdate -format Logic /tb_mips_top/int_uart_rx +add wave -noupdate -format Logic /tb_mips_top/rx +add wave -noupdate -format Logic /tb_mips_top/tx +add wave -noupdate -divider {Memory bus} +add wave -noupdate -format Logic /tb_mips_top/clk +add wave -noupdate -format Literal /tb_mips_top/mem_area +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {222066850 ps} 0} +configure wave -namecolwidth 150 +configure wave -valuecolwidth 100 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 100 +configure wave -griddelta 40 +configure wave -timeline 1 +update +WaveRestoreZoom {221809160 ps} {222394902 ps} diff --git a/lib/CPUs/MIPS/doc/mips_pipeline.pdf b/lib/CPUs/MIPS/doc/mips_pipeline.pdf new file mode 100644 index 0000000..65a3621 Binary files /dev/null and b/lib/CPUs/MIPS/doc/mips_pipeline.pdf differ