From f105cb5bbd87361c1b3ffc10bf10549bf9533578 Mon Sep 17 00:00:00 2001 From: Serge Vakulenko Date: Thu, 1 May 2014 10:41:41 -0700 Subject: [PATCH 1/6] /bin/cc command modified to use SmallerC compiler by default (not LCC). For LCC, please use /bin/lcc instead. I believe SmallerC is mature enough to try to use it as a primary compiler. System include files might need some changes (ifdefs) to adapt. --- src/cmd/cc/Makefile | 2 +- src/cmd/cc/cc.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/cmd/cc/Makefile b/src/cmd/cc/Makefile index ded7034..b54ffcf 100644 --- a/src/cmd/cc/Makefile +++ b/src/cmd/cc/Makefile @@ -26,4 +26,4 @@ clean: install: all install cc $(DESTDIR)/bin/ install cc $(DESTDIR)/bin/scc - install cc $(DESTDIR)/bin/srcc + install cc $(DESTDIR)/bin/lcc diff --git a/src/cmd/cc/cc.c b/src/cmd/cc/cc.c index b008e09..1c30ede 100644 --- a/src/cmd/cc/cc.c +++ b/src/cmd/cc/cc.c @@ -449,17 +449,16 @@ main(int argc, char *argv[]) pass0 = LIBEXECDIR "/smallc"; incdir = STDINC "/smallc"; - } else if (strcmp ("srcc", progname) == 0) { - /* Smaller C. */ - mode = MODE_SMALLERC; - cppadd[0] = "-D__SMALLER_C__"; - pass0 = LIBEXECDIR "/smlrc"; - incdir = STDINC "/smallerc"; - } else { + } else if (strcmp ("lcc", progname) == 0) { /* LCC: retargetable C compiler. */ mode = MODE_LCC; cppadd[0] = "-D__LCC__"; pass0 = LIBEXECDIR "/lccom"; + } else { + /* Smaller C. */ + mode = MODE_SMALLERC; + cppadd[0] = "-D__SMALLER_C__"; + pass0 = LIBEXECDIR "/smlrc"; } if (argc == 1) From 777ad1471bce478d368a24fa4299ef00477f3969 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 May 2014 01:28:48 -0700 Subject: [PATCH 2/6] Smlrc: option -v moved to target-dependent part. Fixed bug in simulator: read from incorrect file descriptor when the second SD card not configured. --- src/cmd/smlrc/cgmips.c | 4 ++++ src/cmd/smlrc/smlrc.c | 4 ---- tools/virtualmips/dev_sdcard.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cmd/smlrc/cgmips.c b/src/cmd/smlrc/cgmips.c index 9f75376..edc7e03 100644 --- a/src/cmd/smlrc/cgmips.c +++ b/src/cmd/smlrc/cgmips.c @@ -63,6 +63,10 @@ int GenInitParams(int argc, char** argv, int* idx) UseGp = 1; return 1; } + else if (!strcmp(argv[*idx], "-v")) + { + return 1; + } return 0; } diff --git a/src/cmd/smlrc/smlrc.c b/src/cmd/smlrc/smlrc.c index 977fc13..d65021a 100644 --- a/src/cmd/smlrc/smlrc.c +++ b/src/cmd/smlrc/smlrc.c @@ -7593,10 +7593,6 @@ int main(int argc, char** argv) verbose = 1; continue; } - else if (!strcmp(argv[i], "-v")) - { - continue; - } #ifndef NO_PREPROCESSOR else if (!strcmp(argv[i], "-I")) { diff --git a/tools/virtualmips/dev_sdcard.c b/tools/virtualmips/dev_sdcard.c index 38fd9b0..478cbac 100644 --- a/tools/virtualmips/dev_sdcard.c +++ b/tools/virtualmips/dev_sdcard.c @@ -140,7 +140,7 @@ unsigned dev_sdcard_io (cpu_mips_t *cpu, unsigned data) pic32->sdcard[1].select ? &pic32->sdcard[1] : 0; unsigned reply; - if (! d) { + if (! d || ! d->fd) { TRACE ("sdcard: unselected i/o\n"); return 0xFF; } From 51a8fd3313ea6c64c36fd1a99591e7627ac0e997 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 May 2014 16:34:19 -0700 Subject: [PATCH 3/6] Assembler: added support for large constants for 2-reg variants (macros) of 3-reg instructions (add, addu, and, or, slt, sltu, sub, subu, xor). When mode ".set at" enabled, an additional LI instruction is inserted sing $1 as a scratch register. --- src/cmd/as/as.c | 53 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/src/cmd/as/as.c b/src/cmd/as/as.c index 0df415c..71d868c 100644 --- a/src/cmd/as/as.c +++ b/src/cmd/as/as.c @@ -1238,7 +1238,7 @@ void emitword (w, r, clobber_reg) reorder_word = w; reorder_rel = *r; reorder_full = 1; - reorder_clobber = clobber_reg; + reorder_clobber = clobber_reg & 15; } else { fputword (w, sfile[segm]); fputrel (r, rfile[segm]); @@ -1317,10 +1317,9 @@ void makecmd (opcode, type, emitfunc) unsigned opcode; void (*emitfunc) (unsigned, struct reloc*); { - register int clex; - register unsigned offset; + unsigned offset, orig_opcode = 0; struct reloc relinfo; - int cval, segment, clobber_reg, negate_literal; + int clex, cval, segment, clobber_reg, negate_literal; offset = 0; relinfo.flags = RABS; @@ -1480,6 +1479,7 @@ frs1: clex = getlex (&cval); cval = (opcode >> 11) & 31; /* get 1-st register */ newop |= cval << 16; /* set 1-st register */ newop |= opcode & (31 << 21); /* set 2-nd register */ + orig_opcode = opcode; opcode = newop; type = FRT1 | FRS2 | FOFF16 | FMOD; goto foff16; @@ -1572,6 +1572,8 @@ fsa: offset = getexpr (&segment); } } else if (type & (FOFF16 | FOFF18 | FAOFF18 | FAOFF28 | FHIGH16)) { /* Relocatable offset */ + int valid_range; + if ((type & (FOFF16 | FOFF18 | FHIGH16)) && getlex (&cval) != ',') uerror ("comma expected"); foff16: expr_flags = 0; @@ -1589,7 +1591,48 @@ foff16: expr_flags = 0; relinfo.flags |= RGPREL; switch (type & (FOFF16 | FOFF18 | FAOFF18 | FAOFF28 | FHIGH16)) { case FOFF16: /* low 16-bit byte address */ - opcode |= offset & 0xffff; + /* Test whether the immediate is in valid range + * for the opcode. */ + switch (opcode & 0xfc000000) { + case 0x20000000: // addi + case 0x24000000: // addiu + case 0x28000000: // slti + case 0x2c000000: // sltiu + /* 16-bit signed value. */ + valid_range = (offset >= -0x8000) && (offset <= 0x7fff); + break; + case 0x30000000: // andi + case 0x34000000: // ori + case 0x38000000: // xori + default: + /* 16-bit unsigned value. */ + valid_range = (offset >= 0) && (offset <= 0xffff); + break; + } + if (valid_range) { + opcode |= offset & 0xffff; + } else if (orig_opcode == 0) { + uerror ("value out of range"); + } else { + /* Convert back to 3-reg opcode. + * Insert an extra LI instruction. */ + if (segment != SABS) + uerror ("absolute value required"); + + if (offset <= 0xffff) { + /* ori $1, $zero, value */ + emitword (0x34010000 | offset, &relabs, 1); + } else if (offset >= -0x8000) { + /* addiu $1, $zero, value */ + emitword (0x24010000 | (offset & 0xffff), &relabs, 1); + } else { + /* lui $1, value[31:16] + * ori $1, $1, value[15:0]) */ + emitword (0x3c010000 | (offset >> 16), &relabs, 1); + emitword (0x34210000 | (offset & 0xffff), &relabs, 1); + } + opcode = orig_opcode | 0x10000; + } break; case FHIGH16: /* high 16-bit byte address */ if (expr_flags & EXPR_HI) { From babef284ae9cf0ca3e9ac60245d46ba4f7597074 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 May 2014 16:55:40 -0700 Subject: [PATCH 4/6] Assembler: mode ".set at" required to enable wide immediates in 2-red macros. --- src/cmd/as/as.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/as/as.c b/src/cmd/as/as.c index 71d868c..390e077 100644 --- a/src/cmd/as/as.c +++ b/src/cmd/as/as.c @@ -1611,7 +1611,7 @@ foff16: expr_flags = 0; } if (valid_range) { opcode |= offset & 0xffff; - } else if (orig_opcode == 0) { + } else if (orig_opcode == 0 || ! mode_at) { uerror ("value out of range"); } else { /* Convert back to 3-reg opcode. From e0ba61225050cb2c211aab461c870e9a60d2003d Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 May 2014 17:33:56 -0700 Subject: [PATCH 5/6] Range check fixed in assembler. --- src/cmd/as/as.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd/as/as.c b/src/cmd/as/as.c index 390e077..a2cccf5 100644 --- a/src/cmd/as/as.c +++ b/src/cmd/as/as.c @@ -1599,14 +1599,14 @@ foff16: expr_flags = 0; case 0x28000000: // slti case 0x2c000000: // sltiu /* 16-bit signed value. */ - valid_range = (offset >= -0x8000) && (offset <= 0x7fff); + valid_range = (offset >= -0x8000) || (offset <= 0x7fff); break; case 0x30000000: // andi case 0x34000000: // ori case 0x38000000: // xori default: /* 16-bit unsigned value. */ - valid_range = (offset >= 0) && (offset <= 0xffff); + valid_range = (offset <= 0xffff); break; } if (valid_range) { From 6f47acb2ae8623c0511424d143af2e49371fbf92 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 May 2014 23:56:57 -0700 Subject: [PATCH 6/6] Fixed bug in assembler, introduced by previos patch. (Negative offsets in LW/SW not recognized) Also, modified stdlib.h for compatibility with SmallerC. --- include/stdlib.h | 42 +++++++++++++++++++----------------- src/cmd/as/as.c | 12 ++++------- src/libc/gen/getenv.c | 2 +- src/libc/stdlib/getsubopt.c | 3 ++- src/libc/stdlib/strtol.c | 4 ++-- src/libc/stdlib/strtoul.c | 4 ++-- tools/virtualmips/.gitignore | 1 + 7 files changed, 34 insertions(+), 34 deletions(-) diff --git a/include/stdlib.h b/include/stdlib.h index 40b310f..eee38c7 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -54,49 +54,51 @@ #define RAND_MAX 0x7fff -void abort(); +void abort (void); int abs (int); int atexit (void (*)(void)); -double atof(); -int atoi(); -long atol(); +int atoi (const char *); +long atol (const char *); void *calloc (size_t, size_t); void exit (int); void free (void *); -char *getenv(); +char *getenv (const char *); long labs (long); void *malloc (size_t); char *mktemp (char *); int mkstemp (char *); -void qsort(); -int rand(); +void qsort (void *, size_t, size_t, int (*)(const void *, const void *)); +int rand (void); void *realloc (void*, size_t); -void srand(); -double strtod(); -long strtol(); -unsigned long strtoul(); -int system(); +void srand (unsigned); +long strtol (const char *, char **, int); +unsigned long strtoul (const char *, char **, int); +int system (const char *); int putenv (char *string); int setenv (const char *name, const char *value, int overwrite); int unsetenv (const char *name); char *_findenv (const char *name, int *offset); -void *alloca(); +void *alloca (size_t size); -int daemon(); -char *devname(); -int getloadavg(unsigned loadavg[], int nelem); +int daemon (int, int); +char *devname (dev_t dev, mode_t type); +int getloadavg (unsigned loadavg[], int nelem); extern char *suboptarg; /* getsubopt(3) external variable */ -int getsubopt(); +int getsubopt (char **, char **, char **); long random (void); char *setstate (char *); void srandom (unsigned); -char *ecvt (double, int, int *, int *); -char *fcvt (double, int, int *, int *); -char *gcvt (double, int, char *); +#ifndef __SMALLER_C__ +double atof (const char *); +double strtod (const char *, char **); +char *ecvt (double, int, int *, int *); +char *fcvt (double, int, int *, int *); +char *gcvt (double, int, char *); +#endif #endif /* _STDLIB_H_ */ diff --git a/src/cmd/as/as.c b/src/cmd/as/as.c index a2cccf5..9496577 100644 --- a/src/cmd/as/as.c +++ b/src/cmd/as/as.c @@ -1594,17 +1594,13 @@ foff16: expr_flags = 0; /* Test whether the immediate is in valid range * for the opcode. */ switch (opcode & 0xfc000000) { - case 0x20000000: // addi - case 0x24000000: // addiu - case 0x28000000: // slti - case 0x2c000000: // sltiu + default: /* addi, addiu, slti, sltiu, lw, sw */ /* 16-bit signed value. */ valid_range = (offset >= -0x8000) || (offset <= 0x7fff); break; - case 0x30000000: // andi - case 0x34000000: // ori - case 0x38000000: // xori - default: + case 0x30000000: /* andi */ + case 0x34000000: /* ori */ + case 0x38000000: /* xori */ /* 16-bit unsigned value. */ valid_range = (offset <= 0xffff); break; diff --git a/src/libc/gen/getenv.c b/src/libc/gen/getenv.c index 09f721a..273cb1b 100644 --- a/src/libc/gen/getenv.c +++ b/src/libc/gen/getenv.c @@ -14,7 +14,7 @@ */ char * getenv(name) - char *name; + const char *name; { int offset; char *_findenv(); diff --git a/src/libc/stdlib/getsubopt.c b/src/libc/stdlib/getsubopt.c index bfe64c3..af9030f 100644 --- a/src/libc/stdlib/getsubopt.c +++ b/src/libc/stdlib/getsubopt.c @@ -43,7 +43,8 @@ char *suboptarg; int getsubopt(optionp, tokens, valuep) - register char **optionp, **valuep; + register char **optionp; + register char **valuep; register char **tokens; { register int cnt; diff --git a/src/libc/stdlib/strtol.c b/src/libc/stdlib/strtol.c index 2d39de4..1b4601a 100644 --- a/src/libc/stdlib/strtol.c +++ b/src/libc/stdlib/strtol.c @@ -43,11 +43,11 @@ */ long strtol(nptr, endptr, base) - char *nptr; + const char *nptr; char **endptr; register int base; { - register char *s = nptr; + register const char *s = nptr; register unsigned long acc; register int c; register unsigned long cutoff; diff --git a/src/libc/stdlib/strtoul.c b/src/libc/stdlib/strtoul.c index 93e16d2..48f4989 100644 --- a/src/libc/stdlib/strtoul.c +++ b/src/libc/stdlib/strtoul.c @@ -43,11 +43,11 @@ */ unsigned long strtoul(nptr, endptr, base) - char *nptr; + const char *nptr; char **endptr; register int base; { - register char *s = nptr; + register const char *s = nptr; register unsigned long acc; register int c; register unsigned long cutoff; diff --git a/tools/virtualmips/.gitignore b/tools/virtualmips/.gitignore index 0c79fa8..cba2dbe 100644 --- a/tools/virtualmips/.gitignore +++ b/tools/virtualmips/.gitignore @@ -1,2 +1,3 @@ .deps pic32 +pic32-log.txt