Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Copy some software code from the original Milkymist SoC.

Libbase should keep its RAM usage to a minimum as it is meant to
be executed before the SDRAM is up and running. (Having lots of
code is OK though as we XIP from the flash)
  • Loading branch information...
commit 1a4a6eb445a51eb8953ba5285ca07be9d70b7572 1 parent b5cb108
@sbourdeauducq sbourdeauducq authored
Showing with 5,360 additions and 0 deletions.
  1. +45 −0 software/include.mak
  2. +24 −0 software/include/base/assert.h
  3. +35 −0 software/include/base/board.h
  4. +34 −0 software/include/base/console.h
  5. +68 −0 software/include/base/ctype.h
  6. +39 −0 software/include/base/endian.h
  7. +62 −0 software/include/base/irq.h
  8. +25 −0 software/include/base/limits.h
  9. +43 −0 software/include/base/stdarg.h
  10. +29 −0 software/include/base/stdio.h
  11. +55 −0 software/include/base/stdlib.h
  12. +39 −0 software/include/base/string.h
  13. +26 −0 software/include/base/system.h
  14. +29 −0 software/include/base/uart.h
  15. +6 −0 software/include/base/version.h
  16. +31 −0 software/include/extra/blockdev.h
  17. +24 −0 software/include/extra/crc.h
  18. +28 −0 software/include/extra/fatfs.h
  19. +34 −0 software/include/hw/capabilities.h
  20. +27 −0 software/include/hw/common.h
  21. +34 −0 software/include/hw/flash.h
  22. +35 −0 software/include/hw/gpio.h
  23. +23 −0 software/include/hw/interrupts.h
  24. +55 −0 software/include/hw/sysctl.h
  25. +39 −0 software/include/hw/uart.h
  26. +15 −0 software/libbase/Makefile
  27. +84 −0 software/libbase/atof.c
  28. +87 −0 software/libbase/board.c
  29. +108 −0 software/libbase/console.c
  30. +53 −0 software/libbase/divsi3.c
  31. +577 −0 software/libbase/libc.c
  32. +126 −0 software/libbase/milieu.h
  33. +125 −0 software/libbase/softfloat-glue.c
  34. +646 −0 software/libbase/softfloat-macros.h
  35. +125 −0 software/libbase/softfloat-specialize.h
  36. +1,030 −0 software/libbase/softfloat.c
  37. +119 −0 software/libbase/softfloat.h
  38. +82 −0 software/libbase/system.c
  39. +125 −0 software/libbase/uart.c
  40. +328 −0 software/libbase/vsnprintf.c
  41. +273 −0 software/libextra/blockdev.c
  42. +47 −0 software/libextra/crc16.c
  43. +81 −0 software/libextra/crc32.c
  44. +440 −0 software/libextra/fatfs.c
View
45 software/include.mak
@@ -0,0 +1,45 @@
+# Mico32 toolchain
+#
+CROSS_COMPILER=lm32-rtems4.11-
+
+CC_normal := $(CROSS_COMPILER)gcc
+AR_normal := $(CROSS_COMPILER)ar
+AS_normal := $(CROSS_COMPILER)as
+LD_normal := $(CROSS_COMPILER)ld
+OBJCOPY_normal := $(CROSS_COMPILER)objcopy
+RANLIB_normal := $(CROSS_COMPILER)ranlib
+
+CC_quiet = @echo " CC " $@ && $(CROSS_COMPILER)gcc
+AR_quiet = @echo " AR " $@ && $(CROSS_COMPILER)ar
+AS_quiet = @echo " AS " $@ && $(CROSS_COMPILER)as
+LD_quiet = @echo " LD " $@ && $(CROSS_COMPILER)ld
+OBJCOPY_quiet = @echo " OBJCOPY " $@ && $(CROSS_COMPILER)objcopy
+RANLIB_quiet = @echo " RANLIB " $@ && $(CROSS_COMPILER)ranlib
+
+ifeq ($(V),1)
+ CC = $(CC_normal)
+ AR = $(AR_normal)
+ AS = $(AS_normal)
+ LD = $(LD_normal)
+ OBJCOPY = $(OBJCOPY_normal)
+ RANLIB = $(RANLIB_normal)
+else
+ CC = $(CC_quiet)
+ AR = $(AR_quiet)
+ AS = $(AS_quiet)
+ LD = $(LD_quiet)
+ OBJCOPY = $(OBJCOPY_quiet)
+ RANLIB = $(RANLIB_quiet)
+endif
+
+# Toolchain options
+#
+INCLUDES_NOLIBC ?= -nostdinc -I$(MMDIR)/software/include/base
+INCLUDES = $(INCLUDES_NOLIBC) -I$(MMDIR)/software/include -I$(MMDIR)/tools
+ASFLAGS = $(INCLUDES) -nostdinc
+# later: -Wmissing-prototypes
+CFLAGS = -O9 -Wall -Wstrict-prototypes -Wold-style-definition -Wshadow \
+ -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled \
+ -msign-extend-enabled -fno-builtin -fsigned-char \
+ -fsingle-precision-constant $(INCLUDES)
+LDFLAGS = -nostdlib -nodefaultlibs
View
24 software/include/base/assert.h
@@ -0,0 +1,24 @@
+/*
+ * Milkymist 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/>.
+ */
+
+#ifndef __ASSERT_H
+#define __ASSERT_H
+
+#define assert(x)
+
+#endif /* __ASSERT_H */
View
35 software/include/base/board.h
@@ -0,0 +1,35 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011 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 __BOARD_H
+#define __BOARD_H
+
+#define BOARD_NAME_LEN 32
+
+struct board_desc {
+ unsigned short int id;
+ char name[BOARD_NAME_LEN];
+ unsigned int ethernet_phyadr;
+};
+
+const struct board_desc *get_board_desc_id(unsigned short int id);
+const struct board_desc *get_board_desc(void);
+int get_pcb_revision(void);
+void get_soc_version(unsigned int *major, unsigned int *minor, unsigned int *subminor, unsigned int *rc);
+void get_soc_version_formatted(char *version);
+
+#endif /* __BOARD_H */
View
34 software/include/base/console.h
@@ -0,0 +1,34 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __CONSOLE_H
+#define __CONSOLE_H
+
+typedef void (*console_write_hook)(char);
+typedef char (*console_read_hook)(void);
+typedef int (*console_read_nonblock_hook)(void);
+
+void console_set_write_hook(console_write_hook h);
+void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn);
+
+char readchar(void);
+int readchar_nonblock(void);
+
+int puts(const char *s);
+void putsnonl(const char *s);
+
+#endif /* __CONSOLE_H */
View
68 software/include/base/ctype.h
@@ -0,0 +1,68 @@
+/*
+ * Milkymist 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 __CTYPE_H
+#define __CTYPE_H
+
+static inline int isdigit(char c)
+{
+ return (c >= '0') && (c <= '9');
+}
+
+static inline int isxdigit(char c)
+{
+ return isdigit(c) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'));
+}
+
+static inline int isupper(char c)
+{
+ return (c >= 'A') && (c <= 'Z');
+}
+
+static inline int islower(char c)
+{
+ return (c >= 'a') && (c <= 'z');
+}
+
+static inline unsigned char tolower(unsigned char c)
+{
+ if (isupper(c))
+ c -= 'A'-'a';
+ return c;
+}
+
+static inline unsigned char toupper(unsigned char c)
+{
+ if (islower(c))
+ c -= 'a'-'A';
+ return c;
+}
+
+static inline char isspace(unsigned char c)
+{
+ if(c == ' '
+ || c == '\f'
+ || c == '\n'
+ || c == '\r'
+ || c == '\t'
+ || c == '\v')
+ return 1;
+
+ return 0;
+}
+
+#endif /* __CTYPE_H */
View
39 software/include/base/endian.h
@@ -0,0 +1,39 @@
+/*
+ * Milkymist 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 __ENDIAN_H
+#define __ENDIAN_H
+
+#define __LITTLE_ENDIAN 0
+#define __BIG_ENDIAN 1
+#define __BYTE_ORDER __BIG_ENDIAN
+
+static inline unsigned int le32toh(unsigned int val)
+{
+ return (val & 0xff) << 24 |
+ (val & 0xff00) << 8 |
+ (val & 0xff0000) >> 8 |
+ (val & 0xff000000) >> 24;
+}
+
+static inline unsigned short le16toh(unsigned short val)
+{
+ return (val & 0xff) << 8 |
+ (val & 0xff00) >> 8;
+}
+
+#endif /* __ENDIAN_H */
View
62 software/include/base/irq.h
@@ -0,0 +1,62 @@
+/*
+ * Milkymist 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 __IRQ_H
+#define __IRQ_H
+
+static inline void irq_enable(unsigned int en)
+{
+ __asm__ __volatile__("wcsr IE, %0" : : "r" (en));
+}
+
+static inline unsigned int irq_getmask(void)
+{
+ unsigned int mask;
+ __asm__ __volatile__("rcsr %0, IM" : "=r" (mask));
+ return mask;
+}
+
+static inline void irq_setmask(unsigned int mask)
+{
+ __asm__ __volatile__("wcsr IM, %0" : : "r" (mask));
+}
+
+static inline unsigned int irq_pending(void)
+{
+ unsigned int pending;
+ __asm__ __volatile__("rcsr %0, IP" : "=r" (pending));
+ return pending;
+}
+
+static inline void irq_ack(unsigned int mask)
+{
+ __asm__ __volatile__("wcsr IP, %0" : : "r" (mask));
+}
+
+static inline unsigned int irq_getie(void)
+{
+ unsigned int ie;
+ __asm__ __volatile__("rcsr %0, IE" : "=r" (ie));
+ return ie;
+}
+
+static inline void irq_setie(unsigned int ie)
+{
+ __asm__ __volatile__("wcsr IE, %0" : : "r" (ie));
+}
+
+#endif /* __IRQ_H */
View
25 software/include/base/limits.h
@@ -0,0 +1,25 @@
+/*
+ * Milkymist 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/>.
+ */
+
+#ifndef __LIMITS_H
+#define __LIMITS_H
+
+#define INT_MIN ((((unsigned long)-1) >> 1) + 1)
+#define INT_MAX (((unsigned long)-1) >> 1)
+
+#endif /* __LIMITS_H */
View
43 software/include/base/stdarg.h
@@ -0,0 +1,43 @@
+/*
+ * Milkymist 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/>.
+ */
+
+#ifndef __STDARG_H
+#define __STDARG_H
+
+#include <stdlib.h>
+
+#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4))
+#define va_start(v,l) __builtin_va_start((v),l)
+#else
+#define va_start(v,l) __builtin_stdarg_start((v),l)
+#endif
+
+#define va_arg(ap, type) \
+ __builtin_va_arg((ap), type)
+
+#define va_end(ap) \
+ __builtin_va_end(ap)
+
+#define va_list \
+ __builtin_va_list
+
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
+int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
+int vsprintf(char *buf, const char *fmt, va_list args);
+
+#endif /* __STDARG_H */
View
29 software/include/base/stdio.h
@@ -0,0 +1,29 @@
+/*
+ * Milkymist 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 __STDIO_H
+#define __STDIO_H
+
+#include <stdlib.h>
+
+int snprintf(char *buf, size_t size, const char *fmt, ...);
+int scnprintf(char *buf, size_t size, const char *fmt, ...);
+int sprintf(char *buf, const char *fmt, ...);
+
+int printf(const char *fmt, ...);
+
+#endif /* __STDIO_H */
View
55 software/include/base/stdlib.h
@@ -0,0 +1,55 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2011 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/>.
+ */
+
+#ifndef __STDLIB_H
+#define __STDLIB_H
+
+#define PRINTF_ZEROPAD 1 /* pad with zero */
+#define PRINTF_SIGN 2 /* unsigned/signed long */
+#define PRINTF_PLUS 4 /* show plus */
+#define PRINTF_SPACE 8 /* space if plus */
+#define PRINTF_LEFT 16 /* left justified */
+#define PRINTF_SPECIAL 32 /* 0x */
+#define PRINTF_LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
+
+typedef int size_t;
+typedef int ptrdiff_t;
+
+#define NULL ((void *)0)
+
+#define likely(x) x
+#define unlikely(x) x
+
+#define abs(x) ((x) > 0 ? (x) : -(x))
+
+unsigned long strtoul(const char *nptr, char **endptr, int base);
+int skip_atoi(const char **s);
+static inline int atoi(const char *nptr) {
+ return strtoul(nptr, NULL, 0);
+}
+static inline long atol(const char *nptr) {
+ return (long)atoi(nptr);
+}
+char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type);
+long strtol(const char *nptr, char **endptr, int base);
+float atof(const char *s);
+
+unsigned int rand(void);
+void abort(void);
+
+#endif /* __STDLIB_H */
View
39 software/include/base/string.h
@@ -0,0 +1,39 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
+ * Copyright (C) Linus Torvalds and 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/>.
+ */
+
+#ifndef __STRING_H
+#define __STRING_H
+
+#include <stdlib.h>
+
+char *strchr(const char *s, int c);
+char *strrchr(const char *s, int c);
+char *strnchr(const char *s, size_t count, int c);
+char *strcpy(char *dest, const char *src);
+char *strncpy(char *dest, const char *src, size_t count);
+int strcmp(const char *cs, const char *ct);
+int strncmp(const char *cs, const char *ct, size_t count);
+size_t strlen(const char *s);
+size_t strnlen(const char *s, size_t count);
+int memcmp(const void *cs, const void *ct, size_t count);
+void *memset(void *s, int c, size_t count);
+void *memcpy(void *to, const void *from, size_t n);
+void *memmove(void *dest, const void *src, size_t count);
+char *strstr(const char *s1, const char *s2);
+
+#endif /* __STRING_H */
View
26 software/include/base/system.h
@@ -0,0 +1,26 @@
+/*
+ * Milkymist 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 __SYSTEM_H
+#define __SYSTEM_H
+
+void flush_cpu_icache(void);
+void flush_cpu_dcache(void);
+__attribute__((noreturn)) void reboot(void);
+__attribute__((noreturn)) void reconf(void);
+
+#endif /* __SYSTEM_H */
View
29 software/include/base/uart.h
@@ -0,0 +1,29 @@
+/*
+ * Milkymist 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 __UART_H
+#define __UART_H
+
+void uart_init(void);
+void uart_isr(void);
+void uart_sync(void);
+
+void uart_write(char c);
+char uart_read(void);
+int uart_read_nonblock(void);
+
+#endif
View
6 software/include/base/version.h
@@ -0,0 +1,6 @@
+#ifndef __VERSION_H
+#define __VERSION_H
+
+#define VERSION "2.0-X"
+
+#endif /* __VERSION_H */
View
31 software/include/extra/blockdev.h
@@ -0,0 +1,31 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __BLOCKDEV_H
+#define __BLOCKDEV_H
+
+enum {
+ BLOCKDEV_MEMORY_CARD
+};
+
+int bd_init(int devnr);
+int bd_readblock(unsigned int block, void *buffer);
+void bd_done(void);
+
+int bd_has_part_table(int devnr);
+
+#endif /* __BLOCKDEV_H */
View
24 software/include/extra/crc.h
@@ -0,0 +1,24 @@
+/*
+ * Milkymist 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 __CRC_H
+#define __CRC_H
+
+unsigned short crc16(const unsigned char *buffer, int len);
+unsigned int crc32(const unsigned char *buffer, unsigned int len);
+
+#endif
View
28 software/include/extra/fatfs.h
@@ -0,0 +1,28 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __FATFS_H
+#define __FATFS_H
+
+typedef int (*fatfs_dir_callback)(const char *, const char *, void *);
+
+int fatfs_init(int devnr);
+int fatfs_list_files(fatfs_dir_callback cb, void *param);
+int fatfs_load(const char *filename, char *buffer, int size, int *realsize);
+void fatfs_done(void);
+
+#endif /* __FATFS_H */
View
34 software/include/hw/capabilities.h
@@ -0,0 +1,34 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __HW_CAPABILITIES
+#define __HW_CAPABILITIES
+
+#define CAP_MEMORYCARD (0x00000001)
+#define CAP_AC97 (0x00000002)
+#define CAP_PFPU (0x00000004)
+#define CAP_TMU (0x00000008)
+#define CAP_ETHERNET (0x00000010)
+#define CAP_FMLMETER (0x00000020)
+#define CAP_VIDEOIN (0x00000040)
+#define CAP_MIDI (0x00000080)
+#define CAP_DMX (0x00000100)
+#define CAP_IR (0x00000200)
+#define CAP_USB (0x00000400)
+#define CAP_MEMTEST (0x00000800)
+
+#endif /* __HW_CAPABILITIES */
View
27 software/include/hw/common.h
@@ -0,0 +1,27 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __HW_COMMON_H
+#define __HW_COMMON_H
+
+#ifdef __ASSEMBLER__
+#define MMPTR(x) x
+#else
+#define MMPTR(x) (*((volatile unsigned int *)(x)))
+#endif
+
+#endif
View
34 software/include/hw/flash.h
@@ -0,0 +1,34 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __HW_FLASH_H
+#define __HW_FLASH_H
+
+#define FLASH_OFFSET_STANDBY_BITSTREAM (0x00000000) /* 640k */
+
+#define FLASH_OFFSET_RESCUE_BITSTREAM (0x000A0000) /* 1536k */
+#define FLASH_OFFSET_RESCUE_BIOS (0x00220000) /* 128k */
+#define FLASH_OFFSET_MAC_ADDRESS (0x002200E0) /* within rescue BIOS */
+#define FLASH_OFFSET_RESCUE_SPLASH (0x00240000) /* 640k */
+#define FLASH_OFFSET_RESCUE_APP (0x002E0000) /* 4096k */
+
+#define FLASH_OFFSET_REGULAR_BITSTREAM (0x006E0000) /* 1536k */
+#define FLASH_OFFSET_REGULAR_BIOS (0x00860000) /* 128k */
+#define FLASH_OFFSET_REGULAR_SPLASH (0x00880000) /* 640k */
+#define FLASH_OFFSET_REGULAR_APP (0x00920000) /* remaining space (23424k) */
+
+#endif /* __HW_FLASH_H */
View
35 software/include/hw/gpio.h
@@ -0,0 +1,35 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __HW_GPIO_H
+#define __HW_GPIO_H
+
+/* Inputs */
+#define GPIO_BTN1 (0x00000001)
+#define GPIO_BTN2 (0x00000002)
+#define GPIO_BTN3 (0x00000004)
+
+#define GPIO_PCBREV0 (0x00000008)
+#define GPIO_PCBREV1 (0x00000010)
+#define GPIO_PCBREV2 (0x00000020)
+#define GPIO_PCBREV3 (0x00000040)
+
+/* Outputs */
+#define GPIO_LED1 (0x00000001)
+#define GPIO_LED2 (0x00000002)
+
+#endif /* __HW_GPIO_H */
View
23 software/include/hw/interrupts.h
@@ -0,0 +1,23 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __HW_INTERRUPTS_H
+#define __HW_INTERRUPTS_H
+
+#define IRQ_UART (0x00000001) /* 0 */
+
+#endif /* __HW_INTERRUPTS_H */
View
55 software/include/hw/sysctl.h
@@ -0,0 +1,55 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __HW_SYSCTL_H
+#define __HW_SYSCTL_H
+
+#include <hw/common.h>
+
+#define CSR_GPIO_IN MMPTR(0xe0001000)
+#define CSR_GPIO_OUT MMPTR(0xe0001004)
+#define CSR_GPIO_INTEN MMPTR(0xe0001008)
+
+#define CSR_TIMER0_CONTROL MMPTR(0xe0001010)
+#define CSR_TIMER0_COMPARE MMPTR(0xe0001014)
+#define CSR_TIMER0_COUNTER MMPTR(0xe0001018)
+
+#define CSR_TIMER1_CONTROL MMPTR(0xe0001020)
+#define CSR_TIMER1_COMPARE MMPTR(0xe0001024)
+#define CSR_TIMER1_COUNTER MMPTR(0xe0001028)
+
+#define TIMER_ENABLE (0x01)
+#define TIMER_AUTORESTART (0x02)
+
+#define CSR_ICAP MMPTR(0xe0001040)
+
+#define ICAP_READY (0x01)
+
+#define ICAP_CE (0x10000)
+#define ICAP_WRITE (0x20000)
+
+#define CSR_DBG_SCRATCHPAD MMPTR(0xe0001050)
+#define CSR_DBG_CTRL MMPTR(0xe0001054)
+
+#define DBG_CTRL_GDB_ROM_LOCK (0x01)
+#define DBG_CTRL_BUS_ERR_EN (0x02)
+
+#define CSR_FREQUENCY MMPTR(0xe0001074)
+#define CSR_CAPABILITIES MMPTR(0xe0001078)
+#define CSR_SYSTEM_ID MMPTR(0xe000107c)
+
+#endif /* __HW_SYSCTL_H */
View
39 software/include/hw/uart.h
@@ -0,0 +1,39 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 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 __HW_UART_H
+#define __HW_UART_H
+
+#include <hw/common.h>
+
+#define CSR_UART_RXTX MMPTR(0xe0000000)
+#define CSR_UART_DIVISOR MMPTR(0xe0000004)
+#define CSR_UART_STAT MMPTR(0xe0000008)
+#define CSR_UART_CTRL MMPTR(0xe000000c)
+#define CSR_UART_DEBUG MMPTR(0xe0000010)
+
+#define UART_STAT_THRE (0x1)
+#define UART_STAT_RX_EVT (0x2)
+#define UART_STAT_TX_EVT (0x4)
+
+#define UART_CTRL_RX_INT (0x1)
+#define UART_CTRL_TX_INT (0x2)
+#define UART_CTRL_THRU (0x4)
+
+#define UART_DEBUG_BREAK_EN (0x1)
+
+#endif /* __HW_UART_H */
View
15 software/libbase/Makefile
@@ -0,0 +1,15 @@
+MMDIR=../..
+include $(MMDIR)/software/include.mak
+
+OBJECTS=divsi3.o libc.o console.o system.o board.o uart.o softfloat.o softfloat-glue.o vsnprintf.o atof.o
+
+all: libbase.a
+
+libbase.a: $(OBJECTS)
+ $(AR) clr libbase.a $(OBJECTS)
+ $(RANLIB) libbase.a
+
+.PHONY: clean
+
+clean:
+ rm -f *.o libbase.a .*~ *~ Makefile.bak
View
84 software/libbase/atof.c
@@ -0,0 +1,84 @@
+/* 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 <stdlib.h>
+#include <ctype.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);
+}
View
87 software/libbase/board.c
@@ -0,0 +1,87 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2011 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 <hw/gpio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <board.h>
+
+static const struct board_desc boards[1] = {
+ {
+ .id = 0x4D31, /* M1 */
+ .name = "Milkymist One",
+ .ethernet_phyadr = 1
+ },
+};
+
+const struct board_desc *get_board_desc_id(unsigned short 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(void)
+{
+ return get_board_desc_id(CSR_SYSTEM_ID & 0xffff);
+}
+
+int get_pcb_revision(void)
+{
+ int r;
+ unsigned int io;
+
+ io = CSR_GPIO_IN;
+ r = 0;
+ if(io & GPIO_PCBREV0)
+ r |= 0x1;
+ if(io & GPIO_PCBREV1)
+ r |= 0x2;
+ if(io & GPIO_PCBREV2)
+ r |= 0x4;
+ if(io & GPIO_PCBREV3)
+ r |= 0x8;
+ return r;
+}
+
+void get_soc_version(unsigned int *major, unsigned int *minor, unsigned int *subminor, unsigned int *rc)
+{
+ unsigned int id;
+
+ id = CSR_SYSTEM_ID;
+ *major = (id & 0xf0000000) >> 28;
+ *minor = (id & 0x0f000000) >> 24;
+ *subminor = (id & 0x00f00000) >> 20;
+ *rc = (id & 0x000f0000) >> 16;
+}
+
+void get_soc_version_formatted(char *version)
+{
+ unsigned int major, minor, subminor, rc;
+
+ get_soc_version(&major, &minor, &subminor, &rc);
+
+ version += sprintf(version, "%u.%u", major, minor);
+ if(subminor != 0)
+ version += sprintf(version, ".%u", subminor);
+ if(rc != 0)
+ sprintf(version, "RC%u", rc);
+}
View
108 software/libbase/console.c
@@ -0,0 +1,108 @@
+/*
+ * Milkymist 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 <console.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <irq.h>
+#include <hw/interrupts.h>
+
+static console_write_hook write_hook;
+static console_read_hook read_hook;
+static console_read_nonblock_hook read_nonblock_hook;
+
+void console_set_write_hook(console_write_hook h)
+{
+ write_hook = h;
+}
+
+void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn)
+{
+ read_hook = r;
+ read_nonblock_hook = rn;
+}
+
+static void writechar(char c)
+{
+ uart_write(c);
+ if(write_hook != NULL)
+ write_hook(c);
+}
+
+char readchar(void)
+{
+ while(1) {
+ if(uart_read_nonblock())
+ return uart_read();
+ if((read_nonblock_hook != NULL) && read_nonblock_hook())
+ return read_hook();
+ }
+}
+
+int readchar_nonblock(void)
+{
+ return (uart_read_nonblock()
+ || ((read_nonblock_hook != NULL) && read_nonblock_hook()));
+}
+
+int puts(const char *s)
+{
+ unsigned int oldmask;
+
+ oldmask = irq_getmask();
+ irq_setmask(IRQ_UART); // HACK: prevent UART data loss
+
+ while(*s) {
+ writechar(*s);
+ s++;
+ }
+ writechar('\n');
+
+ irq_setmask(oldmask);
+ return 1;
+}
+
+void putsnonl(const char *s)
+{
+ unsigned int oldmask;
+
+ oldmask = irq_getmask();
+ irq_setmask(IRQ_UART); // HACK: prevent UART data loss
+
+ while(*s) {
+ writechar(*s);
+ s++;
+ }
+
+ irq_setmask(oldmask);
+}
+
+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;
+}
View
53 software/libbase/divsi3.c
@@ -0,0 +1,53 @@
+#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;
+}
View
577 software/libbase/libc.c
@@ -0,0 +1,577 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
+ * Copyright (C) Linus Torvalds and 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 <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.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 *to, const void *from, size_t n)
+{
+ void *xto = to;
+ size_t temp;
+
+ if(!n)
+ return xto;
+ if((long)to & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ *cto++ = *cfrom++;
+ to = cto;
+ from = cfrom;
+ n--;
+ }
+ if(n > 2 && (long)to & 2) {
+ short *sto = to;
+ const short *sfrom = from;
+ *sto++ = *sfrom++;
+ to = sto;
+ from = sfrom;
+ n -= 2;
+ }
+ temp = n >> 2;
+ if(temp) {
+ long *lto = to;
+ const long *lfrom = from;
+ for(; temp; temp--)
+ *lto++ = *lfrom++;
+ to = lto;
+ from = lfrom;
+ }
+ if(n & 2) {
+ short *sto = to;
+ const short *sfrom = from;
+ *sto++ = *sfrom++;
+ to = sto;
+ from = sfrom;
+ }
+ if(n & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ *cto = *cfrom;
+ }
+ return xto;
+}
+
+/**
+ * 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;
+}
+
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char *strstr(const char *s1, const char *s2)
+{
+ size_t l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *)s1;
+ l1 = strlen(s1);
+ while (l1 >= l2) {
+ l1--;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
+ s1++;
+ }
+ return NULL;
+}
+
+/**
+ * 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(void)
+{
+ seed = 129 * seed + 907633385;
+ return seed;
+}
+
+void abort(void)
+{
+ printf("Aborted.");
+ while(1);
+}
View
126 software/libbase/milieu.h
@@ -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
+};
+
View
125 software/libbase/softfloat-glue.c
@@ -0,0 +1,125 @@
+/*
+ * Milkymist 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 "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
+}
+
View
646 software/libbase/softfloat-macros.h
@@ -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 );