GNU compliant library naming
authorlekernel <sebastien.bourdeauducq@lekernel.net>
Fri, 16 Oct 2009 22:30:50 +0000 (00:30 +0200)
committerlekernel <sebastien.bourdeauducq@lekernel.net>
Fri, 16 Oct 2009 22:30:50 +0000 (00:30 +0200)
106 files changed:
build_bios.sh
build_demo.sh
build_sdk.sh
clean_all.sh
software/baselib/Makefile [deleted file]
software/baselib/atof.c [deleted file]
software/baselib/board.c [deleted file]
software/baselib/cfcard.c [deleted file]
software/baselib/cffat.c [deleted file]
software/baselib/console.c [deleted file]
software/baselib/crc16.c [deleted file]
software/baselib/crc32.c [deleted file]
software/baselib/divsi3.c [deleted file]
software/baselib/irq.S [deleted file]
software/baselib/libc.c [deleted file]
software/baselib/malloc.c [deleted file]
software/baselib/milieu.h [deleted file]
software/baselib/softfloat-glue.c [deleted file]
software/baselib/softfloat-macros.h [deleted file]
software/baselib/softfloat-specialize.h [deleted file]
software/baselib/softfloat.c [deleted file]
software/baselib/softfloat.h [deleted file]
software/baselib/system.c [deleted file]
software/baselib/uart-async.c [deleted file]
software/baselib/uart.c [deleted file]
software/baselib/vsnprintf-nofloat.c [deleted file]
software/baselib/vsnprintf.c [deleted file]
software/bios/Makefile
software/demo/Makefile
software/libbase/Makefile [new file with mode: 0644]
software/libbase/atof.c [new file with mode: 0644]
software/libbase/board.c [new file with mode: 0644]
software/libbase/cfcard.c [new file with mode: 0644]
software/libbase/cffat.c [new file with mode: 0644]
software/libbase/console.c [new file with mode: 0644]
software/libbase/crc16.c [new file with mode: 0644]
software/libbase/crc32.c [new file with mode: 0644]
software/libbase/divsi3.c [new file with mode: 0644]
software/libbase/irq.S [new file with mode: 0644]
software/libbase/libc.c [new file with mode: 0644]
software/libbase/malloc.c [new file with mode: 0644]
software/libbase/milieu.h [new file with mode: 0644]
software/libbase/softfloat-glue.c [new file with mode: 0644]
software/libbase/softfloat-macros.h [new file with mode: 0644]
software/libbase/softfloat-specialize.h [new file with mode: 0644]
software/libbase/softfloat.c [new file with mode: 0644]
software/libbase/softfloat.h [new file with mode: 0644]
software/libbase/system.c [new file with mode: 0644]
software/libbase/uart-async.c [new file with mode: 0644]
software/libbase/uart.c [new file with mode: 0644]
software/libbase/vsnprintf-nofloat.c [new file with mode: 0644]
software/libbase/vsnprintf.c [new file with mode: 0644]
software/libmath/Makefile [new file with mode: 0644]
software/libmath/acosf.c [new file with mode: 0644]
software/libmath/asincosf.c [new file with mode: 0644]
software/libmath/asinf.c [new file with mode: 0644]
software/libmath/atan2f.c [new file with mode: 0644]
software/libmath/atanf.c [new file with mode: 0644]
software/libmath/ceilf.c [new file with mode: 0644]
software/libmath/cosf.c [new file with mode: 0644]
software/libmath/coshf.c [new file with mode: 0644]
software/libmath/cotf.c [new file with mode: 0644]
software/libmath/expf.c [new file with mode: 0644]
software/libmath/fabsf.c [new file with mode: 0644]
software/libmath/floorf.c [new file with mode: 0644]
software/libmath/frexpf.c [new file with mode: 0644]
software/libmath/ldexpf.c [new file with mode: 0644]
software/libmath/log10f.c [new file with mode: 0644]
software/libmath/logf.c [new file with mode: 0644]
software/libmath/modff.c [new file with mode: 0644]
software/libmath/powf.c [new file with mode: 0644]
software/libmath/sincosf.c [new file with mode: 0644]
software/libmath/sincoshf.c [new file with mode: 0644]
software/libmath/sinf.c [new file with mode: 0644]
software/libmath/sinhf.c [new file with mode: 0644]
software/libmath/sqrtf.c [new file with mode: 0644]
software/libmath/tancotf.c [new file with mode: 0644]
software/libmath/tanf.c [new file with mode: 0644]
software/libmath/tanhf.c [new file with mode: 0644]
software/mathlib/Makefile [deleted file]
software/mathlib/acosf.c [deleted file]
software/mathlib/asincosf.c [deleted file]
software/mathlib/asinf.c [deleted file]
software/mathlib/atan2f.c [deleted file]
software/mathlib/atanf.c [deleted file]
software/mathlib/ceilf.c [deleted file]
software/mathlib/cosf.c [deleted file]
software/mathlib/coshf.c [deleted file]
software/mathlib/cotf.c [deleted file]
software/mathlib/expf.c [deleted file]
software/mathlib/fabsf.c [deleted file]
software/mathlib/floorf.c [deleted file]
software/mathlib/frexpf.c [deleted file]
software/mathlib/ldexpf.c [deleted file]
software/mathlib/log10f.c [deleted file]
software/mathlib/logf.c [deleted file]
software/mathlib/modff.c [deleted file]
software/mathlib/powf.c [deleted file]
software/mathlib/sincosf.c [deleted file]
software/mathlib/sincoshf.c [deleted file]
software/mathlib/sinf.c [deleted file]
software/mathlib/sinhf.c [deleted file]
software/mathlib/sqrtf.c [deleted file]
software/mathlib/tancotf.c [deleted file]
software/mathlib/tanf.c [deleted file]
software/mathlib/tanhf.c [deleted file]

index ec3a597..e17397b 100755 (executable)
@@ -24,7 +24,7 @@ fi
 
 echo "Building embedded software :"
 echo -n "  Base library..."
-cd $BASEDIR/software/baselib && make >> $LOGFILE 2>&1
+cd $BASEDIR/software/libbase && make >> $LOGFILE 2>&1
 if [ "$?" != 0 ] ; then
         echo "FAILED"
        exit 1
index 995da76..30fed13 100755 (executable)
@@ -26,7 +26,7 @@ fi
 
 echo "Building embedded software:"
 echo -n "  Base library..."
-cd $BASEDIR/software/baselib && make >> $LOGFILE 2>&1
+cd $BASEDIR/software/libbase && make >> $LOGFILE 2>&1
 if [ "$?" != 0 ] ; then
         echo "FAILED"
        exit 1
@@ -34,7 +34,7 @@ else
         echo "OK"
 fi
 echo -n "  Math library..."
-cd $BASEDIR/software/mathlib && make >> $LOGFILE 2>&1
+cd $BASEDIR/software/libmath && make >> $LOGFILE 2>&1
 if [ "$?" != 0 ] ; then
         echo "FAILED"
        exit 1
index 4dadb09..af436d9 100755 (executable)
@@ -25,7 +25,7 @@ else
 fi
 
 echo -n "Building base library..."
-cd $BASEDIR/software/baselib && make >> $LOGFILE 2>&1
+cd $BASEDIR/software/libbase && make >> $LOGFILE 2>&1
 if [ "$?" != 0 ] ; then
         echo "FAILED"
        exit 1
@@ -33,7 +33,7 @@ else
         echo "OK"
 fi
 echo -n "Building math library..."
-cd $BASEDIR/software/mathlib && make >> $LOGFILE 2>&1
+cd $BASEDIR/software/libmath && make >> $LOGFILE 2>&1
 if [ "$?" != 0 ] ; then
         echo "FAILED"
        exit 1
index c9fe21f..ff9d5a6 100755 (executable)
@@ -6,8 +6,8 @@ source $BASEDIR/coredoc.inc
 
 cd $BASEDIR/tools && make clean
 
-cd $BASEDIR/software/baselib && make clean
-cd $BASEDIR/software/mathlib && make clean
+cd $BASEDIR/software/libbase && make clean
+cd $BASEDIR/software/libmath && make clean
 cd $BASEDIR/software/bios && make clean
 cd $BASEDIR/software/demo && make clean
 
diff --git a/software/baselib/Makefile b/software/baselib/Makefile
deleted file mode 100644 (file)
index c7cbf63..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-MMDIR?=../..
-include $(MMDIR)/software/include.mak
-
-OBJECTS_ALL=divsi3.o libc.o crc16.o crc32.o console.o cfcard.o cffat.o system.o board.o
-OBJECTS=$(OBJECTS_ALL) irq.o softfloat.o softfloat-glue.o vsnprintf.o atof.o malloc.o uart-async.o
-OBJECTS_LIGHT=$(OBJECTS_ALL) vsnprintf-nofloat.o uart.o
-
-all: baselib-light.a baselib.a
-
-baselib-light.a: $(OBJECTS_LIGHT)
-       $(AR) clr baselib-light.a $(OBJECTS_LIGHT)
-       $(RANLIB) baselib-light.a
-
-baselib.a: $(OBJECTS)
-       $(AR) clr baselib.a $(OBJECTS)
-       $(RANLIB) baselib.a
-
-.PHONY: clean depend
-
-depend:
-       makedepend -Y -- $(CFLAGS) -- *.c
-
-clean:
-       rm -f *.o baselib.a baselib-light.a .*~ *~ Makefile.bak
-
-# DO NOT DELETE
-
-atof.o: ../../software/include/libc.h
-board.o: ../../software/include/hw/sysctl.h
-board.o: ../../software/include/hw/common.h ../../software/include/libc.h
-board.o: ../../software/include/board.h
-cfcard.o: ../../software/include/hw/systemace.h
-cfcard.o: ../../software/include/hw/common.h ../../software/include/libc.h
-cfcard.o: ../../software/include/cfcard.h ../../software/include/console.h
-cffat.o: ../../software/include/libc.h ../../software/include/endian.h
-cffat.o: ../../software/include/cfcard.h ../../software/include/console.h
-cffat.o: ../../software/include/cffat.h
-console.o: ../../software/include/libc.h ../../software/include/uart.h
-console.o: ../../software/include/console.h
-crc16.o: ../../software/include/crc.h
-crc32.o: ../../software/include/crc.h
-libc.o: ../../software/include/libc.h
-malloc.o: ../../software/include/libc.h ../../software/include/console.h
-malloc.o: ../../software/include/malloc.h
-softfloat-glue.o: ../../software/include/libc.h softfloat.h
-softfloat.o: milieu.h softfloat.h softfloat-macros.h softfloat-specialize.h
-system.o: ../../software/include/hw/fmlbrg.h ../../software/include/system.h
-uart-async.o: ../../software/include/uart.h ../../software/include/irq.h
-uart-async.o: ../../software/include/hw/uart.h
-uart-async.o: ../../software/include/hw/common.h
-uart-async.o: ../../software/include/hw/interrupts.h
-uart.o: ../../software/include/hw/uart.h ../../software/include/hw/common.h
-uart.o: ../../software/include/uart.h
-vsnprintf-nofloat.o: ../../software/include/libc.h
-vsnprintf.o: ../../software/include/libc.h
diff --git a/software/baselib/atof.c b/software/baselib/atof.c
deleted file mode 100644 (file)
index 107e267..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*  atof.c: converts an ASCII string to float
-
-    Copyright (C) 2003  Jesus Calvino-Fraga, jesusc@ieee.org
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library 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
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
-
-#include <libc.h>
-
-float atof(const char * s)
-{
-       float value, fraction;
-       char iexp;
-       char sign;
-
-       //Skip leading blanks
-       while (isspace(*s)) s++;
-
-       //Get the sign
-       if (*s == '-')
-       {
-               sign=1;
-               s++;
-       }
-       else
-       {
-               sign=0;
-               if (*s == '+') s++;
-       }
-
-       //Get the integer part
-       for (value=0.0f; isdigit(*s); s++)
-       {
-               value=10.0f*value+(*s-'0');
-       }
-
-       //Get the fraction
-       if (*s == '.')
-       {
-               s++;
-               for (fraction=0.1f; isdigit(*s); s++)
-               {
-                       value+=(*s-'0')*fraction;
-                       fraction*=0.1f;
-               }
-       }
-
-       //Finally, the exponent (not very efficient, but enough for now)
-       if (toupper(*s)=='E')
-       {
-               s++;
-               iexp=(char)atoi(s);
-               {
-                       while(iexp!=0)
-                       {
-                               if(iexp<0)
-                               {
-                                       value*=0.1f;
-                                       iexp++;
-                               }
-                               else
-                               {
-                                       value*=10.0f;
-                                       iexp--;
-                               }
-                       }
-               }
-       }
-
-       if(sign) value*=-1.0f;
-       return (value);
-}
diff --git a/software/baselib/board.c b/software/baselib/board.c
deleted file mode 100644 (file)
index 4de25a8..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <hw/sysctl.h>
-#include <libc.h>
-#include <board.h>
-
-static const struct board_desc boards[2] = {
-       {
-               .id = 0x58343031, /* X401 */
-               .name = "Xilinx ML401 development board",
-               .clk_frequency = 100000000,
-               .sdram_size = 64,
-               .ddr_clkphase = 0,
-               .ddr_idelay = 0,
-               .ddr_dqsdelay = 244
-       },
-       {
-               .id = 0x53334145, /* S3AE */
-               .name = "Avnet Spartan-3A evaluation kit",
-               .clk_frequency = 64000000,
-               .sdram_size = 0
-       },
-       {
-               .id = 0x4D4F4E45, /* MONE */
-               .name = "Milkymist One",
-               .clk_frequency = 80000000,
-               .sdram_size = 64,
-               .ddr_clkphase = 0,
-               .ddr_idelay = 0,
-               .ddr_dqsdelay = 244
-       },
-};
-
-const struct board_desc *get_board_desc_id(unsigned int id)
-{
-       unsigned int i;
-       
-       for(i=0;i<sizeof(boards)/sizeof(boards[0]);i++)
-               if(boards[i].id == id)
-                       return &boards[i];
-       return NULL;
-}
-
-const struct board_desc *get_board_desc()
-{
-       return get_board_desc_id(CSR_SYSTEM_ID);
-}
-
diff --git a/software/baselib/cfcard.c b/software/baselib/cfcard.c
deleted file mode 100644 (file)
index ba48dfb..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <hw/systemace.h>
-#include <libc.h>
-#include <cfcard.h>
-#include <console.h>
-
-#define TIMEOUT 10000000
-
-int cf_init()
-{
-       int timeout;
-       
-       CSR_ACE_BUSMODE = ACE_BUSMODE_16BIT;
-       
-       if(!(CSR_ACE_STATUSL & ACE_STATUSL_CFDETECT)) return 0;
-       if((CSR_ACE_ERRORL != 0) || (CSR_ACE_ERRORH != 0)) return 0;
-       
-       CSR_ACE_CTLL |= ACE_CTLL_LOCKREQ;
-       timeout = TIMEOUT;
-       while((timeout > 0) && (!(CSR_ACE_STATUSL & ACE_STATUSL_MPULOCK))) timeout--;
-       if(timeout == 0) return 0;
-       
-       return 1;
-}
-
-int cf_readblock(unsigned int blocknr, unsigned char *buf)
-{
-       unsigned short int *bufw = (unsigned short int *)buf;
-       int buffer_count;
-       int i;
-       int timeout;
-       
-       /* See p. 39 */
-       timeout = TIMEOUT;
-       while((timeout > 0) && (!(CSR_ACE_STATUSL & ACE_STATUSL_CFCMDRDY))) timeout--;
-       if(timeout == 0) return 0;
-       
-       CSR_ACE_MLBAL = blocknr & 0x0000ffff;
-       CSR_ACE_MLBAH = (blocknr & 0x0fff0000) >> 16;
-       
-       CSR_ACE_SECCMD = ACE_SECCMD_READ|0x01;
-       
-       CSR_ACE_CTLL |= ACE_CTLL_CFGRESET;
-       
-       buffer_count = 16;
-       while(buffer_count > 0) {
-               timeout = TIMEOUT;
-               while((timeout > 0) && (!(CSR_ACE_STATUSL & ACE_STATUSL_DATARDY))) timeout--;
-               if(timeout == 0) return 0;
-
-               for(i=0;i<16;i++) {
-                       *bufw = CSR_ACE_DATA;
-                       /* SystemACE data buffer access seems little-endian. */
-                       *bufw = ((*bufw & 0xff00) >> 8) | ((*bufw & 0x00ff) << 8);
-                       bufw++;
-               }
-                       
-               buffer_count--;
-       }
-       
-       CSR_ACE_CTLL &= ~ACE_CTLL_CFGRESET;
-       
-       return 1;
-}
-
-void cf_done()
-{
-       CSR_ACE_CTLL &= ~ACE_CTLL_LOCKREQ;
-}
diff --git a/software/baselib/cffat.c b/software/baselib/cffat.c
deleted file mode 100644 (file)
index a2c5bce..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <libc.h>
-#include <endian.h>
-#include <cfcard.h>
-#include <console.h>
-#include <cffat.h>
-
-struct partition_descriptor {
-       unsigned char flags;
-       unsigned char start_head;
-       unsigned short start_cylinder;
-       unsigned char type;
-       unsigned char end_head;
-       unsigned short end_cylinder;
-       unsigned int start_sector;
-       unsigned int end_sector;
-} __attribute__((packed));
-
-struct firstsector {
-       unsigned char bootsector[446];
-       struct partition_descriptor partitions[4];
-       unsigned char signature[2];
-} __attribute__((packed));
-
-
-struct fat16_firstsector {
-       /* Common to FATxx */
-       char jmp[3];
-       char oem[8];
-       unsigned short bytes_per_sector;
-       unsigned char sectors_per_cluster;
-       unsigned short reserved_sectors;
-       unsigned char number_of_fat;
-       unsigned short max_root_entries;
-       unsigned short total_sectors_short;
-       unsigned char media_descriptor;
-       unsigned short sectors_per_fat;
-       unsigned short sectors_per_track;
-       unsigned short head_count;
-       unsigned int hidden_sectors;
-       unsigned int total_sectors;
-       
-       /* FAT16 specific */
-       unsigned char drive_nr;
-       unsigned char reserved;
-       unsigned char ext_boot_signature;
-       unsigned int id;
-       unsigned char volume_label[11];
-       unsigned char fstype[8];
-       unsigned char bootcode[448];
-       unsigned char signature[2];
-} __attribute__((packed));
-
-struct directory_entry {
-       unsigned char filename[8];
-       unsigned char extension[3];
-       unsigned char attributes;
-       unsigned char reserved;
-       unsigned char create_time_ms;
-       unsigned short create_time;
-       unsigned short create_date;
-       unsigned short last_access;
-       unsigned short ea_index;
-       unsigned short lastm_time;
-       unsigned short lastm_date;
-       unsigned short first_cluster;
-       unsigned int file_size;
-} __attribute__((packed));
-
-struct directory_entry_lfn {
-       unsigned char seq;
-       unsigned short name1[5]; /* UTF16 */
-       unsigned char attributes;
-       unsigned char reserved;
-       unsigned char checksum;
-       unsigned short name2[6];
-       unsigned short first_cluster;
-       unsigned short name3[2];
-} __attribute__((packed));
-
-#define PARTITION_TYPE_FAT16           0x06
-
-static int cffat_partition_start_sector;       /* Sector# of the beginning of the FAT16 partition */
-
-static int cffat_sectors_per_cluster;
-static int cffat_fat_sector;                   /* Sector of the first FAT */
-static int cffat_fat_entries;                  /* Number of entries in the FAT */
-static int cffat_max_root_entries;
-static int cffat_root_table_sector;            /* Sector# of the beginning of the root table */
-
-static int cffat_fat_cached_sector;
-static unsigned short int cffat_fat_sector_cache[CF_BLOCK_SIZE/2];
-
-static int cffat_dir_cached_sector;
-static struct directory_entry cffat_dir_sector_cache[CF_BLOCK_SIZE/sizeof(struct directory_entry)];
-
-static int cffat_data_start_sector;
-
-int cffat_init()
-{
-       struct firstsector s0;
-       struct fat16_firstsector s;
-       int i;
-       
-       if(!cf_init()) {
-               printf("E: Unable to initialize CF card driver\n");
-               return 0;
-       }
-       
-       /* Read sector 0, with partition table */
-       if(!cf_readblock(0, (void *)&s0)) {
-               printf("E: Unable to read block 0\n");
-               return 0;
-       }
-       
-       cffat_partition_start_sector = -1;
-       for(i=0;i<4;i++)
-               if(s0.partitions[i].type == PARTITION_TYPE_FAT16) {
-                       /*printf("I: Using partition #%d: start sector %08x, end sector %08x\n", i, 
-                               le32toh(s0.partitions[i].start_sector), le32toh(s0.partitions[i].end_sector));*/
-                       cffat_partition_start_sector = le32toh(s0.partitions[i].start_sector);
-                       break;
-               }
-       if(cffat_partition_start_sector == -1) {
-               printf("E: No FAT partition was found\n");
-               return 0;
-       }
-       
-       /* Read first FAT16 sector */
-       if(!cf_readblock(cffat_partition_start_sector, (void *)&s)) {
-               printf("E: Unable to read first FAT sector\n");
-               return 0;
-       }
-       
-       s.volume_label[10] = 0;
-       //printf("I: Volume label: %s\n", s.volume_label);
-       
-       if(le16toh(s.bytes_per_sector) != CF_BLOCK_SIZE) return 0;
-       cffat_sectors_per_cluster = s.sectors_per_cluster;
-       
-       cffat_fat_entries = (le16toh(s.sectors_per_fat)*CF_BLOCK_SIZE)/2;
-       cffat_fat_sector = cffat_partition_start_sector + 1;
-       cffat_fat_cached_sector = -1;
-       
-       cffat_max_root_entries = le16toh(s.max_root_entries);
-       cffat_root_table_sector = cffat_fat_sector + s.number_of_fat*le16toh(s.sectors_per_fat);
-       cffat_dir_cached_sector = -1;
-       
-       cffat_data_start_sector = cffat_root_table_sector + (cffat_max_root_entries*sizeof(struct directory_entry))/CF_BLOCK_SIZE;
-       
-       /*printf("I: Cluster is %d sectors, FAT has %d entries, FAT 1 is at sector %d,\nI: root table is at sector %d (max %d), data is at sector %d\n",
-               cffat_sectors_per_cluster, cffat_fat_entries, cffat_fat_sector,
-               cffat_root_table_sector, cffat_max_root_entries,
-               cffat_data_start_sector);*/
-       return 1;
-}
-
-static int cffat_read_fat(int offset)
-{
-       int wanted_sector;
-       
-       if((offset < 0) || (offset >= cffat_fat_entries))
-               return -1;
-               
-       wanted_sector = cffat_fat_sector + (offset*2)/CF_BLOCK_SIZE;
-       if(wanted_sector != cffat_fat_cached_sector) {
-               if(!cf_readblock(wanted_sector, (void *)&cffat_fat_sector_cache)) {
-                       printf("E: CF failed (FAT), sector %d\n", wanted_sector);
-                       return -1;
-               }
-               cffat_fat_cached_sector = wanted_sector;
-       }
-       
-       return le16toh(cffat_fat_sector_cache[offset % (CF_BLOCK_SIZE/2)]);
-}
-
-static const struct directory_entry *cffat_read_root_directory(int offset)
-{
-       int wanted_sector;
-       
-       if((offset < 0) || (offset >= cffat_max_root_entries))
-               return NULL;
-
-       wanted_sector = cffat_root_table_sector + (offset*sizeof(struct directory_entry))/CF_BLOCK_SIZE;
-
-       if(wanted_sector != cffat_dir_cached_sector) {
-               if(!cf_readblock(wanted_sector, (void *)&cffat_dir_sector_cache)) {
-                       printf("E: CF failed (Rootdir), sector %d\n", wanted_sector);
-                       return NULL;
-               }
-               cffat_dir_cached_sector = wanted_sector;
-       }
-       return &cffat_dir_sector_cache[offset % (CF_BLOCK_SIZE/sizeof(struct directory_entry))];
-}
-
-static void lfn_to_ascii(const struct directory_entry_lfn *entry, char *name, int terminate)
-{
-       int i;
-       unsigned short c;
-
-       for(i=0;i<5;i++) {
-               c = le16toh(entry->name1[i]);
-               if(c <= 255) {
-                       *name = c;
-                       name++;
-                       if(c == 0) return;
-               }
-       }
-       for(i=0;i<6;i++) {
-               c = le16toh(entry->name2[i]);
-               if(c <= 255) {
-                       *name = c;
-                       name++;
-                       if(c == 0) return;
-               }
-       }
-       for(i=0;i<2;i++) {
-               c = le16toh(entry->name3[i]);
-               if(c <= 255) {
-                       *name = c;
-                       name++;
-                       if(c == 0) return;
-               }
-       }
-
-       if(terminate)
-               *name = 0;
-}
-
-static int cffat_is_regular(const struct directory_entry *entry)
-{
-       return ((entry->attributes & 0x10) == 0)
-               && ((entry->attributes & 0x08) == 0)
-               && (entry->filename[0] != 0xe5);
-}
-
-int cffat_list_files(cffat_dir_callback cb, void *param)
-{
-       const struct directory_entry *entry;
-       char fmtbuf[8+1+3+1];
-       char longname[131];
-       int has_longname;
-       int i, j, k;
-
-       has_longname = 0;
-       longname[sizeof(longname)-1] = 0; /* avoid crashing when reading a corrupt FS */
-       for(k=0;k<cffat_max_root_entries;k++) {
-               entry = cffat_read_root_directory(k);
-               if(entry->attributes == 0x0f) {
-                       const struct directory_entry_lfn *entry_lfn;
-                       unsigned char frag;
-                       int terminate;
-
-                       entry_lfn = (const struct directory_entry_lfn *)entry;
-                       frag = entry_lfn->seq & 0x3f;
-                       terminate = entry_lfn->seq & 0x40;
-                       if(frag*13 < sizeof(longname)) {
-                               lfn_to_ascii((const struct directory_entry_lfn *)entry, &longname[(frag-1)*13], terminate);
-                               if(frag == 1) has_longname = 1;
-                       }
-                       continue;
-               } else {
-                       if(!cffat_is_regular(entry)) {
-                               has_longname = 0;
-                               continue;
-                       }
-               }
-               if(entry == NULL) return 0;
-               if(entry->filename[0] == 0) {
-                       has_longname = 0;
-                       break;
-               }
-               j = 0;
-               for(i=0;i<8;i++) {
-                       if(entry->filename[i] == ' ') break;
-                       fmtbuf[j++] = entry->filename[i];
-               }
-               fmtbuf[j++] = '.';
-               for(i=0;i<3;i++) {
-                       if(entry->extension[i] == ' ') break;
-                       fmtbuf[j++] = entry->extension[i];
-               }
-               fmtbuf[j++] = 0;
-               if(!cb(fmtbuf, has_longname ? longname : fmtbuf, param)) return 0;
-               has_longname = 0;
-       }
-       return 1;
-}
-
-static const struct directory_entry *cffat_find_file_by_name(const char *filename)
-{
-       char searched_filename[8];
-       char searched_extension[3];
-       char *dot;
-       const char *c;
-       int i;
-       const struct directory_entry *entry;
-       
-       dot = strrchr(filename, '.');
-       if(dot == NULL)
-               return NULL;
-       
-       memset(searched_filename, ' ', 8);
-       memset(searched_extension, ' ', 3);
-       i = 0;
-       for(c=filename;c<dot;c++)
-               searched_filename[i++] = toupper(*c);
-               
-       i = 0;
-       for(c=dot+1;*c!=0;c++)
-               searched_extension[i++] = toupper(*c);
-               
-       for(i=0;i<cffat_max_root_entries;i++) {
-               entry = cffat_read_root_directory(i);
-               if(entry == NULL) break;
-               if(entry->filename[0] == 0) break;
-               if(!cffat_is_regular(entry)) continue;
-               if(!memcmp(searched_filename, entry->filename, 8)
-                &&!memcmp(searched_extension, entry->extension, 3))
-                       return entry;
-       }
-       return NULL;
-}
-
-static int cffat_load_cluster(int clustern, char *buffer, int maxsectors)
-{
-       int startsector;
-       int i;
-       int toread;
-       
-       clustern = clustern - 2;
-       startsector = cffat_data_start_sector + clustern*cffat_sectors_per_cluster;
-       if(maxsectors < cffat_sectors_per_cluster)
-               toread = maxsectors;
-       else
-               toread = cffat_sectors_per_cluster;
-       for(i=0;i<toread;i++)
-               if(!cf_readblock(startsector+i, (unsigned char *)buffer+i*CF_BLOCK_SIZE)) {
-                       printf("E: CF failed (Cluster), sector %d\n", startsector+i);
-                       return 0;
-               }
-       return 1;
-}
-
-int cffat_load(const char *filename, char *buffer, int size, int *realsize)
-{
-       const struct directory_entry *entry;
-       int cluster_size;
-       int cluster;
-       int n;
-       
-       cluster_size = cffat_sectors_per_cluster*CF_BLOCK_SIZE;
-       size /= CF_BLOCK_SIZE;
-       
-       entry = cffat_find_file_by_name(filename);
-       if(entry == NULL) {
-               printf("E: File not found: %s\n", filename);
-               return 0;
-       }
-       
-       if(realsize != NULL) *realsize = le32toh(entry->file_size);
-       
-       n = 0;
-       cluster = le16toh(entry->first_cluster);
-       while(size > 0) {
-               if(!cffat_load_cluster(cluster, buffer+n*cluster_size, size))
-                       return 0;
-               size -= cffat_sectors_per_cluster;
-               n++;
-               cluster = cffat_read_fat(cluster);
-               if(cluster >= 0xFFF8) break;
-               if(cluster == -1) return 0;
-       }
-       //putsnonl("\n");
-       
-       return n*cluster_size;
-}
-
-void cffat_done()
-{
-       cf_done();
-}
diff --git a/software/baselib/console.c b/software/baselib/console.c
deleted file mode 100644 (file)
index 400f26a..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <libc.h>
-#include <uart.h>
-#include <console.h>
-
-int puts(const char *s)
-{
-       while(*s) {
-               writechar(*s);
-               s++;
-       }
-       writechar('\n');
-       return 1;
-}
-
-void putsnonl(const char *s)
-{
-       while(*s) {
-               writechar(*s);
-               s++;
-       }
-}
-
-void readstr(char *s, int size)
-{
-       char c;
-       int ptr;
-       
-       ptr = 0;
-       while(1) {
-               c = readchar();
-               switch(c) {
-                       case 0x7f:
-                       case 0x08:
-                               if(ptr > 0) {
-                                       ptr--;
-                                       putsnonl("\x08 \x08");
-                               }
-                               break;
-                       case '\r':
-                       case '\n':
-                               s[ptr] = 0x00;
-                               putsnonl("\n");
-                               return;
-                       default:
-                               writechar(c);
-                               s[ptr] = c;
-                               ptr++;
-                               break;
-               }
-       }
-}
-
-int printf(const char *fmt, ...)
-{
-       va_list args;
-       int len;
-       char outbuf[256];
-
-       va_start(args, fmt);
-       len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
-       va_end(args);
-       outbuf[len] = 0;
-       putsnonl(outbuf);
-
-       return len;
-}
diff --git a/software/baselib/crc16.c b/software/baselib/crc16.c
deleted file mode 100644 (file)
index c3fd320..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <crc.h>
-
-unsigned int crc16_table[256] = {
-       0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
-       0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
-       0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
-       0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
-       0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
-       0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
-       0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
-       0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
-       0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
-       0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
-       0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
-       0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
-       0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
-       0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
-       0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
-       0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
-       0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
-       0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
-       0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
-       0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
-       0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
-       0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
-       0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
-       0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
-       0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
-       0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
-       0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
-       0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
-       0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
-       0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
-       0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
-       0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
-};
-
-unsigned short crc16(const unsigned char *buffer, int len)
-{
-       unsigned short crc;
-       
-       crc = 0;
-       while(len-- > 0)
-           crc = crc16_table[((crc >> 8) ^ (*buffer++)) & 0xFF] ^ (crc << 8);
-       
-       return crc;
-}
diff --git a/software/baselib/crc32.c b/software/baselib/crc32.c
deleted file mode 100644 (file)
index dae2332..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include <crc.h>
-
-const unsigned int crc_table[256] = {
-       0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
-       0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
-       0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
-       0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
-       0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
-       0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
-       0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
-       0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
-       0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
-       0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
-       0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
-       0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
-       0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
-       0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
-       0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
-       0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
-       0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
-       0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
-       0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
-       0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
-       0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
-       0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
-       0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
-       0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
-       0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
-       0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
-       0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
-       0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
-       0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
-       0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
-       0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
-       0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
-       0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
-       0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
-       0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
-       0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
-       0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
-       0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
-       0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
-       0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
-       0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
-       0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
-       0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
-       0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
-       0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
-       0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
-       0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
-       0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
-       0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
-       0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
-       0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
-       0x2d02ef8dL
-};
-
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf)  DO1(buf); DO1(buf);
-#define DO4(buf)  DO2(buf); DO2(buf);
-#define DO8(buf)  DO4(buf); DO4(buf);
-
-unsigned int crc32(const unsigned char *buffer, unsigned int len)
-{
-       unsigned int crc;
-       crc = 0;
-       crc = crc ^ 0xffffffffL;
-       while(len >= 8) {
-               DO8(buffer);
-               len -= 8;
-       }
-       if(len) do {
-               DO1(buffer);
-       } while(--len);
-       return crc ^ 0xffffffffL;
-}
diff --git a/software/baselib/divsi3.c b/software/baselib/divsi3.c
deleted file mode 100644 (file)
index 2519cbb..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#define divnorm(num, den, sign)                \
-{                                              \
-  if (num < 0)                                         \
-    {                                          \
-      num = -num;                              \
-      sign = 1;                                        \
-    }                                          \
-  else                                                 \
-    {                                          \
-      sign = 0;                                        \
-    }                                          \
-                                               \
-  if (den < 0)                                         \
-    {                                          \
-      den = - den;                             \
-      sign = 1 - sign;                         \
-    }                                          \
-}
-
-#define exitdiv(sign, res) if (sign) { res = - res;} return res;
-
-long __divsi3 (long numerator, long denominator)
-{
-  int sign;
-  long dividend;
-  divnorm (numerator, denominator, sign);
-
-  dividend = (unsigned int)numerator/(unsigned int)denominator;
-  exitdiv (sign, dividend);
-}
-
-long __modsi3 (long numerator, long denominator)
-{
-       int sign;
-       long res;
-
-       if(numerator < 0) {
-               numerator = -numerator;
-               sign = 1;
-       } else
-               sign = 0;
-
-       if(denominator < 0)
-               denominator = -denominator;
-
-       res = (unsigned int)numerator % (unsigned int)denominator;
-
-       if(sign)
-               return -res;
-       else
-               return res;
-}
diff --git a/software/baselib/irq.S b/software/baselib/irq.S
deleted file mode 100644 (file)
index d9f118d..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-.section .text, "ax", @progbits
-.global irq_enable, irq_isenabled, irq_setmask, irq_getmask, irq_pending, irq_ack
-
-/* Parameter: 1=enable, 0=disable */
-irq_enable:
-       wcsr    IE, r1
-       ret
-
-/* No parameter */
-/* Return value: 1/0 */
-irq_isenabled:
-       rcsr    r1, IE
-       andi    r1, r1, 1
-       ret
-
-/* Parameter: the mask */
-irq_setmask:
-       wcsr    IM, r1
-       ret
-
-/* No parameter */
-/* Return value: the mask */
-irq_getmask:
-       rcsr    r1, IM
-       ret
-
-/* No parameter */
-/* Return value: pending IRQs */
-irq_pending:
-       rcsr    r1, IP
-       ret
-
-/* Parameter: the mask */
-irq_ack:
-       wcsr    IP, r1
-       ret
diff --git a/software/baselib/libc.c b/software/baselib/libc.c
deleted file mode 100644 (file)
index 0ee1462..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * Copyright (C) Linux kernel developers
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <libc.h>
-
-/**
- * strchr - Find the first occurrence of a character in a string
- * @s: The string to be searched
- * @c: The character to search for
- */
-char *strchr(const char *s, int c)
-{
-       for (; *s != (char)c; ++s)
-               if (*s == '\0')
-                       return NULL;
-       return (char *)s;
-}
-
-/**
- * strrchr - Find the last occurrence of a character in a string
- * @s: The string to be searched
- * @c: The character to search for
- */
-char *strrchr(const char *s, int c)
-{
-       const char *p = s + strlen(s);
-       do {
-           if (*p == (char)c)
-               return (char *)p;
-       } while (--p >= s);
-       return NULL;
-}
-
-/**
- * strnchr - Find a character in a length limited string
- * @s: The string to be searched
- * @count: The number of characters to be searched
- * @c: The character to search for
- */
-char *strnchr(const char *s, size_t count, int c)
-{
-       for (; count-- && *s != '\0'; ++s)
-               if (*s == (char)c)
-                       return (char *)s;
-       return NULL;
-}
-
-/**
- * strcpy - Copy a %NUL terminated string
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
- */
-char *strcpy(char *dest, const char *src)
-{
-       char *tmp = dest;
-
-       while ((*dest++ = *src++) != '\0')
-               /* nothing */;
-       return tmp;
-}
-
-/**
- * strncpy - Copy a length-limited, %NUL-terminated string
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
- * @count: The maximum number of bytes to copy
- *
- * The result is not %NUL-terminated if the source exceeds
- * @count bytes.
- *
- * In the case where the length of @src is less than  that  of
- * count, the remainder of @dest will be padded with %NUL.
- *
- */
-char *strncpy(char *dest, const char *src, size_t count)
-{
-       char *tmp = dest;
-       
-       while (count) {
-               if ((*tmp = *src) != 0)
-                       src++;
-               tmp++;
-               count--;
-       }
-       return dest;
-}
-
-/**
- * strcmp - Compare two strings
- * @cs: One string
- * @ct: Another string
- */
-int strcmp(const char *cs, const char *ct)
-{
-       signed char __res;
-
-       while (1) {
-               if ((__res = *cs - *ct++) != 0 || !*cs++)
-                       break;
-       }
-       return __res;
-}
-
-/**
- * strncmp - Compare two strings using the first characters only
- * @cs: One string
- * @ct: Another string
- * @count: Number of characters
- */
-int strncmp(const char *cs, const char *ct, size_t count)
-{
-       signed char __res;
-       size_t n;
-
-       n = 0;
-       __res = 0;
-       while (n < count) {
-               if ((__res = *cs - *ct++) != 0 || !*cs++)
-                       break;
-               n++;
-       }
-       return __res;
-}
-
-/**
- * strlen - Find the length of a string
- * @s: The string to be sized
- */
-size_t strlen(const char *s)
-{
-       const char *sc;
-
-       for (sc = s; *sc != '\0'; ++sc)
-               /* nothing */;
-       return sc - s;
-}
-
-/**
- * strnlen - Find the length of a length-limited string
- * @s: The string to be sized
- * @count: The maximum number of bytes to search
- */
-size_t strnlen(const char *s, size_t count)
-{
-       const char *sc;
-
-       for (sc = s; count-- && *sc != '\0'; ++sc)
-               /* nothing */;
-       return sc - s;
-}
-
-/**
- * memcmp - Compare two areas of memory
- * @cs: One area of memory
- * @ct: Another area of memory
- * @count: The size of the area.
- */
-int memcmp(const void *cs, const void *ct, size_t count)
-{
-       const unsigned char *su1, *su2;
-       int res = 0;
-
-       for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
-               if ((res = *su1 - *su2) != 0)
-                       break;
-       return res;
-}
-
-/**
- * memset - Fill a region of memory with the given value
- * @s: Pointer to the start of the area.
- * @c: The byte to fill the area with
- * @count: The size of the area.
- */
-void *memset(void *s, int c, size_t count)
-{
-       char *xs = s;
-
-       while (count--)
-               *xs++ = c;
-       return s;
-}
-
-/**
- * memcpy - Copies one area of memory to another
- * @dest: Destination
- * @src: Source
- * @n: The size to copy.
- */
-void *memcpy(void *dest, const void *src, size_t n)
-{
-       char *_dest = (char *)dest;
-       char *_src = (char *)src;
-       size_t i;
-
-       for(i=0;i<n;i++)
-               _dest[i] = _src[i];
-
-       return dest;
-}
-
-/**
- * memmove - Copies one area of memory to another, overlap possible
- * @dest: Destination
- * @src: Source
- * @n: The size to copy.
- */
-void *memmove(void *dest, const void *src, size_t count)
-{
-       char *tmp, *s;
-
-       if(dest <= src) {
-               tmp = (char *) dest;
-               s = (char *) src;
-               while(count--)
-                       *tmp++ = *s++;
-       } else {
-               tmp = (char *)dest + count;
-               s = (char *)src + count;
-               while(count--)
-                       *--tmp = *--s;
-       }
-
-       return dest;
-}
-
-
-/**
- * strtoul - convert a string to an unsigned long
- * @nptr: The start of the string
- * @endptr: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-unsigned long strtoul(const char *nptr, char **endptr, int base)
-{
-       unsigned long result = 0,value;
-
-       if (!base) {
-               base = 10;
-               if (*nptr == '0') {
-                       base = 8;
-                       nptr++;
-                       if ((toupper(*nptr) == 'X') && isxdigit(nptr[1])) {
-                               nptr++;
-                               base = 16;
-                       }
-               }
-       } else if (base == 16) {
-               if (nptr[0] == '0' && toupper(nptr[1]) == 'X')
-                       nptr += 2;
-       }
-       while (isxdigit(*nptr) &&
-              (value = isdigit(*nptr) ? *nptr-'0' : toupper(*nptr)-'A'+10) < base) {
-               result = result*base + value;
-               nptr++;
-       }
-       if (endptr)
-               *endptr = (char *)nptr;
-       return result;
-}
-
-/**
- * strtol - convert a string to a signed long
- * @nptr: The start of the string
- * @endptr: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-long strtol(const char *nptr, char **endptr, int base)
-{
-       if(*nptr=='-')
-               return -strtoul(nptr+1,endptr,base);
-       return strtoul(nptr,endptr,base);
-}
-
-int skip_atoi(const char **s)
-{
-       int i=0;
-
-       while (isdigit(**s))
-               i = i*10 + *((*s)++) - '0';
-       return i;
-}
-
-char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type)
-{
-       char c,sign,tmp[66];
-       const char *digits;
-       static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-       static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-       int i;
-
-       digits = (type & PRINTF_LARGE) ? large_digits : small_digits;
-       if (type & PRINTF_LEFT)
-               type &= ~PRINTF_ZEROPAD;
-       if (base < 2 || base > 36)
-               return NULL;
-       c = (type & PRINTF_ZEROPAD) ? '0' : ' ';
-       sign = 0;
-       if (type & PRINTF_SIGN) {
-               if ((signed long) num < 0) {
-                       sign = '-';
-                       num = - (signed long) num;
-                       size--;
-               } else if (type & PRINTF_PLUS) {
-                       sign = '+';
-                       size--;
-               } else if (type & PRINTF_SPACE) {
-                       sign = ' ';
-                       size--;
-               }
-       }
-       if (type & PRINTF_SPECIAL) {
-               if (base == 16)
-                       size -= 2;
-               else if (base == 8)
-                       size--;
-       }
-       i = 0;
-       if (num == 0)
-               tmp[i++]='0';
-       else while (num != 0) {
-               tmp[i++] = digits[num % base];
-               num = num / base;
-       }
-       if (i > precision)
-               precision = i;
-       size -= precision;
-       if (!(type&(PRINTF_ZEROPAD+PRINTF_LEFT))) {
-               while(size-->0) {
-                       if (buf < end)
-                               *buf = ' ';
-                       ++buf;
-               }
-       }
-       if (sign) {
-               if (buf < end)
-                       *buf = sign;
-               ++buf;
-       }
-       if (type & PRINTF_SPECIAL) {
-               if (base==8) {
-                       if (buf < end)
-                               *buf = '0';
-                       ++buf;
-               } else if (base==16) {
-                       if (buf < end)
-                               *buf = '0';
-                       ++buf;
-                       if (buf < end)
-                               *buf = digits[33];
-                       ++buf;
-               }
-       }
-       if (!(type & PRINTF_LEFT)) {
-               while (size-- > 0) {
-                       if (buf < end)
-                               *buf = c;
-                       ++buf;
-               }
-       }
-       while (i < precision--) {
-               if (buf < end)
-                       *buf = '0';
-               ++buf;
-       }
-       while (i-- > 0) {
-               if (buf < end)
-                       *buf = tmp[i];
-               ++buf;
-       }
-       while (size-- > 0) {
-               if (buf < end)
-                       *buf = ' ';
-               ++buf;
-       }
-       return buf;
-}
-
-/**
- * vscnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The return value is the number of characters which have been written into
- * the @buf not including the trailing '\0'. If @size is <= 0 the function
- * returns 0.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want scnprintf() instead.
- */
-int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
-       int i;
-
-       i=vsnprintf(buf,size,fmt,args);
-       return (i >= size) ? (size - 1) : i;
-}
-
-
-/**
- * snprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The return value is the number of characters which would be
- * generated for the given input, excluding the trailing null,
- * as per ISO C99.  If the return is greater than or equal to
- * @size, the resulting string is truncated.
- */
-int snprintf(char * buf, size_t size, const char *fmt, ...)
-{
-       va_list args;
-       int i;
-
-       va_start(args, fmt);
-       i=vsnprintf(buf,size,fmt,args);
-       va_end(args);
-       return i;
-}
-
-/**
- * scnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The return value is the number of characters written into @buf not including
- * the trailing '\0'. If @size is <= 0 the function returns 0.
- */
-
-int scnprintf(char * buf, size_t size, const char *fmt, ...)
-{
-       va_list args;
-       int i;
-
-       va_start(args, fmt);
-       i = vsnprintf(buf, size, fmt, args);
-       va_end(args);
-       return (i >= size) ? (size - 1) : i;
-}
-
-/**
- * vsprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The function returns the number of characters written
- * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
- * buffer overflows.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want sprintf() instead.
- */
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
-       return vsnprintf(buf, INT_MAX, fmt, args);
-}
-
-/**
- * sprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The function returns the number of characters written
- * into @buf. Use snprintf() or scnprintf() in order to avoid
- * buffer overflows.
- */
-int sprintf(char * buf, const char *fmt, ...)
-{
-       va_list args;
-       int i;
-
-       va_start(args, fmt);
-       i=vsnprintf(buf, INT_MAX, fmt, args);
-       va_end(args);
-       return i;
-}
-
-/**
- * rand - Returns a pseudo random number
- */
-
-static unsigned int seed;
-unsigned int rand()
-{
-       seed = 129 * seed + 907633385;
-       return seed;
-}
diff --git a/software/baselib/malloc.c b/software/baselib/malloc.c
deleted file mode 100644 (file)
index 94572bf..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PC_TEST
-#include <libc.h>
-#include <console.h>
-#else
-#include <stdio.h>
-#endif
-
-#include "malloc.h"
-
-/* from http://en.wikipedia.org/wiki/Binary_GCD_algorithm */
-static unsigned int gcd(unsigned int u, unsigned int v)
-{
-       int shift;
-       
-       /* GCD(0,x) := x */
-       if (u == 0 || v == 0)
-               return u | v;
-       
-       /* Let shift := lg K, where K is the greatest power of 2
-        * dividing both u and v. */
-       for(shift = 0; ((u | v) & 1) == 0; ++shift) {
-               u >>= 1;
-               v >>= 1;
-       }
-       
-       while ((u & 1) == 0) u >>= 1;
-       
-       /* From here on, u is always odd. */
-       do {
-               while ((v & 1) == 0)  /* Loop X */
-                       v >>= 1;
-               
-               /* Now u and v are both odd, so diff(u, v) is even.
-                * Let u = min(u, v), v = diff(u, v)/2. */
-               if (u < v) {
-                       v -= u;
-               } else {
-                       unsigned int diff = u - v;
-                       u = v;
-                       v = diff;
-               }
-               v >>= 1;
-       } while (v != 0);
-       
-       return u << shift;
-}
-
-static unsigned int lcm(unsigned int u, unsigned int v)
-{
-       return u*v/gcd(u, v);
-}
-
-/*
- * Memory is split in elements of the size of a bookkeeping
- * record (struct m_bk).
- * Those records are placed in front of each chunk.
- */
-struct m_bk {
-       /* Indice of next element. If there is no next element,
-        * this condition can be spotted by using the last_allocated
-        * field of the bank, and this indice is invalid.
-        */
-       unsigned int next;
-       /* Size of the allocation in elements, counting this one. */
-       unsigned int size;
-} __attribute__((packed));
-
-struct malloc_bank *m_banks;
-static unsigned int m_nbanks;
-static unsigned int m_defaultbank;
-
-static inline struct m_bk *getbk(unsigned int bank)
-{
-       return (struct m_bk *)(m_banks[bank].addr_start);
-}
-
-static inline unsigned int getnbk(unsigned int bank)
-{
-       return (m_banks[bank].addr_end - m_banks[bank].addr_start)/sizeof(struct m_bk);
-}
-
-void malloc_init(struct malloc_bank *banks, unsigned int n, unsigned int defaultbank)
-{
-       unsigned int i;
-       
-       m_banks = banks;
-       m_nbanks = n;
-       m_defaultbank = defaultbank;
-       
-       for(i=0;i<n;i++) {
-               m_banks[i].first_allocated = -1;
-               m_banks[i].last_allocated = -1;
-       }
-}
-
-void *mallocex(unsigned int size, unsigned int bank, unsigned int alignment)
-{
-       struct malloc_bank *b;
-       unsigned int extra;
-       unsigned int datastart;
-       int freespace;
-       struct m_bk *bk;
-       int curindex;
-       int allocindex;
-       
-       if(size == 0) return NULL;
-       
-       /* Resolve alignment and size constraints */
-       alignment = lcm(alignment, sizeof(struct m_bk));
-       if((size % sizeof(struct m_bk)) != 0)
-               size += sizeof(struct m_bk) - (size % sizeof(struct m_bk));
-       
-       b = &m_banks[bank]; /* convenience pointers */
-       bk = getbk(bank);
-       
-       /* First, try allocation at the beginning of the bank */
-       
-       /* How much space we will need to respect the alignment constraint */
-       datastart = b->addr_start + sizeof(struct m_bk);
-       if((datastart % alignment) != 0)
-               extra = alignment - (datastart % alignment);
-       else
-               extra = 0;
-       
-       /* Case: bank is entirely free */
-       if(b->first_allocated == -1) {
-               freespace = b->addr_end - b->addr_start;
-               if(freespace < (size + extra + sizeof(struct m_bk)))
-                       return NULL; /* bank is too small for requested buffer */
-                       
-               /* Everything OK, perform the allocation */
-               extra /= sizeof(struct m_bk);
-               size /= sizeof(struct m_bk);
-               bk[extra].size = size+1;
-               b->first_allocated = extra;
-               b->last_allocated = extra;
-               return &bk[extra+1];
-       }
-       
-       /* Case: can allocate at the very beginning of the bank */
-       freespace = sizeof(struct m_bk)*b->first_allocated;
-       if(freespace >= (size + extra + sizeof(struct m_bk))) {
-               extra /= sizeof(struct m_bk);
-               size /= sizeof(struct m_bk);
-               bk[extra].next = b->first_allocated;
-               bk[extra].size = size+1;
-               b->first_allocated = extra;
-               return &bk[extra+1];
-       }
-       
-       /* Case: can allocate after the last chunk */
-       datastart = b->addr_start
-               + (b->last_allocated+bk[b->last_allocated].size+1)*sizeof(struct m_bk);
-       if((datastart % alignment) != 0)
-               extra = alignment - (datastart % alignment);
-       else
-               extra = 0;
-       freespace = sizeof(struct m_bk)*(getnbk(bank) - b->last_allocated - bk[b->last_allocated].size);
-       if(freespace >= (size + extra + sizeof(struct m_bk))) {
-               extra /= sizeof(struct m_bk);
-               size /= sizeof(struct m_bk);
-               allocindex = b->last_allocated + bk[b->last_allocated].size + extra;
-               bk[b->last_allocated].next = allocindex;
-               bk[allocindex].size = size+1;
-               b->last_allocated = allocindex;
-               return &bk[allocindex+1];
-       }
-       
-       /* Case: can allocate between two chunks */
-       curindex = b->first_allocated;
-       while(curindex < b->last_allocated) {
-               int nextindex;
-               
-               nextindex = bk[curindex].next;
-               
-               datastart = b->addr_start
-                       + (curindex+bk[curindex].size+1)*sizeof(struct m_bk);
-               if((datastart % alignment) != 0)
-                       extra = alignment - (datastart % alignment);
-               else
-                       extra = 0;
-               
-               freespace = sizeof(struct m_bk)*(nextindex - (curindex + bk[curindex].size));
-               
-               if(freespace >= (size + extra + sizeof(struct m_bk))) {
-                       extra /= sizeof(struct m_bk);
-                       size /= sizeof(struct m_bk);
-                       
-                       allocindex = curindex + bk[curindex].size + extra;
-                       bk[allocindex].size = size+1;
-                       bk[allocindex].next = nextindex;
-                       bk[curindex].next = allocindex;
-                       
-                       return &bk[allocindex+1];
-               }
-               
-               curindex = nextindex;
-       }
-       return NULL;
-}
-
-#ifdef PC_TEST
-void test_free(void *p)
-#else
-void free(void *p)
-#endif
-{
-       struct malloc_bank *b;
-       struct m_bk *bk;
-       unsigned int i;
-       unsigned int pa;
-       unsigned int pbki;
-       
-       pa = (unsigned int)p;
-       
-       //printf("free: %08x\n", pa);
-       
-       /* Find which bank p belongs to */
-       b = NULL;
-       bk = NULL;
-       for(i=0;i<m_nbanks;i++) 
-               if((m_banks[i].addr_start <= pa) && (m_banks[i].addr_end > pa)) {
-                       bk = getbk(i);
-                       b = &m_banks[i];
-                       break;
-               }
-       if(b == NULL) {
-#ifdef PC_TEST
-               printf("ERR: Trying to free a pointer out of any bank\n");
-#endif
-               return;
-       }
-
-       /* Case: freeing the only chunk */
-       if(b->first_allocated == b->last_allocated) {
-               /* We assume p is the data of the only chunk (as it should) */
-               b->first_allocated = -1;
-               b->last_allocated = -1;
-               return;
-       }
-       
-       pbki = (pa - b->addr_start)/sizeof(struct m_bk) - 1;
-       
-       /* Case: freeing the first chunk */
-       if(pbki == b->first_allocated) {
-               b->first_allocated = bk[b->first_allocated].next;
-               return;
-       }
-       
-       /* Case: freeing the last chunk */
-       if(pbki == b->last_allocated) {
-               i = b->first_allocated;
-               while(bk[i].next != pbki)
-                       i = bk[i].next;
-               b->last_allocated = i;
-               return;
-       }
-       
-       /* Case: freeing a chunk between two others */
-       i = b->first_allocated;
-       while(bk[i].next != pbki)
-               i = bk[i].next;
-       bk[i].next = bk[pbki].next;
-}
-
-#ifdef PC_TEST
-void *test_malloc(size_t size)
-#else
-void *malloc(size_t size)
-#endif
-{
-       void *r;
-       r = mallocex(size, m_defaultbank, 1);
-       //printf("alloc: %08x\n", (unsigned int)r);
-       return r;
-}
-
-#ifdef PC_TEST
-void *test_calloc(size_t nmemb, size_t size)
-#else
-void *calloc(size_t nmemb, size_t size)
-#endif
-{
-       void *ret;
-
-       size *= nmemb;
-       ret = malloc(size);
-       if(ret == NULL) return ret;
-       memset(ret, 0, size);
-       return ret;
-}
diff --git a/software/baselib/milieu.h b/software/baselib/milieu.h
deleted file mode 100644 (file)
index 58d688d..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/*
-===============================================================================
-
-This C header file is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2.
-
-Written by John R. Hauser.  This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704.  Funding was partially provided by the
-National Science Foundation under grant MIP-9311980.  The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
-is available through the Web page `http://http.cs.berkeley.edu/~jhauser/
-arithmetic/softfloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
-has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
-TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
-PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
-AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) they include prominent notice that the work is derivative, and (2) they
-include prominent notice akin to these three paragraphs for those parts of
-this code that are retained.
-
-===============================================================================
-*/
-
-/*
--------------------------------------------------------------------------------
-Common integer types and flags.
--------------------------------------------------------------------------------
-*/
-
-/*
--------------------------------------------------------------------------------
-One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
--------------------------------------------------------------------------------
-*/
-#define BIGENDIAN
-
-/*
--------------------------------------------------------------------------------
-The macro `BITS64' can be defined to indicate that 64-bit integer types are
-supported by the compiler.
--------------------------------------------------------------------------------
-*/
-//#define BITS64
-
-/*
--------------------------------------------------------------------------------
-Each of the following `typedef's defines the most convenient type that holds
-integers of at least as many bits as specified.  For example, `uint8' should
-be the most convenient type that can hold unsigned integers of as many as
-8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
-implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
-to the same as `int'.
--------------------------------------------------------------------------------
-*/
-typedef int flag;
-typedef int uint8;
-typedef int int8;
-typedef int uint16;
-typedef int int16;
-typedef unsigned int uint32;
-typedef signed int int32;
-#ifdef BITS64
-typedef unsigned long long int bits64;
-typedef signed long long int sbits64;
-#endif
-
-/*
--------------------------------------------------------------------------------
-Each of the following `typedef's defines a type that holds integers
-of _exactly_ the number of bits specified.  For instance, for most
-implementation of C, `bits16' and `sbits16' should be `typedef'ed to
-`unsigned short int' and `signed short int' (or `short int'), respectively.
--------------------------------------------------------------------------------
-*/
-typedef unsigned char bits8;
-typedef signed char sbits8;
-typedef unsigned short int bits16;
-typedef signed short int sbits16;
-typedef unsigned int bits32;
-typedef signed int sbits32;
-#ifdef BITS64
-typedef unsigned long long int uint64;
-typedef signed long long int int64;
-#endif
-
-#ifdef BITS64
-/*
--------------------------------------------------------------------------------
-The `LIT64' macro takes as its argument a textual integer literal and if
-necessary ``marks'' the literal as having a 64-bit integer type.  For
-example, the Gnu C Compiler (`gcc') requires that 64-bit literals be
-appended with the letters `LL' standing for `long long', which is `gcc's
-name for the 64-bit integer type.  Some compilers may allow `LIT64' to be
-defined as the identity macro:  `#define LIT64( a ) a'.
--------------------------------------------------------------------------------
-*/
-#define LIT64( a ) a##LL
-#endif
-
-/*
--------------------------------------------------------------------------------
-The macro `INLINE' can be used before functions that should be inlined.  If
-a compiler does not support explicit inlining, this macro should be defined
-to be `static'.
--------------------------------------------------------------------------------
-*/
-#define INLINE extern inline
-
-/*
--------------------------------------------------------------------------------
-Symbolic Boolean literals.
--------------------------------------------------------------------------------
-*/
-enum {
-    FALSE = 0,
-    TRUE  = 1
-};
-
diff --git a/software/baselib/softfloat-glue.c b/software/baselib/softfloat-glue.c
deleted file mode 100644 (file)
index 45ceabd..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <libc.h>
-#include "softfloat.h"
-
-/*
- * 'Equal' wrapper. This returns 0 if the numbers are equal, or (1 | -1)
- * otherwise. So we need to invert the output.
- */
-int __eqsf2(float32 a, float32 b)
-{
-       return !float32_eq(a, b);
-}
-
-/*
- * 'Not Equal' wrapper. This returns -1 or 1 (say, 1!) if the numbers are
- * not equal, 0 otherwise. However no not equal call is provided, so we have
- * to use an 'equal' call and invert the result. The result is already
- * inverted though! Confusing?!
- */
-int __nesf2(float32 a, float32 b)
-{
-       return !float32_eq(a, b);
-}
-
-/*
- * 'Greater Than' wrapper. This returns 1 if the number is greater, 0
- * or -1 otherwise. Unfortunately, no such function exists. We have to
- * instead compare the numbers using the 'less than' calls in order to
- * make up our mind. This means that we can call 'less than or equal' and
- * invert the result.
- */
-int __gtsf2(float32 a, float32 b)
-{
-       return !float32_le(a, b);
-}
-
-/*
- * 'Greater Than or Equal' wrapper. We emulate this by inverting the result
- * of a 'less than' call.
- */
-int __gesf2(float32 a, float32 b)
-{
-       return !float32_lt(a, b);
-}
-
-/*
- * 'Less Than' wrapper.
- */
-int __ltsf2(float32 a, float32 b)
-{
-       return float32_lt(a, b);
-}
-
-/*
- * 'Less Than or Equal' wrapper. A 0 must turn into a 1, and a 1 into a 0.
- */
-int __lesf2(float32 a, float32 b)
-{
-       return !float32_le(a, b);
-}
-
-/*
- * Float negate... This isn't provided by the library, but it's hardly the
- * hardest function in the world to write... :) In fact, because of the
- * position in the registers of arguments, the double precision version can
- * go here too ;-)
- */
-float32 __negsf2(float32 x)
-{
-       return x ^ 0x80000000;
-}
-
-/*
- * 32-bit operations.
- */
-float32 __addsf3(float32 a, float32 b)
-{
-       return float32_add(a, b);
-}
-
-float32 __subsf3(float32 a, float32 b)
-{
-       return float32_sub(a, b);
-}
-
-float32 __mulsf3(float32 a, float32 b)
-{
-       return float32_mul(a, b);
-}
-
-float32 __divsf3(float32 a, float32 b)
-{
-       return float32_div(a, b);
-}
-
-float32 __floatsisf(int x)
-{
-       return int32_to_float32(x);
-}
-
-int __fixsfsi(float32 x)
-{
-       return float32_to_int32_round_to_zero(x);
-}
-
-unsigned int __fixunssfsi(float32 x)
-{
-       return float32_to_int32_round_to_zero(x); // XXX
-}
-
diff --git a/software/baselib/softfloat-macros.h b/software/baselib/softfloat-macros.h
deleted file mode 100644 (file)
index 40d1182..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-
-/*
-===============================================================================
-
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2.
-
-Written by John R. Hauser.  This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704.  Funding was partially provided by the
-National Science Foundation under grant MIP-9311980.  The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
-is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
-has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
-TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
-PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
-AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) they include prominent notice that the work is derivative, and (2) they
-include prominent notice akin to these three paragraphs for those parts of
-this code that are retained.
-
-===============================================================================
-*/
-
-/*
--------------------------------------------------------------------------------
-Shifts `a' right by the number of bits given in `count'.  If any nonzero
-bits are shifted off, they are ``jammed'' into the least significant bit of
-the result by setting the least significant bit to 1.  The value of `count'
-can be arbitrarily large; in particular, if `count' is greater than 32, the
-result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-The result is stored in the location pointed to by `zPtr'.
--------------------------------------------------------------------------------
-*/
-INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
-{
-    bits32 z;
-
-    if ( count == 0 ) {
-        z = a;
-    }
-    else if ( count < 32 ) {
-        z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
-    }
-    else {
-        z = ( a != 0 );
-    }
-    *zPtr = z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the
-number of bits given in `count'.  Any bits shifted off are lost.  The value
-of `count' can be arbitrarily large; in particular, if `count' is greater
-than 64, the result will be 0.  The result is broken into two 32-bit pieces
-which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- shift64Right(
-     bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr )
-{
-    bits32 z0, z1;
-    int8 negCount = ( - count ) & 31;
-
-    if ( count == 0 ) {
-        z1 = a1;
-        z0 = a0;
-    }
-    else if ( count < 32 ) {
-        z1 = ( a0<<negCount ) | ( a1>>count );
-        z0 = a0>>count;
-    }
-    else {
-        z1 = ( count < 64 ) ? ( a0>>( count & 31 ) ) : 0;
-        z0 = 0;
-    }
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the
-number of bits given in `count'.  If any nonzero bits are shifted off, they
-are ``jammed'' into the least significant bit of the result by setting the
-least significant bit to 1.  The value of `count' can be arbitrarily large;
-in particular, if `count' is greater than 64, the result will be either 0
-or 1, depending on whether the concatenation of `a0' and `a1' is zero or
-nonzero.  The result is broken into two 32-bit pieces which are stored at
-the locations pointed to by `z0Ptr' and `z1Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- shift64RightJamming(
-     bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr )
-{
-    bits32 z0, z1;
-    int8 negCount = ( - count ) & 31;
-
-    if ( count == 0 ) {
-        z1 = a1;
-        z0 = a0;
-    }
-    else if ( count < 32 ) {
-        z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
-        z0 = a0>>count;
-    }
-    else {
-        if ( count == 32 ) {
-            z1 = a0 | ( a1 != 0 );
-        }
-        else if ( count < 64 ) {
-            z1 = ( a0>>( count & 31 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
-        }
-        else {
-            z1 = ( ( a0 | a1 ) != 0 );
-        }
-        z0 = 0;
-    }
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' right
-by 32 _plus_ the number of bits given in `count'.  The shifted result is
-at most 64 nonzero bits; these are broken into two 32-bit pieces which are
-stored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
-off form a third 32-bit result as follows:  The _last_ bit shifted off is
-the most-significant bit of the extra result, and the other 31 bits of the
-extra result are all zero if and only if _all_but_the_last_ bits shifted off
-were all zero.  This extra result is stored in the location pointed to by
-`z2Ptr'.  The value of `count' can be arbitrarily large.
-    (This routine makes more sense if `a0', `a1', and `a2' are considered
-to form a fixed-point value with binary point between `a1' and `a2'.  This
-fixed-point value is shifted right by the number of bits given in `count',
-and the integer part of the result is returned at the locations pointed to
-by `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
-corrupted as described above, and is returned at the location pointed to by
-`z2Ptr'.)
--------------------------------------------------------------------------------
-*/
-INLINE void
- shift64ExtraRightJamming(
-     bits32 a0,
-     bits32 a1,
-     bits32 a2,
-     int16 count,
-     bits32 *z0Ptr,
-     bits32 *z1Ptr,
-     bits32 *z2Ptr
- )
-{
-    bits32 z0, z1, z2;
-    int8 negCount = ( - count ) & 31;
-
-    if ( count == 0 ) {
-        z2 = a2;
-        z1 = a1;
-        z0 = a0;
-    }
-    else {
-        if ( count < 32 ) {
-            z2 = a1<<negCount;
-            z1 = ( a0<<negCount ) | ( a1>>count );
-            z0 = a0>>count;
-        }
-        else {
-            if ( count == 32 ) {
-                z2 = a1;
-                z1 = a0;
-            }
-            else {
-                a2 |= a1;
-                if ( count < 64 ) {
-                    z2 = a0<<negCount;
-                    z1 = a0>>( count & 31 );
-                }
-                else {
-                    z2 = ( count == 64 ) ? a0 : ( a0 != 0 );
-                    z1 = 0;
-                }
-            }
-            z0 = 0;
-        }
-        z2 |= ( a2 != 0 );
-    }
-    *z2Ptr = z2;
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Shifts the 64-bit value formed by concatenating `a0' and `a1' left by the
-number of bits given in `count'.  Any bits shifted off are lost.  The value
-of `count' must be less than 32.  The result is broken into two 32-bit
-pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- shortShift64Left(
-     bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr )
-{
-
-    *z1Ptr = a1<<count;
-    *z0Ptr =
-        ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 31 ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' left by
-the number of bits given in `count'.  Any bits shifted off are lost.  The
-value of `count' must be less than 32.  The result is broken into three
-32-bit pieces which are stored at the locations pointed to by `z0Ptr',
-`z1Ptr', and `z2Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- shortShift96Left(
-     bits32 a0,
-     bits32 a1,
-     bits32 a2,
-     int16 count,
-     bits32 *z0Ptr,
-     bits32 *z1Ptr,
-     bits32 *z2Ptr
- )
-{
-    bits32 z0, z1, z2;
-    int8 negCount;
-
-    z2 = a2<<count;
-    z1 = a1<<count;
-    z0 = a0<<count;
-    if ( 0 < count ) {
-        negCount = ( ( - count ) & 31 );
-        z1 |= a2>>negCount;
-        z0 |= a1>>negCount;
-    }
-    *z2Ptr = z2;
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Adds the 64-bit value formed by concatenating `a0' and `a1' to the 64-bit
-value formed by concatenating `b0' and `b1'.  Addition is modulo 2^64, so
-any carry out is lost.  The result is broken into two 32-bit pieces which
-are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- add64(
-     bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr )
-{
-    bits32 z1;
-
-    z1 = a1 + b1;
-    *z1Ptr = z1;
-    *z0Ptr = a0 + b0 + ( z1 < a1 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Adds the 96-bit value formed by concatenating `a0', `a1', and `a2' to the
-96-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
-modulo 2^96, so any carry out is lost.  The result is broken into three
-32-bit pieces which are stored at the locations pointed to by `z0Ptr',
-`z1Ptr', and `z2Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- add96(
-     bits32 a0,
-     bits32 a1,
-     bits32 a2,
-     bits32 b0,
-     bits32 b1,
-     bits32 b2,
-     bits32 *z0Ptr,
-     bits32 *z1Ptr,
-     bits32 *z2Ptr
- )
-{
-    bits32 z0, z1, z2;
-    int8 carry0, carry1;
-
-    z2 = a2 + b2;
-    carry1 = ( z2 < a2 );
-    z1 = a1 + b1;
-    carry0 = ( z1 < a1 );
-    z0 = a0 + b0;
-    z1 += carry1;
-    z0 += ( z1 < carry1 );
-    z0 += carry0;
-    *z2Ptr = z2;
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Subtracts the 64-bit value formed by concatenating `b0' and `b1' from the
-64-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
-2^64, so any borrow out (carry out) is lost.  The result is broken into two
-32-bit pieces which are stored at the locations pointed to by `z0Ptr' and
-`z1Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- sub64(
-     bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr )
-{
-
-    *z1Ptr = a1 - b1;
-    *z0Ptr = a0 - b0 - ( a1 < b1 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Subtracts the 96-bit value formed by concatenating `b0', `b1', and `b2' from
-the 96-bit value formed by concatenating `a0', `a1', and `a2'.  Subtraction
-is modulo 2^96, so any borrow out (carry out) is lost.  The result is broken
-into three 32-bit pieces which are stored at the locations pointed to by
-`z0Ptr', `z1Ptr', and `z2Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- sub96(
-     bits32 a0,
-     bits32 a1,
-     bits32 a2,
-     bits32 b0,
-     bits32 b1,
-     bits32 b2,
-     bits32 *z0Ptr,
-     bits32 *z1Ptr,
-     bits32 *z2Ptr
- )
-{
-    bits32 z0, z1, z2;
-    int8 borrow0, borrow1;
-
-    z2 = a2 - b2;
-    borrow1 = ( a2 < b2 );
-    z1 = a1 - b1;
-    borrow0 = ( a1 < b1 );
-    z0 = a0 - b0;
-    z0 -= ( z1 < borrow1 );
-    z1 -= borrow1;
-    z0 -= borrow0;
-    *z2Ptr = z2;
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Multiplies `a' by `b' to obtain a 64-bit product.  The product is broken
-into two 32-bit pieces which are stored at the locations pointed to by
-`z0Ptr' and `z1Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void mul32To64( bits32 a, bits32 b, bits32 *z0Ptr, bits32 *z1Ptr )
-{
-    bits16 aHigh, aLow, bHigh, bLow;
-    bits32 z0, zMiddleA, zMiddleB, z1;
-
-    aLow = a;
-    aHigh = a>>16;
-    bLow = b;
-    bHigh = b>>16;
-    z1 = ( (bits32) aLow ) * bLow;
-    zMiddleA = ( (bits32) aLow ) * bHigh;
-    zMiddleB = ( (bits32) aHigh ) * bLow;
-    z0 = ( (bits32) aHigh ) * bHigh;
-    zMiddleA += zMiddleB;
-    z0 += ( ( (bits32) ( zMiddleA < zMiddleB ) )<<16 ) + ( zMiddleA>>16 );
-    zMiddleA <<= 16;
-    z1 += zMiddleA;
-    z0 += ( z1 < zMiddleA );
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Multiplies the 64-bit value formed by concatenating `a0' and `a1' by `b' to
-obtain a 96-bit product.  The product is broken into three 32-bit pieces
-which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
-`z2Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- mul64By32To96(
-     bits32 a0,
-     bits32 a1,
-     bits32 b,
-     bits32 *z0Ptr,
-     bits32 *z1Ptr,
-     bits32 *z2Ptr
- )
-{
-    bits32 z0, z1, z2, more1;
-
-    mul32To64( a1, b, &z1, &z2 );
-    mul32To64( a0, b, &z0, &more1 );
-    add64( z0, more1, 0, z1, &z0, &z1 );
-    *z2Ptr = z2;
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Multiplies the 64-bit value formed by concatenating `a0' and `a1' to the
-64-bit value formed by concatenating `b0' and `b1' to obtain a 128-bit
-product.  The product is broken into four 32-bit pieces which are stored at
-the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
--------------------------------------------------------------------------------
-*/
-INLINE void
- mul64To128(
-     bits32 a0,
-     bits32 a1,
-     bits32 b0,
-     bits32 b1,
-     bits32 *z0Ptr,
-     bits32 *z1Ptr,
-     bits32 *z2Ptr,
-     bits32 *z3Ptr
- )
-{
-    bits32 z0, z1, z2, z3;
-    bits32 more1, more2;
-
-    mul32To64( a1, b1, &z2, &z3 );
-    mul32To64( a1, b0, &z1, &more2 );
-    add64( z1, more2, 0, z2, &z1, &z2 );
-    mul32To64( a0, b0, &z0, &more1 );
-    add64( z0, more1, 0, z1, &z0, &z1 );
-    mul32To64( a0, b1, &more1, &more2 );
-    add64( more1, more2, 0, z2, &more1, &z2 );
-    add64( z0, z1, 0, more1, &z0, &z1 );
-    *z3Ptr = z3;
-    *z2Ptr = z2;
-    *z1Ptr = z1;
-    *z0Ptr = z0;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns an approximation to the 32-bit integer quotient obtained by dividing
-`b' into the 64-bit value formed by concatenating `a0' and `a1'.  The divisor
-`b' must be at least 2^31.  If q is the exact quotient truncated toward
-zero, the approximation returned lies between q and q + 2 inclusive.  If
-the exact quotient q is larger than 32 bits, the maximum positive 32-bit
-unsigned integer is returned.
--------------------------------------------------------------------------------
-*/
-static bits32 estimateDiv64To32( bits32 a0, bits32 a1, bits32 b )
-{
-    bits32 b0, b1;
-    bits32 rem0, rem1, term0, term1;
-    bits32 z;
-
-    if ( b <= a0 ) return 0xFFFFFFFF;
-    b0 = b>>16;
-    z = ( b0<<16 <= a0 ) ? 0xFFFF0000 : ( a0 / b0 )<<16;
-    mul32To64( b, z, &term0, &term1 );
-    sub64( a0, a1, term0, term1, &rem0, &rem1 );
-    while ( ( (sbits32) rem0 ) < 0 ) {
-        z -= 0x10000;
-        b1 = b<<16;
-        add64( rem0, rem1, b0, b1, &rem0, &rem1 );
-    }
-    rem0 = ( rem0<<16 ) | ( rem1>>16 );
-    z |= ( b0<<16 <= rem0 ) ? 0xFFFF : rem0 / b0;
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns an approximation to the square root of the 32-bit significand given
-by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
-`aExp' (the least significant bit) is 1, the integer returned approximates
-2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
-is 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
-case, the approximation returned lies strictly within +/-2 of the exact
-value.
--------------------------------------------------------------------------------
-*/
-static bits32 estimateSqrt32( int16 aExp, bits32 a )
-{
-    static const bits16 sqrtOddAdjustments[] = {
-        0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
-        0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
-    };
-    static const bits16 sqrtEvenAdjustments[] = {
-        0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
-        0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
-    };
-    int8 index;
-    bits32 z;
-
-    index = ( a>>27 ) & 15;
-    if ( aExp & 1 ) {
-        z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
-        z = ( ( a / z )<<14 ) + ( z<<15 );
-        a >>= 1;
-    }
-    else {
-        z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
-        z = a / z + z;
-        z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
-        if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
-    }
-    return ( ( estimateDiv64To32( a, 0, z ) )>>1 ) + ( z>>1 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the number of leading 0 bits before the most-significant 1 bit
-of `a'.  If `a' is zero, 32 is returned.
--------------------------------------------------------------------------------
-*/
-static int8 countLeadingZeros32( bits32 a )
-{
-    static const int8 countLeadingZerosHigh[] = {
-        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
-        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    int8 shiftCount;
-
-    shiftCount = 0;
-    if ( a < 0x10000 ) {
-        shiftCount += 16;
-        a <<= 16;
-    }
-    if ( a < 0x1000000 ) {
-        shiftCount += 8;
-        a <<= 8;
-    }
-    shiftCount += countLeadingZerosHigh[ a>>24 ];
-    return shiftCount;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is equal
-to the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,
-returns 0.
--------------------------------------------------------------------------------
-*/
-INLINE flag eq64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
-{
-
-    return ( a0 == b0 ) && ( a1 == b1 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less
-than or equal to the 64-bit value formed by concatenating `b0' and `b1'.
-Otherwise, returns 0.
--------------------------------------------------------------------------------
-*/
-INLINE flag le64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
-{
-
-    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less
-than the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,
-returns 0.
--------------------------------------------------------------------------------
-*/
-INLINE flag lt64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
-{
-
-    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is not
-equal to the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,
-returns 0.
--------------------------------------------------------------------------------
-*/
-INLINE flag ne64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
-{
-
-    return ( a0 != b0 ) || ( a1 != b1 );
-
-}
-
diff --git a/software/baselib/softfloat-specialize.h b/software/baselib/softfloat-specialize.h
deleted file mode 100644 (file)
index 9f3466f..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-
-/*
-===============================================================================
-
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2.
-
-Written by John R. Hauser.  This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704.  Funding was partially provided by the
-National Science Foundation under grant MIP-9311980.  The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
-is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
-has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
-TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
-PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
-AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) they include prominent notice that the work is derivative, and (2) they
-include prominent notice akin to these three paragraphs for those parts of
-this code that are retained.
-
-===============================================================================
-*/
-
-/*
--------------------------------------------------------------------------------
-Underflow tininess-detection mode, statically initialized to default value.
-(The declaration in `softfloat.h' must match the `int8' type here.)
--------------------------------------------------------------------------------
-*/
-int8 float_detect_tininess = float_tininess_after_rounding;
-
-/*
--------------------------------------------------------------------------------
-Raises the exceptions specified by `flags'.  Floating-point traps can be
-defined here if desired.  It is currently not possible for such a trap to
-substitute a result value.  If traps are not implemented, this routine
-should be simply `float_exception_flags |= flags;'.
--------------------------------------------------------------------------------
-*/
-void float_raise( int8 flags )
-{
-
-    float_exception_flags |= flags;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Internal canonical NaN format.
--------------------------------------------------------------------------------
-*/
-typedef struct {
-    flag sign;
-    bits32 high, low;
-} commonNaNT;
-
-/*
--------------------------------------------------------------------------------
-The pattern for a default generated single-precision NaN.
--------------------------------------------------------------------------------
-*/
-enum {
-    float32_default_nan = 0xFFFFFFFF
-};
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is a NaN;
-otherwise returns 0.
--------------------------------------------------------------------------------
-*/
-flag float32_is_nan( float32 a )
-{
-
-    return ( 0xFF000000 < (bits32) ( a<<1 ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is a signaling
-NaN; otherwise returns 0.
--------------------------------------------------------------------------------
-*/
-flag float32_is_signaling_nan( float32 a )
-{
-
-    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Takes two single-precision floating-point values `a' and `b', one of which
-is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
-signaling NaN, the invalid exception is raised.
--------------------------------------------------------------------------------
-*/
-static float32 propagateFloat32NaN( float32 a, float32 b )
-{
-    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
-    aIsNaN = float32_is_nan( a );
-    aIsSignalingNaN = float32_is_signaling_nan( a );
-    bIsNaN = float32_is_nan( b );
-    bIsSignalingNaN = float32_is_signaling_nan( b );
-    a |= 0x00400000;
-    b |= 0x00400000;
-    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
-    if ( aIsNaN ) {
-        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
-    }
-    else {
-        return b;
-    }
-
-}
diff --git a/software/baselib/softfloat.c b/software/baselib/softfloat.c
deleted file mode 100644 (file)
index b41c497..0000000
+++ /dev/null
@@ -1,1031 +0,0 @@
-
-/*
-===============================================================================
-
-This C source file is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2.
-
-Written by John R. Hauser.  This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704.  Funding was partially provided by the
-National Science Foundation under grant MIP-9311980.  The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
-is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
-has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
-TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
-PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
-AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) they include prominent notice that the work is derivative, and (2) they
-include prominent notice akin to these three paragraphs for those parts of
-this code that are retained.
-
-===============================================================================
-*/
-
-#include "milieu.h"
-#include "softfloat.h"
-
-/*
--------------------------------------------------------------------------------
-Floating-point rounding mode and exception flags.
--------------------------------------------------------------------------------
-*/
-int8 float_rounding_mode = float_round_nearest_even;
-int8 float_exception_flags = 0;
-
-/*
--------------------------------------------------------------------------------
-Primitive arithmetic functions, including multi-word arithmetic, and
-division and square root approximations.  (Can be specialized to target if
-desired.)
--------------------------------------------------------------------------------
-*/
-#include "softfloat-macros.h"
-
-/*
--------------------------------------------------------------------------------
-Functions and definitions to determine:  (1) whether tininess for underflow
-is detected before or after rounding by default, (2) what (if anything)
-happens when exceptions are raised, (3) how signaling NaNs are distinguished
-from quiet NaNs, (4) the default generated quiet NaNs, and (4) how NaNs
-are propagated from function inputs to output.  These details are target-
-specific.
--------------------------------------------------------------------------------
-*/
-#include "softfloat-specialize.h"
-
-/*
--------------------------------------------------------------------------------
-Returns the fraction bits of the single-precision floating-point value `a'.
--------------------------------------------------------------------------------
-*/
-INLINE bits32 extractFloat32Frac( float32 a )
-{
-
-    return a & 0x007FFFFF;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the exponent bits of the single-precision floating-point value `a'.
--------------------------------------------------------------------------------
-*/
-INLINE int16 extractFloat32Exp( float32 a )
-{
-
-    return ( a>>23 ) & 0xFF;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the sign bit of the single-precision floating-point value `a'.
--------------------------------------------------------------------------------
-*/
-INLINE flag extractFloat32Sign( float32 a )
-{
-
-    return a>>31;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Normalizes the subnormal single-precision floating-point value represented
-by the denormalized significand `aSig'.  The normalized exponent and
-significand are stored at the locations pointed to by `zExpPtr' and
-`zSigPtr', respectively.
--------------------------------------------------------------------------------
-*/
-static void
- normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
-{
-    int8 shiftCount;
-
-    shiftCount = countLeadingZeros32( aSig ) - 8;
-    *zSigPtr = aSig<<shiftCount;
-    *zExpPtr = 1 - shiftCount;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-single-precision floating-point value, returning the result.  After being
-shifted into the proper positions, the three fields are simply added
-together to form the result.  This means that any integer portion of `zSig'
-will be added into the exponent.  Since a properly normalized significand
-will have an integer portion equal to 1, the `zExp' input should be 1 less
-than the desired result exponent whenever `zSig' is a complete, normalized
-significand.
--------------------------------------------------------------------------------
-*/
-INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
-{
-
-    return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-and significand `zSig', and returns the proper single-precision floating-
-point value corresponding to the abstract input.  Ordinarily, the abstract
-value is simply rounded and packed into the single-precision format, with
-the inexact exception raised if the abstract input cannot be represented
-exactly.  If the abstract value is too large, however, the overflow and
-inexact exceptions are raised and an infinity or maximal finite value is
-returned.  If the abstract value is too small, the input value is rounded to
-a subnormal number, and the underflow and inexact exceptions are raised if
-the abstract input cannot be represented exactly as a subnormal single-
-precision floating-point number.
-    The input significand `zSig' has its binary point between bits 30
-and 29, which is 7 bits to the left of the usual location.  This shifted
-significand must be normalized or smaller.  If `zSig' is not normalized,
-`zExp' must be 0; in that case, the result returned is a subnormal number,
-and it must not require rounding.  In the usual case that `zSig' is
-normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-The handling of underflow and overflow follows the IEC/IEEE Standard for
-Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
-{
-    int8 roundingMode;
-    flag roundNearestEven;
-    int8 roundIncrement, roundBits;
-    flag isTiny;
-
-    roundingMode = float_rounding_mode;
-    roundNearestEven = roundingMode == float_round_nearest_even;
-    roundIncrement = 0x40;
-    if ( ! roundNearestEven ) {
-        if ( roundingMode == float_round_to_zero ) {
-            roundIncrement = 0;
-        }
-        else {
-            roundIncrement = 0x7F;
-            if ( zSign ) {
-                if ( roundingMode == float_round_up ) roundIncrement = 0;
-            }
-            else {
-                if ( roundingMode == float_round_down ) roundIncrement = 0;
-            }
-        }
-    }
-    roundBits = zSig & 0x7F;
-    if ( 0xFD <= (bits16) zExp ) {
-        if (    ( 0xFD < zExp )
-             || (    ( zExp == 0xFD )
-                  && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
-           ) {
-            float_raise( float_flag_overflow | float_flag_inexact );
-            return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
-        }
-        if ( zExp < 0 ) {
-            isTiny =
-                   ( float_detect_tininess == float_tininess_before_rounding )
-                || ( zExp < -1 )
-                || ( zSig + roundIncrement < 0x80000000 );
-            shift32RightJamming( zSig, - zExp, &zSig );
-            zExp = 0;
-            roundBits = zSig & 0x7F;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
-        }
-    }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
-    zSig = ( zSig + roundIncrement )>>7;
-    zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
-    if ( zSig == 0 ) zExp = 0;
-    return packFloat32( zSign, zExp, zSig );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-and significand `zSig', and returns the proper single-precision floating-
-point value corresponding to the abstract input.  This routine is just like
-`roundAndPackFloat32' except that `zSig' does not have to be normalized in
-any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
-point exponent.
--------------------------------------------------------------------------------
-*/
-static float32
- normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
-{
-    int8 shiftCount;
-
-    shiftCount = countLeadingZeros32( zSig ) - 1;
-    return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the 32-bit two's complement integer `a' to
-the single-precision floating-point format.  The conversion is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 int32_to_float32( int32 a )
-{
-    flag zSign;
-
-    if ( a == 0 ) return 0;
-    if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
-    zSign = ( a < 0 );
-    return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the single-precision floating-point value
-`a' to the 32-bit two's complement integer format.  The conversion is
-performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic---which means in particular that the conversion is rounded
-according to the current rounding mode.  If `a' is a NaN, the largest
-positive integer is returned.  Otherwise, if the conversion overflows, the
-largest integer with the same sign as `a' is returned.
--------------------------------------------------------------------------------
-*/
-int32 float32_to_int32( float32 a )
-{
-    flag aSign;
-    int16 aExp, shiftCount;
-    bits32 aSig, zExtra;
-    int32 z;
-    int8 roundingMode;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    shiftCount = aExp - 0x96;
-    if ( 0 <= shiftCount ) {
-        if ( 0x9E <= aExp ) {
-            if ( a == 0xCF000000 ) return 0x80000000;
-            float_raise( float_flag_invalid );
-            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
-            return 0x80000000;
-        }
-        z = ( aSig | 0x00800000 )<<shiftCount;
-        if ( aSign ) z = - z;
-    }
-    else {
-        if ( aExp < 0x7E ) {
-            zExtra = aExp | aSig;
-            z = 0;
-        }
-        else {
-            aSig |= 0x00800000;
-            zExtra = aSig<<( shiftCount & 31 );
-            z = aSig>>( - shiftCount );
-        }
-        if ( zExtra ) float_exception_flags |= float_flag_inexact;
-        roundingMode = float_rounding_mode;
-        if ( roundingMode == float_round_nearest_even ) {
-            if ( (sbits32) zExtra < 0 ) {
-                ++z;
-                if ( (bits32) ( zExtra<<1 ) == 0 ) z &= ~1;
-            }
-            if ( aSign ) z = - z;
-        }
-        else {
-            zExtra = ( zExtra != 0 );
-            if ( aSign ) {
-                z += ( roundingMode == float_round_down ) & zExtra;
-                z = - z;
-            }
-            else {
-                z += ( roundingMode == float_round_up ) & zExtra;
-            }
-        }
-    }
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the single-precision floating-point value
-`a' to the 32-bit two's complement integer format.  The conversion is
-performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic, except that the conversion is always rounded toward zero.  If
-`a' is a NaN, the largest positive integer is returned.  Otherwise, if the
-conversion overflows, the largest integer with the same sign as `a' is
-returned.
--------------------------------------------------------------------------------
-*/
-int32 float32_to_int32_round_to_zero( float32 a )
-{
-    flag aSign;
-    int16 aExp, shiftCount;
-    bits32 aSig;
-    int32 z;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    shiftCount = aExp - 0x9E;
-    if ( 0 <= shiftCount ) {
-        if ( a == 0xCF000000 ) return 0x80000000;
-        float_raise( float_flag_invalid );
-        if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
-        return 0x80000000;
-    }
-    else if ( aExp <= 0x7E ) {
-        if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
-        return 0;
-    }
-    aSig = ( aSig | 0x00800000 )<<8;
-    z = aSig>>( - shiftCount );
-    if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
-        float_exception_flags |= float_flag_inexact;
-    }
-    return aSign ? - z : z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Rounds the single-precision floating-point value `a' to an integer, and
-returns the result as a single-precision floating-point value.  The
-operation is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float32_round_to_int( float32 a )
-{
-    flag aSign;
-    int16 aExp;
-    bits32 lastBitMask, roundBitsMask;
-    int8 roundingMode;
-    float32 z;
-
-    aExp = extractFloat32Exp( a );
-    if ( 0x96 <= aExp ) {
-        if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
-            return propagateFloat32NaN( a, a );
-        }
-        return a;
-    }
-    if ( aExp <= 0x7E ) {
-        if ( (bits32) ( a<<1 ) == 0 ) return a;
-        float_exception_flags |= float_flag_inexact;
-        aSign = extractFloat32Sign( a );
-        switch ( float_rounding_mode ) {
-         case float_round_nearest_even:
-            if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
-                return packFloat32( aSign, 0x7F, 0 );
-            }
-            break;
-         case float_round_down:
-            return aSign ? 0xBF800000 : 0;
-         case float_round_up:
-            return aSign ? 0x80000000 : 0x3F800000;
-        }
-        return packFloat32( aSign, 0, 0 );
-    }
-    lastBitMask = 1;
-    lastBitMask <<= 0x96 - aExp;
-    roundBitsMask = lastBitMask - 1;
-    z = a;
-    roundingMode = float_rounding_mode;
-    if ( roundingMode == float_round_nearest_even ) {
-        z += lastBitMask>>1;
-        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
-    }
-    else if ( roundingMode != float_round_to_zero ) {
-        if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
-            z += roundBitsMask;
-        }
-    }
-    z &= ~ roundBitsMask;
-    if ( z != a ) float_exception_flags |= float_flag_inexact;
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of adding the absolute values of the single-precision
-floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
-before being returned.  `zSign' is ignored if the result is a NaN.  The
-addition is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
-{
-    int16 aExp, bExp, zExp;
-    bits32 aSig, bSig, zSig;
-    int16 expDiff;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    bSig = extractFloat32Frac( b );
-    bExp = extractFloat32Exp( b );
-    expDiff = aExp - bExp;
-    aSig <<= 6;
-    bSig <<= 6;
-    if ( 0 < expDiff ) {
-        if ( aExp == 0xFF ) {
-            if ( aSig ) return propagateFloat32NaN( a, b );
-            return a;
-        }
-        if ( bExp == 0 ) {
-            --expDiff;
-        }
-        else {
-            bSig |= 0x20000000;
-        }
-        shift32RightJamming( bSig, expDiff, &bSig );
-        zExp = aExp;
-    }
-    else if ( expDiff < 0 ) {
-        if ( bExp == 0xFF ) {
-            if ( bSig ) return propagateFloat32NaN( a, b );
-            return packFloat32( zSign, 0xFF, 0 );
-        }
-        if ( aExp == 0 ) {
-            ++expDiff;
-        }
-        else {
-            aSig |= 0x20000000;
-        }
-        shift32RightJamming( aSig, - expDiff, &aSig );
-        zExp = bExp;
-    }
-    else {
-        if ( aExp == 0xFF ) {
-            if ( aSig | bSig ) return propagateFloat32NaN( a, b );
-            return a;
-        }
-        if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
-        zSig = 0x40000000 + aSig + bSig;
-        zExp = aExp;
-        goto roundAndPack;
-    }
-    aSig |= 0x20000000;
-    zSig = ( aSig + bSig )<<1;
-    --zExp;
-    if ( (sbits32) zSig < 0 ) {
-        zSig = aSig + bSig;
-        ++zExp;
-    }
- roundAndPack:
-    return roundAndPackFloat32( zSign, zExp, zSig );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of subtracting the absolute values of the single-
-precision floating-point values `a' and `b'.  If `zSign' is true, the
-difference is negated before being returned.  `zSign' is ignored if the
-result is a NaN.  The subtraction is performed according to the IEC/IEEE
-Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
-{
-    int16 aExp, bExp, zExp;
-    bits32 aSig, bSig, zSig;
-    int16 expDiff;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    bSig = extractFloat32Frac( b );
-    bExp = extractFloat32Exp( b );
-    expDiff = aExp - bExp;
-    aSig <<= 7;
-    bSig <<= 7;
-    if ( 0 < expDiff ) goto aExpBigger;
-    if ( expDiff < 0 ) goto bExpBigger;
-    if ( aExp == 0xFF ) {
-        if ( aSig | bSig ) return propagateFloat32NaN( a, b );
-        float_raise( float_flag_invalid );
-        return float32_default_nan;
-    }
-    if ( aExp == 0 ) {
-        aExp = 1;
-        bExp = 1;
-    }
-    if ( bSig < aSig ) goto aBigger;
-    if ( aSig < bSig ) goto bBigger;
-    return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
- bExpBigger:
-    if ( bExp == 0xFF ) {
-        if ( bSig ) return propagateFloat32NaN( a, b );
-        return packFloat32( zSign ^ 1, 0xFF, 0 );
-    }
-    if ( aExp == 0 ) {
-        ++expDiff;
-    }
-    else {
-        aSig |= 0x40000000;
-    }
-    shift32RightJamming( aSig, - expDiff, &aSig );
-    bSig |= 0x40000000;
- bBigger:
-    zSig = bSig - aSig;
-    zExp = bExp;
-    zSign ^= 1;
-    goto normalizeRoundAndPack;
- aExpBigger:
-    if ( aExp == 0xFF ) {
-        if ( aSig ) return propagateFloat32NaN( a, b );
-        return a;
-    }
-    if ( bExp == 0 ) {
-        --expDiff;
-    }
-    else {
-        bSig |= 0x40000000;
-    }
-    shift32RightJamming( bSig, expDiff, &bSig );
-    aSig |= 0x40000000;
- aBigger:
-    zSig = aSig - bSig;
-    zExp = aExp;
- normalizeRoundAndPack:
-    --zExp;
-    return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of adding the single-precision floating-point values `a'
-and `b'.  The operation is performed according to the IEC/IEEE Standard for
-Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float32_add( float32 a, float32 b )
-{
-    flag aSign, bSign;
-
-    aSign = extractFloat32Sign( a );
-    bSign = extractFloat32Sign( b );
-    if ( aSign == bSign ) {
-        return addFloat32Sigs( a, b, aSign );
-    }
-    else {
-        return subFloat32Sigs( a, b, aSign );
-    }
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of subtracting the single-precision floating-point values
-`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
-for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float32_sub( float32 a, float32 b )
-{
-    flag aSign, bSign;
-
-    aSign = extractFloat32Sign( a );
-    bSign = extractFloat32Sign( b );
-    if ( aSign == bSign ) {
-        return subFloat32Sigs( a, b, aSign );
-    }
-    else {
-        return addFloat32Sigs( a, b, aSign );
-    }
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of multiplying the single-precision floating-point values
-`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
-for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float32_mul( float32 a, float32 b )
-{
-    flag aSign, bSign, zSign;
-    int16 aExp, bExp, zExp;
-    bits32 aSig, bSig, zSig0, zSig1;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    bSig = extractFloat32Frac( b );
-    bExp = extractFloat32Exp( b );
-    bSign = extractFloat32Sign( b );
-    zSign = aSign ^ bSign;
-    if ( aExp == 0xFF ) {
-        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
-            return propagateFloat32NaN( a, b );
-        }
-        if ( ( bExp | bSig ) == 0 ) {
-            float_raise( float_flag_invalid );
-            return float32_default_nan;
-        }
-        return packFloat32( zSign, 0xFF, 0 );
-    }
-    if ( bExp == 0xFF ) {
-        if ( bSig ) return propagateFloat32NaN( a, b );
-        if ( ( aExp | aSig ) == 0 ) {
-            float_raise( float_flag_invalid );
-            return float32_default_nan;
-        }
-        return packFloat32( zSign, 0xFF, 0 );
-    }
-    if ( aExp == 0 ) {
-        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
-        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
-    }
-    if ( bExp == 0 ) {
-        if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
-        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
-    }
-    zExp = aExp + bExp - 0x7F;
-    aSig = ( aSig | 0x00800000 )<<7;
-    bSig = ( bSig | 0x00800000 )<<8;
-    mul32To64( aSig, bSig, &zSig0, &zSig1 );
-    zSig0 |= ( zSig1 != 0 );
-    if ( 0 <= (sbits32) ( zSig0<<1 ) ) {
-        zSig0 <<= 1;
-        --zExp;
-    }
-    return roundAndPackFloat32( zSign, zExp, zSig0 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of dividing the single-precision floating-point value `a'
-by the corresponding value `b'.  The operation is performed according to
-the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float32_div( float32 a, float32 b )
-{
-    flag aSign, bSign, zSign;
-    int16 aExp, bExp, zExp;
-    bits32 aSig, bSig, zSig;
-    bits32 rem0, rem1;
-    bits32 term0, term1;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    bSig = extractFloat32Frac( b );
-    bExp = extractFloat32Exp( b );
-    bSign = extractFloat32Sign( b );
-    zSign = aSign ^ bSign;
-    if ( aExp == 0xFF ) {
-        if ( aSig ) return propagateFloat32NaN( a, b );
-        if ( bExp == 0xFF ) {
-            if ( bSig ) return propagateFloat32NaN( a, b );
-            float_raise( float_flag_invalid );
-            return float32_default_nan;
-        }
-        return packFloat32( zSign, 0xFF, 0 );
-    }
-    if ( bExp == 0xFF ) {
-        if ( bSig ) return propagateFloat32NaN( a, b );
-        return packFloat32( zSign, 0, 0 );
-    }
-    if ( bExp == 0 ) {
-        if ( bSig == 0 ) {
-            if ( ( aExp | aSig ) == 0 ) {
-                float_raise( float_flag_invalid );
-                return float32_default_nan;
-            }
-            float_raise( float_flag_divbyzero );
-            return packFloat32( zSign, 0xFF, 0 );
-        }
-        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
-    }
-    if ( aExp == 0 ) {
-        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
-        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
-    }
-    zExp = aExp - bExp + 0x7D;
-    aSig = ( aSig | 0x00800000 )<<7;
-    bSig = ( bSig | 0x00800000 )<<8;
-    if ( bSig <= ( aSig + aSig ) ) {
-        aSig >>= 1;
-        ++zExp;
-    }
-    zSig = estimateDiv64To32( aSig, 0, bSig );
-    if ( ( zSig & 0x3F ) <= 2 ) {
-        mul32To64( bSig, zSig, &term0, &term1 );
-        sub64( aSig, 0, term0, term1, &rem0, &rem1 );
-        while ( (sbits32) rem0 < 0 ) {
-            --zSig;
-            add64( rem0, rem1, 0, bSig, &rem0, &rem1 );
-        }
-        zSig |= ( rem1 != 0 );
-    }
-    return roundAndPackFloat32( zSign, zExp, zSig );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the remainder of the single-precision floating-point value `a'
-with respect to the corresponding value `b'.  The operation is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float32_rem( float32 a, float32 b )
-{
-    flag aSign, bSign, zSign;
-    int16 aExp, bExp, expDiff;
-    bits32 aSig, bSig;
-    bits32 q, allZero, alternateASig;
-    sbits32 sigMean;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    bSig = extractFloat32Frac( b );
-    bExp = extractFloat32Exp( b );
-    bSign = extractFloat32Sign( b );
-    if ( aExp == 0xFF ) {
-        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
-            return propagateFloat32NaN( a, b );
-        }
-        float_raise( float_flag_invalid );
-        return float32_default_nan;
-    }
-    if ( bExp == 0xFF ) {
-        if ( bSig ) return propagateFloat32NaN( a, b );
-        return a;
-    }
-    if ( bExp == 0 ) {
-        if ( bSig == 0 ) {
-            float_raise( float_flag_invalid );
-            return float32_default_nan;
-        }
-        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
-    }
-    if ( aExp == 0 ) {
-        if ( aSig == 0 ) return a;
-        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
-    }
-    expDiff = aExp - bExp;
-    aSig = ( aSig | 0x00800000 )<<8;
-    bSig = ( bSig | 0x00800000 )<<8;
-    if ( expDiff < 0 ) {
-        if ( expDiff < -1 ) return a;
-        aSig >>= 1;
-    }
-    q = ( bSig <= aSig );
-    if ( q ) aSig -= bSig;
-    expDiff -= 32;
-    while ( 0 < expDiff ) {
-        q = estimateDiv64To32( aSig, 0, bSig );
-        q = ( 2 < q ) ? q - 2 : 0;
-        aSig = - ( ( bSig>>2 ) * q );
-        expDiff -= 30;
-    }
-    expDiff += 32;
-    if ( 0 < expDiff ) {
-        q = estimateDiv64To32( aSig, 0, bSig );
-        q = ( 2 < q ) ? q - 2 : 0;
-        q >>= 32 - expDiff;
-        bSig >>= 2;
-        aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
-    }
-    else {
-        aSig >>= 2;
-        bSig >>= 2;
-    }
-    do {
-        alternateASig = aSig;
-        ++q;
-        aSig -= bSig;
-    } while ( 0 <= (sbits32) aSig );
-    sigMean = aSig + alternateASig;
-    if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
-        aSig = alternateASig;
-    }
-    zSign = ( (sbits32) aSig < 0 );
-    if ( zSign ) aSig = - aSig;
-    return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the square root of the single-precision floating-point value `a'.
-The operation is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float32_sqrt( float32 a )
-{
-    flag aSign;
-    int16 aExp, zExp;
-    bits32 aSig, zSig;
-    bits32 rem0, rem1;
-    bits32 term0, term1;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    if ( aExp == 0xFF ) {
-        if ( aSig ) return propagateFloat32NaN( a, 0 );
-        if ( ! aSign ) return a;
-        float_raise( float_flag_invalid );
-        return float32_default_nan;
-    }
-    if ( aSign ) {
-        if ( ( aExp | aSig ) == 0 ) return a;
-        float_raise( float_flag_invalid );
-        return float32_default_nan;
-    }
-    if ( aExp == 0 ) {
-        if ( aSig == 0 ) return 0;
-        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
-    }
-    zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
-    aSig = ( aSig | 0x00800000 )<<8;
-    zSig = estimateSqrt32( aExp, aSig ) + 2;
-    if ( ( zSig & 0x7F ) <= 5 ) {
-        if ( zSig < 2 ) {
-            zSig = 0xFFFFFFFF;
-        }
-        else {
-            aSig >>= aExp & 1;
-            mul32To64( zSig, zSig, &term0, &term1 );
-            sub64( aSig, 0, term0, term1, &rem0, &rem1 );
-            while ( (sbits32) rem0 < 0 ) {
-                --zSig;
-                shortShift64Left( 0, zSig, 1, &term0, &term1 );
-                term1 |= 1;
-                add64( rem0, rem1, term0, term1, &rem0, &rem1 );
-            }
-            zSig |= ( ( rem0 | rem1 ) != 0 );
-        }
-    }
-    shift32RightJamming( zSig, 1, &zSig );
-    return roundAndPackFloat32( 0, zExp, zSig );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is equal to the
-corresponding value `b', and 0 otherwise.  The comparison is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float32_eq( float32 a, float32 b )
-{
-
-    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
-         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
-       ) {
-        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
-        return 0;
-    }
-    return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is less than or
-equal to the corresponding value `b', and 0 otherwise.  The comparison is
-performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float32_le( float32 a, float32 b )
-{
-    flag aSign, bSign;
-
-    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
-         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
-       ) {
-        float_raise( float_flag_invalid );
-        return 0;
-    }
-    aSign = extractFloat32Sign( a );
-    bSign = extractFloat32Sign( b );
-    if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
-    return ( a == b ) || ( aSign ^ ( a < b ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is less than
-the corresponding value `b', and 0 otherwise.  The comparison is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float32_lt( float32 a, float32 b )
-{
-    flag aSign, bSign;
-
-    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
-         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
-       ) {
-        float_raise( float_flag_invalid );
-        return 0;
-    }
-    aSign = extractFloat32Sign( a );
-    bSign = extractFloat32Sign( b );
-    if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
-    return ( a != b ) && ( aSign ^ ( a < b ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is equal to the
-corresponding value `b', and 0 otherwise.  The invalid exception is raised
-if either operand is a NaN.  Otherwise, the comparison is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float32_eq_signaling( float32 a, float32 b )
-{
-
-    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
-         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
-       ) {
-        float_raise( float_flag_invalid );
-        return 0;
-    }
-    return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is less than or
-equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
-cause an exception.  Otherwise, the comparison is performed according to the
-IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float32_le_quiet( float32 a, float32 b )
-{
-    flag aSign, bSign;
-    int16 aExp, bExp;
-
-    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
-         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
-       ) {
-        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
-        return 0;
-    }
-    aSign = extractFloat32Sign( a );
-    bSign = extractFloat32Sign( b );
-    if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
-    return ( a == b ) || ( aSign ^ ( a < b ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the single-precision floating-point value `a' is less than
-the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
-exception.  Otherwise, the comparison is performed according to the IEC/IEEE
-Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float32_lt_quiet( float32 a, float32 b )
-{
-    flag aSign, bSign;
-
-    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
-         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
-       ) {
-        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
-        return 0;
-    }
-    aSign = extractFloat32Sign( a );
-    bSign = extractFloat32Sign( b );
-    if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
-    return ( a != b ) && ( aSign ^ ( a < b ) );
-
-}
-
diff --git a/software/baselib/softfloat.h b/software/baselib/softfloat.h
deleted file mode 100644 (file)
index 29454c0..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-
-/*
-===============================================================================
-
-This C header file is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2.
-
-Written by John R. Hauser.  This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704.  Funding was partially provided by the
-National Science Foundation under grant MIP-9311980.  The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
-is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
-arithmetic/softfloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
-has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
-TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
-PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
-AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) they include prominent notice that the work is derivative, and (2) they
-include prominent notice akin to these three paragraphs for those parts of
-this code that are retained.
-
-===============================================================================
-*/
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE floating-point types.
--------------------------------------------------------------------------------
-*/
-typedef unsigned int float32;
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE floating-point underflow tininess-detection mode.
--------------------------------------------------------------------------------
-*/
-extern int float_detect_tininess;
-enum {
-    float_tininess_after_rounding  = 0,
-    float_tininess_before_rounding = 1
-};
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE floating-point rounding mode.
--------------------------------------------------------------------------------
-*/
-extern int float_rounding_mode;
-enum {
-    float_round_nearest_even = 0,
-    float_round_to_zero      = 1,
-    float_round_up           = 2,
-    float_round_down         = 3
-};
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE floating-point exception flags.
--------------------------------------------------------------------------------
-*/
-extern int float_exception_flags;
-enum {
-    float_flag_inexact   =  1,
-    float_flag_divbyzero =  2,
-    float_flag_underflow =  4,
-    float_flag_overflow  =  8,
-    float_flag_invalid   = 16
-};
-
-/*
--------------------------------------------------------------------------------
-Routine to raise any or all of the software IEC/IEEE floating-point
-exception flags.
--------------------------------------------------------------------------------
-*/
-void float_raise( int );
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE integer-to-floating-point conversion routines.
--------------------------------------------------------------------------------
-*/
-float32 int32_to_float32( int );
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE single-precision conversion routines.
--------------------------------------------------------------------------------
-*/
-int float32_to_int32( float32 );
-int float32_to_int32_round_to_zero( float32 );
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE single-precision operations.
--------------------------------------------------------------------------------
-*/
-float32 float32_round_to_int( float32 );
-float32 float32_add( float32, float32 );
-float32 float32_sub( float32, float32 );
-float32 float32_mul( float32, float32 );
-float32 float32_div( float32, float32 );
-float32 float32_rem( float32, float32 );
-float32 float32_sqrt( float32 );
-int float32_eq( float32, float32 );
-int float32_le( float32, float32 );
-int float32_lt( float32, float32 );
-int float32_eq_signaling( float32, float32 );
-int float32_le_quiet( float32, float32 );
-int float32_lt_quiet( float32, float32 );
-int float32_is_signaling_nan( float32 );
-
diff --git a/software/baselib/system.c b/software/baselib/system.c
deleted file mode 100644 (file)
index 04a0f2b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <hw/fmlbrg.h>
-#include <system.h>
-
-void flush_bridge_cache()
-{
-       volatile char *flushbase = (char *)FMLBRG_FLUSH_BASE;
-       int i, offset;
-       
-       offset = 0;
-       for(i=0;i<FMLBRG_LINE_COUNT;i++) {
-               flushbase[offset] = 0;
-               offset += FMLBRG_LINE_LENGTH;
-       }
-}
diff --git a/software/baselib/uart-async.c b/software/baselib/uart-async.c
deleted file mode 100644 (file)
index ca258c2..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <uart.h>
-#include <irq.h>
-#include <hw/uart.h>
-#include <hw/interrupts.h>
-
-/*
- * Buffer sizes must be a power of 2 so that modulos can be computed
- * with logical AND.
- * RX functions are written in such a way that they do not require locking.
- * TX functions already implement locking.
- */
-
-#define UART_RINGBUFFER_SIZE_RX 4096
-#define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1)
-
-static char rx_buf[UART_RINGBUFFER_SIZE_RX];
-static volatile unsigned int rx_produce;
-static volatile unsigned int rx_consume;
-
-void uart_async_isr_rx()
-{
-       if(CSR_UART_UCR & UART_RXAVAIL) {
-               rx_buf[rx_produce] = CSR_UART_RXTX;
-               CSR_UART_UCR = UART_RXACK;
-               rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
-       }
-       if(CSR_UART_UCR & UART_RXERROR)
-               CSR_UART_UCR = UART_RXACK;
-}
-
-char readchar()
-{
-       char c;
-       
-       while(rx_consume == rx_produce);
-       c = rx_buf[rx_consume];
-       rx_consume = (rx_consume + 1) & UART_RINGBUFFER_MASK_RX;
-       return c;
-}
-
-int readchar_nonblock()
-{
-       return (rx_consume != rx_produce);
-}
-
-#define UART_RINGBUFFER_SIZE_TX 131072
-#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
-
-static char tx_buf[UART_RINGBUFFER_SIZE_TX];
-static unsigned int tx_produce;
-static unsigned int tx_consume;
-static volatile int tx_cts;
-
-static int force_sync;
-
-void uart_async_isr_tx()
-{
-       CSR_UART_UCR = UART_TXACK;
-       if(tx_produce != tx_consume) {
-               CSR_UART_RXTX = tx_buf[tx_consume];
-               tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
-       } else
-               tx_cts = 1;
-}
-
-void writechar(char c)
-{
-       unsigned int oldmask = 0;
-       
-       /* Synchronization required because of CTS */
-       oldmask = irq_getmask();
-       irq_setmask(oldmask & (~IRQ_UARTTX));
-       if(force_sync) {
-               CSR_UART_RXTX = c;
-               while(CSR_UART_UCR & UART_TXBUSY);
-               CSR_UART_UCR = UART_TXACK;
-       } else {
-               if(tx_cts) {
-                       tx_cts = 0;
-                       CSR_UART_RXTX = c;
-               } else {
-                       tx_buf[tx_produce] = c;
-                       tx_produce = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
-               }
-       }
-       irq_setmask(oldmask);
-}
-
-void uart_async_init()
-{
-       unsigned int mask;
-       
-       rx_produce = 0;
-       rx_consume = 0;
-       tx_produce = 0;
-       tx_consume = 0;
-       tx_cts = 1;
-       
-       mask = irq_getmask();
-       mask |= IRQ_UARTRX|IRQ_UARTTX;
-       irq_setmask(mask);
-}
-
-void uart_force_sync(int f)
-{
-       if(f) while(!tx_cts);
-       force_sync = f;
-}
diff --git a/software/baselib/uart.c b/software/baselib/uart.c
deleted file mode 100644 (file)
index 62a9b3e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <hw/uart.h>
-#include <uart.h>
-
-void writechar(char c)
-{
-       while(CSR_UART_UCR & UART_TXBUSY);
-       CSR_UART_RXTX = c;
-}
-
-char readchar()
-{
-       char c;
-
-       while(!(CSR_UART_UCR & UART_RXAVAIL));
-       c = CSR_UART_RXTX;
-       CSR_UART_UCR = UART_RXACK;
-       return c;
-}
-
-int readchar_nonblock()
-{
-       if(CSR_UART_UCR & UART_RXAVAIL)
-               return 1;
-       else
-               return 0;
-}
diff --git a/software/baselib/vsnprintf-nofloat.c b/software/baselib/vsnprintf-nofloat.c
deleted file mode 100644 (file)
index 494e575..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * Copyright (C) Linux kernel developers
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <libc.h>
-
-/**
- * vsnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The return value is the number of characters which would
- * be generated for the given input, excluding the trailing
- * '\0', as per ISO C99. If you want to have the exact
- * number of characters written into @buf as return value
- * (not including the trailing '\0'), use vscnprintf(). If the
- * return is greater than or equal to @size, the resulting
- * string is truncated.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want snprintf() instead.
- */
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
-       int len;
-       unsigned long long num;
-       int i, base;
-       char *str, *end, c;
-       const char *s;
-
-       int flags;              /* flags to number() */
-
-       int field_width;        /* width of output field */
-       int precision;          /* min. # of digits for integers; max
-                                  number of chars for from string */
-       int qualifier;          /* 'h', 'l', or 'L' for integer fields */
-                               /* 'z' support added 23/7/1999 S.H.    */
-                               /* 'z' changed to 'Z' --davidm 1/25/99 */
-                               /* 't' added for ptrdiff_t */
-
-       /* Reject out-of-range values early.  Large positive sizes are
-          used for unknown buffer sizes. */
-       if (unlikely((int) size < 0))
-               return 0;
-
-       str = buf;
-       end = buf + size;
-
-       /* Make sure end is always >= buf */
-       if (end < buf) {
-               end = ((void *)-1);
-               size = end - buf;
-       }
-
-       for (; *fmt ; ++fmt) {
-               if (*fmt != '%') {
-                       if (str < end)
-                               *str = *fmt;
-                       ++str;
-                       continue;
-               }
-
-               /* process flags */
-               flags = 0;
-               repeat:
-                       ++fmt;          /* this also skips first '%' */
-                       switch (*fmt) {
-                               case '-': flags |= PRINTF_LEFT; goto repeat;
-                               case '+': flags |= PRINTF_PLUS; goto repeat;
-                               case ' ': flags |= PRINTF_SPACE; goto repeat;
-                               case '#': flags |= PRINTF_SPECIAL; goto repeat;
-                               case '0': flags |= PRINTF_ZEROPAD; goto repeat;
-                       }
-
-               /* get field width */
-               field_width = -1;
-               if (isdigit(*fmt))
-                       field_width = skip_atoi(&fmt);
-               else if (*fmt == '*') {
-                       ++fmt;
-                       /* it's the next argument */
-                       field_width = va_arg(args, int);
-                       if (field_width < 0) {
-                               field_width = -field_width;
-                               flags |= PRINTF_LEFT;
-                       }
-               }
-
-               /* get the precision */
-               precision = -1;
-               if (*fmt == '.') {
-                       ++fmt;  
-                       if (isdigit(*fmt))
-                               precision = skip_atoi(&fmt);
-                       else if (*fmt == '*') {
-                               ++fmt;
-                               /* it's the next argument */
-                               precision = va_arg(args, int);
-                       }
-                       if (precision < 0)
-                               precision = 0;
-               }
-
-               /* get the conversion qualifier */
-               qualifier = -1;
-               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-                   *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
-                       qualifier = *fmt;
-                       ++fmt;
-                       if (qualifier == 'l' && *fmt == 'l') {
-                               qualifier = 'L';
-                               ++fmt;
-                       }
-               }
-
-               /* default base */
-               base = 10;
-
-               switch (*fmt) {
-                       case 'c':
-                               if (!(flags & PRINTF_LEFT)) {
-                                       while (--field_width > 0) {
-                                               if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               c = (unsigned char) va_arg(args, int);
-                               if (str < end)
-                                       *str = c;
-                               ++str;
-                               while (--field_width > 0) {
-                                       if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-                               continue;
-
-                       case 's':
-                               s = va_arg(args, char *);
-                               if (s == NULL)
-                                       s = "<NULL>";
-
-                               len = strnlen(s, precision);
-
-                               if (!(flags & PRINTF_LEFT)) {
-                                       while (len < field_width--) {
-                                               if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               for (i = 0; i < len; ++i) {
-                                       if (str < end)
-                                               *str = *s;
-                                       ++str; ++s;
-                               }
-                               while (len < field_width--) {
-                                       if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-                               continue;
-
-                       case 'p':
-                               if (field_width == -1) {
-                                       field_width = 2*sizeof(void *);
-                                       flags |= PRINTF_ZEROPAD;
-                               }
-                               str = number(str, end,
-                                               (unsigned long) va_arg(args, void *),
-                                               16, field_width, precision, flags);
-                               continue;
-
-
-                       case 'n':
-                               /* FIXME:
-                               * What does C99 say about the overflow case here? */
-                               if (qualifier == 'l') {
-                                       long * ip = va_arg(args, long *);
-                                       *ip = (str - buf);
-                               } else if (qualifier == 'Z' || qualifier == 'z') {
-                                       size_t * ip = va_arg(args, size_t *);
-                                       *ip = (str - buf);
-                               } else {
-                                       int * ip = va_arg(args, int *);
-                                       *ip = (str - buf);
-                               }
-                               continue;
-
-                       case '%':
-                               if (str < end)
-                                       *str = '%';
-                               ++str;
-                               continue;
-
-                               /* integer number formats - set up the flags and "break" */
-                       case 'o':
-                               base = 8;
-                               break;
-
-                       case 'X':
-                               flags |= PRINTF_LARGE;
-                       case 'x':
-                               base = 16;
-                               break;
-
-                       case 'd':
-                       case 'i':
-                               flags |= PRINTF_SIGN;
-                       case 'u':
-                               break;
-
-                       default:
-                               if (str < end)
-                                       *str = '%';
-                               ++str;
-                               if (*fmt) {
-                                       if (str < end)
-                                               *str = *fmt;
-                                       ++str;
-                               } else {
-                                       --fmt;
-                               }
-                               continue;
-               }
-               if (qualifier == 'L')
-                       num = va_arg(args, long long);
-               else if (qualifier == 'l') {
-                       num = va_arg(args, unsigned long);
-                       if (flags & PRINTF_SIGN)
-                               num = (signed long) num;
-               } else if (qualifier == 'Z' || qualifier == 'z') {
-                       num = va_arg(args, size_t);
-               } else if (qualifier == 't') {
-                       num = va_arg(args, ptrdiff_t);
-               } else if (qualifier == 'h') {
-                       num = (unsigned short) va_arg(args, int);
-                       if (flags & PRINTF_SIGN)
-                               num = (signed short) num;
-               } else {
-                       num = va_arg(args, unsigned int);
-                       if (flags & PRINTF_SIGN)
-                               num = (signed int) num;
-               }
-               str = number(str, end, num, base,
-                               field_width, precision, flags);
-       }
-       if (size > 0) {
-               if (str < end)
-                       *str = '\0';
-               else
-                       end[-1] = '\0';
-       }
-       /* the trailing null byte doesn't count towards the total */
-       return str-buf;
-}
diff --git a/software/baselib/vsnprintf.c b/software/baselib/vsnprintf.c
deleted file mode 100644 (file)
index 1cfa0ff..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * Copyright (C) Linux kernel developers
- * 
- * 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, version 3 of the License.
- * 
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <libc.h>
-
-#define fabsf(x) ((x) > 0.0 ? x : -x)
-
-/**
- * vsnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The return value is the number of characters which would
- * be generated for the given input, excluding the trailing
- * '\0', as per ISO C99. If you want to have the exact
- * number of characters written into @buf as return value
- * (not including the trailing '\0'), use vscnprintf(). If the
- * return is greater than or equal to @size, the resulting
- * string is truncated.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want snprintf() instead.
- */
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
-       int len;
-       unsigned long long num;
-       int i, base;
-       char *str, *end, c;
-       const char *s;
-
-       int flags;              /* flags to number() */
-
-       int field_width;        /* width of output field */
-       int precision;          /* min. # of digits for integers; max
-                                  number of chars for from string */
-       int qualifier;          /* 'h', 'l', or 'L' for integer fields */
-                               /* 'z' support added 23/7/1999 S.H.    */
-                               /* 'z' changed to 'Z' --davidm 1/25/99 */
-                               /* 't' added for ptrdiff_t */
-
-       /* Reject out-of-range values early.  Large positive sizes are
-          used for unknown buffer sizes. */
-       if (unlikely((int) size < 0))
-               return 0;
-
-       str = buf;
-       end = buf + size;
-
-       /* Make sure end is always >= buf */
-       if (end < buf) {
-               end = ((void *)-1);
-               size = end - buf;
-       }
-
-       for (; *fmt ; ++fmt) {
-               if (*fmt != '%') {
-                       if (str < end)
-                               *str = *fmt;
-                       ++str;
-                       continue;
-               }
-
-               /* process flags */
-               flags = 0;
-               repeat:
-                       ++fmt;          /* this also skips first '%' */
-                       switch (*fmt) {
-                               case '-': flags |= PRINTF_LEFT; goto repeat;
-                               case '+': flags |= PRINTF_PLUS; goto repeat;
-                               case ' ': flags |= PRINTF_SPACE; goto repeat;
-                               case '#': flags |= PRINTF_SPECIAL; goto repeat;
-                               case '0': flags |= PRINTF_ZEROPAD; goto repeat;
-                       }
-
-               /* get field width */
-               field_width = -1;
-               if (isdigit(*fmt))
-                       field_width = skip_atoi(&fmt);
-               else if (*fmt == '*') {
-                       ++fmt;
-                       /* it's the next argument */
-                       field_width = va_arg(args, int);
-                       if (field_width < 0) {
-                               field_width = -field_width;
-                               flags |= PRINTF_LEFT;
-                       }
-               }
-
-               /* get the precision */
-               precision = -1;
-               if (*fmt == '.') {
-                       ++fmt;  
-                       if (isdigit(*fmt))
-                               precision = skip_atoi(&fmt);
-                       else if (*fmt == '*') {
-                               ++fmt;
-                               /* it's the next argument */
-                               precision = va_arg(args, int);
-                       }
-                       if (precision < 0)
-                               precision = 0;
-               }
-
-               /* get the conversion qualifier */
-               qualifier = -1;
-               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-                   *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
-                       qualifier = *fmt;
-                       ++fmt;
-                       if (qualifier == 'l' && *fmt == 'l') {
-                               qualifier = 'L';
-                               ++fmt;
-                       }
-               }
-
-               /* default base */
-               base = 10;
-
-               switch (*fmt) {
-                       case 'c':
-                               if (!(flags & PRINTF_LEFT)) {
-                                       while (--field_width > 0) {
-                                               if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               c = (unsigned char) va_arg(args, int);
-                               if (str < end)
-                                       *str = c;
-                               ++str;
-                               while (--field_width > 0) {
-                                       if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-                               continue;
-
-                       case 's':
-                               s = va_arg(args, char *);
-                               if (s == NULL)
-                                       s = "<NULL>";
-
-                               len = strnlen(s, precision);
-
-                               if (!(flags & PRINTF_LEFT)) {
-                                       while (len < field_width--) {
-                                               if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               for (i = 0; i < len; ++i) {
-                                       if (str < end)
-                                               *str = *s;
-                                       ++str; ++s;
-                               }
-                               while (len < field_width--) {
-                                       if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-                               continue;
-
-                       case 'p':
-                               if (field_width == -1) {
-                                       field_width = 2*sizeof(void *);
-                                       flags |= PRINTF_ZEROPAD;
-                               }
-                               str = number(str, end,
-                                               (unsigned long) va_arg(args, void *),
-                                               16, field_width, precision, flags);
-                               continue;
-
-                       case 'f': {
-                               int m;
-                               float f;
-                               int integer;
-                               int i;
-                               
-                               /* until I sort out how to disable this stupid promotion to double ... */
-                               f = *(va_arg(args, float *));
-                               if((f <= 0.0f) && (f != 0.0f)) { /* TODO: fix that |[#{'"é! '<' operator */
-                                       *str = '-';
-                                       str++;
-                                       f = -f;
-                               }
-
-                               integer = f;
-                               if(integer > 0) {
-                                       m = 1;
-                                       while(integer > (m*10)) m *= 10;
-                                       while((m >= 1) && (str < end)) {
-                                               int n;
-                                               n = integer/m;
-                                               *str = '0' + n;
-                                               str++;
-                                               f = f - m*n;
-                                               integer = integer - m*n;
-                                               m /= 10;
-                                       }
-                               } else if(str < end) {
-                                       *str = '0';
-                                       str++;
-                               }
-
-                               if(str < end) {
-                                       *str = '.';
-                                       str++;
-                               }
-
-                               for(i=0;i<6;i++) {
-                                       int n;
-
-                                       f = f*10.0f;
-                                       n = f;
-                                       f = f - n;
-                                       if(str >= end) break;
-                                       *str = '0' + n;
-                                       str++;
-                               }
-                               
-                               continue;
-                       }
-
-                       case 'n':
-                               /* FIXME:
-                                * What does C99 say about the overflow case here? */
-                               if (qualifier == 'l') {
-                                       long * ip = va_arg(args, long *);
-                                       *ip = (str - buf);
-                               } else if (qualifier == 'Z' || qualifier == 'z') {
-                                       size_t * ip = va_arg(args, size_t *);
-                                       *ip = (str - buf);
-                               } else {
-                                       int * ip = va_arg(args, int *);
-                                       *ip = (str - buf);
-                               }
-                               continue;
-
-                       case '%':
-                               if (str < end)
-                                       *str = '%';
-                               ++str;
-                               continue;
-
-                               /* integer number formats - set up the flags and "break" */
-                       case 'o':
-                               base = 8;
-                               break;
-
-                       case 'X':
-                               flags |= PRINTF_LARGE;
-                       case 'x':
-                               base = 16;
-                               break;
-
-                       case 'd':
-                       case 'i':
-                               flags |= PRINTF_SIGN;
-                       case 'u':
-                               break;
-
-                       default:
-                               if (str < end)
-                                       *str = '%';
-                               ++str;
-                               if (*fmt) {
-                                       if (str < end)
-                                               *str = *fmt;
-                                       ++str;
-                               } else {
-                                       --fmt;
-                               }
-                               continue;
-               }
-               if (qualifier == 'L')
-                       num = va_arg(args, long long);
-               else if (qualifier == 'l') {
-                       num = va_arg(args, unsigned long);
-                       if (flags & PRINTF_SIGN)
-                               num = (signed long) num;
-               } else if (qualifier == 'Z' || qualifier == 'z') {
-                       num = va_arg(args, size_t);
-               } else if (qualifier == 't') {
-                       num = va_arg(args, ptrdiff_t);
-               } else if (qualifier == 'h') {
-                       num = (unsigned short) va_arg(args, int);
-                       if (flags & PRINTF_SIGN)
-                               num = (signed short) num;
-               } else {
-                       num = va_arg(args, unsigned int);
-                       if (flags & PRINTF_SIGN)
-                               num = (signed int) num;
-               }
-               str = number(str, end, num, base,
-                               field_width, precision, flags);
-       }
-       if (size > 0) {
-               if (str < end)
-                       *str = '\0';
-               else
-                       end[-1] = '\0';
-       }
-       /* the trailing null byte doesn't count towards the total */
-       return str-buf;
-}
index 6da1ef4..3d837d8 100644 (file)
@@ -10,8 +10,8 @@ all: bios_splash.bin
        $(OBJCOPY) $(SEGMENTS) -O binary $< $@
        $(MMDIR)/tools/crc32 $@ write
 
-bios.elf: linker.ld $(OBJECTS) $(MMDIR)/software/baselib/baselib-light.a
-       $(LD) $(LDFLAGS) -T linker.ld -N -o $@ $(OBJECTS) $(MMDIR)/software/baselib/baselib-light.a
+bios.elf: linker.ld $(OBJECTS)
+       $(LD) $(LDFLAGS) -T linker.ld -N -o $@ $(OBJECTS) -L$(MMDIR)/software/libbase -lbase-light
 
 splash.raw: splash.png
        $(MMDIR)/tools/makeraw splash.png
index 19784f5..6f1efe0 100644 (file)
@@ -29,8 +29,8 @@ spam.h: spam.raw
        $(OBJCOPY) $(SEGMENTS) -O binary $< $@
        $(MMDIR)/tools/crc32 $@
 
-boot.elf: linker.ld $(OBJECTS) $(MMDIR)/software/baselib/baselib.a $(MMDIR)/software/mathlib/mathlib.a
-       $(LD) $(LDFLAGS) -T linker.ld -N -o $@ $(OBJECTS) $(MMDIR)/software/baselib/baselib.a $(MMDIR)/software/mathlib/mathlib.a
+boot.elf: linker.ld $(OBJECTS)
+       $(LD) $(LDFLAGS) -T linker.ld -N -o $@ $(OBJECTS) -L$(MMDIR)/software/libbase -L$(MMDIR)/software/libmath -lbase -lmath
 
 .PHONY: clean depend
 
diff --git a/software/libbase/Makefile b/software/libbase/Makefile
new file mode 100644 (file)
index 0000000..b7b882d
--- /dev/null
@@ -0,0 +1,55 @@
+MMDIR?=../..
+include $(MMDIR)/software/include.mak
+
+OBJECTS_ALL=divsi3.o libc.o crc16.o crc32.o console.o cfcard.o cffat.o system.o board.o
+OBJECTS=$(OBJECTS_ALL) irq.o softfloat.o softfloat-glue.o vsnprintf.o atof.o malloc.o uart-async.o
+OBJECTS_LIGHT=$(OBJECTS_ALL) vsnprintf-nofloat.o uart.o
+
+all: libbase-light.a libbase.a
+
+libbase-light.a: $(OBJECTS_LIGHT)
+       $(AR) clr libbase-light.a $(OBJECTS_LIGHT)
+       $(RANLIB) libbase-light.a
+
+libbase.a: $(OBJECTS)
+       $(AR) clr libbase.a $(OBJECTS)
+       $(RANLIB) libbase.a
+
+.PHONY: clean depend
+
+depend:
+       makedepend -Y -- $(CFLAGS) -- *.c
+
+clean:
+       rm -f *.o libbase.a libbase-light.a .*~ *~ Makefile.bak
+
+# DO NOT DELETE
+
+atof.o: ../../software/include/libc.h
+board.o: ../../software/include/hw/sysctl.h
+board.o: ../../software/include/hw/common.h ../../software/include/libc.h
+board.o: ../../software/include/board.h
+cfcard.o: ../../software/include/hw/systemace.h
+cfcard.o: ../../software/include/hw/common.h ../../software/include/libc.h
+cfcard.o: ../../software/include/cfcard.h ../../software/include/console.h
+cffat.o: ../../software/include/libc.h ../../software/include/endian.h
+cffat.o: ../../software/include/cfcard.h ../../software/include/console.h
+cffat.o: ../../software/include/cffat.h
+console.o: ../../software/include/libc.h ../../software/include/uart.h
+console.o: ../../software/include/console.h
+crc16.o: ../../software/include/crc.h
+crc32.o: ../../software/include/crc.h
+libc.o: ../../software/include/libc.h
+malloc.o: ../../software/include/libc.h ../../software/include/console.h
+malloc.o: ../../software/include/malloc.h
+softfloat-glue.o: ../../software/include/libc.h softfloat.h
+softfloat.o: milieu.h softfloat.h softfloat-macros.h softfloat-specialize.h
+system.o: ../../software/include/hw/fmlbrg.h ../../software/include/system.h
+uart-async.o: ../../software/include/uart.h ../../software/include/irq.h
+uart-async.o: ../../software/include/hw/uart.h
+uart-async.o: ../../software/include/hw/common.h
+uart-async.o: ../../software/include/hw/interrupts.h
+uart.o: ../../software/include/hw/uart.h ../../software/include/hw/common.h
+uart.o: ../../software/include/uart.h
+vsnprintf-nofloat.o: ../../software/include/libc.h
+vsnprintf.o: ../../software/include/libc.h
diff --git a/software/libbase/atof.c b/software/libbase/atof.c
new file mode 100644 (file)
index 0000000..107e267
--- /dev/null
@@ -0,0 +1,83 @@
+/*  atof.c: converts an ASCII string to float
+
+    Copyright (C) 2003  Jesus Calvino-Fraga, jesusc@ieee.org
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
+
+#include <libc.h>
+
+float atof(const char * s)
+{
+       float value, fraction;
+       char iexp;
+       char sign;
+
+       //Skip leading blanks
+       while (isspace(*s)) s++;
+
+       //Get the sign
+       if (*s == '-')
+       {
+               sign=1;
+               s++;
+       }
+       else
+       {
+               sign=0;
+               if (*s == '+') s++;
+       }
+
+       //Get the integer part
+       for (value=0.0f; isdigit(*s); s++)
+       {
+               value=10.0f*value+(*s-'0');
+       }
+
+       //Get the fraction
+       if (*s == '.')
+       {
+               s++;
+               for (fraction=0.1f; isdigit(*s); s++)
+               {
+                       value+=(*s-'0')*fraction;
+                       fraction*=0.1f;
+               }
+       }
+
+       //Finally, the exponent (not very efficient, but enough for now)
+       if (toupper(*s)=='E')
+       {
+               s++;
+               iexp=(char)atoi(s);
+               {
+                       while(iexp!=0)
+                       {
+                               if(iexp<0)
+                               {
+                                       value*=0.1f;
+                                       iexp++;
+                               }
+                               else
+                               {
+                                       value*=10.0f;
+                                       iexp--;
+                               }
+                       }
+               }
+       }
+
+       if(sign) value*=-1.0f;
+       return (value);
+}
diff --git a/software/libbase/board.c b/software/libbase/board.c
new file mode 100644 (file)
index 0000000..4de25a8
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <hw/sysctl.h>
+#include <libc.h>
+#include <board.h>
+
+static const struct board_desc boards[2] = {
+       {
+               .id = 0x58343031, /* X401 */
+               .name = "Xilinx ML401 development board",
+               .clk_frequency = 100000000,
+               .sdram_size = 64,
+               .ddr_clkphase = 0,
+               .ddr_idelay = 0,
+               .ddr_dqsdelay = 244
+       },
+       {
+               .id = 0x53334145, /* S3AE */
+               .name = "Avnet Spartan-3A evaluation kit",
+               .clk_frequency = 64000000,
+               .sdram_size = 0
+       },
+       {
+               .id = 0x4D4F4E45, /* MONE */
+               .name = "Milkymist One",
+               .clk_frequency = 80000000,
+               .sdram_size = 64,
+               .ddr_clkphase = 0,
+               .ddr_idelay = 0,
+               .ddr_dqsdelay = 244
+       },
+};
+
+const struct board_desc *get_board_desc_id(unsigned int id)
+{
+       unsigned int i;
+       
+       for(i=0;i<sizeof(boards)/sizeof(boards[0]);i++)
+               if(boards[i].id == id)
+                       return &boards[i];
+       return NULL;
+}
+
+const struct board_desc *get_board_desc()
+{
+       return get_board_desc_id(CSR_SYSTEM_ID);
+}
+
diff --git a/software/libbase/cfcard.c b/software/libbase/cfcard.c
new file mode 100644 (file)
index 0000000..ba48dfb
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <hw/systemace.h>
+#include <libc.h>
+#include <cfcard.h>
+#include <console.h>
+
+#define TIMEOUT 10000000
+
+int cf_init()
+{
+       int timeout;
+       
+       CSR_ACE_BUSMODE = ACE_BUSMODE_16BIT;
+       
+       if(!(CSR_ACE_STATUSL & ACE_STATUSL_CFDETECT)) return 0;
+       if((CSR_ACE_ERRORL != 0) || (CSR_ACE_ERRORH != 0)) return 0;
+       
+       CSR_ACE_CTLL |= ACE_CTLL_LOCKREQ;
+       timeout = TIMEOUT;
+       while((timeout > 0) && (!(CSR_ACE_STATUSL & ACE_STATUSL_MPULOCK))) timeout--;
+       if(timeout == 0) return 0;
+       
+       return 1;
+}
+
+int cf_readblock(unsigned int blocknr, unsigned char *buf)
+{
+       unsigned short int *bufw = (unsigned short int *)buf;
+       int buffer_count;
+       int i;
+       int timeout;
+       
+       /* See p. 39 */
+       timeout = TIMEOUT;
+       while((timeout > 0) && (!(CSR_ACE_STATUSL & ACE_STATUSL_CFCMDRDY))) timeout--;
+       if(timeout == 0) return 0;
+       
+       CSR_ACE_MLBAL = blocknr & 0x0000ffff;
+       CSR_ACE_MLBAH = (blocknr & 0x0fff0000) >> 16;
+       
+       CSR_ACE_SECCMD = ACE_SECCMD_READ|0x01;
+       
+       CSR_ACE_CTLL |= ACE_CTLL_CFGRESET;
+       
+       buffer_count = 16;
+       while(buffer_count > 0) {
+               timeout = TIMEOUT;
+               while((timeout > 0) && (!(CSR_ACE_STATUSL & ACE_STATUSL_DATARDY))) timeout--;
+               if(timeout == 0) return 0;
+
+               for(i=0;i<16;i++) {
+                       *bufw = CSR_ACE_DATA;
+                       /* SystemACE data buffer access seems little-endian. */
+                       *bufw = ((*bufw & 0xff00) >> 8) | ((*bufw & 0x00ff) << 8);
+                       bufw++;
+               }
+                       
+               buffer_count--;
+       }
+       
+       CSR_ACE_CTLL &= ~ACE_CTLL_CFGRESET;
+       
+       return 1;
+}
+
+void cf_done()
+{
+       CSR_ACE_CTLL &= ~ACE_CTLL_LOCKREQ;
+}
diff --git a/software/libbase/cffat.c b/software/libbase/cffat.c
new file mode 100644 (file)
index 0000000..a2c5bce
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <libc.h>
+#include <endian.h>
+#include <cfcard.h>
+#include <console.h>
+#include <cffat.h>
+
+struct partition_descriptor {
+       unsigned char flags;
+       unsigned char start_head;
+       unsigned short start_cylinder;
+       unsigned char type;
+       unsigned char end_head;
+       unsigned short end_cylinder;
+       unsigned int start_sector;
+       unsigned int end_sector;
+} __attribute__((packed));
+
+struct firstsector {
+       unsigned char bootsector[446];
+       struct partition_descriptor partitions[4];
+       unsigned char signature[2];
+} __attribute__((packed));
+
+
+struct fat16_firstsector {
+       /* Common to FATxx */
+       char jmp[3];
+       char oem[8];
+       unsigned short bytes_per_sector;
+       unsigned char sectors_per_cluster;
+       unsigned short reserved_sectors;
+       unsigned char number_of_fat;
+       unsigned short max_root_entries;
+       unsigned short total_sectors_short;
+       unsigned char media_descriptor;
+       unsigned short sectors_per_fat;
+       unsigned short sectors_per_track;
+       unsigned short head_count;
+       unsigned int hidden_sectors;
+       unsigned int total_sectors;
+       
+       /* FAT16 specific */
+       unsigned char drive_nr;
+       unsigned char reserved;
+       unsigned char ext_boot_signature;
+       unsigned int id;
+       unsigned char volume_label[11];
+       unsigned char fstype[8];
+       unsigned char bootcode[448];
+       unsigned char signature[2];
+} __attribute__((packed));
+
+struct directory_entry {
+       unsigned char filename[8];
+       unsigned char extension[3];
+       unsigned char attributes;
+       unsigned char reserved;
+       unsigned char create_time_ms;
+       unsigned short create_time;
+       unsigned short create_date;
+       unsigned short last_access;
+       unsigned short ea_index;
+       unsigned short lastm_time;
+       unsigned short lastm_date;
+       unsigned short first_cluster;
+       unsigned int file_size;
+} __attribute__((packed));
+
+struct directory_entry_lfn {
+       unsigned char seq;
+       unsigned short name1[5]; /* UTF16 */
+       unsigned char attributes;
+       unsigned char reserved;
+       unsigned char checksum;
+       unsigned short name2[6];
+       unsigned short first_cluster;
+       unsigned short name3[2];
+} __attribute__((packed));
+
+#define PARTITION_TYPE_FAT16           0x06
+
+static int cffat_partition_start_sector;       /* Sector# of the beginning of the FAT16 partition */
+
+static int cffat_sectors_per_cluster;
+static int cffat_fat_sector;                   /* Sector of the first FAT */
+static int cffat_fat_entries;                  /* Number of entries in the FAT */
+static int cffat_max_root_entries;
+static int cffat_root_table_sector;            /* Sector# of the beginning of the root table */
+
+static int cffat_fat_cached_sector;
+static unsigned short int cffat_fat_sector_cache[CF_BLOCK_SIZE/2];
+
+static int cffat_dir_cached_sector;
+static struct directory_entry cffat_dir_sector_cache[CF_BLOCK_SIZE/sizeof(struct directory_entry)];
+
+static int cffat_data_start_sector;
+
+int cffat_init()
+{
+       struct firstsector s0;
+       struct fat16_firstsector s;
+       int i;
+       
+       if(!cf_init()) {
+               printf("E: Unable to initialize CF card driver\n");
+               return 0;
+       }
+       
+       /* Read sector 0, with partition table */
+       if(!cf_readblock(0, (void *)&s0)) {
+               printf("E: Unable to read block 0\n");
+               return 0;
+       }
+       
+       cffat_partition_start_sector = -1;
+       for(i=0;i<4;i++)
+               if(s0.partitions[i].type == PARTITION_TYPE_FAT16) {
+                       /*printf("I: Using partition #%d: start sector %08x, end sector %08x\n", i, 
+                               le32toh(s0.partitions[i].start_sector), le32toh(s0.partitions[i].end_sector));*/
+                       cffat_partition_start_sector = le32toh(s0.partitions[i].start_sector);
+                       break;
+               }
+       if(cffat_partition_start_sector == -1) {
+               printf("E: No FAT partition was found\n");
+               return 0;
+       }
+       
+       /* Read first FAT16 sector */
+       if(!cf_readblock(cffat_partition_start_sector, (void *)&s)) {
+               printf("E: Unable to read first FAT sector\n");
+               return 0;
+       }
+       
+       s.volume_label[10] = 0;
+       //printf("I: Volume label: %s\n", s.volume_label);
+       
+       if(le16toh(s.bytes_per_sector) != CF_BLOCK_SIZE) return 0;
+       cffat_sectors_per_cluster = s.sectors_per_cluster;
+       
+       cffat_fat_entries = (le16toh(s.sectors_per_fat)*CF_BLOCK_SIZE)/2;
+       cffat_fat_sector = cffat_partition_start_sector + 1;
+       cffat_fat_cached_sector = -1;
+       
+       cffat_max_root_entries = le16toh(s.max_root_entries);
+       cffat_root_table_sector = cffat_fat_sector + s.number_of_fat*le16toh(s.sectors_per_fat);
+       cffat_dir_cached_sector = -1;
+       
+       cffat_data_start_sector = cffat_root_table_sector + (cffat_max_root_entries*sizeof(struct directory_entry))/CF_BLOCK_SIZE;
+       
+       /*printf("I: Cluster is %d sectors, FAT has %d entries, FAT 1 is at sector %d,\nI: root table is at sector %d (max %d), data is at sector %d\n",
+               cffat_sectors_per_cluster, cffat_fat_entries, cffat_fat_sector,
+               cffat_root_table_sector, cffat_max_root_entries,
+               cffat_data_start_sector);*/
+       return 1;
+}
+
+static int cffat_read_fat(int offset)
+{
+       int wanted_sector;
+       
+       if((offset < 0) || (offset >= cffat_fat_entries))
+               return -1;
+               
+       wanted_sector = cffat_fat_sector + (offset*2)/CF_BLOCK_SIZE;
+       if(wanted_sector != cffat_fat_cached_sector) {
+               if(!cf_readblock(wanted_sector, (void *)&cffat_fat_sector_cache)) {
+                       printf("E: CF failed (FAT), sector %d\n", wanted_sector);
+                       return -1;
+               }
+               cffat_fat_cached_sector = wanted_sector;
+       }
+       
+       return le16toh(cffat_fat_sector_cache[offset % (CF_BLOCK_SIZE/2)]);
+}
+
+static const struct directory_entry *cffat_read_root_directory(int offset)
+{
+       int wanted_sector;
+       
+       if((offset < 0) || (offset >= cffat_max_root_entries))
+               return NULL;
+
+       wanted_sector = cffat_root_table_sector + (offset*sizeof(struct directory_entry))/CF_BLOCK_SIZE;
+
+       if(wanted_sector != cffat_dir_cached_sector) {
+               if(!cf_readblock(wanted_sector, (void *)&cffat_dir_sector_cache)) {
+                       printf("E: CF failed (Rootdir), sector %d\n", wanted_sector);
+                       return NULL;
+               }
+               cffat_dir_cached_sector = wanted_sector;
+       }
+       return &cffat_dir_sector_cache[offset % (CF_BLOCK_SIZE/sizeof(struct directory_entry))];
+}
+
+static void lfn_to_ascii(const struct directory_entry_lfn *entry, char *name, int terminate)
+{
+       int i;
+       unsigned short c;
+
+       for(i=0;i<5;i++) {
+               c = le16toh(entry->name1[i]);
+               if(c <= 255) {
+                       *name = c;
+                       name++;
+                       if(c == 0) return;
+               }
+       }
+       for(i=0;i<6;i++) {
+               c = le16toh(entry->name2[i]);
+               if(c <= 255) {
+                       *name = c;
+                       name++;
+                       if(c == 0) return;
+               }
+       }
+       for(i=0;i<2;i++) {
+               c = le16toh(entry->name3[i]);
+               if(c <= 255) {
+                       *name = c;
+                       name++;
+                       if(c == 0) return;
+               }
+       }
+
+       if(terminate)
+               *name = 0;
+}
+
+static int cffat_is_regular(const struct directory_entry *entry)
+{
+       return ((entry->attributes & 0x10) == 0)
+               && ((entry->attributes & 0x08) == 0)
+               && (entry->filename[0] != 0xe5);
+}
+
+int cffat_list_files(cffat_dir_callback cb, void *param)
+{
+       const struct directory_entry *entry;
+       char fmtbuf[8+1+3+1];
+       char longname[131];
+       int has_longname;
+       int i, j, k;
+
+       has_longname = 0;
+       longname[sizeof(longname)-1] = 0; /* avoid crashing when reading a corrupt FS */
+       for(k=0;k<cffat_max_root_entries;k++) {
+               entry = cffat_read_root_directory(k);
+               if(entry->attributes == 0x0f) {
+                       const struct directory_entry_lfn *entry_lfn;
+                       unsigned char frag;
+                       int terminate;
+
+                       entry_lfn = (const struct directory_entry_lfn *)entry;
+                       frag = entry_lfn->seq & 0x3f;
+                       terminate = entry_lfn->seq & 0x40;
+                       if(frag*13 < sizeof(longname)) {
+                               lfn_to_ascii((const struct directory_entry_lfn *)entry, &longname[(frag-1)*13], terminate);
+                               if(frag == 1) has_longname = 1;
+                       }
+                       continue;
+               } else {
+                       if(!cffat_is_regular(entry)) {
+                               has_longname = 0;
+                               continue;
+                       }
+               }
+               if(entry == NULL) return 0;
+               if(entry->filename[0] == 0) {
+                       has_longname = 0;
+                       break;
+               }
+               j = 0;
+               for(i=0;i<8;i++) {
+                       if(entry->filename[i] == ' ') break;
+                       fmtbuf[j++] = entry->filename[i];
+               }
+               fmtbuf[j++] = '.';
+               for(i=0;i<3;i++) {
+                       if(entry->extension[i] == ' ') break;
+                       fmtbuf[j++] = entry->extension[i];
+               }
+               fmtbuf[j++] = 0;
+               if(!cb(fmtbuf, has_longname ? longname : fmtbuf, param)) return 0;
+               has_longname = 0;
+       }
+       return 1;
+}
+
+static const struct directory_entry *cffat_find_file_by_name(const char *filename)
+{
+       char searched_filename[8];
+       char searched_extension[3];
+       char *dot;
+       const char *c;
+       int i;
+       const struct directory_entry *entry;
+       
+       dot = strrchr(filename, '.');
+       if(dot == NULL)
+               return NULL;
+       
+       memset(searched_filename, ' ', 8);
+       memset(searched_extension, ' ', 3);
+       i = 0;
+       for(c=filename;c<dot;c++)
+               searched_filename[i++] = toupper(*c);
+               
+       i = 0;
+       for(c=dot+1;*c!=0;c++)
+               searched_extension[i++] = toupper(*c);
+               
+       for(i=0;i<cffat_max_root_entries;i++) {
+               entry = cffat_read_root_directory(i);
+               if(entry == NULL) break;
+               if(entry->filename[0] == 0) break;
+               if(!cffat_is_regular(entry)) continue;
+               if(!memcmp(searched_filename, entry->filename, 8)
+                &&!memcmp(searched_extension, entry->extension, 3))
+                       return entry;
+       }
+       return NULL;
+}
+
+static int cffat_load_cluster(int clustern, char *buffer, int maxsectors)
+{
+       int startsector;
+       int i;
+       int toread;
+       
+       clustern = clustern - 2;
+       startsector = cffat_data_start_sector + clustern*cffat_sectors_per_cluster;
+       if(maxsectors < cffat_sectors_per_cluster)
+               toread = maxsectors;
+       else
+               toread = cffat_sectors_per_cluster;
+       for(i=0;i<toread;i++)
+               if(!cf_readblock(startsector+i, (unsigned char *)buffer+i*CF_BLOCK_SIZE)) {
+                       printf("E: CF failed (Cluster), sector %d\n", startsector+i);
+                       return 0;
+               }
+       return 1;
+}
+
+int cffat_load(const char *filename, char *buffer, int size, int *realsize)
+{
+       const struct directory_entry *entry;
+       int cluster_size;
+       int cluster;
+       int n;
+       
+       cluster_size = cffat_sectors_per_cluster*CF_BLOCK_SIZE;
+       size /= CF_BLOCK_SIZE;
+       
+       entry = cffat_find_file_by_name(filename);
+       if(entry == NULL) {
+               printf("E: File not found: %s\n", filename);
+               return 0;
+       }
+       
+       if(realsize != NULL) *realsize = le32toh(entry->file_size);
+       
+       n = 0;
+       cluster = le16toh(entry->first_cluster);
+       while(size > 0) {
+               if(!cffat_load_cluster(cluster, buffer+n*cluster_size, size))
+                       return 0;
+               size -= cffat_sectors_per_cluster;
+               n++;
+               cluster = cffat_read_fat(cluster);
+               if(cluster >= 0xFFF8) break;
+               if(cluster == -1) return 0;
+       }
+       //putsnonl("\n");
+       
+       return n*cluster_size;
+}
+
+void cffat_done()
+{
+       cf_done();
+}
diff --git a/software/libbase/console.c b/software/libbase/console.c
new file mode 100644 (file)
index 0000000..400f26a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <libc.h>
+#include <uart.h>
+#include <console.h>
+
+int puts(const char *s)
+{
+       while(*s) {
+               writechar(*s);
+               s++;
+       }
+       writechar('\n');
+       return 1;
+}
+
+void putsnonl(const char *s)
+{
+       while(*s) {
+               writechar(*s);
+               s++;
+       }
+}
+
+void readstr(char *s, int size)
+{
+       char c;
+       int ptr;
+       
+       ptr = 0;
+       while(1) {
+               c = readchar();
+               switch(c) {
+                       case 0x7f:
+                       case 0x08:
+                               if(ptr > 0) {
+                                       ptr--;
+                                       putsnonl("\x08 \x08");
+                               }
+                               break;
+                       case '\r':
+                       case '\n':
+                               s[ptr] = 0x00;
+                               putsnonl("\n");
+                               return;
+                       default:
+                               writechar(c);
+                               s[ptr] = c;
+                               ptr++;
+                               break;
+               }
+       }
+}
+
+int printf(const char *fmt, ...)
+{
+       va_list args;
+       int len;
+       char outbuf[256];
+
+       va_start(args, fmt);
+       len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
+       va_end(args);
+       outbuf[len] = 0;
+       putsnonl(outbuf);
+
+       return len;
+}
diff --git a/software/libbase/crc16.c b/software/libbase/crc16.c
new file mode 100644 (file)
index 0000000..c3fd320
--- /dev/null
@@ -0,0 +1,47 @@
+#include <crc.h>
+
+unsigned int crc16_table[256] = {
+       0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+       0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+       0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+       0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+       0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+       0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+       0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+       0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+       0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+       0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+       0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+       0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+       0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+       0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+       0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+       0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+       0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+       0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+       0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+       0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+       0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+       0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+       0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+       0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+       0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+       0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+       0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+       0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+       0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+       0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+       0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+       0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+};
+
+unsigned short crc16(const unsigned char *buffer, int len)
+{
+       unsigned short crc;
+       
+       crc = 0;
+       while(len-- > 0)
+           crc = crc16_table[((crc >> 8) ^ (*buffer++)) & 0xFF] ^ (crc << 8);
+       
+       return crc;
+}
diff --git a/software/libbase/crc32.c b/software/libbase/crc32.c
new file mode 100644 (file)
index 0000000..dae2332
--- /dev/null
@@ -0,0 +1,81 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <crc.h>
+
+const unsigned int crc_table[256] = {
+       0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+       0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+       0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+       0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+       0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+       0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+       0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+       0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+       0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+       0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+       0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+       0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+       0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+       0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+       0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+       0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+       0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+       0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+       0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+       0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+       0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+       0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+       0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+       0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+       0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+       0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+       0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+       0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+       0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+       0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+       0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+       0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+       0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+       0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+       0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+       0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+       0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+       0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+       0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+       0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+       0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+       0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+       0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+       0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+       0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+       0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+       0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+       0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+       0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+       0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+       0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+       0x2d02ef8dL
+};
+
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+unsigned int crc32(const unsigned char *buffer, unsigned int len)
+{
+       unsigned int crc;
+       crc = 0;
+       crc = crc ^ 0xffffffffL;
+       while(len >= 8) {
+               DO8(buffer);
+               len -= 8;
+       }
+       if(len) do {
+               DO1(buffer);
+       } while(--len);
+       return crc ^ 0xffffffffL;
+}
diff --git a/software/libbase/divsi3.c b/software/libbase/divsi3.c
new file mode 100644 (file)
index 0000000..2519cbb
--- /dev/null
@@ -0,0 +1,52 @@
+#define divnorm(num, den, sign)                \
+{                                              \
+  if (num < 0)                                         \
+    {                                          \
+      num = -num;                              \
+      sign = 1;                                        \
+    }                                          \
+  else                                                 \
+    {                                          \
+      sign = 0;                                        \
+    }                                          \
+                                               \
+  if (den < 0)                                         \
+    {                                          \
+      den = - den;                             \
+      sign = 1 - sign;                         \
+    }                                          \
+}
+
+#define exitdiv(sign, res) if (sign) { res = - res;} return res;
+
+long __divsi3 (long numerator, long denominator)
+{
+  int sign;
+  long dividend;
+  divnorm (numerator, denominator, sign);
+
+  dividend = (unsigned int)numerator/(unsigned int)denominator;
+  exitdiv (sign, dividend);
+}
+
+long __modsi3 (long numerator, long denominator)
+{
+       int sign;
+       long res;
+
+       if(numerator < 0) {
+               numerator = -numerator;
+               sign = 1;
+       } else
+               sign = 0;
+
+       if(denominator < 0)
+               denominator = -denominator;
+
+       res = (unsigned int)numerator % (unsigned int)denominator;
+
+       if(sign)
+               return -res;
+       else
+               return res;
+}
diff --git a/software/libbase/irq.S b/software/libbase/irq.S
new file mode 100644 (file)
index 0000000..d9f118d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+.section .text, "ax", @progbits
+.global irq_enable, irq_isenabled, irq_setmask, irq_getmask, irq_pending, irq_ack
+
+/* Parameter: 1=enable, 0=disable */
+irq_enable:
+       wcsr    IE, r1
+       ret
+
+/* No parameter */
+/* Return value: 1/0 */
+irq_isenabled:
+       rcsr    r1, IE
+       andi    r1, r1, 1
+       ret
+
+/* Parameter: the mask */
+irq_setmask:
+       wcsr    IM, r1
+       ret
+
+/* No parameter */
+/* Return value: the mask */
+irq_getmask:
+       rcsr    r1, IM
+       ret
+
+/* No parameter */
+/* Return value: pending IRQs */
+irq_pending:
+       rcsr    r1, IP
+       ret
+
+/* Parameter: the mask */
+irq_ack:
+       wcsr    IP, r1
+       ret
diff --git a/software/libbase/libc.c b/software/libbase/libc.c
new file mode 100644 (file)
index 0000000..0ee1462
--- /dev/null
@@ -0,0 +1,510 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * Copyright (C) Linux kernel developers
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <libc.h>
+
+/**
+ * strchr - Find the first occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char *strchr(const char *s, int c)
+{
+       for (; *s != (char)c; ++s)
+               if (*s == '\0')
+                       return NULL;
+       return (char *)s;
+}
+
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char *strrchr(const char *s, int c)
+{
+       const char *p = s + strlen(s);
+       do {
+           if (*p == (char)c)
+               return (char *)p;
+       } while (--p >= s);
+       return NULL;
+}
+
+/**
+ * strnchr - Find a character in a length limited string
+ * @s: The string to be searched
+ * @count: The number of characters to be searched
+ * @c: The character to search for
+ */
+char *strnchr(const char *s, size_t count, int c)
+{
+       for (; count-- && *s != '\0'; ++s)
+               if (*s == (char)c)
+                       return (char *)s;
+       return NULL;
+}
+
+/**
+ * strcpy - Copy a %NUL terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ */
+char *strcpy(char *dest, const char *src)
+{
+       char *tmp = dest;
+
+       while ((*dest++ = *src++) != '\0')
+               /* nothing */;
+       return tmp;
+}
+
+/**
+ * strncpy - Copy a length-limited, %NUL-terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @count: The maximum number of bytes to copy
+ *
+ * The result is not %NUL-terminated if the source exceeds
+ * @count bytes.
+ *
+ * In the case where the length of @src is less than  that  of
+ * count, the remainder of @dest will be padded with %NUL.
+ *
+ */
+char *strncpy(char *dest, const char *src, size_t count)
+{
+       char *tmp = dest;
+       
+       while (count) {
+               if ((*tmp = *src) != 0)
+                       src++;
+               tmp++;
+               count--;
+       }
+       return dest;
+}
+
+/**
+ * strcmp - Compare two strings
+ * @cs: One string
+ * @ct: Another string
+ */
+int strcmp(const char *cs, const char *ct)
+{
+       signed char __res;
+
+       while (1) {
+               if ((__res = *cs - *ct++) != 0 || !*cs++)
+                       break;
+       }
+       return __res;
+}
+
+/**
+ * strncmp - Compare two strings using the first characters only
+ * @cs: One string
+ * @ct: Another string
+ * @count: Number of characters
+ */
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+       signed char __res;
+       size_t n;
+
+       n = 0;
+       __res = 0;
+       while (n < count) {
+               if ((__res = *cs - *ct++) != 0 || !*cs++)
+                       break;
+               n++;
+       }
+       return __res;
+}
+
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char *s)
+{
+       const char *sc;
+
+       for (sc = s; *sc != '\0'; ++sc)
+               /* nothing */;
+       return sc - s;
+}
+
+/**
+ * strnlen - Find the length of a length-limited string
+ * @s: The string to be sized
+ * @count: The maximum number of bytes to search
+ */
+size_t strnlen(const char *s, size_t count)
+{
+       const char *sc;
+
+       for (sc = s; count-- && *sc != '\0'; ++sc)
+               /* nothing */;
+       return sc - s;
+}
+
+/**
+ * memcmp - Compare two areas of memory
+ * @cs: One area of memory
+ * @ct: Another area of memory
+ * @count: The size of the area.
+ */
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+       const unsigned char *su1, *su2;
+       int res = 0;
+
+       for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+               if ((res = *su1 - *su2) != 0)
+                       break;
+       return res;
+}
+
+/**
+ * memset - Fill a region of memory with the given value
+ * @s: Pointer to the start of the area.
+ * @c: The byte to fill the area with
+ * @count: The size of the area.
+ */
+void *memset(void *s, int c, size_t count)
+{
+       char *xs = s;
+
+       while (count--)
+               *xs++ = c;
+       return s;
+}
+
+/**
+ * memcpy - Copies one area of memory to another
+ * @dest: Destination
+ * @src: Source
+ * @n: The size to copy.
+ */
+void *memcpy(void *dest, const void *src, size_t n)
+{
+       char *_dest = (char *)dest;
+       char *_src = (char *)src;
+       size_t i;
+
+       for(i=0;i<n;i++)
+               _dest[i] = _src[i];
+
+       return dest;
+}
+
+/**
+ * memmove - Copies one area of memory to another, overlap possible
+ * @dest: Destination
+ * @src: Source
+ * @n: The size to copy.
+ */
+void *memmove(void *dest, const void *src, size_t count)
+{
+       char *tmp, *s;
+
+       if(dest <= src) {
+               tmp = (char *) dest;
+               s = (char *) src;
+               while(count--)
+                       *tmp++ = *s++;
+       } else {
+               tmp = (char *)dest + count;
+               s = (char *)src + count;
+               while(count--)
+                       *--tmp = *--s;
+       }
+
+       return dest;
+}
+
+
+/**
+ * strtoul - convert a string to an unsigned long
+ * @nptr: The start of the string
+ * @endptr: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long strtoul(const char *nptr, char **endptr, int base)
+{
+       unsigned long result = 0,value;
+
+       if (!base) {
+               base = 10;
+               if (*nptr == '0') {
+                       base = 8;
+                       nptr++;
+                       if ((toupper(*nptr) == 'X') && isxdigit(nptr[1])) {
+                               nptr++;
+                               base = 16;
+                       }
+               }
+       } else if (base == 16) {
+               if (nptr[0] == '0' && toupper(nptr[1]) == 'X')
+                       nptr += 2;
+       }
+       while (isxdigit(*nptr) &&
+              (value = isdigit(*nptr) ? *nptr-'0' : toupper(*nptr)-'A'+10) < base) {
+               result = result*base + value;
+               nptr++;
+       }
+       if (endptr)
+               *endptr = (char *)nptr;
+       return result;
+}
+
+/**
+ * strtol - convert a string to a signed long
+ * @nptr: The start of the string
+ * @endptr: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long strtol(const char *nptr, char **endptr, int base)
+{
+       if(*nptr=='-')
+               return -strtoul(nptr+1,endptr,base);
+       return strtoul(nptr,endptr,base);
+}
+
+int skip_atoi(const char **s)
+{
+       int i=0;
+
+       while (isdigit(**s))
+               i = i*10 + *((*s)++) - '0';
+       return i;
+}
+
+char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type)
+{
+       char c,sign,tmp[66];
+       const char *digits;
+       static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+       static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+       int i;
+
+       digits = (type & PRINTF_LARGE) ? large_digits : small_digits;
+       if (type & PRINTF_LEFT)
+               type &= ~PRINTF_ZEROPAD;
+       if (base < 2 || base > 36)
+               return NULL;
+       c = (type & PRINTF_ZEROPAD) ? '0' : ' ';
+       sign = 0;
+       if (type & PRINTF_SIGN) {
+               if ((signed long) num < 0) {
+                       sign = '-';
+                       num = - (signed long) num;
+                       size--;
+               } else if (type & PRINTF_PLUS) {
+                       sign = '+';
+                       size--;
+               } else if (type & PRINTF_SPACE) {
+                       sign = ' ';
+                       size--;
+               }
+       }
+       if (type & PRINTF_SPECIAL) {
+               if (base == 16)
+                       size -= 2;
+               else if (base == 8)
+                       size--;
+       }
+       i = 0;
+       if (num == 0)
+               tmp[i++]='0';
+       else while (num != 0) {
+               tmp[i++] = digits[num % base];
+               num = num / base;
+       }
+       if (i > precision)
+               precision = i;
+       size -= precision;
+       if (!(type&(PRINTF_ZEROPAD+PRINTF_LEFT))) {
+               while(size-->0) {
+                       if (buf < end)
+                               *buf = ' ';
+                       ++buf;
+               }
+       }
+       if (sign) {
+               if (buf < end)
+                       *buf = sign;
+               ++buf;
+       }
+       if (type & PRINTF_SPECIAL) {
+               if (base==8) {
+                       if (buf < end)
+                               *buf = '0';
+                       ++buf;
+               } else if (base==16) {
+                       if (buf < end)
+                               *buf = '0';
+                       ++buf;
+                       if (buf < end)
+                               *buf = digits[33];
+                       ++buf;
+               }
+       }
+       if (!(type & PRINTF_LEFT)) {
+               while (size-- > 0) {
+                       if (buf < end)
+                               *buf = c;
+                       ++buf;
+               }
+       }
+       while (i < precision--) {
+               if (buf < end)
+                       *buf = '0';
+               ++buf;
+       }
+       while (i-- > 0) {
+               if (buf < end)
+                       *buf = tmp[i];
+               ++buf;
+       }
+       while (size-- > 0) {
+               if (buf < end)
+                       *buf = ' ';
+               ++buf;
+       }
+       return buf;
+}
+
+/**
+ * vscnprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * The return value is the number of characters which have been written into
+ * the @buf not including the trailing '\0'. If @size is <= 0 the function
+ * returns 0.
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want scnprintf() instead.
+ */
+int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+       int i;
+
+       i=vsnprintf(buf,size,fmt,args);
+       return (i >= size) ? (size - 1) : i;
+}
+
+
+/**
+ * snprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The return value is the number of characters which would be
+ * generated for the given input, excluding the trailing null,
+ * as per ISO C99.  If the return is greater than or equal to
+ * @size, the resulting string is truncated.
+ */
+int snprintf(char * buf, size_t size, const char *fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args, fmt);
+       i=vsnprintf(buf,size,fmt,args);
+       va_end(args);
+       return i;
+}
+
+/**
+ * scnprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The return value is the number of characters written into @buf not including
+ * the trailing '\0'. If @size is <= 0 the function returns 0.
+ */
+
+int scnprintf(char * buf, size_t size, const char *fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args, fmt);
+       i = vsnprintf(buf, size, fmt, args);
+       va_end(args);
+       return (i >= size) ? (size - 1) : i;
+}
+
+/**
+ * vsprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * The function returns the number of characters written
+ * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
+ * buffer overflows.
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want sprintf() instead.
+ */
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+       return vsnprintf(buf, INT_MAX, fmt, args);
+}
+
+/**
+ * sprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The function returns the number of characters written
+ * into @buf. Use snprintf() or scnprintf() in order to avoid
+ * buffer overflows.
+ */
+int sprintf(char * buf, const char *fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args, fmt);
+       i=vsnprintf(buf, INT_MAX, fmt, args);
+       va_end(args);
+       return i;
+}
+
+/**
+ * rand - Returns a pseudo random number
+ */
+
+static unsigned int seed;
+unsigned int rand()
+{
+       seed = 129 * seed + 907633385;
+       return seed;
+}
diff --git a/software/libbase/malloc.c b/software/libbase/malloc.c
new file mode 100644 (file)
index 0000000..94572bf
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PC_TEST
+#include <libc.h>
+#include <console.h>
+#else
+#include <stdio.h>
+#endif
+
+#include "malloc.h"
+
+/* from http://en.wikipedia.org/wiki/Binary_GCD_algorithm */
+static unsigned int gcd(unsigned int u, unsigned int v)
+{
+       int shift;
+       
+       /* GCD(0,x) := x */
+       if (u == 0 || v == 0)
+               return u | v;
+       
+       /* Let shift := lg K, where K is the greatest power of 2
+        * dividing both u and v. */
+       for(shift = 0; ((u | v) & 1) == 0; ++shift) {
+               u >>= 1;
+               v >>= 1;
+       }
+       
+       while ((u & 1) == 0) u >>= 1;
+       
+       /* From here on, u is always odd. */
+       do {
+               while ((v & 1) == 0)  /* Loop X */
+                       v >>= 1;
+               
+               /* Now u and v are both odd, so diff(u, v) is even.
+                * Let u = min(u, v), v = diff(u, v)/2. */
+               if (u < v) {
+                       v -= u;
+               } else {
+                       unsigned int diff = u - v;
+                       u = v;
+                       v = diff;
+               }
+               v >>= 1;
+       } while (v != 0);
+       
+       return u << shift;
+}
+
+static unsigned int lcm(unsigned int u, unsigned int v)
+{
+       return u*v/gcd(u, v);
+}
+
+/*
+ * Memory is split in elements of the size of a bookkeeping
+ * record (struct m_bk).
+ * Those records are placed in front of each chunk.
+ */
+struct m_bk {
+       /* Indice of next element. If there is no next element,
+        * this condition can be spotted by using the last_allocated
+        * field of the bank, and this indice is invalid.
+        */
+       unsigned int next;
+       /* Size of the allocation in elements, counting this one. */
+       unsigned int size;
+} __attribute__((packed));
+
+struct malloc_bank *m_banks;
+static unsigned int m_nbanks;
+static unsigned int m_defaultbank;
+
+static inline struct m_bk *getbk(unsigned int bank)
+{
+       return (struct m_bk *)(m_banks[bank].addr_start);
+}
+
+static inline unsigned int getnbk(unsigned int bank)
+{
+       return (m_banks[bank].addr_end - m_banks[bank].addr_start)/sizeof(struct m_bk);
+}
+
+void malloc_init(struct malloc_bank *banks, unsigned int n, unsigned int defaultbank)
+{
+       unsigned int i;
+       
+       m_banks = banks;
+       m_nbanks = n;
+       m_defaultbank = defaultbank;
+       
+       for(i=0;i<n;i++) {
+               m_banks[i].first_allocated = -1;
+               m_banks[i].last_allocated = -1;
+       }
+}
+
+void *mallocex(unsigned int size, unsigned int bank, unsigned int alignment)
+{
+       struct malloc_bank *b;
+       unsigned int extra;
+       unsigned int datastart;
+       int freespace;
+       struct m_bk *bk;
+       int curindex;
+       int allocindex;
+       
+       if(size == 0) return NULL;
+       
+       /* Resolve alignment and size constraints */
+       alignment = lcm(alignment, sizeof(struct m_bk));
+       if((size % sizeof(struct m_bk)) != 0)
+               size += sizeof(struct m_bk) - (size % sizeof(struct m_bk));
+       
+       b = &m_banks[bank]; /* convenience pointers */
+       bk = getbk(bank);
+       
+       /* First, try allocation at the beginning of the bank */
+       
+       /* How much space we will need to respect the alignment constraint */
+       datastart = b->addr_start + sizeof(struct m_bk);
+       if((datastart % alignment) != 0)
+               extra = alignment - (datastart % alignment);
+       else
+               extra = 0;
+       
+       /* Case: bank is entirely free */
+       if(b->first_allocated == -1) {
+               freespace = b->addr_end - b->addr_start;
+               if(freespace < (size + extra + sizeof(struct m_bk)))
+                       return NULL; /* bank is too small for requested buffer */
+                       
+               /* Everything OK, perform the allocation */
+               extra /= sizeof(struct m_bk);
+               size /= sizeof(struct m_bk);
+               bk[extra].size = size+1;
+               b->first_allocated = extra;
+               b->last_allocated = extra;
+               return &bk[extra+1];
+       }
+       
+       /* Case: can allocate at the very beginning of the bank */
+       freespace = sizeof(struct m_bk)*b->first_allocated;
+       if(freespace >= (size + extra + sizeof(struct m_bk))) {
+               extra /= sizeof(struct m_bk);
+               size /= sizeof(struct m_bk);
+               bk[extra].next = b->first_allocated;
+               bk[extra].size = size+1;
+               b->first_allocated = extra;
+               return &bk[extra+1];
+       }
+       
+       /* Case: can allocate after the last chunk */
+       datastart = b->addr_start
+               + (b->last_allocated+bk[b->last_allocated].size+1)*sizeof(struct m_bk);
+       if((datastart % alignment) != 0)
+               extra = alignment - (datastart % alignment);
+       else
+               extra = 0;
+       freespace = sizeof(struct m_bk)*(getnbk(bank) - b->last_allocated - bk[b->last_allocated].size);
+       if(freespace >= (size + extra + sizeof(struct m_bk))) {
+               extra /= sizeof(struct m_bk);
+               size /= sizeof(struct m_bk);
+               allocindex = b->last_allocated + bk[b->last_allocated].size + extra;
+               bk[b->last_allocated].next = allocindex;
+               bk[allocindex].size = size+1;
+               b->last_allocated = allocindex;
+               return &bk[allocindex+1];
+       }
+       
+       /* Case: can allocate between two chunks */
+       curindex = b->first_allocated;
+       while(curindex < b->last_allocated) {
+               int nextindex;
+               
+               nextindex = bk[curindex].next;
+               
+               datastart = b->addr_start
+                       + (curindex+bk[curindex].size+1)*sizeof(struct m_bk);
+               if((datastart % alignment) != 0)
+                       extra = alignment - (datastart % alignment);
+               else
+                       extra = 0;
+               
+               freespace = sizeof(struct m_bk)*(nextindex - (curindex + bk[curindex].size));
+               
+               if(freespace >= (size + extra + sizeof(struct m_bk))) {
+                       extra /= sizeof(struct m_bk);
+                       size /= sizeof(struct m_bk);
+                       
+                       allocindex = curindex + bk[curindex].size + extra;
+                       bk[allocindex].size = size+1;
+                       bk[allocindex].next = nextindex;
+                       bk[curindex].next = allocindex;
+                       
+                       return &bk[allocindex+1];
+               }
+               
+               curindex = nextindex;
+       }
+       return NULL;
+}
+
+#ifdef PC_TEST
+void test_free(void *p)
+#else
+void free(void *p)
+#endif
+{
+       struct malloc_bank *b;
+       struct m_bk *bk;
+       unsigned int i;
+       unsigned int pa;
+       unsigned int pbki;
+       
+       pa = (unsigned int)p;
+       
+       //printf("free: %08x\n", pa);
+       
+       /* Find which bank p belongs to */
+       b = NULL;
+       bk = NULL;
+       for(i=0;i<m_nbanks;i++) 
+               if((m_banks[i].addr_start <= pa) && (m_banks[i].addr_end > pa)) {
+                       bk = getbk(i);
+                       b = &m_banks[i];
+                       break;
+               }
+       if(b == NULL) {
+#ifdef PC_TEST
+               printf("ERR: Trying to free a pointer out of any bank\n");
+#endif
+               return;
+       }
+
+       /* Case: freeing the only chunk */
+       if(b->first_allocated == b->last_allocated) {
+               /* We assume p is the data of the only chunk (as it should) */
+               b->first_allocated = -1;
+               b->last_allocated = -1;
+               return;
+       }
+       
+       pbki = (pa - b->addr_start)/sizeof(struct m_bk) - 1;
+       
+       /* Case: freeing the first chunk */
+       if(pbki == b->first_allocated) {
+               b->first_allocated = bk[b->first_allocated].next;
+               return;
+       }
+       
+       /* Case: freeing the last chunk */
+       if(pbki == b->last_allocated) {
+               i = b->first_allocated;
+               while(bk[i].next != pbki)
+                       i = bk[i].next;
+               b->last_allocated = i;
+               return;
+       }
+       
+       /* Case: freeing a chunk between two others */
+       i = b->first_allocated;
+       while(bk[i].next != pbki)
+               i = bk[i].next;
+       bk[i].next = bk[pbki].next;
+}
+
+#ifdef PC_TEST
+void *test_malloc(size_t size)
+#else
+void *malloc(size_t size)
+#endif
+{
+       void *r;
+       r = mallocex(size, m_defaultbank, 1);
+       //printf("alloc: %08x\n", (unsigned int)r);
+       return r;
+}
+
+#ifdef PC_TEST
+void *test_calloc(size_t nmemb, size_t size)
+#else
+void *calloc(size_t nmemb, size_t size)
+#endif
+{
+       void *ret;
+
+       size *= nmemb;
+       ret = malloc(size);
+       if(ret == NULL) return ret;
+       memset(ret, 0, size);
+       return ret;
+}
diff --git a/software/libbase/milieu.h b/software/libbase/milieu.h
new file mode 100644 (file)
index 0000000..58d688d
--- /dev/null
@@ -0,0 +1,126 @@
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://http.cs.berkeley.edu/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+
+/*
+-------------------------------------------------------------------------------
+One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
+-------------------------------------------------------------------------------
+*/
+#define BIGENDIAN
+
+/*
+-------------------------------------------------------------------------------
+The macro `BITS64' can be defined to indicate that 64-bit integer types are
+supported by the compiler.
+-------------------------------------------------------------------------------
+*/
+//#define BITS64
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines the most convenient type that holds
+integers of at least as many bits as specified.  For example, `uint8' should
+be the most convenient type that can hold unsigned integers of as many as
+8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
+implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+to the same as `int'.
+-------------------------------------------------------------------------------
+*/
+typedef int flag;
+typedef int uint8;
+typedef int int8;
+typedef int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long long int bits64;
+typedef signed long long int sbits64;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines a type that holds integers
+of _exactly_ the number of bits specified.  For instance, for most
+implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+`unsigned short int' and `signed short int' (or `short int'), respectively.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long long int uint64;
+typedef signed long long int int64;
+#endif
+
+#ifdef BITS64
+/*
+-------------------------------------------------------------------------------
+The `LIT64' macro takes as its argument a textual integer literal and if
+necessary ``marks'' the literal as having a 64-bit integer type.  For
+example, the Gnu C Compiler (`gcc') requires that 64-bit literals be
+appended with the letters `LL' standing for `long long', which is `gcc's
+name for the 64-bit integer type.  Some compilers may allow `LIT64' to be
+defined as the identity macro:  `#define LIT64( a ) a'.
+-------------------------------------------------------------------------------
+*/
+#define LIT64( a ) a##LL
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `INLINE' can be used before functions that should be inlined.  If
+a compiler does not support explicit inlining, this macro should be defined
+to be `static'.
+-------------------------------------------------------------------------------
+*/
+#define INLINE extern inline
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+    FALSE = 0,
+    TRUE  = 1
+};
+
diff --git a/software/libbase/softfloat-glue.c b/software/libbase/softfloat-glue.c
new file mode 100644 (file)
index 0000000..45ceabd
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * 
+ * 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, version 3 of the License.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <libc.h>
+#include "softfloat.h"
+
+/*
+ * 'Equal' wrapper. This returns 0 if the numbers are equal, or (1 | -1)
+ * otherwise. So we need to invert the output.
+ */
+int __eqsf2(float32 a, float32 b)
+{
+       return !float32_eq(a, b);
+}
+
+/*
+ * 'Not Equal' wrapper. This returns -1 or 1 (say, 1!) if the numbers are
+ * not equal, 0 otherwise. However no not equal call is provided, so we have
+ * to use an 'equal' call and invert the result. The result is already
+ * inverted though! Confusing?!
+ */
+int __nesf2(float32 a, float32 b)
+{
+       return !float32_eq(a, b);
+}
+
+/*
+ * 'Greater Than' wrapper. This returns 1 if the number is greater, 0
+ * or -1 otherwise. Unfortunately, no such function exists. We have to
+ * instead compare the numbers using the 'less than' calls in order to
+ * make up our mind. This means that we can call 'less than or equal' and
+ * invert the result.
+ */
+int __gtsf2(float32 a, float32 b)
+{
+       return !float32_le(a, b);
+}
+
+/*
+ * 'Greater Than or Equal' wrapper. We emulate this by inverting the result
+ * of a 'less than' call.
+ */
+int __gesf2(float32 a, float32 b)
+{
+       return !float32_lt(a, b);
+}
+
+/*
+ * 'Less Than' wrapper.
+ */
+int __ltsf2(float32 a, float32 b)
+{
+       return float32_lt(a, b);
+}
+
+/*
+ * 'Less Than or Equal' wrapper. A 0 must turn into a 1, and a 1 into a 0.
+ */
+int __lesf2(float32 a, float32 b)
+{
+       return !float32_le(a, b);
+}
+
+/*
+ * Float negate... This isn't provided by the library, but it's hardly the
+ * hardest function in the world to write... :) In fact, because of the
+ * position in the registers of arguments, the double precision version can
+ * go here too ;-)
+ */
+float32 __negsf2(float32 x)
+{
+       return x ^ 0x80000000;
+}
+
+/*
+ * 32-bit operations.
+ */
+float32 __addsf3(float32 a, float32 b)
+{
+       return float32_add(a, b);
+}
+
+float32 __subsf3(float32 a, float32 b)
+{
+       return float32_sub(a, b);
+}
+
+float32 __mulsf3(float32 a, float32 b)
+{
+       return float32_mul(a, b);
+}
+
+float32 __divsf3(float32 a, float32 b)
+{
+       return float32_div(a, b);
+}
+
+float32 __floatsisf(int x)
+{
+       return int32_to_float32(x);
+}
+
+int __fixsfsi(float32 x)
+{
+       return float32_to_int32_round_to_zero(x);
+}
+
+unsigned int __fixunssfsi(float32 x)
+{
+       return float32_to_int32_round_to_zero(x); // XXX
+}
+
diff --git a/software/libbase/softfloat-macros.h b/software/libbase/softfloat-macros.h
new file mode 100644 (file)
index 0000000..40d1182
--- /dev/null
@@ -0,0 +1,646 @@
+
+/*
+===============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Shifts `a' right by the number of bits given in `count'.  If any nonzero
+bits are shifted off, they are ``jammed'' into the least significant bit of
+the result by setting the least significant bit to 1.  The value of `count'
+can be arbitrarily large; in particular, if `count' is greater than 32, the
+result will be either 0 or 1, depending on whether `a' is zero or nonzero.
+The result is stored in the location pointed to by `zPtr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
+{
+    bits32 z;
+
+    if ( count == 0 ) {
+        z = a;
+    }
+    else if ( count < 32 ) {
+        z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
+    }
+    else {
+        z = ( a != 0 );
+    }
+    *zPtr = z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the
+number of bits given in `count'.  Any bits shifted off are lost.  The value
+of `count' can be arbitrarily large; in particular, if `count' is greater
+than 64, the result will be 0.  The result is broken into two 32-bit pieces
+which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift64Right(
+     bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr )
+{
+    bits32 z0, z1;
+    int8 negCount = ( - count ) & 31;
+
+    if ( count == 0 ) {
+        z1 = a1;
+        z0 = a0;
+    }
+    else if ( count < 32 ) {
+        z1 = ( a0<<negCount ) | ( a1>>count );
+        z0 = a0>>count;
+    }
+    else {
+        z1 = ( count < 64 ) ? ( a0>>( count & 31 ) ) : 0;
+        z0 = 0;
+    }
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the
+number of bits given in `count'.  If any nonzero bits are shifted off, they
+are ``jammed'' into the least significant bit of the result by setting the
+least significant bit to 1.  The value of `count' can be arbitrarily large;
+in particular, if `count' is greater than 64, the result will be either 0
+or 1, depending on whether the concatenation of `a0' and `a1' is zero or
+nonzero.  The result is broken into two 32-bit pieces which are stored at
+the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift64RightJamming(
+     bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr )
+{
+    bits32 z0, z1;
+    int8 negCount = ( - count ) & 31;
+
+    if ( count == 0 ) {
+        z1 = a1;
+        z0 = a0;
+    }
+    else if ( count < 32 ) {
+        z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
+        z0 = a0>>count;
+    }
+    else {
+        if ( count == 32 ) {
+            z1 = a0 | ( a1 != 0 );
+        }
+        else if ( count < 64 ) {
+            z1 = ( a0>>( count & 31 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
+        }
+        else {
+            z1 = ( ( a0 | a1 ) != 0 );
+        }
+        z0 = 0;
+    }
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' right
+by 32 _plus_ the number of bits given in `count'.  The shifted result is
+at most 64 nonzero bits; these are broken into two 32-bit pieces which are
+stored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
+off form a third 32-bit result as follows:  The _last_ bit shifted off is
+the most-significant bit of the extra result, and the other 31 bits of the
+extra result are all zero if and only if _all_but_the_last_ bits shifted off
+were all zero.  This extra result is stored in the location pointed to by
+`z2Ptr'.  The value of `count' can be arbitrarily large.
+    (This routine makes more sense if `a0', `a1', and `a2' are considered
+to form a fixed-point value with binary point between `a1' and `a2'.  This
+fixed-point value is shifted right by the number of bits given in `count',
+and the integer part of the result is returned at the locations pointed to
+by `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
+corrupted as described above, and is returned at the location pointed to by
+`z2Ptr'.)
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift64ExtraRightJamming(
+     bits32 a0,
+     bits32 a1,
+     bits32 a2,
+     int16 count,
+     bits32 *z0Ptr,
+     bits32 *z1Ptr,
+     bits32 *z2Ptr
+ )
+{
+    bits32 z0, z1, z2;
+    int8 negCount = ( - count ) & 31;
+
+    if ( count == 0 ) {
+        z2 = a2;
+        z1 = a1;
+        z0 = a0;
+    }
+    else {
+        if ( count < 32 ) {
+            z2 = a1<<negCount;
+            z1 = ( a0<<negCount ) | ( a1>>count );
+            z0 = a0>>count;
+        }
+        else {
+            if ( count == 32 ) {
+                z2 = a1;
+                z1 = a0;
+            }
+            else {
+                a2 |= a1;
+                if ( count < 64 ) {
+                    z2 = a0<<negCount;
+                    z1 = a0>>( count & 31 );
+                }
+                else {
+                    z2 = ( count == 64 ) ? a0 : ( a0 != 0 );
+                    z1 = 0;
+                }
+            }
+            z0 = 0;
+        }
+        z2 |= ( a2 != 0 );
+    }
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 64-bit value formed by concatenating `a0' and `a1' left by the
+number of bits given in `count'.  Any bits shifted off are lost.  The value
+of `count' must be less than 32.  The result is broken into two 32-bit
+pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shortShift64Left(
+     bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr )
+{
+
+    *z1Ptr = a1<<count;
+    *z0Ptr =
+        ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 31 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' left by
+the number of bits given in `count'.  Any bits shifted off are lost.  The
+value of `count' must be less than 32.  The result is broken into three
+32-bit pieces which are stored at the locations pointed to by `z0Ptr',
+`z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shortShift96Left(
+     bits32 a0,
+     bits32 a1,
+     bits32 a2,
+     int16 count,
+     bits32 *z0Ptr,
+     bits32 *z1Ptr,
+     bits32 *z2Ptr
+ )
+{
+    bits32 z0, z1, z2;
+    int8 negCount;
+
+    z2 = a2<<count;
+    z1 = a1<<count;
+    z0 = a0<<count;
+    if ( 0 < count ) {
+        negCount = ( ( - count ) & 31 );
+        z1 |= a2>>negCount;
+        z0 |= a1>>negCount;
+    }
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Adds the 64-bit value formed by concatenating `a0' and `a1' to the 64-bit
+value formed by concatenating `b0' and `b1'.  Addition is modulo 2^64, so
+any carry out is lost.  The result is broken into two 32-bit pieces which
+are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ add64(
+     bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr )
+{
+    bits32 z1;
+
+    z1 = a1 + b1;
+    *z1Ptr = z1;
+    *z0Ptr = a0 + b0 + ( z1 < a1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Adds the 96-bit value formed by concatenating `a0', `a1', and `a2' to the
+96-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
+modulo 2^96, so any carry out is lost.  The result is broken into three
+32-bit pieces which are stored at the locations pointed to by `z0Ptr',
+`z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ add96(
+     bits32 a0,
+     bits32 a1,
+     bits32 a2,
+     bits32 b0,
+     bits32 b1,
+     bits32 b2,
+     bits32 *z0Ptr,
+     bits32 *z1Ptr,
+     bits32 *z2Ptr
+ )
+{
+    bits32 z0, z1, z2;
+    int8 carry0, carry1;
+
+    z2 = a2 + b2;
+    carry1 = ( z2 < a2 );
+    z1 = a1 + b1;
+    carry0 = ( z1 < a1 );
+    z0 = a0 + b0;
+    z1 += carry1;
+    z0 += ( z1 < carry1 );
+    z0 += carry0;
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Subtracts the 64-bit value formed by concatenating `b0' and `b1' from the
+64-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
+2^64, so any borrow out (carry out) is lost.  The result is broken into two
+32-bit pieces which are stored at the locations pointed to by `z0Ptr' and
+`z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ sub64(
+     bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr )
+{
+
+    *z1Ptr = a1 - b1;
+    *z0Ptr = a0 - b0 - ( a1 < b1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Subtracts the 96-bit value formed by concatenating `b0', `b1', and `b2' from
+the 96-bit value formed by concatenating `a0', `a1', and `a2'.  Subtraction
+is modulo 2^96, so any borrow out (carry out) is lost.  The result is broken
+into three 32-bit pieces which are stored at the locations pointed to by
+`z0Ptr', `z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ sub96(
+     bits32 a0,
+     bits32 a1,
+     bits32 a2,
+     bits32 b0,
+     bits32 b1,
+     bits32 b2,
+     bits32 *z0Ptr,
+     bits32 *z1Ptr,
+     bits32 *z2Ptr
+ )
+{
+    bits32 z0, z1, z2;
+    int8 borrow0, borrow1;
+
+    z2 = a2 - b2;
+    borrow1 = ( a2 < b2 );
+    z1 = a1 - b1;
+    borrow0 = ( a1 < b1 );
+    z0 = a0 - b0;
+    z0 -= ( z1 < borrow1 );
+    z1 -= borrow1;
+    z0 -= borrow0;
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies `a' by `b' to obtain a 64-bit product.  The product is broken
+into two 32-bit pieces which are stored at the locations pointed to by
+`z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void mul32To64( bits32 a, bits32 b, bits32 *z0Ptr, bits32 *z1Ptr )
+{
+    bits16 aHigh, aLow, bHigh, bLow;
+    bits32 z0, zMiddleA, zMiddleB, z1;
+
+    aLow = a;
+    aHigh = a>>16;
+    bLow = b;
+    bHigh = b>>16;
+    z1 = ( (bits32) aLow ) * bLow;
+    zMiddleA = ( (bits32) aLow ) * bHigh;
+    zMiddleB = ( (bits32) aHigh ) * bLow;
+    z0 = ( (bits32) aHigh ) * bHigh;
+    zMiddleA += zMiddleB;
+    z0 += ( ( (bits32) ( zMiddleA < zMiddleB ) )<<16 ) + ( zMiddleA>>16 );
+    zMiddleA <<= 16;
+    z1 += zMiddleA;
+    z0 += ( z1 < zMiddleA );
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies the 64-bit value formed by concatenating `a0' and `a1' by `b' to
+obtain a 96-bit product.  The product is broken into three 32-bit pieces
+which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
+`z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ mul64By32To96(
+     bits32 a0,
+     bits32 a1,
+     bits32 b,
+     bits32 *z0Ptr,
+     bits32 *z1Ptr,
+     bits32 *z2Ptr
+ )
+{
+    bits32 z0, z1, z2, more1;
+
+    mul32To64( a1, b, &z1, &z2 );
+    mul32To64( a0, b, &z0, &more1 );
+    add64( z0, more1, 0, z1, &z0, &z1 );
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies the 64-bit value formed by concatenating `a0' and `a1' to the
+64-bit value formed by concatenating `b0' and `b1' to obtain a 128-bit
+product.  The product is broken into four 32-bit pieces which are stored at
+the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ mul64To128(
+     bits32 a0,
+     bits32 a1,
+     bits32 b0,
+     bits32 b1,
+     bits32 *z0Ptr,
+     bits32 *z1Ptr,
+     bits32 *z2Ptr,
+     bits32 *z3Ptr
+ )
+{
+    bits32 z0, z1, z2, z3;
+    bits32 more1, more2;
+
+    mul32To64( a1, b1, &z2, &z3 );
+    mul32To64( a1, b0, &z1, &more2 );
+    add64( z1, more2, 0, z2, &z1, &z2 );
+    mul32To64( a0, b0, &z0, &more1 );
+    add64( z0, more1, 0, z1, &z0, &z1 );
+    mul32To64( a0, b1, &more1, &more2 );
+    add64( more1, more2, 0, z2, &more1, &z2 );
+    add64( z0, z1, 0, more1, &z0, &z1 );
+    *z3Ptr = z3;
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns an approximation to the 32-bit integer quotient obtained by dividing
+`b' into the 64-bit value formed by concatenating `a0' and `a1'.  The divisor
+`b' must be at least 2^31.  If q is the exact quotient truncated toward
+zero, the approximation returned lies between q and q + 2 inclusive.  If
+the exact quotient q is larger than 32 bits, the maximum positive 32-bit
+unsigned integer is returned.
+-------------------------------------------------------------------------------
+*/
+static bits32 estimateDiv64To32( bits32 a0, bits32 a1, bits32 b )
+{
+    bits32 b0, b1;
+    bits32 rem0, rem1, term0, term1;
+    bits32 z;
+
+    if ( b <= a0 ) return 0xFFFFFFFF;
+    b0 = b>>16;
+    z = ( b0<<16 <= a0 ) ? 0xFFFF0000 : ( a0 / b0 )<<16;
+    mul32To64( b, z, &term0, &term1 );
+    sub64( a0, a1, term0, term1, &rem0, &rem1 );
+    while ( ( (sbits32) rem0 ) < 0 ) {
+        z -= 0x10000;
+        b1 = b<<16;
+        add64( rem0, rem1, b0, b1, &rem0, &rem1 );
+    }
+    rem0 = ( rem0<<16 ) | ( rem1>>16 );
+    z |= ( b0<<16 <= rem0 ) ? 0xFFFF : rem0 / b0;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns an approximation to the square root of the 32-bit significand given
+by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
+`aExp' (the least significant bit) is 1, the integer returned approximates
+2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
+is 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
+case, the approximation returned lies strictly within +/-2 of the exact
+value.
+-------------------------------------------------------------------------------
+*/
+static bits32 estimateSqrt32( int16 aExp, bits32 a )
+{
+    static const bits16 sqrtOddAdjustments[] = {
+        0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
+        0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
+    };
+    static const bits16 sqrtEvenAdjustments[] = {
+        0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
+        0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
+    };
+    int8 index;
+    bits32 z;
+
+    index = ( a>>27 ) & 15;
+    if ( aExp & 1 ) {
+        z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
+        z = ( ( a / z )<<14 ) + ( z<<15 );
+        a >>= 1;
+    }
+    else {
+        z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
+        z = a / z + z;
+        z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
+        if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
+    }
+    return ( ( estimateDiv64To32( a, 0, z ) )>>1 ) + ( z>>1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the number of leading 0 bits before the most-significant 1 bit
+of `a'.  If `a' is zero, 32 is returned.
+-------------------------------------------------------------------------------
+*/
+static int8 countLeadingZeros32( bits32 a )
+{
+    static const int8 countLeadingZerosHigh[] = {
+        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+    int8 shiftCount;
+
+    shiftCount = 0;
+    if ( a < 0x10000 ) {
+        shiftCount += 16;
+        a <<= 16;
+    }
+    if ( a < 0x1000000 ) {
+        shiftCount += 8;
+        a <<= 8;
+    }
+    shiftCount += countLeadingZerosHigh[ a>>24 ];
+    return shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is equal
+to the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,
+returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag eq64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
+{
+
+    return ( a0 == b0 ) && ( a1 == b1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less
+than or equal to the 64-bit value formed by concatenating `b0' and `b1'.
+Otherwise, returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag le64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
+{
+
+    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less
+than the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,
+returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag lt64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
+{
+
+    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is not
+equal to the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,
+returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag ne64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 )
+{
+
+    return ( a0 != b0 ) || ( a1 != b1 );
+
+}
+
diff --git a/software/libbase/softfloat-specialize.h b/software/libbase/softfloat-specialize.h
new file mode 100644 (file)
index 0000000..9f3466f
--- /dev/null
@@ -0,0 +1,125 @@
+
+/*
+===============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Underflow tininess-detection mode, statically initialized to default value.
+(The declaration in `softfloat.h' must match the `int8' type here.)
+-------------------------------------------------------------------------------
+*/
+int8 float_detect_tininess = float_tininess_after_rounding;
+
+/*
+-------------------------------------------------------------------------------
+Raises the exceptions specified by `flags'.  Floating-point traps can be
+defined here if desired.  It is currently not possible for such a trap to
+substitute a result value.  If traps are not implemented, this routine
+should be simply `float_exception_flags |= flags;'.
+-------------------------------------------------------------------------------
+*/
+void float_raise( int8 flags )
+{
+
+    float_exception_flags |= flags;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Internal canonical NaN format.
+-------------------------------------------------------------------------------
+*/
+typedef struct {
+    flag sign;
+    bits32 high, low;
+} commonNaNT;
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated single-precision NaN.
+-------------------------------------------------------------------------------
+*/
+enum {
+    float32_default_nan = 0xFFFFFFFF
+};
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is a NaN;
+otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float32_is_nan( float32 a )
+{
+
+    return ( 0xFF000000 < (bits32) ( a<<1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is a signaling
+NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float32_is_signaling_nan( float32 a )
+{
+
+    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two single-precision floating-point values `a' and `b', one of which
+is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
+signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static float32 propagateFloat32NaN( float32 a, float32 b )
+{
+    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+    aIsNaN = float32_is_nan( a );
+    aIsSignalingNaN = float32_is_signaling_nan( a );
+    bIsNaN = float32_is_nan( b );
+    bIsSignalingNaN = float32_is_signaling_nan( b );
+    a |= 0x00400000;
+    b |= 0x00400000;
+    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+    if ( aIsNaN ) {
+        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+    }
+    else {
+        return b;
+    }
+
+}
diff --git a/software/libbase/softfloat.c b/software/libbase/softfloat.c
new file mode 100644 (file)
index 0000000..b41c497
--- /dev/null
@@ -0,0 +1,1031 @@
+
+/*
+===============================================================================
+
+This C source file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "softfloat.h"
+
+/*
+-------------------------------------------------------------------------------
+Floating-point rounding mode and exception flags.
+-------------------------------------------------------------------------------
+*/
+int8 float_rounding_mode = float_round_nearest_even;
+int8 float_exception_flags = 0;
+
+/*
+-------------------------------------------------------------------------------
+Primitive arithmetic functions, including multi-word arithmetic, and
+division and square root approximations.  (Can be specialized to target if
+desired.)
+-------------------------------------------------------------------------------
+*/
+#include "softfloat-macros.h"
+
+/*
+-------------------------------------------------------------------------------
+Functions and definitions to determine:  (1) whether tininess for underflow
+is detected before or after rounding by default, (2) what (if anything)
+happens when exceptions are raised, (3) how signaling NaNs are distinguished
+from quiet NaNs, (4) the default generated quiet NaNs, and (4) how NaNs
+are propagated from function inputs to output.  These details are target-
+specific.
+-------------------------------------------------------------------------------
+*/
+#include "softfloat-specialize.h"
+
+/*
+-------------------------------------------------------------------------------
+Returns the fraction bits of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits32 extractFloat32Frac( float32 a )
+{
+
+    return a & 0x007FFFFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int16 extractFloat32Exp( float32 a )
+{
+
+    return ( a>>23 ) & 0xFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE flag extractFloat32Sign( float32 a )
+{
+
+    return a>>31;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal single-precision floating-point value represented
+by the denormalized significand `aSig'.  The normalized exponent and
+significand are stored at the locations pointed to by `zExpPtr' and
+`zSigPtr', respectively.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
+{
+    int8 shiftCount;
+
+    shiftCount = countLeadingZeros32( aSig ) - 8;
+    *zSigPtr = aSig<<shiftCount;
+    *zExpPtr = 1 - shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+single-precision floating-point value, returning the result.  After being
+shifted into the proper positions, the three fields are simply added
+together to form the result.  This means that any integer portion of `zSig'
+will be added into the exponent.  Since a properly normalized significand
+will have an integer portion equal to 1, the `zExp' input should be 1 less
+than the desired result exponent whenever `zSig' is a complete, normalized
+significand.
+-------------------------------------------------------------------------------
+*/
+INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
+{
+
+    return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper single-precision floating-
+point value corresponding to the abstract input.  Ordinarily, the abstract
+value is simply rounded and packed into the single-precision format, with
+the inexact exception raised if the abstract input cannot be represented
+exactly.  If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned.  If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal single-
+precision floating-point number.
+    The input significand `zSig' has its binary point between bits 30
+and 29, which is 7 bits to the left of the usual location.  This shifted
+significand must be normalized or smaller.  If `zSig' is not normalized,
+`zExp' must be 0; in that case, the result returned is a subnormal number,
+and it must not require rounding.  In the usual case that `zSig' is
+normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+The handling of underflow and overflow follows the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+{
+    int8 roundingMode;
+    flag roundNearestEven;
+    int8 roundIncrement, roundBits;
+    flag isTiny;
+
+    roundingMode = float_rounding_mode;
+    roundNearestEven = roundingMode == float_round_nearest_even;
+    roundIncrement = 0x40;
+    if ( ! roundNearestEven ) {
+        if ( roundingMode == float_round_to_zero ) {
+            roundIncrement = 0;
+        }
+        else {
+            roundIncrement = 0x7F;
+            if ( zSign ) {
+                if ( roundingMode == float_round_up ) roundIncrement = 0;
+            }
+            else {
+                if ( roundingMode == float_round_down ) roundIncrement = 0;
+            }
+        }
+    }
+    roundBits = zSig & 0x7F;
+    if ( 0xFD <= (bits16) zExp ) {
+        if (    ( 0xFD < zExp )
+             || (    ( zExp == 0xFD )
+                  && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
+           ) {
+            float_raise( float_flag_overflow | float_flag_inexact );
+            return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
+        }
+        if ( zExp < 0 ) {
+            isTiny =
+                   ( float_detect_tininess == float_tininess_before_rounding )
+                || ( zExp < -1 )
+                || ( zSig + roundIncrement < 0x80000000 );
+            shift32RightJamming( zSig, - zExp, &zSig );
+            zExp = 0;
+            roundBits = zSig & 0x7F;
+            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+        }
+    }
+    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    zSig = ( zSig + roundIncrement )>>7;
+    zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
+    if ( zSig == 0 ) zExp = 0;
+    return packFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper single-precision floating-
+point value corresponding to the abstract input.  This routine is just like
+`roundAndPackFloat32' except that `zSig' does not have to be normalized in
+any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
+point exponent.
+-------------------------------------------------------------------------------
+*/
+static float32
+ normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+{
+    int8 shiftCount;
+
+    shiftCount = countLeadingZeros32( zSig ) - 1;
+    return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a' to
+the single-precision floating-point format.  The conversion is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 int32_to_float32( int32 a )
+{
+    flag zSign;
+
+    if ( a == 0 ) return 0;
+    if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
+    zSign = ( a < 0 );
+    return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the 32-bit two's complement integer format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode.  If `a' is a NaN, the largest
+positive integer is returned.  Otherwise, if the conversion overflows, the
+largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float32_to_int32( float32 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits32 aSig, zExtra;
+    int32 z;
+    int8 roundingMode;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    shiftCount = aExp - 0x96;
+    if ( 0 <= shiftCount ) {
+        if ( 0x9E <= aExp ) {
+            if ( a == 0xCF000000 ) return 0x80000000;
+            float_raise( float_flag_invalid );
+            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
+            return 0x80000000;
+        }
+        z = ( aSig | 0x00800000 )<<shiftCount;
+        if ( aSign ) z = - z;
+    }
+    else {
+        if ( aExp < 0x7E ) {
+            zExtra = aExp | aSig;
+            z = 0;
+        }
+        else {
+            aSig |= 0x00800000;
+            zExtra = aSig<<( shiftCount & 31 );
+            z = aSig>>( - shiftCount );
+        }
+        if ( zExtra ) float_exception_flags |= float_flag_inexact;
+        roundingMode = float_rounding_mode;
+        if ( roundingMode == float_round_nearest_even ) {
+            if ( (sbits32) zExtra < 0 ) {
+                ++z;
+                if ( (bits32) ( zExtra<<1 ) == 0 ) z &= ~1;
+            }
+            if ( aSign ) z = - z;
+        }
+        else {
+            zExtra = ( zExtra != 0 );
+            if ( aSign ) {
+                z += ( roundingMode == float_round_down ) & zExtra;
+                z = - z;
+            }
+            else {
+                z += ( roundingMode == float_round_up ) & zExtra;
+            }
+        }
+    }
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the 32-bit two's complement integer format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero.  If
+`a' is a NaN, the largest positive integer is returned.  Otherwise, if the
+conversion overflows, the largest integer with the same sign as `a' is
+returned.
+-------------------------------------------------------------------------------
+*/
+int32 float32_to_int32_round_to_zero( float32 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits32 aSig;
+    int32 z;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    shiftCount = aExp - 0x9E;
+    if ( 0 <= shiftCount ) {
+        if ( a == 0xCF000000 ) return 0x80000000;
+        float_raise( float_flag_invalid );
+        if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
+        return 0x80000000;
+    }
+    else if ( aExp <= 0x7E ) {
+        if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
+        return 0;
+    }
+    aSig = ( aSig | 0x00800000 )<<8;
+    z = aSig>>( - shiftCount );
+    if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
+        float_exception_flags |= float_flag_inexact;
+    }
+    return aSign ? - z : z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Rounds the single-precision floating-point value `a' to an integer, and
+returns the result as a single-precision floating-point value.  The
+operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_round_to_int( float32 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits32 lastBitMask, roundBitsMask;
+    int8 roundingMode;
+    float32 z;
+
+    aExp = extractFloat32Exp( a );
+    if ( 0x96 <= aExp ) {
+        if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
+            return propagateFloat32NaN( a, a );
+        }
+        return a;
+    }
+    if ( aExp <= 0x7E ) {
+        if ( (bits32) ( a<<1 ) == 0 ) return a;
+        float_exception_flags |= float_flag_inexact;
+        aSign = extractFloat32Sign( a );
+        switch ( float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
+                return packFloat32( aSign, 0x7F, 0 );
+            }
+            break;
+         case float_round_down:
+            return aSign ? 0xBF800000 : 0;
+         case float_round_up:
+            return aSign ? 0x80000000 : 0x3F800000;
+        }
+        return packFloat32( aSign, 0, 0 );
+    }
+    lastBitMask = 1;
+    lastBitMask <<= 0x96 - aExp;
+    roundBitsMask = lastBitMask - 1;
+    z = a;
+    roundingMode = float_rounding_mode;
+    if ( roundingMode == float_round_nearest_even ) {
+        z += lastBitMask>>1;
+        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
+    }
+    else if ( roundingMode != float_round_to_zero ) {
+        if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+            z += roundBitsMask;
+        }
+    }
+    z &= ~ roundBitsMask;
+    if ( z != a ) float_exception_flags |= float_flag_inexact;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the single-precision
+floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
+before being returned.  `zSign' is ignored if the result is a NaN.  The
+addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
+{
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig, zSig;
+    int16 expDiff;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    expDiff = aExp - bExp;
+    aSig <<= 6;
+    bSig <<= 6;
+    if ( 0 < expDiff ) {
+        if ( aExp == 0xFF ) {
+            if ( aSig ) return propagateFloat32NaN( a, b );
+            return a;
+        }
+        if ( bExp == 0 ) {
+            --expDiff;
+        }
+        else {
+            bSig |= 0x20000000;
+        }
+        shift32RightJamming( bSig, expDiff, &bSig );
+        zExp = aExp;
+    }
+    else if ( expDiff < 0 ) {
+        if ( bExp == 0xFF ) {
+            if ( bSig ) return propagateFloat32NaN( a, b );
+            return packFloat32( zSign, 0xFF, 0 );
+        }
+        if ( aExp == 0 ) {
+            ++expDiff;
+        }
+        else {
+            aSig |= 0x20000000;
+        }
+        shift32RightJamming( aSig, - expDiff, &aSig );
+        zExp = bExp;
+    }
+    else {
+        if ( aExp == 0xFF ) {
+            if ( aSig | bSig ) return propagateFloat32NaN( a, b );
+            return a;
+        }
+        if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
+        zSig = 0x40000000 + aSig + bSig;
+        zExp = aExp;
+        goto roundAndPack;
+    }
+    aSig |= 0x20000000;
+    zSig = ( aSig + bSig )<<1;
+    --zExp;
+    if ( (sbits32) zSig < 0 ) {
+        zSig = aSig + bSig;
+        ++zExp;
+    }
+ roundAndPack:
+    return roundAndPackFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the single-
+precision floating-point values `a' and `b'.  If `zSign' is true, the
+difference is negated before being returned.  `zSign' is ignored if the
+result is a NaN.  The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
+{
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig, zSig;
+    int16 expDiff;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    expDiff = aExp - bExp;
+    aSig <<= 7;
+    bSig <<= 7;
+    if ( 0 < expDiff ) goto aExpBigger;
+    if ( expDiff < 0 ) goto bExpBigger;
+    if ( aExp == 0xFF ) {
+        if ( aSig | bSig ) return propagateFloat32NaN( a, b );
+        float_raise( float_flag_invalid );
+        return float32_default_nan;
+    }
+    if ( aExp == 0 ) {
+        aExp = 1;
+        bExp = 1;
+    }
+    if ( bSig < aSig ) goto aBigger;
+    if ( aSig < bSig ) goto bBigger;
+    return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
+ bExpBigger:
+    if ( bExp == 0xFF ) {
+        if ( bSig ) return propagateFloat32NaN( a, b );
+        return packFloat32( zSign ^ 1, 0xFF, 0 );
+    }
+    if ( aExp == 0 ) {
+        ++expDiff;
+    }
+    else {
+        aSig |= 0x40000000;
+    }
+    shift32RightJamming( aSig, - expDiff, &aSig );
+    bSig |= 0x40000000;
+ bBigger:
+    zSig = bSig - aSig;
+    zExp = bExp;
+    zSign ^= 1;
+    goto normalizeRoundAndPack;
+ aExpBigger:
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return propagateFloat32NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        --expDiff;
+    }
+    else {
+        bSig |= 0x40000000;
+    }
+    shift32RightJamming( bSig, expDiff, &bSig );
+    aSig |= 0x40000000;
+ aBigger:
+    zSig = aSig - bSig;
+    zExp = aExp;
+ normalizeRoundAndPack:
+    --zExp;
+    return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the single-precision floating-point values `a'
+and `b'.  The operation is performed according to the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_add( float32 a, float32 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign == bSign ) {
+        return addFloat32Sigs( a, b, aSign );
+    }
+    else {
+        return subFloat32Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the single-precision floating-point values
+`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_sub( float32 a, float32 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign == bSign ) {
+        return subFloat32Sigs( a, b, aSign );
+    }
+    else {
+        return addFloat32Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the single-precision floating-point values
+`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_mul( float32 a, float32 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig, zSig0, zSig1;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    bSign = extractFloat32Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0xFF ) {
+        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
+            return propagateFloat32NaN( a, b );
+        }
+        if ( ( bExp | bSig ) == 0 ) {
+            float_raise( float_flag_invalid );
+            return float32_default_nan;
+        }
+        return packFloat32( zSign, 0xFF, 0 );
+    }
+    if ( bExp == 0xFF ) {
+        if ( bSig ) return propagateFloat32NaN( a, b );
+        if ( ( aExp | aSig ) == 0 ) {
+            float_raise( float_flag_invalid );
+            return float32_default_nan;
+        }
+        return packFloat32( zSign, 0xFF, 0 );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
+        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
+    }
+    zExp = aExp + bExp - 0x7F;
+    aSig = ( aSig | 0x00800000 )<<7;
+    bSig = ( bSig | 0x00800000 )<<8;
+    mul32To64( aSig, bSig, &zSig0, &zSig1 );
+    zSig0 |= ( zSig1 != 0 );
+    if ( 0 <= (sbits32) ( zSig0<<1 ) ) {
+        zSig0 <<= 1;
+        --zExp;
+    }
+    return roundAndPackFloat32( zSign, zExp, zSig0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the single-precision floating-point value `a'
+by the corresponding value `b'.  The operation is performed according to
+the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_div( float32 a, float32 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig, zSig;
+    bits32 rem0, rem1;
+    bits32 term0, term1;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    bSign = extractFloat32Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return propagateFloat32NaN( a, b );
+        if ( bExp == 0xFF ) {
+            if ( bSig ) return propagateFloat32NaN( a, b );
+            float_raise( float_flag_invalid );
+            return float32_default_nan;
+        }
+        return packFloat32( zSign, 0xFF, 0 );
+  &nb