diff options
| author | forsyth <forsyth@lavoro.terzarima.net> | 2013-06-03 21:01:14 +0000 |
|---|---|---|
| committer | forsyth <forsyth@lavoro.terzarima.net> | 2013-06-03 21:01:14 +0000 |
| commit | 45a20ab721a513710138340faff3d59a31c3e01e (patch) | |
| tree | eea29d2684c51cc73725b8992a2125bede48e118 | |
| parent | cd8e99851af33e52bcdf8faf34f9d4e62fa0cbaf (diff) | |
sync compilers with Plan 9
remove 1[acl] 2[acl]
257 files changed, 9476 insertions, 36968 deletions
diff --git a/utils/0a/lex.c b/utils/0a/lex.c index 6d736d7c..35c12f91 100644 --- a/utils/0a/lex.c +++ b/utils/0a/lex.c @@ -458,7 +458,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } } diff --git a/utils/0c/gc.h b/utils/0c/gc.h index 23f0bdd9..c93ebca6 100644 --- a/utils/0c/gc.h +++ b/utils/0c/gc.h @@ -255,7 +255,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*, Node*); void casf(void); @@ -285,7 +285,7 @@ int Bconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); Bits mkvar(Adr*, int); diff --git a/utils/0c/list.c b/utils/0c/list.c index f89b17ca..b96130f4 100644 --- a/utils/0c/list.c +++ b/utils/0c/list.c @@ -70,7 +70,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/0c/reg.c b/utils/0c/reg.c index 813ace1a..1f286c5e 100644 --- a/utils/0c/reg.c +++ b/utils/0c/reg.c @@ -18,7 +18,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; diff --git a/utils/0c/swt.c b/utils/0c/swt.c index 2e24fedd..0b0623c0 100644 --- a/utils/0c/swt.c +++ b/utils/0c/swt.c @@ -1,7 +1,7 @@ #include "gc.h" int -swcmp(const void *a1, const void *a2) +swcmp(void *a1, void *a2) { C1 *p1, *p2; @@ -198,7 +198,7 @@ outstring(char *s, long n) } long -outlstring(ushort *s, long n) +outlstring(TRune *s, long n) { char buf[2]; int c; @@ -323,22 +323,6 @@ nullwarn(Node *l, Node *r) cgen(r, Z); } -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0)); - p->from.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} void gextern(Sym *s, Node *a, long o, long w) diff --git a/utils/0l/Nt.c b/utils/0l/Nt.c deleted file mode 100644 index 2efff499..00000000 --- a/utils/0l/Nt.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <windows.h> -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/0l/Plan9.c b/utils/0l/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/0l/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/0l/Posix.c b/utils/0l/Posix.c deleted file mode 100644 index aa5d9551..00000000 --- a/utils/0l/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fials if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} diff --git a/utils/0l/l.h b/utils/0l/l.h index 6b027814..b58e92c5 100644 --- a/utils/0l/l.h +++ b/utils/0l/l.h @@ -306,7 +306,7 @@ void nocache(Prog*); void noops(void); void nuxiinit(void); void objfile(char*); -int ocmp(const void*, const void*); +int ocmp(void*, void*); long opirr(int); Optab* oplook(Prog*); long oprrr(int); diff --git a/utils/0l/list.c b/utils/0l/list.c index 9261bc8e..c5033a5b 100644 --- a/utils/0l/list.c +++ b/utils/0l/list.c @@ -56,7 +56,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/0l/mkfile b/utils/0l/mkfile index 3001002b..65d2eb40 100644 --- a/utils/0l/mkfile +++ b/utils/0l/mkfile @@ -24,7 +24,10 @@ BIN=$ROOT/$OBJDIR/bin <$ROOT/mkfiles/mkone-$SHELLTYPE -CFLAGS= $CFLAGS -I ../include +CFLAGS= $CFLAGS -I ../include -I. enam.$O: ../0c/enam.c $CC $CFLAGS ../0c/enam.c + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/0l/span.c b/utils/0l/span.c index 3c9d2d50..f0a423dc 100644 --- a/utils/0l/span.c +++ b/utils/0l/span.c @@ -401,7 +401,7 @@ cmp(int a, int b) } int -ocmp(const void *a1, const void *a2) +ocmp(void *a1, void *a2) { Optab *p1, *p2; int n; diff --git a/utils/1a/a.h b/utils/1a/a.h deleted file mode 100644 index 7c064db1..00000000 --- a/utils/1a/a.h +++ /dev/null @@ -1,198 +0,0 @@ -#include <lib9.h> -#include <bio.h> -#include "../2c/2.out.h" - -#ifndef EXTERN -#define EXTERN extern -#endif - -typedef struct Sym Sym; -typedef struct Ref Ref; -typedef struct Gen Gen; -typedef struct Io Io; -typedef struct Hist Hist; -typedef struct Addr Addr; -typedef struct Gen2 Gen2; - -#define MAXALIGN 7 -#define FPCHIP 1 -#define NSYMB 500 -#define BUFSIZ 8192 -#define HISTSZ 20 -#define NINCLUDE 10 -#define NHUNK 10000 -#define EOF (-1) -#define IGN (-2) -#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff) -#define NHASH 503 -#define STRINGSZ 200 -#define NMACRO 10 - -struct Sym -{ - Sym* link; - Ref* ref; - char* macro; - long value; - ushort type; - char *name; - char sym; -}; -#define S ((Sym*)0) - -struct Ref -{ - int class; -}; - -EXTERN struct -{ - char* p; - int c; -} fi; - -struct Io -{ - Io* link; - char b[BUFSIZ]; - char* p; - short c; - short f; -}; -#define I ((Io*)0) - -EXTERN struct -{ - Sym* sym; - short type; -} h[NSYM]; - -struct Addr -{ - Sym* sym; - long offset; - short type; -}; -struct Gen -{ - Addr s0; - double dval; - char sval[8]; - long displace; - short type; - short field; -}; -struct Gen2 -{ - Gen from; - Gen to; -}; - -struct Hist -{ - Hist* link; - char* name; - long line; - long offset; -}; -#define H ((Hist*)0) - -enum -{ - CLAST, - CMACARG, - CMACRO, - CPREPROC, -}; - -EXTERN char debug[256]; -EXTERN Sym* hash[NHASH]; -EXTERN char* Dlist[30]; -EXTERN int nDlist; -EXTERN Hist* ehist; -EXTERN int newflag; -EXTERN Hist* hist; -EXTERN char* hunk; -EXTERN char* include[NINCLUDE]; -EXTERN Io* iofree; -EXTERN Io* ionext; -EXTERN Io* iostack; -EXTERN long lineno; -EXTERN int nerrors; -EXTERN long nhunk; -EXTERN int ninclude; -EXTERN Gen nullgen; -EXTERN char* outfile; -EXTERN int pass; -EXTERN char* pathname; -EXTERN long pc; -EXTERN int peekc; -EXTERN int sym; -EXTERN char symb[NSYMB]; -EXTERN int thechar; -EXTERN char* thestring; -EXTERN long thunk; -EXTERN Biobuf obuf; - -int assemble(char*); -void* allocn(void*, long, long); -void errorexit(void); -void pushio(void); -void newio(void); -void newfile(char*, int); -Sym* slookup(char*); -Sym* lookup(void); -void syminit(Sym*); -long yylex(void); -int getc(void); -int getnsc(void); -void unget(int); -int escchar(int); -void cinit(void); -void pinit(char*); -void cclean(void); -int isreg(Gen*); -void outcode(int, Gen2*); -void outhist(void); -void zaddr(Gen*, int); -void zname(char*, int, int); -void ieeedtod(Ieee*, double); -int filbuf(void); -Sym* getsym(void); -void domacro(void); -void macund(void); -void macdef(void); -void macexpand(Sym*, char*); -void macinc(void); -void macprag(void); -void maclin(void); -void macif(int); -void macend(void); -void dodefine(char*); -void prfile(long); -void linehist(char*, int); -void gethunk(void); -void yyerror(char*, ...); -int yyparse(void); -void setinclude(char*); -int assemble(char*); - -/* - * compat - */ -enum /* keep in synch with ../cc/cc.h */ -{ - Plan9 = 1<<0, - Unix = 1<<1, - Windows = 1<<2, -}; -int mywait(int*); -int mycreat(char*, int); -int systemtype(int); -int pathchar(void); -char* mygetwd(char*, int); -int myexec(char*, char*[]); -int mydup(int, int); -int myfork(void); -int mypipe(int*); -void* mysbrk(ulong); diff --git a/utils/1a/a.y b/utils/1a/a.y deleted file mode 100644 index 626154d5..00000000 --- a/utils/1a/a.y +++ /dev/null @@ -1,402 +0,0 @@ -%{ -#include "a.h" -%} -%union { - Sym *sym; - long lval; - double dval; - char sval[8]; - Addr addr; - Gen gen; - Gen2 gen2; -} -%left '|' -%left '^' -%left '&' -%left '<' '>' -%left '+' '-' -%left '*' '/' '%' -%token <lval> LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5 -%token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA LTYPEB -%token <lval> LCONST LSP LSB LFP LPC LTOS LAREG LDREG LFREG -%token <dval> LFCONST -%token <sval> LSCONST -%token <sym> LNAME LLAB LVAR -%type <lval> con expr type pointer reg offset -%type <addr> name areg -%type <gen> gen rel -%type <gen2> noaddr gengen dstgen spec1 spec2 spec3 srcgen dstrel genrel -%% -prog: -| prog line - -line: - LLAB ':' - { - if($1->value != pc) - yyerror("redeclaration of %s", $1->name); - $1->value = pc; - } - line -| LNAME ':' - { - $1->type = LLAB; - $1->value = pc; - } - line -| ';' -| inst ';' -| error ';' - -inst: - LNAME '=' expr - { - $1->type = LVAR; - $1->value = $3; - } -| LVAR '=' expr - { - if($1->value != $3) - yyerror("redeclaration of %s", $1->name); - $1->value = $3; - } -| LTYPE1 gengen { outcode($1, &$2); } -| LTYPE2 noaddr { outcode($1, &$2); } -| LTYPE3 dstgen { outcode($1, &$2); } -| LTYPE4 spec1 { outcode($1, &$2); } -| LTYPE5 srcgen { outcode($1, &$2); } -| LTYPE6 dstrel { outcode($1, &$2); } -| LTYPE7 genrel { outcode($1, &$2); } -| LTYPE8 dstgen { outcode($1, &$2); } -| LTYPE8 gengen { outcode($1, &$2); } -| LTYPE9 noaddr { outcode($1, &$2); } -| LTYPE9 dstgen { outcode($1, &$2); } -| LTYPEA spec2 { outcode($1, &$2); } -| LTYPEB spec3 { outcode($1, &$2); } - -noaddr: - { - $$.from = nullgen; - $$.to = nullgen; - } -| ',' - { - $$.from = nullgen; - $$.to = nullgen; - } - -srcgen: - gen - { - $$.from = $1; - $$.to = nullgen; - } -| gen ',' - { - $$.from = $1; - $$.to = nullgen; - } - -dstgen: - gen - { - $$.from = nullgen; - $$.to = $1; - } -| ',' gen - { - $$.from = nullgen; - $$.to = $2; - } - -gengen: - gen ',' gen - { - $$.from = $1; - $$.to = $3; - } - -dstrel: - rel - { - $$.from = nullgen; - $$.to = $1; - } -| ',' rel - { - $$.from = nullgen; - $$.to = $2; - } - -genrel: - gen ',' rel - { - $$.from = $1; - $$.to = $3; - } - -spec1: /* DATA opcode */ - gen '/' con ',' gen - { - $1.displace = $3; - $$.from = $1; - $$.to = $5; - } - -spec2: /* bit field opcodes */ - gen ',' gen ',' con ',' con - { - $1.field = $7; - $3.field = $5; - $$.from = $1; - $$.to = $3; - } - -spec3: /* TEXT opcode */ - gengen -| gen ',' con ',' gen - { - $1.displace = $3; - $$.from = $1; - $$.to = $5; - } - -rel: - con '(' LPC ')' - { - $$ = nullgen; - $$.type = D_BRANCH; - $$.s0.offset = $1 + pc; - } -| LNAME offset - { - $$ = nullgen; - if(pass == 2) - yyerror("undefined label: %s", $1->name); - $$.type = D_BRANCH; - $$.s0.sym = $1; - $$.s0.offset = $2; - } -| LLAB offset - { - $$ = nullgen; - $$.type = D_BRANCH; - $$.s0.sym = $1; - $$.s0.offset = $1->value + $2; - } - -gen: - type - { - $$ = nullgen; - $$.type = $1; - } -| '$' con - { - $$ = nullgen; - $$.type = D_CONST; - $$.s0.offset = $2; - } -| '$' name - { - $$ = nullgen; - { - Addr *a; - a = &$$.s0; - *a = $2; - } - if($2.type == D_AUTO || $2.type == D_PARAM) - yyerror("constant cannot be automatic: %s", - $2.sym->name); - $$.type = $2.type | I_ADDR; - } -| '$' LSCONST - { - $$ = nullgen; - $$.type = D_SCONST; - memcpy($$.sval, $2, sizeof($$.sval)); - } -| '$' LFCONST - { - $$ = nullgen; - $$.type = D_FCONST; - $$.dval = $2; - } -| '$' '-' LFCONST - { - $$ = nullgen; - $$.type = D_FCONST; - $$.dval = -$3; - } -| LTOS '+' con - { - $$ = nullgen; - $$.type = D_STACK; - $$.s0.offset = $3; - } -| LTOS '-' con - { - $$ = nullgen; - $$.type = D_STACK; - $$.s0.offset = -$3; - } -| con - { - $$ = nullgen; - $$.type = D_CONST | I_INDIR; - $$.s0.offset = $1; - } -| '-' '(' LAREG ')' - { - $$ = nullgen; - $$.type = $3 | I_INDDEC; - } -| '(' LAREG ')' '+' - { - $$ = nullgen; - $$.type = $2 | I_INDINC; - } -| areg - { - $$ = nullgen; - $$.type = $1.type; - { - Addr *a; - a = &$$.s0; - *a = $1; - } - } - -type: - reg -| LFREG - -reg: - LAREG -| LDREG -| LTOS - -areg: - '(' LAREG ')' - { - $$.type = $2 | I_INDIR; - $$.sym = S; - $$.offset = 0; - } -| con '(' LAREG ')' - { - $$.type = $3 | I_INDIR; - $$.sym = S; - $$.offset = $1; - } -| '(' ')' - { - $$.type = D_NONE | I_INDIR; - $$.sym = S; - $$.offset = 0; - } -| con '(' ')' - { - $$.type = D_NONE | I_INDIR; - $$.sym = S; - $$.offset = $1; - } -| name - -name: - LNAME offset '(' pointer ')' - { - $$.type = $4; - $$.sym = $1; - $$.offset = $2; - } -| LNAME '<' '>' offset '(' LSB ')' - { - $$.type = D_STATIC; - $$.sym = $1; - $$.offset = $4; - } - -offset: - { - $$ = 0; - } -| '+' con - { - $$ = $2; - } -| '-' con - { - $$ = -$2; - } - -pointer: - LSB -| LSP -| LFP - -con: - LCONST -| LVAR - { - $$ = $1->value; - } -| '-' con - { - $$ = -$2; - } -| '+' con - { - $$ = $2; - } -| '~' con - { - $$ = ~$2; - } -| '(' expr ')' - { - $$ = $2; - } - -expr: - con -| expr '+' expr - { - $$ = $1 + $3; - } -| expr '-' expr - { - $$ = $1 - $3; - } -| expr '*' expr - { - $$ = $1 * $3; - } -| expr '/' expr - { - $$ = $1 / $3; - } -| expr '%' expr - { - $$ = $1 % $3; - } -| expr '<' '<' expr - { - $$ = $1 << $4; - } -| expr '>' '>' expr - { - $$ = $1 >> $4; - } -| expr '&' expr - { - $$ = $1 & $3; - } -| expr '^' expr - { - $$ = $1 ^ $3; - } -| expr '|' expr - { - $$ = $1 | $3; - } diff --git a/utils/1a/l.s b/utils/1a/l.s deleted file mode 100644 index 6f3cca3a..00000000 --- a/utils/1a/l.s +++ /dev/null @@ -1,479 +0,0 @@ - -/* - * Memory and machine-specific definitions. Used in C and assembler. - */ - -/* - * Sizes - */ - -#define BI2BY 8 /* bits per byte */ -#define BI2WD 32 /* bits per word */ -#define BY2WD 4 /* bytes per word */ -#define BY2PG 8192 /* bytes per page */ -#define WD2PG (BY2PG/BY2WD) /* words per page */ -#define PGSHIFT 13 /* log(BY2PG) */ -#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) -#define ICACHESIZE 0 -#define MB4 (4*1024*1024) /* Lots of things are 4Mb in size */ - -#define MAXMACH 1 /* max # cpus system can run */ - -/* - * Time - */ -#define HZ (60) /* clock frequency */ -#define MS2HZ (1000/HZ) /* millisec per clock tick */ -#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ -#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ -#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ - -/* - * SR bits - */ -#define SUPER 0x2000 -#define SPL(n) (n<<8) - -/* - * CACR - */ -#define CCLEAR 0x08 -#define CENABLE 0x01 - -/* - * Magic registers (unused in current system) - */ - -#define MACH A5 /* A5 is m-> */ -#define USER A4 /* A4 is u-> */ - -/* - * Fundamental addresses - */ - -#define USERADDR 0x80000000 -/* assuming we're in a syscall, this is the address of the Ureg structure */ -#define UREGVARSZ (23*BY2WD) /* size of variable part of Ureg */ -#define UREGADDR (USERADDR+BY2PG-(UREGVARSZ+2+4+2+(8+8+1+1)*BY2WD)) - -/* - * Devices poked during bootstrap - */ -#define TACADDR 0x40600000 -#define MOUSE 0x40200000 - -/* - * MMU - */ - -#define VAMASK 0xCFFFFFFF /* clear balu bits in address */ -#define KUSEG 0x00000000 -#define KSEG 0x80000000 - -/* - * MMU entries - */ -#define PTEVALID (1<<13) -#define PTEWRITE 0 -#define PTERONLY (1<<14) -#define PTEKERNEL (1<<15) -#define PTEUNCACHED 0 -#define INVALIDPTE 0 -#define PTEMAPMEM (1024*1024) -#define PTEPERTAB (PTEMAPMEM/BY2PG) -#define SEGMAPSIZE 16 - -#define PPN(pa) ((pa>>13)&0x1FFF) - -#define KMAP ((unsigned long *)0xD0000000) -#define UMAP ((unsigned long *)0x50000000) - -/* - * Virtual addresses - */ -#define VTAG(va) ((va>>22)&0x03F) -#define VPN(va) ((va>>13)&0x1FF) - -#define PARAM ((char*)0x40500000) -#define TLBFLUSH_ 0x01 - -/* - * Address spaces - */ - -#define UZERO KUSEG /* base of user address space */ -#define UTZERO (UZERO+BY2PG) /* first address in user text */ -#define TSTKTOP 0x10000000 /* end of new stack in sysexec */ -#define TSTKSIZ 100 -#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */ -#define KZERO KSEG /* base of kernel address space */ -#define KTZERO (KZERO+BY2PG) /* first address in kernel text */ -#define USTKSIZE (4*1024*1024) /* size of user stack */ - -#define MACHSIZE 4096 - - -#define isphys(p) ((((ulong)(p))&0xF0000000) == KSEG) -#define DBMAGIC 0xBADC0C0A - -/* - * Boot first processor - */ -TEXT start(SB), $-4 - - MOVW $(SUPER|SPL(7)), SR - MOVL $a6base(SB), A6 - MOVL $0, R0 - MOVL R0, CACR - MOVL R0, TACADDR /* zero tac counter (cause an intr?) */ - - MOVL $mach0(SB), A0 - MOVL A0, m(SB) - MOVL $0, 0(A0) - MOVL A0, A7 - ADDL $(MACHSIZE-4), A7 /* start stack under machine struct */ - MOVL $0, u(SB) - - MOVL $vectors(SB), A0 - MOVL A0, VBR - - BSR main(SB) - /* never returns */ -dead: - BRA dead - -/* - * Take first processor into user mode. Leave enough room on the stack - * for a full-sized Ureg (including long bus error format) to fit - */ - -TEXT touser(SB), $-4 - - MOVL $(USERADDR+BY2PG-UREGVARSZ), A7 - MOVW $0, -(A7) - MOVL $(UTZERO+32), -(A7) /* header is in text */ - MOVW $0, -(A7) - MOVL $(USTKTOP-6*BY2WD), A0 /* MAXSYSARG=6 */ - MOVL A0, USP - MOVW $(SUPER|SPL(0)), SR - MOVL $8, R0 - MOVL R0, CACR - RTE - -TEXT firmware(SB), $0 - - MOVL $0x40000090, A0 - JMP (A0) - -TEXT splhi(SB), $0 - - MOVL m(SB), A0 - MOVL (A7), 4(A0) - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(7)), SR - RTS - -TEXT splduart(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(5)), SR - RTS - -TEXT spllo(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(0)), SR - RTS - -TEXT splx(SB), $0 - - MOVL sr+0(FP), R0 - MOVW R0, SR - RTS - -TEXT spldone(SB), $0 - - RTS - -TEXT spl1(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(1)), SR - RTS - -TEXT flushcpucache(SB), $0 - - MOVL $(CCLEAR|CENABLE), R0 - MOVL R0, CACR - RTS - -TEXT cacrtrap(SB), $0 /* user entry point to control cache, e.g. flush */ - - MOVL R0, CACR - RTE - -TEXT setlabel(SB), $0 - - MOVL sr+0(FP), A0 - MOVL A7, (A0)+ /* stack pointer */ - MOVL (A7), (A0)+ /* pc of caller */ - MOVW SR, (A0)+ /* status register */ - CLRL R0 /* ret 0 => not returning */ - RTS - -TEXT gotolabel(SB), $0 - - MOVL p+0(FP), A0 - MOVW $(SUPER|SPL(7)), SR - MOVL (A0)+, A7 /* stack pointer */ - MOVL (A0)+, (A7) /* pc; stuff into stack frame */ - MOVW (A0)+, R0 /* status register */ - MOVW R0, SR - MOVL $1, R0 /* ret 1 => returning */ - RTS - -/* - * Test and set, as a subroutine - */ - -TEXT tas(SB), $0 - - MOVL $0, R0 - MOVL a+0(FP), A0 - TAS (A0) - BEQ tas_1 - MOVL $1, R0 -tas_1: - RTS - -/* - * Floating point - */ - -TEXT fpsave(SB), $0 - - FSAVE (fp+0(FP)) - RTS - -TEXT fprestore(SB), $0 - - FRESTORE (fp+0(FP)) - RTS - -TEXT fpregsave(SB), $0 - - FMOVEM $0xFF, (3*4)(fr+0(FP)) - FMOVEMC $0x7, (fr+0(FP)) - RTS - -TEXT fpregrestore(SB), $0 - - FMOVEMC (fr+0(FP)), $0x7 - FMOVEM (3*4)(fr+0(FP)), $0xFF - RTS - -TEXT fpcr(SB), $0 - - MOVL new+0(FP), R1 - MOVL FPCR, R0 - MOVL R1, FPCR - RTS - - -TEXT rfnote(SB), $0 - - MOVL uregp+0(FP), A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1+1)*BY2WD), A7 - RTE - -TEXT illegal(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR trap(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE - -TEXT systrap(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVL A6, ((8+6)*BY2WD)(A7) - MOVL R0, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR syscall(SB) - MOVL ((1+8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVL ((1+8+6)*BY2WD)(A7), A6 - ADDL $((1+8+8+1)*BY2WD+BY2WD), A7 - RTE - -TEXT buserror(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - PEA ((8+8+1+3)*BY2WD)(A7) - PEA 4(A7) - BSR fault68020(SB) - ADDL $8, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE - -TEXT tacintr(SB), $0 /* level 1 */ - - MOVL R0, -(A7) - MOVL TACADDR, R0 - MOVL (A7)+, R0 - RTE - -TEXT portintr(SB), $0 /* level 2 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR devportintr(SB) - BRA retintr - -TEXT dkintr(SB), $0 /* level 3 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR inconintr(SB) - BRA retintr - -TEXT mouseintr(SB), $0 /* level 4 */ - - MOVEM $0x80C2, -(A7) /* D0, A0, A1, A6 */ - MOVL $a6base(SB), A6 - MOVL $15, R0 /* mask off hex switch */ - ANDB MOUSE,R0 /* clears quadrature interrupt */ - LEA mousetab(SB)(R0.W*8), A0 - LEA mouse(SB), A1 - MOVL (A0)+, R0 - ADDL R0, (A1)+ /* dx */ - MOVL (A0), R0 - ADDL R0, (A1)+ /* dy */ - ADDL $1, (A1) /* track */ - MOVEM (A7)+, $0x4301 - RTE - -TEXT uartintr(SB), $0 /* level 5 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR duartintr(SB) - BRA retintr - -TEXT syncintr(SB), $0 /* level 6 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR clock(SB) - /* fall through */ -retintr: - BSR mousetry(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE - -GLOBL duarttimer+0(SB),$4 - -TEXT duartreadtimer+0(SB), $0 - MOVW SR, R1 /* spl7() */ - MOVW $0x2700, SR - MOVL $0x40100000, A0 - CLRL R0 - TSTB 15(A0) /* stop timer */ - MOVW 6(A0), R0 /* read hi,lo */ - TSTB 14(A0) /* restart timer */ - NOTW R0 /* timer counts down from 0xffff */ - ADDL duarttimer(SB), R0 - MOVL R0, duarttimer(SB) - MOVW R1, SR - RTS - -GLOBL mousetab(SB), $128 -DATA mousetab+ 0(SB)/4, -1 /* x down, */ -DATA mousetab+ 4(SB)/4, 1 /* y up */ -DATA mousetab+ 8(SB)/4, 0 /* x - */ -DATA mousetab+ 12(SB)/4, 1 /* y up */ -DATA mousetab+ 16(SB)/4, 1 /* x up */ -DATA mousetab+ 20(SB)/4, 1 /* y up */ -DATA mousetab+ 24(SB)/4, 0 /* x - */ -DATA mousetab+ 28(SB)/4, 1 /* y up */ -DATA mousetab+ 32(SB)/4, -1 /* x down */ -DATA mousetab+ 36(SB)/4, 0 /* y - */ -DATA mousetab+ 40(SB)/4, 0 /* x - */ -DATA mousetab+ 44(SB)/4, 0 /* y - */ -DATA mousetab+ 48(SB)/4, 1 /* x up, */ -DATA mousetab+ 52(SB)/4, 0 /* y - */ -DATA mousetab+ 56(SB)/4, 0 /* x - */ -DATA mousetab+ 60(SB)/4, 0 /* y - */ -DATA mousetab+ 64(SB)/4, -1 /* x down */ -DATA mousetab+ 68(SB)/4, -1 /* y down */ -DATA mousetab+ 72(SB)/4, 0 /* x - */ -DATA mousetab+ 76(SB)/4, -1 /* y down */ -DATA mousetab+ 80(SB)/4, 1 /* x up */ -DATA mousetab+ 84(SB)/4, -1 /* y down */ -DATA mousetab+ 88(SB)/4, 0 /* x - */ -DATA mousetab+ 92(SB)/4, -1 /* y down */ -DATA mousetab+ 96(SB)/4, -1 /* x down */ -DATA mousetab+100(SB)/4, 0 /* y - */ -DATA mousetab+104(SB)/4, 0 /* x - */ -DATA mousetab+108(SB)/4, 0 /* y - */ -DATA mousetab+112(SB)/4, 1 /* x up */ -DATA mousetab+116(SB)/4, 0 /* y - */ -DATA mousetab+120(SB)/4, 0 /* x - */ -DATA mousetab+124(SB)/4, 0 /* y - */ - -GLOBL mach0+0(SB), $MACHSIZE -GLOBL u(SB), $4 -GLOBL m(SB), $4 diff --git a/utils/1a/lex.c b/utils/1a/lex.c deleted file mode 100644 index a3936d26..00000000 --- a/utils/1a/lex.c +++ /dev/null @@ -1,925 +0,0 @@ -#define EXTERN -#include "a.h" -#include "y.tab.h" -#include <ctype.h> - -void -main(int argc, char *argv[]) -{ - char *p; - int nout, nproc, status, i, c; - - thechar = '1'; - thestring = "68000"; - memset(debug, 0, sizeof(debug)); - cinit(); - outfile = 0; - include[ninclude++] = "."; - ARGBEGIN { - default: - c = ARGC(); - if(c >= 0 || c < sizeof(debug)) - debug[c] = 1; - break; - - case 'o': - outfile = ARGF(); - break; - - case 'D': - p = ARGF(); - if(p) - Dlist[nDlist++] = p; - break; - - case 'I': - p = ARGF(); - setinclude(p); - break; - } ARGEND - if(*argv == 0) { - print("usage: %ca [-options] file.s\n", thechar); - errorexit(); - } - if(argc > 1 && systemtype(Windows)){ - print("can't assemble multiple files on windows\n"); - errorexit(); - } - if(argc > 1 && !systemtype(Windows)) { - nproc = 1; - if(p = getenv("NPROC")) - nproc = atol(p); /* */ - c = 0; - nout = 0; - for(;;) { - while(nout < nproc && argc > 0) { - i = myfork(); - if(i < 0) { - i = mywait(&status); - if(i < 0) - errorexit(); - if(status) - c++; - nout--; - continue; - } - if(i == 0) { - print("%s:\n", *argv); - if(assemble(*argv)) - errorexit(); - exits(0); - } - nout++; - argc--; - argv++; - } - i = mywait(&status); - if(i < 0) { - if(c) - errorexit(); - exits(0); - } - if(status) - c++; - nout--; - } - } - if(assemble(argv[0])) - errorexit(); - exits(0); -} - -int -assemble(char *file) -{ - char ofile[100], incfile[20], *p; - int i, of; - - strcpy(ofile, file); - p = utfrrune(ofile, pathchar()); - if(p) { - include[0] = ofile; - *p++ = 0; - } else - p = ofile; - if(outfile == 0) { - outfile = p; - if(outfile){ - p = utfrrune(outfile, '.'); - if(p) - if(p[1] == 's' && p[2] == 0) - p[0] = 0; - p = utfrune(outfile, 0); - p[0] = '.'; - p[1] = thechar; - p[2] = 0; - } else - outfile = "/dev/null"; - } - p = getenv("INCLUDE"); - if(p) { - setinclude(p); - } else { - if(systemtype(Plan9)) { - sprint(incfile,"/%s/include", thestring); - setinclude(strdup(incfile)); - } - } - - of = mycreat(outfile, 0664); - if(of < 0) { - yyerror("%ca: cannot create %s", thechar, outfile); - errorexit(); - } - Binit(&obuf, of, OWRITE); - - pass = 1; - pinit(file); - for(i=0; i<nDlist; i++) - dodefine(Dlist[i]); - yyparse(); - if(nerrors) { - cclean(); - return nerrors; - } - - pass = 2; - outhist(); - pinit(file); - for(i=0; i<nDlist; i++) - dodefine(Dlist[i]); - yyparse(); - cclean(); - return nerrors; -} - -struct -{ - char *name; - ushort type; - ushort value; -} itab[] = -{ - "SP", LSP, D_AUTO, - "SB", LSB, D_EXTERN, - "FP", LFP, D_PARAM, - "PC", LPC, D_BRANCH, - "TOS", LTOS, D_TOS, - "CCR", LTOS, D_CCR, - "SR", LTOS, D_SR, - "SFC", LTOS, D_SFC, - "DFC", LTOS, D_DFC, - "CACR", LTOS, D_CACR, - "USP", LTOS, D_USP, - "VBR", LTOS, D_VBR, - "CAAR", LTOS, D_CAAR, - "MSP", LTOS, D_MSP, - "ISP", LTOS, D_ISP, - "FPCR", LTOS, D_FPCR, - "FPSR", LTOS, D_FPSR, - "FPIAR", LTOS, D_FPIAR, - "TC", LTOS, D_TC, - "ITT0", LTOS, D_ITT0, - "ITT1", LTOS, D_ITT1, - "DTT0", LTOS, D_DTT0, - "DTT1", LTOS, D_DTT1, - "MMUSR", LTOS, D_MMUSR, - "URP", LTOS, D_URP, - "SRP", LTOS, D_SRP, - - "R0", LDREG, D_R0+0, - "R1", LDREG, D_R0+1, - "R2", LDREG, D_R0+2, - "R3", LDREG, D_R0+3, - "R4", LDREG, D_R0+4, - "R5", LDREG, D_R0+5, - "R6", LDREG, D_R0+6, - "R7", LDREG, D_R0+7, - - "A0", LAREG, D_A0+0, - "A1", LAREG, D_A0+1, - "A2", LAREG, D_A0+2, - "A3", LAREG, D_A0+3, - "A4", LAREG, D_A0+4, - "A5", LAREG, D_A0+5, - "A6", LAREG, D_A0+6, - "A7", LAREG, D_A0+7, - - "F0", LFREG, D_F0+0, - "F1", LFREG, D_F0+1, - "F2", LFREG, D_F0+2, - "F3", LFREG, D_F0+3, - "F4", LFREG, D_F0+4, - "F5", LFREG, D_F0+5, - "F6", LFREG, D_F0+6, - "F7", LFREG, D_F0+7, - - "ABCD", LTYPE1, AABCD, - "ADDB", LTYPE1, AADDB, - "ADDL", LTYPE1, AADDL, - "ADDW", LTYPE1, AADDW, - "ADDXB", LTYPE1, AADDXB, - "ADDXL", LTYPE1, AADDXL, - "ADDXW", LTYPE1, AADDXW, - "ADJSP", LTYPE5, AADJSP, - "ANDB", LTYPE1, AANDB, - "ANDL", LTYPE1, AANDL, - "ANDW", LTYPE1, AANDW, - "ASLB", LTYPE1, AASLB, - "ASLL", LTYPE1, AASLL, - "ASLW", LTYPE1, AASLW, - "ASRB", LTYPE1, AASRB, - "ASRL", LTYPE1, AASRL, - "ASRW", LTYPE1, AASRW, - "BCASE", LTYPE7, ABCASE, - "BCC", LTYPE6, ABCC, - "BCHG", LTYPE1, ABCHG, - "BCLR", LTYPE1, ABCLR, - "BCS", LTYPE6, ABCS, - "BEQ", LTYPE6, ABEQ, - "BFCHG", LTYPEA, ABFCHG, - "BFCLR", LTYPEA, ABFCLR, - "BFEXTS", LTYPEA, ABFEXTS, - "BFEXTU", LTYPEA, ABFEXTU, - "BFFFO", LTYPEA, ABFFFO, - "BFINS", LTYPEA, ABFINS, - "BFSET", LTYPEA, ABFSET, - "BFTST", LTYPEA, ABFTST, - "BGE", LTYPE6, ABGE, - "BGT", LTYPE6, ABGT, - "BHI", LTYPE6, ABHI, - "BKPT", LTYPE1, ABKPT, - "BLE", LTYPE6, ABLE, - "BLS", LTYPE6, ABLS, - "BLT", LTYPE6, ABLT, - "BMI", LTYPE6, ABMI, - "BNE", LTYPE6, ABNE, - "BPL", LTYPE6, ABPL, - "BRA", LTYPE6, ABRA, - "BSET", LTYPE1, ABSET, - "BSR", LTYPE3, ABSR, - "BTST", LTYPE1, ABTST, - "BVC", LTYPE6, ABVC, - "BVS", LTYPE6, ABVS, - "CALLM", LTYPE1, ACALLM, - "CAS2B", LTYPE1, ACAS2B, - "CAS2L", LTYPE1, ACAS2L, - "CAS2W", LTYPE1, ACAS2W, - "CASB", LTYPE1, ACASB, - "CASEW", LTYPE2, ACASEW, - "CASL", LTYPE1, ACASL, - "CASW", LTYPE1, ACASW, - "CHK2B", LTYPE1, ACHK2B, - "CHK2L", LTYPE1, ACHK2L, - "CHK2W", LTYPE1, ACHK2W, - "CHKL", LTYPE1, ACHKL, - "CHKW", LTYPE1, ACHKW, - "CLRB", LTYPE3, ACLRB, - "CLRL", LTYPE3, ACLRL, - "CLRW", LTYPE3, ACLRW, - "CMP2B", LTYPE1, ACMP2B, - "CMP2L", LTYPE1, ACMP2L, - "CMP2W", LTYPE1, ACMP2W, - "CMPB", LTYPE1, ACMPB, - "CMPL", LTYPE1, ACMPL, - "CMPW", LTYPE1, ACMPW, - "DATA", LTYPE4, ADATA, - "DBCC", LTYPE7, ADBCC, - "DBCS", LTYPE7, ADBCS, - "DBEQ", LTYPE7, ADBEQ, - "DBF", LTYPE7, ADBF, - "DBGE", LTYPE7, ADBGE, - "DBGT", LTYPE7, ADBGT, - "DBHI", LTYPE7, ADBHI, - "DBLE", LTYPE7, ADBLE, - "DBLS", LTYPE7, ADBLS, - "DBLT", LTYPE7, ADBLT, - "DBMI", LTYPE7, ADBMI, - "DBNE", LTYPE7, ADBNE, - "DBPL", LTYPE7, ADBPL, - "DBT", LTYPE7, ADBT, - "DBVC", LTYPE7, ADBVC, - "DBVS", LTYPE7, ADBVS, - "DIVSL", LTYPE1, ADIVSL, - "DIVSW", LTYPE1, ADIVSW, - "DIVUL", LTYPE1, ADIVUL, - "DIVUW", LTYPE1, ADIVUW, - "END", LTYPE2, AEND, - "EORB", LTYPE1, AEORB, - "EORL", LTYPE1, AEORL, - "EORW", LTYPE1, AEORW, - "EXG", LTYPE1, AEXG, - "EXTBL", LTYPE3, AEXTBL, - "EXTBW", LTYPE3, AEXTBW, - "EXTWL", LTYPE3, AEXTWL, - "FABSB", LTYPE1, AFABSB, - "FABSD", LTYPE1, AFABSD, - "FABSF", LTYPE1, AFABSF, - "FABSL", LTYPE1, AFABSL, - "FABSW", LTYPE1, AFABSW, - "FACOSB", LTYPE1, AFACOSB, - "FACOSD", LTYPE1, AFACOSD, - "FACOSF", LTYPE1, AFACOSF, - "FACOSL", LTYPE1, AFACOSL, - "FACOSW", LTYPE1, AFACOSW, - "FADDB", LTYPE1, AFADDB, - "FADDD", LTYPE1, AFADDD, - "FADDF", LTYPE1, AFADDF, - "FADDL", LTYPE1, AFADDL, - "FADDW", LTYPE1, AFADDW, - "FASINB", LTYPE1, AFASINB, - "FASIND", LTYPE1, AFASIND, - "FASINF", LTYPE1, AFASINF, - "FASINL", LTYPE1, AFASINL, - "FASINW", LTYPE1, AFASINW, - "FATANB", LTYPE1, AFATANB, - "FATAND", LTYPE1, AFATAND, - "FATANF", LTYPE1, AFATANF, - "FATANHB", LTYPE1, AFATANHB, - "FATANHD", LTYPE1, AFATANHD, - "FATANHF", LTYPE1, AFATANHF, - "FATANHL", LTYPE1, AFATANHL, - "FATANHW", LTYPE1, AFATANHW, - "FATANL", LTYPE1, AFATANL, - "FATANW", LTYPE1, AFATANW, - "FBEQ", LTYPE6, AFBEQ, - "FBF", LTYPE6, AFBF, - "FBGE", LTYPE6, AFBGE, - "FBGT", LTYPE6, AFBGT, - "FBLE", LTYPE6, AFBLE, - "FBLT", LTYPE6, AFBLT, - "FBNE", LTYPE6, AFBNE, - "FBT", LTYPE6, AFBT, - "FCMPB", LTYPE1, AFCMPB, - "FCMPD", LTYPE1, AFCMPD, - "FCMPF", LTYPE1, AFCMPF, - "FCMPL", LTYPE1, AFCMPL, - "FCMPW", LTYPE1, AFCMPW, - "FCOSB", LTYPE1, AFCOSB, - "FCOSD", LTYPE1, AFCOSD, - "FCOSF", LTYPE1, AFCOSF, - "FCOSHB", LTYPE1, AFCOSHB, - "FCOSHD", LTYPE1, AFCOSHD, - "FCOSHF", LTYPE1, AFCOSHF, - "FCOSHL", LTYPE1, AFCOSHL, - "FCOSHW", LTYPE1, AFCOSHW, - "FCOSL", LTYPE1, AFCOSL, - "FCOSW", LTYPE1, AFCOSW, - "FDBEQ", LTYPE7, AFDBEQ, - "FDBF", LTYPE7, AFDBF, - "FDBGE", LTYPE7, AFDBGE, - "FDBGT", LTYPE7, AFDBGT, - "FDBLE", LTYPE7, AFDBLE, - "FDBLT", LTYPE7, AFDBLT, - "FDBNE", LTYPE7, AFDBNE, - "FDBT", LTYPE7, AFDBT, - "FDIVB", LTYPE1, AFDIVB, - "FDIVD", LTYPE1, AFDIVD, - "FDIVF", LTYPE1, AFDIVF, - "FDIVL", LTYPE1, AFDIVL, - "FDIVW", LTYPE1, AFDIVW, - "FETOXB", LTYPE1, AFETOXB, - "FETOXD", LTYPE1, AFETOXD, - "FETOXF", LTYPE1, AFETOXF, - "FETOXL", LTYPE1, AFETOXL, - "FETOXM1B", LTYPE1, AFETOXM1B, - "FETOXM1D", LTYPE1, AFETOXM1D, - "FETOXM1F", LTYPE1, AFETOXM1F, - "FETOXM1L", LTYPE1, AFETOXM1L, - "FETOXM1W", LTYPE1, AFETOXM1W, - "FETOXW", LTYPE1, AFETOXW, - "FGETEXPB", LTYPE1, AFGETEXPB, - "FGETEXPD", LTYPE1, AFGETEXPD, - "FGETEXPF", LTYPE1, AFGETEXPF, - "FGETEXPL", LTYPE1, AFGETEXPL, - "FGETEXPW", LTYPE1, AFGETEXPW, - "FGETMANB", LTYPE1, AFGETMANB, - "FGETMAND", LTYPE1, AFGETMAND, - "FGETMANF", LTYPE1, AFGETMANF, - "FGETMANL", LTYPE1, AFGETMANL, - "FGETMANW", LTYPE1, AFGETMANW, - "FINTB", LTYPE1, AFINTB, - "FINTD", LTYPE1, AFINTD, - "FINTF", LTYPE1, AFINTF, - "FINTL", LTYPE1, AFINTL, - "FINTRZB", LTYPE1, AFINTRZB, - "FINTRZD", LTYPE1, AFINTRZD, - "FINTRZF", LTYPE1, AFINTRZF, - "FINTRZL", LTYPE1, AFINTRZL, - "FINTRZW", LTYPE1, AFINTRZW, - "FINTW", LTYPE1, AFINTW, - "FLOG10B", LTYPE1, AFLOG10B, - "FLOG10D", LTYPE1, AFLOG10D, - "FLOG10F", LTYPE1, AFLOG10F, - "FLOG10L", LTYPE1, AFLOG10L, - "FLOG10W", LTYPE1, AFLOG10W, - "FLOG2B", LTYPE1, AFLOG2B, - "FLOG2D", LTYPE1, AFLOG2D, - "FLOG2F", LTYPE1, AFLOG2F, - "FLOG2L", LTYPE1, AFLOG2L, - "FLOG2W", LTYPE1, AFLOG2W, - "FLOGNB", LTYPE1, AFLOGNB, - "FLOGND", LTYPE1, AFLOGND, - "FLOGNF", LTYPE1, AFLOGNF, - "FLOGNL", LTYPE1, AFLOGNL, - "FLOGNP1B", LTYPE1, AFLOGNP1B, - "FLOGNP1D", LTYPE1, AFLOGNP1D, - "FLOGNP1F", LTYPE1, AFLOGNP1F, - "FLOGNP1L", LTYPE1, AFLOGNP1L, - "FLOGNP1W", LTYPE1, AFLOGNP1W, - "FLOGNW", LTYPE1, AFLOGNW, - "FMODB", LTYPE1, AFMODB, - "FMODD", LTYPE1, AFMODD, - "FMODF", LTYPE1, AFMODF, - "FMODL", LTYPE1, AFMODL, - "FMODW", LTYPE1, AFMODW, - "FMOVEB", LTYPE1, AFMOVEB, - "FMOVED", LTYPE1, AFMOVED, - "FMOVEF", LTYPE1, AFMOVEF, - "FMOVEL", LTYPE1, AFMOVEL, - "FMOVEW", LTYPE1, AFMOVEW, - "FMULB", LTYPE1, AFMULB, - "FMULD", LTYPE1, AFMULD, - "FMULF", LTYPE1, AFMULF, - "FMULL", LTYPE1, AFMULL, - "FMULW", LTYPE1, AFMULW, - "FNEGB", LTYPE8, AFNEGB, - "FNEGD", LTYPE8, AFNEGD, - "FNEGF", LTYPE8, AFNEGF, - "FNEGL", LTYPE8, AFNEGL, - "FNEGW", LTYPE8, AFNEGW, - "FREMB", LTYPE1, AFREMB, - "FREMD", LTYPE1, AFREMD, - "FREMF", LTYPE1, AFREMF, - "FREML", LTYPE1, AFREML, - "FREMW", LTYPE1, AFREMW, - "FSCALEB", LTYPE1, AFSCALEB, - "FSCALED", LTYPE1, AFSCALED, - "FSCALEF", LTYPE1, AFSCALEF, - "FSCALEL", LTYPE1, AFSCALEL, - "FSCALEW", LTYPE1, AFSCALEW, - "FSEQ", LTYPE1, AFSEQ, - "FSF", LTYPE1, AFSF, - "FSGE", LTYPE1, AFSGE, - "FSGT", LTYPE1, AFSGT, - "FSINB", LTYPE1, AFSINB, - "FSIND", LTYPE1, AFSIND, - "FSINF", LTYPE1, AFSINF, - "FSINHB", LTYPE1, AFSINHB, - "FSINHD", LTYPE1, AFSINHD, - "FSINHF", LTYPE1, AFSINHF, - "FSINHL", LTYPE1, AFSINHL, - "FSINHW", LTYPE1, AFSINHW, - "FSINL", LTYPE1, AFSINL, - "FSINW", LTYPE1, AFSINW, - "FSLE", LTYPE1, AFSLE, - "FSLT", LTYPE1, AFSLT, - "FSNE", LTYPE1, AFSNE, - "FSQRTB", LTYPE1, AFSQRTB, - "FSQRTD", LTYPE1, AFSQRTD, - "FSQRTF", LTYPE1, AFSQRTF, - "FSQRTL", LTYPE1, AFSQRTL, - "FSQRTW", LTYPE1, AFSQRTW, - "FST", LTYPE1, AFST, - "FSUBB", LTYPE1, AFSUBB, - "FSUBD", LTYPE1, AFSUBD, - "FSUBF", LTYPE1, AFSUBF, - "FSUBL", LTYPE1, AFSUBL, - "FSUBW", LTYPE1, AFSUBW, - "FTANB", LTYPE1, AFTANB, - "FTAND", LTYPE1, AFTAND, - "FTANF", LTYPE1, AFTANF, - "FTANHB", LTYPE1, AFTANHB, - "FTANHD", LTYPE1, AFTANHD, - "FTANHF", LTYPE1, AFTANHF, - "FTANHL", LTYPE1, AFTANHL, - "FTANHW", LTYPE1, AFTANHW, - "FTANL", LTYPE1, AFTANL, - "FTANW", LTYPE1, AFTANW, - "FTENTOXB", LTYPE1, AFTENTOXB, - "FTENTOXD", LTYPE1, AFTENTOXD, - "FTENTOXF", LTYPE1, AFTENTOXF, - "FTENTOXL", LTYPE1, AFTENTOXL, - "FTENTOXW", LTYPE1, AFTENTOXW, - "FTSTB", LTYPE1, AFTSTB, - "FTSTD", LTYPE1, AFTSTD, - "FTSTF", LTYPE1, AFTSTF, - "FTSTL", LTYPE1, AFTSTL, - "FTSTW", LTYPE1, AFTSTW, - "FTWOTOXB", LTYPE1, AFTWOTOXB, - "FTWOTOXD", LTYPE1, AFTWOTOXD, - "FTWOTOXF", LTYPE1, AFTWOTOXF, - "FTWOTOXL", LTYPE1, AFTWOTOXL, - "FTWOTOXW", LTYPE1, AFTWOTOXW, - "FMOVEM", LTYPE1, AFMOVEM, - "FMOVEMC", LTYPE1, AFMOVEMC, - "FRESTORE", LTYPE3, AFRESTORE, - "FSAVE", LTYPE3, AFSAVE, - "GLOBL", LTYPE1, AGLOBL, - "GOK", LTYPE2, AGOK, - "HISTORY", LTYPE2, AHISTORY, - "ILLEG", LTYPE2, AILLEG, - "INSTR", LTYPE3, AINSTR, - "JMP", LTYPE3, AJMP, - "JSR", LTYPE3, AJSR, - "LEA", LTYPE1, ALEA, - "LINKL", LTYPE1, ALINKL, - "LINKW", LTYPE1, ALINKW, - "LOCATE", LTYPE1, ALOCATE, - "LONG", LTYPE3, ALONG, - "LSLB", LTYPE1, ALSLB, - "LSLL", LTYPE1, ALSLL, - "LSLW", LTYPE1, ALSLW, - "LSRB", LTYPE1, ALSRB, - "LSRL", LTYPE1, ALSRL, - "LSRW", LTYPE1, ALSRW, - "MOVB", LTYPE1, AMOVB, - "MOVEM", LTYPE1, AMOVEM, - "MOVEPL", LTYPE1, AMOVEPL, - "MOVEPW", LTYPE1, AMOVEPW, - "MOVESB", LTYPE1, AMOVESB, - "MOVESL", LTYPE1, AMOVESL, - "MOVESW", LTYPE1, AMOVESW, - "MOVL", LTYPE1, AMOVL, - "MOVW", LTYPE1, AMOVW, - "MULSL", LTYPE1, AMULSL, - "MULSW", LTYPE1, AMULSW, - "MULUL", LTYPE1, AMULUL, - "MULUW", LTYPE1, AMULUW, - "NAME", LTYPE1, ANAME, - "NBCD", LTYPE3, ANBCD, - "NEGB", LTYPE3, ANEGB, - "NEGL", LTYPE3, ANEGL, - "NEGW", LTYPE3, ANEGW, - "NEGXB", LTYPE3, ANEGXB, - "NEGXL", LTYPE3, ANEGXL, - "NEGXW", LTYPE3, ANEGXW, - "NOP", LTYPE9, ANOP, - "NOTB", LTYPE3, ANOTB, - "NOTL", LTYPE3, ANOTL, - "NOTW", LTYPE3, ANOTW, - "ORB", LTYPE1, AORB, - "ORL", LTYPE1, AORL, - "ORW", LTYPE1, AORW, - "PACK", LTYPE1, APACK, - "PEA", LTYPE3, APEA, - "RESET", LTYPE2, ARESET, - "ROTLB", LTYPE1, AROTLB, - "ROTLL", LTYPE1, AROTLL, - "ROTLW", LTYPE1, AROTLW, - "ROTRB", LTYPE1, AROTRB, - "ROTRL", LTYPE1, AROTRL, - "ROTRW", LTYPE1, AROTRW, - "ROXLB", LTYPE1, AROXLB, - "ROXLL", LTYPE1, AROXLL, - "ROXLW", LTYPE1, AROXLW, - "ROXRB", LTYPE1, AROXRB, - "ROXRL", LTYPE1, AROXRL, - "ROXRW", LTYPE1, AROXRW, - "RTD", LTYPE3, ARTD, - "RTE", LTYPE2, ARTE, - "RTM", LTYPE3, ARTM, - "RTR", LTYPE2, ARTR, - "RTS", LTYPE2, ARTS, - "SBCD", LTYPE1, ASBCD, - "SCC", LTYPE3, ASCC, - "SCS", LTYPE3, ASCS, - "SEQ", LTYPE3, ASEQ, - "SF", LTYPE3, ASF, - "SGE", LTYPE3, ASGE, - "SGT", LTYPE3, ASGT, - "SHI", LTYPE3, ASHI, - "SLE", LTYPE3, ASLE, - "SLS", LTYPE3, ASLS, - "SLT", LTYPE3, ASLT, - "SMI", LTYPE3, ASMI, - "SNE", LTYPE3, ASNE, - "SPL", LTYPE3, ASPL, - "ST", LTYPE3, AST, - "STOP", LTYPE3, ASTOP, - "SUBB", LTYPE1, ASUBB, - "SUBL", LTYPE1, ASUBL, - "SUBW", LTYPE1, ASUBW, - "SUBXB", LTYPE1, ASUBXB, - "SUBXL", LTYPE1, ASUBXL, - "SUBXW", LTYPE1, ASUBXW, - "SVC", LTYPE2, ASVC, - "SVS", LTYPE2, ASVS, - "SWAP", LTYPE3, ASWAP, - "SYS", LTYPE2, ASYS, - "TAS", LTYPE3, ATAS, - "TEXT", LTYPEB, ATEXT, - "TRAP", LTYPE3, ATRAP, - "TRAPCC", LTYPE2, ATRAPCC, - "TRAPCS", LTYPE2, ATRAPCS, - "TRAPEQ", LTYPE2, ATRAPEQ, - "TRAPF", LTYPE2, ATRAPF, - "TRAPGE", LTYPE2, ATRAPGE, - "TRAPGT", LTYPE2, ATRAPGT, - "TRAPHI", LTYPE2, ATRAPHI, - "TRAPLE", LTYPE2, ATRAPLE, - "TRAPLS", LTYPE2, ATRAPLS, - "TRAPLT", LTYPE2, ATRAPLT, - "TRAPMI", LTYPE2, ATRAPMI, - "TRAPNE", LTYPE2, ATRAPNE, - "TRAPPL", LTYPE2, ATRAPPL, - "TRAPT", LTYPE2, ATRAPT, - "TRAPV", LTYPE2, ATRAPV, - "TRAPVC", LTYPE2, ATRAPVC, - "TRAPVS", LTYPE2, ATRAPVS, - "TSTB", LTYPE3, ATSTB, - "TSTL", LTYPE3, ATSTL, - "TSTW", LTYPE3, ATSTW, - "UNLK", LTYPE3, AUNLK, - "UNPK", LTYPE1, AUNPK, - "WORD", LTYPE3, AWORD, - - 0 -}; - -void -cinit(void) -{ - Sym *s; - int i; - - nullgen.s0.sym = S; - nullgen.s0.offset = 0; - nullgen.type = D_NONE; - if(FPCHIP) - nullgen.dval = 0; - for(i=0; i<sizeof(nullgen.sval); i++) - nullgen.sval[i] = 0; - nullgen.displace = 0; - nullgen.type = D_NONE; - nullgen.field = 0; - - nerrors = 0; - iostack = I; - iofree = I; - peekc = IGN; - nhunk = 0; - for(i=0; i<NHASH; i++) - hash[i] = S; - for(i=0; itab[i].name; i++) { - s = slookup(itab[i].name); - s->type = itab[i].type; - s->value = itab[i].value; - } - - pathname = allocn(pathname, 0, 100); - if(mygetwd(pathname, 99) == 0) { - pathname = allocn(pathname, 100, 900); - if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); - } -} - -void -syminit(Sym *s) -{ - - s->type = LNAME; - s->value = 0; -} - -void -cclean(void) -{ - Gen2 g2; - - g2.from = nullgen; - g2.to = nullgen; - outcode(AEND, &g2); - Bflush(&obuf); -} - -void -zname(char *n, int t, int s) -{ - - Bputc(&obuf, ANAME); /* as */ - Bputc(&obuf, ANAME>>8); - Bputc(&obuf, t); /* type */ - Bputc(&obuf, s); /* sym */ - while(*n) { - Bputc(&obuf, *n); - n++; - } - Bputc(&obuf, 0); -} - -void -zaddr(Gen *a, int s) -{ - long l; - int i, t; - char *n; - Ieee e; - - t = 0; - if(a->field) - t |= T_FIELD; - if(a->displace != 0) - t |= T_INDEX; - if(a->s0.offset != 0) - t |= T_OFFSET; - if(s != 0) - t |= T_SYM; - - if(a->type == D_FCONST) - t |= T_FCONST; - else - if(a->type == D_SCONST) - t |= T_SCONST; - else - if(a->type & ~0xff) - t |= T_TYPE; - Bputc(&obuf, t); - - if(t & T_FIELD) { /* implies field */ - i = a->field; - Bputc(&obuf, i); - Bputc(&obuf, i>>8); - } - if(t & T_INDEX) { /* implies index, scale, displace */ - i = D_NONE; - Bputc(&obuf, i); - Bputc(&obuf, i>>8); - Bputc(&obuf, 0); - l = a->displace; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - } - if(t & T_OFFSET) { /* implies offset */ - l = a->s0.offset; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - } - if(t & T_SYM) /* implies sym */ - Bputc(&obuf, s); - if(t & T_FCONST) { - ieeedtod(&e, a->dval); - l = e.l; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - l = e.h; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - return; - } - if(t & T_SCONST) { - n = a->sval; - for(i=0; i<NSNAME; i++) { - Bputc(&obuf, *n); - n++; - } - return; - } - i = a->type; - Bputc(&obuf, i); - if(t & T_TYPE) - Bputc(&obuf, i>>8); -} - -void -outcode(int a, Gen2 *g2) -{ - int sf, st, t; - Sym *s; - - if(pass == 1) - goto out; - -jackpot: - sf = 0; - s = g2->from.s0.sym; - while(s != S) { - sf = s->sym; - if(sf < 0 || sf >= NSYM) - sf = 0; - t = g2->from.type & D_MASK; - if(h[sf].type == t) - if(h[sf].sym == s) - break; - zname(s->name, t, sym); - s->sym = sym; - h[sym].sym = s; - h[sym].type = t; - sf = sym; - sym++; - if(sym >= NSYM) - sym = 1; - break; - } - st = 0; - s = g2->to.s0.sym; - while(s != S) { - st = s->sym; - if(st < 0 || st >= NSYM) - st = 0; - t = g2->to.type & D_MASK; - if(h[st].type == t) - if(h[st].sym == s) - break; - zname(s->name, t, sym); - s->sym = sym; - h[sym].sym = s; - h[sym].type = t; - st = sym; - sym++; - if(sym >= NSYM) - sym = 1; - if(st == sf) - goto jackpot; - break; - } - Bputc(&obuf, a); - Bputc(&obuf, a>>8); - Bputc(&obuf, lineno); - Bputc(&obuf, lineno>>8); - Bputc(&obuf, lineno>>16); - Bputc(&obuf, lineno>>24); - zaddr(&g2->from, sf); - zaddr(&g2->to, st); - -out: - if(a != AGLOBL && a != ADATA) - pc++; -} - -void -outhist(void) -{ - Gen g; - Hist *h; - char *p, *q, *op, c; - int n; - - g = nullgen; - c = pathchar(); - for(h = hist; h != H; h = h->link) { - p = h->name; - op = 0; - if(p && p[0] != c && h->offset == 0 && pathname){ - /* on windows skip drive specifier in pathname */ - if(systemtype(Windows) && pathname[1] == ':') { - op = p; - p = pathname+2; - c = *p; - } else if(pathname[0] == c){ - op = p; - p = pathname; - } - } - while(p) { - q = strchr(p, c); - if(q) { - n = q-p; - if(n == 0){ - n = 1; /* leading "/" */ - *p = '/'; /* don't emit "\" on windows */ - } - q++; - } else { - n = strlen(p); - q = 0; - } - if(n) { - Bputc(&obuf, ANAME); - Bputc(&obuf, ANAME>>8); - Bputc(&obuf, D_FILE); /* type */ - Bputc(&obuf, 1); /* sym */ - Bputc(&obuf, '<'); - Bwrite(&obuf, p, n); - Bputc(&obuf, 0); - } - p = q; - if(p == 0 && op) { - p = op; - op = 0; - } - } - g.s0.offset = h->offset; - - Bputc(&obuf, AHISTORY); - Bputc(&obuf, AHISTORY>>8); - Bputc(&obuf, h->line); - Bputc(&obuf, h->line>>8); - Bputc(&obuf, h->line>>16); - Bputc(&obuf, h->line>>24); - zaddr(&nullgen, 0); - zaddr(&g, 0); - } -} - -#include "../cc/lexbody" -#include "../cc/macbody" diff --git a/utils/1a/mkfile b/utils/1a/mkfile deleted file mode 100644 index da0bd1f5..00000000 --- a/utils/1a/mkfile +++ /dev/null @@ -1,30 +0,0 @@ -<../../mkconfig - -TARG=1a - -OFILES=\ - y.tab.$O\ - lex.$O\ - -HFILES=\ - ../2c/2.out.h\ - y.tab.h\ - a.h\ - -YFILES=a.y\ - -LIBS=cc bio 9 # order is important - -BIN=$ROOT/$OBJDIR/bin - -<$ROOT/mkfiles/mkone-$SHELLTYPE - -YFLAGS=-D1 -d -CFLAGS= $CFLAGS -I../include - -lex.$O: ../cc/macbody ../cc/lexbody - -$ROOT/$OBJDIR/lib/libcc.a: - cd ../cc - mk $MKFLAGS install - mk $MKFLAGS clean diff --git a/utils/1c/cgen.c b/utils/1c/cgen.c deleted file mode 100644 index 2f121e51..00000000 --- a/utils/1c/cgen.c +++ /dev/null @@ -1,1396 +0,0 @@ -#include "gc.h" - -void -cgen(Node *n, int result, Node *nn) -{ - Node *l, *r, nod; - int lg, rg, xg, yg, g, o; - long v; - Prog *p1; - - if(n == Z || n->type == T) - return; - if(typesuv[n->type->etype]) { - sugen(n, result, nn, n->type->width); - return; - } - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R\n", result); - prtree(n, "cgen"); - } - l = n->left; - r = n->right; - o = n->op; - if(n->addable >= INDEXED) { - if(result == D_NONE) { - if(nn == Z) - switch(o) { - default: - nullwarn(Z, Z); - break; - case OINDEX: - nullwarn(l, r); - break; - } - return; - } - gmove(n->type, nn->type, D_TREE, n, result, nn); - return; - } - - v = 0; /* set */ - switch(o) { - default: - diag(n, "unknown op in cgen: %O", o); - break; - - case OAS: - if(l->op == OBIT) - goto bitas; - /* - * recursive use of result - */ - if(result == D_NONE) - if(l->addable > INDEXED) - if(l->complex < FNX) { - cgen(r, D_TREE, l); - break; - } - - /* - * function calls on both sides - */ - if(l->complex >= FNX && r->complex >= FNX) { - cgen(r, D_TOS, r); - v = argoff; - lg = regaddr(result); - lcgen(l, lg, Z); - lg |= I_INDIR; - adjsp(v - argoff); - gmove(r->type, l->type, D_TOS, r, lg, l); - if(result != D_NONE) - gmove(l->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - } - - rg = D_TREE; - lg = D_TREE; - if(r->complex >= l->complex) { - /* - * right side before left - */ - if(result != D_NONE) { - rg = regalloc(n->type, result); - cgen(r, rg, n); - } else - if(r->complex >= FNX || r->addable < INDEXED) { - rg = regalloc(r->type, result); - cgen(r, rg, r); - } - if(l->addable < INDEXED) { - lg = regaddr(lg); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - } else { - /* - * left before right - */ - if(l->complex >= FNX || l->addable < INDEXED) { - lg = regaddr(lg); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - if(result != D_NONE) { - rg = regalloc(n->type, result); - cgen(r, rg, n); - } else - if(r->addable < INDEXED) { - rg = regalloc(r->type, result); - cgen(r, rg, r); - } - } - if(result != D_NONE) { - gmove(n->type, l->type, rg, r, lg, l); - gmove(n->type, nn->type, rg, r, result, nn); - } else - gmove(r->type, l->type, rg, r, lg, l); - regfree(lg); - regfree(rg); - break; - - bitas: - n = l->left; - rg = regalloc(tfield, result); - if(l->complex >= r->complex) { - lg = regaddr(D_NONE); - lcgen(n, lg, Z); - lg |= I_INDIR; - cgen(r, rg, r); - } else { - cgen(r, rg, r); - lg = regaddr(D_NONE); - lcgen(n, lg, Z); - lg |= I_INDIR; - } - g = regalloc(n->type, D_NONE); - gmove(l->type, l->type, lg, l, g, l); - bitstore(l, rg, lg, g, result, nn); - break; - - case OBIT: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - g = bitload(n, D_NONE, D_NONE, result, nn); - gopcode(OAS, nn->type, g, n, result, nn); - regfree(g); - break; - - case ODOT: - sugen(l, D_TREE, nodrat, l->type->width); - if(result != D_NONE) { - warn(n, "non-interruptable temporary"); - nod = *nodrat; - if(!r || r->op != OCONST) { - diag(n, "DOT and no offset"); - break; - } - nod.xoffset += r->vconst; - nod.type = n->type; - cgen(&nod, result, nn); - } - break; - - case OASLDIV: - case OASLMOD: - case OASDIV: - case OASMOD: - if(l->op == OBIT) - goto asbitop; - if(typefd[n->type->etype]) - goto asbinop; - rg = D_TREE; - if(l->complex >= FNX || r->complex >= FNX) { - rg = D_TOS; - cgen(r, rg, r); - v = argoff; - } else - if(r->addable < INDEXED) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - lg = D_TREE; - if(!simplv(l)) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); /* destroys register optimization */ - lg |= I_INDIR; - } - g = regpair(result); - gmove(l->type, n->type, lg, l, g, n); - if(rg == D_TOS) - adjsp(v - argoff); - gopcode(o, n->type, rg, r, g, n); - if(o == OASLMOD || o == OASMOD) - gmove(n->type, l->type, g+1, n, lg, l); - else - gmove(n->type, l->type, g, n, lg, l); - if(result != D_NONE) - if(o == OASLMOD || o == OASMOD) - gmove(n->type, nn->type, g+1, n, result, nn); - else - gmove(n->type, nn->type, g, n, result, nn); - regfree(g); - regfree(g+1); - regfree(lg); - regfree(rg); - break; - - case OASXOR: - case OASAND: - case OASOR: - if(l->op == OBIT) - goto asbitop; - if(l->complex >= FNX || - l->addable < INDEXED || - result != D_NONE || - typefd[n->type->etype]) - goto asbinop; - rg = D_TREE; - if(r->op != OCONST) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - gopcode(o, l->type, rg, r, D_TREE, l); - regfree(rg); - break; - - case OASADD: - case OASSUB: - if(l->op == OBIT || - l->complex >= FNX || - l->addable < INDEXED || - result != D_NONE || - typefd[n->type->etype]) - goto asbinop; - v = vconst(r); - if(v > 0 && v <= 8) { - gopcode(o, n->type, D_TREE, r, D_TREE, l); - break; - } - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - gopcode(o, n->type, rg, r, D_TREE, l); - regfree(rg); - break; - - case OASLSHR: - case OASASHR: - case OASASHL: - if(l->op == OBIT || - l->complex >= FNX || - l->addable < INDEXED || - result != D_NONE || - typefd[n->type->etype]) - goto asbinop; - rg = D_TREE; - v = vconst(r); - if(v <= 0 || v > 8) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - lg = regalloc(n->type, D_NONE); - cgen(l, lg, l); - gopcode(o, n->type, rg, r, lg, l); - gmove(n->type, n->type, lg, l, D_TREE, l); - regfree(lg); - regfree(rg); - break; - - case OASLMUL: - case OASMUL: - asbinop: - if(l->op == OBIT) - goto asbitop; - rg = D_TREE; - if(l->complex >= FNX || r->complex >= FNX) { - rg = D_TOS; - cgen(r, rg, r); - v = argoff; - } else - if(r->addable < INDEXED) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } else { - if(o == OASLSHR || o == OASASHR || o == OASASHL) { - v = vconst(r); - if(v <= 0 || v > 8) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - } - } - lg = D_TREE; - if(!simplv(l)) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); /* destroys register optimization */ - lg |= I_INDIR; - } - g = regalloc(n->type, result); - gmove(l->type, n->type, lg, l, g, n); - if(rg == D_TOS) - adjsp(v - argoff); - if(o == OASXOR) - if(rg == D_TREE) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - if(o == OASXOR || o == OASLSHR || o == OASASHR || o == OASASHL) - if(rg == D_TOS) { - rg = regalloc(n->type, D_NONE); - gmove(n->type, n->type, D_TOS, n, rg, n); - } - gopcode(o, n->type, rg, r, g, n); - gmove(n->type, l->type, g, n, lg, l); - if(result != D_NONE) - gmove(n->type, nn->type, g, n, result, nn); - regfree(g); - regfree(lg); - regfree(rg); - break; - - asbitop: - rg = regaddr(D_NONE); - lg = regalloc(tfield, D_NONE); - if(l->complex >= r->complex) { - g = bitload(l, lg, rg, result, nn); - xg = regalloc(r->type, D_NONE); - cgen(r, xg, nn); - } else { - xg = regalloc(r->type, D_NONE); - cgen(r, xg, nn); - g = bitload(l, lg, rg, result, nn); - } - - if(!typefd[n->type->etype]) { - if(o == OASLDIV || o == OASDIV) { - yg = regpair(result); - gmove(tfield, n->type, g, l, yg, n); - gopcode(o, n->type, xg, r, yg, n); - gmove(n->type, tfield, yg, n, g, l); - regfree(yg); - regfree(yg+1); - - regfree(xg); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } - if(o == OASLMOD || o == OASMOD) { - yg = regpair(result); - gmove(tfield, n->type, g, l, yg, n); - gopcode(o, n->type, xg, r, yg, n); - gmove(n->type, tfield, yg+1, n, g, l); - regfree(yg); - regfree(yg+1); - - regfree(xg); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } - } - - yg = regalloc(n->type, result); - gmove(tfield, n->type, g, l, yg, n); - gopcode(o, n->type, xg, r, yg, n); - gmove(n->type, tfield, yg, n, g, l); - regfree(yg); - - regfree(xg); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - - case OCAST: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - lg = result; - if(l->complex >= FNX) - lg = regret(l->type); - lg = eval(l, lg); - if(nocast(l->type, n->type)) { - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - } - if(nocast(n->type, nn->type)) { - gmove(l->type, n->type, lg, l, result, nn); - regfree(lg); - break; - } - rg = regalloc(n->type, result); - gmove(l->type, n->type, lg, l, rg, n); - gmove(n->type, nn->type, rg, n, result, nn); - regfree(rg); - regfree(lg); - break; - - case OCOND: - doinc(l, PRE); - boolgen(l, 1, D_NONE, Z, l); - p1 = p; - - inargs++; - doinc(r->left, PRE); - cgen(r->left, result, nn); - doinc(r->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(r->right, PRE); - cgen(r->right, result, nn); - doinc(r->right, POST); - patch(p1, pc); - inargs--; - break; - - case OIND: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - lg = nodalloc(types[TIND], result, &nod); - nod.lineno = n->lineno; - if(l->op == OADD) { - if(l->left->op == OCONST) { - nod.xoffset += l->left->vconst; - l = l->right; - } else - if(l->right->op == OCONST) { - nod.xoffset += l->right->vconst; - l = l->left; - } - } - cgen(l, lg, l); - gmove(n->type, nn->type, D_TREE, &nod, result, nn); - regfree(lg); - break; - - case OFUNC: - v = argoff; - inargs++; - gargs(r); - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(result); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - inargs--; - doinc(r, POST); - doinc(l, POST); - gopcode(OFUNC, types[TCHAR], D_NONE, Z, lg, l); - regfree(lg); - if(inargs) - adjsp(v - argoff); - if(result != D_NONE) { - lg = regret(n->type); - gmove(n->type, nn->type, lg, n, result, nn); - } - break; - - case OLDIV: - case OLMOD: - case ODIV: - case OMOD: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - if(typefd[n->type->etype]) - goto binop; - if(r->addable >= INDEXED && r->complex < FNX) { - lg = regpair(result); - cgen(l, lg, l); - rg = D_TREE; - } else { - cgen(r, D_TOS, r); - v = argoff; - lg = regpair(result); - cgen(l, lg, l); - adjsp(v - argoff); - rg = D_TOS; - } - gopcode(o, n->type, rg, r, lg, l); - if(o == OMOD || o == OLMOD) - gmove(l->type, nn->type, lg+1, l, result, nn); - else - gmove(l->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(lg+1); - break; - - case OMUL: - case OLMUL: - if(l->op == OCONST) - if(mulcon(r, l, result, nn)) - break; - if(r->op == OCONST) - if(mulcon(l, r, result, nn)) - break; - if(debug['M']) - print("%L multiply\n", n->lineno); - goto binop; - - case OAND: - if(r->op == OCONST) - if(typeil[n->type->etype]) - if(l->op == OCAST) { - if(typec[l->left->type->etype]) - if(!(r->vconst & ~0xff)) { - l = l->left; - goto binop; - } - if(typeh[l->left->type->etype]) - if(!(r->vconst & ~0xffff)) { - l = l->left; - goto binop; - } - } - goto binop; - - case OADD: - if(result == D_TOS) - if(r->addable >= INDEXED) - if(l->op == OCONST) - if(typeil[l->type->etype]) { - v = l->vconst; - if(v > -32768 && v < 32768) { - rg = regaddr(D_NONE); - gmove(r->type, r->type, D_TREE, r, rg, r); - gopcode(OADDR, types[TSHORT], D_NONE, Z, rg, r); - p->to.offset = v; - p->to.type |= I_INDIR; - regfree(rg); - break; - } - } - - case OSUB: - if(result == D_TOS) - if(l->addable >= INDEXED) - if(r->op == OCONST) - if(typeil[r->type->etype]) { - v = r->vconst; - if(v > -32768 && v < 32768) { - if(n->op == OSUB) - v = -v; - lg = regaddr(D_NONE); - gmove(l->type, l->type, D_TREE, l, lg, l); - gopcode(OADDR, types[TSHORT], D_NONE, Z, lg, l); - p->to.offset = v; - p->to.type |= I_INDIR; - regfree(lg); - break; - } - } - goto binop; - - case OOR: - case OXOR: - binop: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - if(l->complex >= FNX && r->complex >= FNX) { - cgen(r, D_TOS, r); - v = argoff; - lg = regalloc(l->type, result); - cgen(l, lg, l); - adjsp(v - argoff); - if(o == OXOR) { - rg = regalloc(r->type, D_NONE); - gmove(r->type, r->type, D_TOS, r, rg, r); - gopcode(o, n->type, rg, r, lg, l); - regfree(rg); - } else - gopcode(o, n->type, D_TOS, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - } - if(l->complex >= r->complex) { - if(l->op == OADDR && (o == OADD || o == OSUB)) - lg = regaddr(result); - else - lg = regalloc(l->type, result); - cgen(l, lg, l); - rg = eval(r, D_NONE); - } else { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - lg = regalloc(l->type, result); - cgen(l, lg, l); - } - if(o == OXOR) { - if(rg == D_TREE) { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - } - if(rg == D_TOS) { - rg = regalloc(r->type, D_NONE); - gmove(r->type, r->type, D_TOS, r, rg, r); - } - } - gopcode(o, n->type, rg, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(rg); - break; - - case OASHL: - if(r->op == OCONST) - if(shlcon(l, r, result, nn)) - break; - case OLSHR: - case OASHR: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - - if(l->complex >= FNX && r->complex >= FNX) { - cgen(r, D_TOS, r); - v = argoff; - lg = regalloc(l->type, result); - cgen(l, lg, l); - adjsp(v - argoff); - rg = regalloc(r->type, D_NONE); - gopcode(OAS, r->type, D_TOS, r, rg, r); - gopcode(n->op, n->type, rg, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(rg); - break; - } - if(l->complex >= r->complex) { - lg = regalloc(l->type, result); - cgen(l, lg, l); - v = vconst(r); - if(v <= 0 || v > 8) { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - } else - rg = eval(r, D_NONE); - } else { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - lg = regalloc(l->type, result); - cgen(l, lg, l); - } - gopcode(o, n->type, rg, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(rg); - break; - - case ONEG: - case OCOM: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - lg = regalloc(l->type, result); - cgen(l, lg, l); - gopcode(o, l->type, D_NONE, Z, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - - case OADDR: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - lcgen(l, result, nn); - break; - - case OEQ: - case ONE: - case OLE: - case OLT: - case OGE: - case OGT: - case OLO: - case OLS: - case OHI: - case OHS: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - boolgen(n, 1, result, nn, Z); - break; - - case OANDAND: - case OOROR: - boolgen(n, 1, result, nn, Z); - if(result == D_NONE) - patch(p, pc); - break; - - case OCOMMA: - cgen(l, D_NONE, l); - doinc(l, POST); - doinc(r, PRE); - cgen(r, result, nn); - break; - - case ONOT: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - boolgen(n, 1, result, nn, Z); - break; - - case OPOSTINC: - case OPOSTDEC: - v = 1; - if(l->type->etype == TIND) - v = l->type->link->width; - if(o == OPOSTDEC) - v = -v; - if(l->op == OBIT) - goto bitinc; - if(nn == Z) - goto pre; - - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - if(result != D_NONE) - gmove(l->type, nn->type, lg, l, result, nn); - if(typefd[n->type->etype]) { - rg = regalloc(n->type, D_NONE); - gmove(l->type, l->type, lg, l, rg, l); - gopcode(o, n->type, D_CONST, nodconst(1), rg, l); - gmove(l->type, l->type, rg, l, lg, l); - regfree(rg); - } else { - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), lg, l); - else - gopcode(o, n->type, D_CONST, nodconst(v), lg, l); - } - regfree(lg); - break; - - case OPREINC: - case OPREDEC: - v = 1; - if(l->type->etype == TIND) - v = l->type->link->width; - if(o == OPREDEC) - v = -v; - if(l->op == OBIT) - goto bitinc; - - pre: - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - if(typefd[n->type->etype]) { - rg = regalloc(n->type, D_NONE); - gmove(l->type, l->type, lg, l, rg, l); - gopcode(o, n->type, D_CONST, nodconst(1), rg, l); - gmove(l->type, l->type, rg, l, lg, l); - regfree(rg); - } else { - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), lg, l); - else - gopcode(o, n->type, D_CONST, nodconst(v), lg, l); - } - if(result != D_NONE) - gmove(l->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - - bitinc: - rg = regaddr(D_NONE); - lg = regalloc(tfield, D_NONE); - if(result != D_NONE && (o == OPOSTINC || o == OPOSTDEC)) { - g = bitload(l, lg, rg, D_NONE, nn); - if(nn != Z) - gmove(l->type, nn->type, g, l, result, nn); - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), g, n); - else - gopcode(o, n->type, D_CONST, nodconst(v), g, n); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } - g = bitload(l, lg, rg, result, nn); - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), g, n); - else - gopcode(o, n->type, D_CONST, nodconst(v), g, n); - if(result != D_NONE) - gmove(l->type, nn->type, g, l, result, nn); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } -} - -void -lcgen(Node *n, int result, Node *nn) -{ - Node rn; - Prog *p1; - int lg; - - if(n == Z || n->type == T) - return; - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R\n", result); - prtree(n, "lcgen"); - } - if(nn == Z) { - nn = &rn; - nn->type = types[TIND]; - } - switch(n->op) { - case OCOMMA: - cgen(n->left, D_NONE, n->left); - doinc(n->left, POST); - doinc(n->right, PRE); - lcgen(n->right, result, nn); - break; - - case OCOND: - doinc(n->left, PRE); - boolgen(n->left, 1, D_NONE, Z, n->left); - p1 = p; - - inargs++; - doinc(n->right->left, PRE); - lcgen(n->right->left, result, nn); - doinc(n->right->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(n->right->right, PRE); - lcgen(n->right->right, result, nn); - doinc(n->right->right, POST); - patch(p1, pc); - inargs--; - break; - - case OIND: - if(n->addable >= INDEXED) { - if(result >= D_A0 && result < D_A0+NREG) { - gopcode(OADDR, types[TLONG], D_TREE, n, result, nn); - break; - } - if(result == D_TOS) { - gopcode(OADDR, types[TSHORT], D_NONE, nn, D_TREE, n); - break; - } - } - cgen(n->left, result, nn); - break; - - default: - if(n->addable < INDEXED) { - diag(n, "unknown op in lcgen: %O", n->op); - break; - } - if(result >= D_A0 && result < D_A0+NREG) { - gopcode(OADDR, types[TLONG], D_TREE, n, result, nn); - break; - } - if(result == D_TOS) { - gopcode(OADDR, types[TSHORT], D_NONE, nn, D_TREE, n); - break; - } - lg = regaddr(result); - gopcode(OADDR, types[TLONG], D_TREE, n, lg, nn); - gopcode(OAS, nn->type, lg, nn, result, nn); - regfree(lg); - break; - } -} - -void -bcgen(Node *n, int true) -{ - - boolgen(n, true, D_NONE, Z, Z); -} - -void -boolgen(Node *n, int true, int result, Node *nn, Node *post) -{ - Prog *p1, *p2; - Node *l, *r; - int lg, rg, fp, o; - long v; - - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R\n", result); - prtree(n, "boolgen"); - } - l = n->left; - r = n->right; - switch(n->op) { - - default: - lg = eval(n, result); - if(lg >= D_A0 && lg < D_A0+NREG) { - rg = regalloc(types[TLONG], D_NONE); - gopcode(OAS, types[TLONG], lg, n, rg, Z); - regfree(rg); - } else - gopcode(OTST, n->type, D_NONE, Z, lg, n); - regfree(lg); - o = ONE; - fp = typefd[n->type->etype]; - goto genbool; - - case OCONST: - fp = vconst(n); - if(!true) - fp = !fp; - gbranch(OGOTO); - if(fp) { - p1 = p; - gbranch(OGOTO); - patch(p1, pc); - } - goto com; - - case ONOT: - boolgen(l, !true, result, nn, post); - break; - - case OCOND: - doinc(l, PRE); - boolgen(l, 1, D_NONE, Z, l); - p1 = p; - - inargs++; - doinc(r->left, PRE); - boolgen(r->left, true, result, nn, r->left); - if(result != D_NONE) { - doinc(r->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(r->right, PRE); - boolgen(r->right, !true, result, nn, r->right); - doinc(r->right, POST); - patch(p1, pc); - inargs--; - break; - } - p2 = p; - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(r->right, PRE); - boolgen(r->right, !true, result, nn, r->right); - patch(p2, pc); - p2 = p; - if(doinc(post, POST|TEST)) { - lg = regalloc(types[TSHORT], D_NONE); - gopcode(OAS, types[TSHORT], D_CCR, Z, lg, Z); - doinc(post, POST); - gopcode(OAS, types[TSHORT], lg, Z, D_CCR, Z); - regfree(lg); - } - gbranch(OGOTO); - patch(p1, pc); - patch(p2, pc); - inargs--; - goto com; - - case OANDAND: - if(!true) - goto caseor; - - caseand: - doinc(l, PRE); - boolgen(l, true, D_NONE, Z, l); - p1 = p; - inargs++; - doinc(r, PRE); - boolgen(r, !true, D_NONE, Z, r); - p2 = p; - patch(p1, pc); - gbranch(OGOTO); - patch(p2, pc); - inargs--; - goto com; - - case OOROR: - if(!true) - goto caseand; - - caseor: - doinc(l, PRE); - boolgen(l, !true, D_NONE, Z, l); - p1 = p; - inargs++; - doinc(r, PRE); - boolgen(r, !true, D_NONE, Z, r); - p2 = p; - gbranch(OGOTO); - patch(p1, pc); - patch(p2, pc); - inargs--; - goto com; - - case OEQ: - case ONE: - if(vconst(l) == 0) { - if(n->op == ONE) { - boolgen(r, true, result, nn, post); - break; - } - boolgen(r, !true, result, nn, post); - break; - } - - case OLE: - case OLT: - case OGE: - case OGT: - case OHI: - case OHS: - case OLO: - case OLS: - fp = typefd[r->type->etype]; - if(l->op == OCONST) { - v = vconst(l); - if(v == 0) { /* tst instruction */ - o = invrel[relindex(n->op)]; - rg = eval(r, result); - gopcode(OTST, r->type, D_NONE, Z, rg, r); - regfree(rg); - goto genbool; - } - if(!fp) { /* cmpi and movq, saves about .5% both time and space */ - if(v < 128 && v >= -128 && - ewidth[r->type->etype] == SZ_LONG) { - rg = eval(r, result); - lg = regalloc(l->type, D_NONE); - cgen(l, lg, l); - o = n->op; - gopcode(o, l->type, lg, l, rg, r); - regfree(lg); - regfree(rg); - goto genbool; - } - o = invrel[relindex(n->op)]; - rg = eval(r, result); - gopcode(o, r->type, rg, r, D_TREE, l); - regfree(rg); - goto genbool; - } - } - lg = D_TOS; - if(r->complex < FNX) - lg = regalloc(l->type, lg); - cgen(l, lg, l); - v = argoff; - rg = eval(r, result); - if(lg == D_TOS) { - adjsp(v - argoff); - lg = regalloc(l->type, lg); - gopcode(OAS, l->type, D_TOS, l, lg, l); - } - o = n->op; - gopcode(o, l->type, lg, l, rg, r); - regfree(lg); - regfree(rg); - - genbool: - if(true) - o = comrel[relindex(o)]; - if(doinc(post, POST|TEST)) { - lg = regalloc(types[TSHORT], D_NONE); - gopcode(OAS, types[TSHORT], D_CCR, Z, lg, Z); - doinc(post, POST); - gopcode(OAS, types[TSHORT], lg, Z, D_CCR, Z); - regfree(lg); - } - gbranch(o); - if(fp) - fpbranch(); - - com: - if(result == D_NONE) - break; - p1 = p; - gopcode(OAS, nn->type, D_CONST, nodconst(1), result, nn); - gbranch(OGOTO); - p2 = p; - patch(p1, pc); - gopcode(OAS, nn->type, D_CONST, nodconst(0), result, nn); - patch(p2, pc); - break; - } -} - -void -sugen(Node *n, int result, Node *nn, long w) -{ - long s, v, o; - int lg, rg, ng; - Prog *p1; - Node *l, *r, nod; - Type *t; - - if(n == Z || n->type == T) - return; - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R width = %ld\n", result, w); - prtree(n, "sugen"); - } - s = argoff; - if(result == D_TREE) { - if(nn == nodrat) - if(w > nrathole) - nrathole = w; - } - - if(n->addable >= INDEXED && n->op != OCONST) - goto copy; - switch(n->op) { - default: - diag(n, "unknown op in sugen: %O", n->op); - break; - - case OCONST: - if(n->type && typev[n->type->etype]) { - if(result == D_NONE) { - nullwarn(n->left, Z); - break; - } - - lg = regaddr(D_NONE); - if(result == D_TOS) { - adjsp(s - argoff + w); - gopcode(OADDR, types[TIND], result, nn, lg, n); - } else - if(result == D_TREE) { - lcgen(nn, lg, Z); - } else - diag(n, "unknown su result: %R", result); - - gopcode(OAS, types[TLONG], D_CONST, nodconst((long)(n->vconst>>32)), - lg|I_INDINC, n); - gopcode(OAS, types[TLONG], D_CONST, nodconst((long)(n->vconst)), - lg|I_INDINC, n); - regfree(lg); - break; - } - goto copy; - - case ODOT: - l = n->left; - sugen(l, D_TREE, nodrat, l->type->width); - if(result != D_NONE) { - warn(n, "non-interruptable temporary"); - nod = *nodrat; - r = n->right; - if(!r || r->op != OCONST) { - diag(n, "DOT and no offset"); - break; - } - nod.xoffset += r->vconst; - nod.type = n->type; - sugen(&nod, result, nn, w); - } - break; - - case OIND: - if(result == D_NONE) { - nullwarn(n->left, Z); - break; - } - goto copy; - - case OSTRUCT: - lg = nodalloc(types[TIND], result, &nod); - nod.lineno = n->lineno; - if(result == D_TREE) - lcgen(nn, lg, Z); - else - if(result == D_TOS) { - adjsp(s - argoff + w); - gopcode(OADDR, types[TIND], result, nn, lg, n); - } else - diag(n, "unknown su result: %R", result); - o = 0; - r = n->left; - for(t = n->type->link; t != T; t = t->down) { - l = r; - if(r->op == OLIST) { - l = r->left; - r = r->right; - } - nod.type = t; - if(l->complex < FNX) { - nod.xoffset = 0; - if(o != t->offset) { - gopcode(OADD, types[TIND], D_CONST, - nodconst(t->offset-o), lg, Z); - o = t->offset; - } - cgen(l, D_TREE, &nod); - continue; - } - nod.xoffset = t->offset - o; - gopcode(OAS, types[TIND], lg, Z, D_TOS, Z); - s = argoff; - if(typesuv[t->etype]) { - sugen(l, D_TREE, nodrat, t->width); - adjsp(s - argoff); - gopcode(OAS, types[TIND], D_TOS, Z, lg, Z); - warn(n, "non-interruptable temporary"); - sugen(nodrat, D_TREE, &nod, t->width); - continue; - } - rg = regalloc(t, D_NONE); - cgen(l, rg, l); - adjsp(s - argoff); - gopcode(OAS, types[TIND], D_TOS, Z, lg, Z); - gopcode(OAS, t, rg, Z, D_TREE, &nod); - regfree(rg); - } - regfree(lg); - break; - - case OAS: - if(result == D_NONE) { - sugen(n->right, D_TREE, n->left, w); - break; - } - sugen(n->right, D_TREE, nodrat, w); /* could do better */ - warn(n, "non-interruptable temporary"); - sugen(nodrat, D_TREE, n->left, w); - sugen(nodrat, result, nn, w); - break; - - case OFUNC: - if(result == D_NONE) { - sugen(n, D_TREE, nodrat, w); - break; - } - inargs++; - /* prepare zero-th arg: address of result */ - if(result == D_TOS) { - adjsp(s - argoff + w); - v = argoff; - gargs(n->right); - gopcode(OADDR, types[TSHORT], D_NONE, nn, result, nn); - p->to.type = D_STACK; - p->to.offset = argoff - v; - } else - if(result == D_TREE) { - v = argoff; - gargs(n->right); - if(nn->complex >= FNX) { - rg = regalloc(types[TIND], regret(types[TIND])); - lcgen(nn, rg, Z); - gopcode(OAS, types[TIND], rg, Z, D_TOS, Z); - regfree(rg); - } else - lcgen(nn, D_TOS, Z); - } else { - diag(n, "unknown result in FUNC sugen"); - break; - } - argoff += types[TIND]->width; - l = n->left; - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(result); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - inargs--; - doinc(n->right, POST); - doinc(n->left, POST); - gopcode(OFUNC, types[TCHAR], D_NONE, Z, lg, l); - regfree(lg); - if(inargs) - adjsp(v - argoff); - break; - - case OCOND: - doinc(n->left, PRE); - boolgen(n->left, 1, D_NONE, Z, n->left); - p1 = p; - - inargs++; - doinc(n->right->left, PRE); - sugen(n->right->left, result, nn, w); - doinc(n->right->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(n->right->right, PRE); - sugen(n->right->right, result, nn, w); - doinc(n->right->right, POST); - patch(p1, pc); - inargs--; - break; - - case OCOMMA: - cgen(n->left, D_NONE, n->left); - doinc(n->left, POST); - doinc(n->right, PRE); - sugen(n->right, result, nn, w); - break; - } - return; - -copy: - if(result == D_NONE) - return; - rg = regaddr(D_NONE); - lcgen(n, rg, Z); - - lg = regaddr(D_NONE); - if(result == D_TOS) { - adjsp(s - argoff + w); - gopcode(OADDR, types[TIND], result, nn, lg, n); - } else - if(result == D_TREE) { - if(nn->complex >= FNX) { - gopcode(OAS, types[TIND], rg, n, D_TOS, n); - s = argoff; - lcgen(nn, lg, Z); - adjsp(s - argoff); - gopcode(OAS, types[TIND], D_TOS, n, rg, n); - } else - lcgen(nn, lg, Z); - } else - diag(n, "unknown su result: %R", result); - - if(w % SZ_LONG) - diag(Z, "sucopy width not 0%%%d", SZ_LONG); - v = w / SZ_LONG; - if(v & 1) { - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - v--; - } - if(v > 6) { - ng = regalloc(types[TLONG], D_NONE); - gopcode(OAS, types[TLONG], D_CONST, nodconst(v/2-1), ng, n); - v = pc; - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - gbranch(OGT); - patch(p, v); - p->from.type = ng; - p->as = ADBF; - regfree(ng); - } else - while(v > 0) { - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - v--; - } - - regfree(lg); - regfree(rg); -} diff --git a/utils/1c/enam.c b/utils/1c/enam.c deleted file mode 100644 index be6917af..00000000 --- a/utils/1c/enam.c +++ /dev/null @@ -1,425 +0,0 @@ -char *anames[] = -{ - "XXX", - "ABCD", - "ADDB", - "ADDL", - "ADDW", - "ADDXB", - "ADDXL", - "ADDXW", - "ADJSP", - "ANDB", - "ANDL", - "ANDW", - "ASLB", - "ASLL", - "ASLW", - "ASRB", - "ASRL", - "ASRW", - "BCASE", - "BCC", - "BCHG", - "BCLR", - "BCS", - "BEQ", - "BFCHG", - "BFCLR", - "BFEXTS", - "BFEXTU", - "BFFFO", - "BFINS", - "BFSET", - "BFTST", - "BGE", - "BGT", - "BHI", - "BKPT", - "BLE", - "BLS", - "BLT", - "BMI", - "BNE", - "BPL", - "BRA", - "BSET", - "BSR", - "BTST", - "BVC", - "BVS", - "CALLM", - "CAS2B", - "CAS2L", - "CAS2W", - "CASB", - "CASEW", - "CASL", - "CASW", - "CHK2B", - "CHK2L", - "CHK2W", - "CHKL", - "CHKW", - "CLRB", - "CLRL", - "CLRW", - "CMP2B", - "CMP2L", - "CMP2W", - "CMPB", - "CMPL", - "CMPW", - "DATA", - "DBCC", - "DBCS", - "DBEQ", - "DBF", - "DBGE", - "DBGT", - "DBHI", - "DBLE", - "DBLS", - "DBLT", - "DBMI", - "DBNE", - "DBPL", - "DBT", - "DBVC", - "DBVS", - "DIVSL", - "DIVSW", - "DIVUL", - "DIVUW", - "END", - "EORB", - "EORL", - "EORW", - "EXG", - "EXTBL", - "EXTBW", - "EXTWL", - "FABSB", - "FABSD", - "FABSF", - "FABSL", - "FABSW", - "FACOSB", - "FACOSD", - "FACOSF", - "FACOSL", - "FACOSW", - "FADDB", - "FADDD", - "FADDF", - "FADDL", - "FADDW", - "FASINB", - "FASIND", - "FASINF", - "FASINL", - "FASINW", - "FATANB", - "FATAND", - "FATANF", - "FATANHB", - "FATANHD", - "FATANHF", - "FATANHL", - "FATANHW", - "FATANL", - "FATANW", - "FBEQ", - "FBF", - "FBGE", - "FBGT", - "FBLE", - "FBLT", - "FBNE", - "FBT", - "FCMPB", - "FCMPD", - "FCMPF", - "FCMPL", - "FCMPW", - "FCOSB", - "FCOSD", - "FCOSF", - "FCOSHB", - "FCOSHD", - "FCOSHF", - "FCOSHL", - "FCOSHW", - "FCOSL", - "FCOSW", - "FDBEQ", - "FDBF", - "FDBGE", - "FDBGT", - "FDBLE", - "FDBLT", - "FDBNE", - "FDBT", - "FDIVB", - "FDIVD", - "FDIVF", - "FDIVL", - "FDIVW", - "FETOXB", - "FETOXD", - "FETOXF", - "FETOXL", - "FETOXM1B", - "FETOXM1D", - "FETOXM1F", - "FETOXM1L", - "FETOXM1W", - "FETOXW", - "FGETEXPB", - "FGETEXPD", - "FGETEXPF", - "FGETEXPL", - "FGETEXPW", - "FGETMANB", - "FGETMAND", - "FGETMANF", - "FGETMANL", - "FGETMANW", - "FINTB", - "FINTD", - "FINTF", - "FINTL", - "FINTRZB", - "FINTRZD", - "FINTRZF", - "FINTRZL", - "FINTRZW", - "FINTW", - "FLOG10B", - "FLOG10D", - "FLOG10F", - "FLOG10L", - "FLOG10W", - "FLOG2B", - "FLOG2D", - "FLOG2F", - "FLOG2L", - "FLOG2W", - "FLOGNB", - "FLOGND", - "FLOGNF", - "FLOGNL", - "FLOGNP1B", - "FLOGNP1D", - "FLOGNP1F", - "FLOGNP1L", - "FLOGNP1W", - "FLOGNW", - "FMODB", - "FMODD", - "FMODF", - "FMODL", - "FMODW", - "FMOVEB", - "FMOVED", - "FMOVEF", - "FMOVEL", - "FMOVEM", - "FMOVEMC", - "FMOVEW", - "FMULB", - "FMULD", - "FMULF", - "FMULL", - "FMULW", - "FNEGB", - "FNEGD", - "FNEGF", - "FNEGL", - "FNEGW", - "FREMB", - "FREMD", - "FREMF", - "FREML", - "FREMW", - "FRESTORE", - "FSAVE", - "FSCALEB", - "FSCALED", - "FSCALEF", - "FSCALEL", - "FSCALEW", - "FSEQ", - "FSF", - "FSGE", - "FSGT", - "FSINB", - "FSIND", - "FSINF", - "FSINHB", - "FSINHD", - "FSINHF", - "FSINHL", - "FSINHW", - "FSINL", - "FSINW", - "FSLE", - "FSLT", - "FSNE", - "FSQRTB", - "FSQRTD", - "FSQRTF", - "FSQRTL", - "FSQRTW", - "FST", - "FSUBB", - "FSUBD", - "FSUBF", - "FSUBL", - "FSUBW", - "FTANB", - "FTAND", - "FTANF", - "FTANHB", - "FTANHD", - "FTANHF", - "FTANHL", - "FTANHW", - "FTANL", - "FTANW", - "FTENTOXB", - "FTENTOXD", - "FTENTOXF", - "FTENTOXL", - "FTENTOXW", - "FTSTB", - "FTSTD", - "FTSTF", - "FTSTL", - "FTSTW", - "FTWOTOXB", - "FTWOTOXD", - "FTWOTOXF", - "FTWOTOXL", - "FTWOTOXW", - "GLOBL", - "GOK", - "HISTORY", - "ILLEG", - "INSTR", - "JMP", - "JSR", - "LEA", - "LINKL", - "LINKW", - "LOCATE", - "LONG", - "LSLB", - "LSLL", - "LSLW", - "LSRB", - "LSRL", - "LSRW", - "MOVB", - "MOVEM", - "MOVEPL", - "MOVEPW", - "MOVESB", - "MOVESL", - "MOVESW", - "MOVL", - "MOVW", - "MULSL", - "MULSW", - "MULUL", - "MULUW", - "NAME", - "NBCD", - "NEGB", - "NEGL", - "NEGW", - "NEGXB", - "NEGXL", - "NEGXW", - "NOP", - "NOTB", - "NOTL", - "NOTW", - "ORB", - "ORL", - "ORW", - "PACK", - "PEA", - "RESET", - "ROTLB", - "ROTLL", - "ROTLW", - "ROTRB", - "ROTRL", - "ROTRW", - "ROXLB", - "ROXLL", - "ROXLW", - "ROXRB", - "ROXRL", - "ROXRW", - "RTD", - "RTE", - "RTM", - "RTR", - "RTS", - "SBCD", - "SCC", - "SCS", - "SEQ", - "SF", - "SGE", - "SGT", - "SHI", - "SLE", - "SLS", - "SLT", - "SMI", - "SNE", - "SPL", - "ST", - "STOP", - "SUBB", - "SUBL", - "SUBW", - "SUBXB", - "SUBXL", - "SUBXW", - "SVC", - "SVS", - "SWAP", - "SYS", - "TAS", - "TEXT", - "TRAP", - "TRAPCC", - "TRAPCS", - "TRAPEQ", - "TRAPF", - "TRAPGE", - "TRAPGT", - "TRAPHI", - "TRAPLE", - "TRAPLS", - "TRAPLT", - "TRAPMI", - "TRAPNE", - "TRAPPL", - "TRAPT", - "TRAPV", - "TRAPVC", - "TRAPVS", - "TSTB", - "TSTL", - "TSTW", - "UNLK", - "UNPK", - "WORD", - "SIGNAME", - "LAST", -}; diff --git a/utils/1c/gc.h b/utils/1c/gc.h deleted file mode 100644 index ca2c84fb..00000000 --- a/utils/1c/gc.h +++ /dev/null @@ -1,339 +0,0 @@ -#include "../cc/cc.h" -#include "../2c/2.out.h" -/* - * 1c/68000 - * Motorola 68000 - */ - -#define SZ_CHAR 1 -#define SZ_SHORT 2 -#define SZ_INT 4 -#define SZ_LONG 4 -#define SZ_IND 4 -#define SZ_FLOAT 4 -#define SZ_VLONG 8 -#define SZ_DOUBLE 8 - -#define ALLOP OEND -#define NRGN 300 -#define FNX 100 -#define INDEXED 9 - -#define PRE 1 -#define POST 2 -#define TEST 4 - -typedef struct Adr Adr; -typedef struct Prog Prog; -typedef struct Txt Txt; -typedef struct Cases Case; -typedef struct Reg Reg; -typedef struct Rgn Rgn; -typedef struct Var Var; -typedef struct Multab Multab; -typedef struct C1 C1; - -struct Adr -{ - long displace; - long offset; - - char sval[NSNAME]; - double dval; - - Sym* sym; - short type; - short field; - short etype; -}; -#define A ((Adr*)0) - -struct Prog -{ - Adr from; - Adr to; - Prog* link; - long lineno; - short as; -}; -#define P ((Prog*)0) - -struct Txt -{ - short movas; - short postext; - char preclr; -}; - -struct Cases -{ - long val; - long label; - uchar def; - Case* link; -}; -#define C ((Case*)0) - -struct Var -{ - long offset; - Sym* sym; - char type; - char etype; -}; - -struct Reg -{ - long pc; - long rpo; /* reverse post ordering */ - - Bits set; - Bits use1; - Bits use2; - - Bits refbehind; - Bits refahead; - Bits calbehind; - Bits calahead; - Bits regdiff; - Bits act; - - ulong regu; - long loop; /* could be shorter */ - - Reg* log5; - long active; - - Reg* p1; - Reg* p2; - Reg* p2link; - Reg* s1; - Reg* s2; - Reg* link; - Prog* prog; -}; -#define R ((Reg*)0) - -struct Rgn -{ - Reg* enter; - short costr; - short costa; - short varno; - short regno; -}; - -struct Multab -{ - short val; - char code[6]; -}; - -struct C1 -{ - long val; - long label; -}; - -#define BLOAD(r) band(bnot(r->refbehind), r->refahead) -#define BSTORE(r) band(bnot(r->calbehind), r->calahead) -#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z]) -#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z]) - -#define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32)) - -#define CLOAD 8 -#define CREF 5 -#define CTEST 2 -#define CXREF 3 -#define CINF 1000 -#define LOOP 3 - -EXTERN Bits externs; -EXTERN Bits params; -EXTERN Bits addrs; -EXTERN ulong regbits; - -#define B_INDIR (1<<0) -#define B_ADDR (1<<1) -EXTERN int mvbits; -EXTERN int changer; -EXTERN int changea; - -EXTERN Txt txt[NTYPE][NTYPE]; -EXTERN short opxt[ALLOP][NTYPE]; -EXTERN Txt* txtp; -EXTERN int multabsize; - -EXTERN Reg* firstr; -EXTERN Reg* lastr; -EXTERN Reg zreg; -EXTERN Reg* freer; - -EXTERN long argoff; -EXTERN long breakpc; -EXTERN Case* cases; -EXTERN long continpc; -EXTERN Prog* firstp; -EXTERN Reg* firstr; -EXTERN int inargs; -EXTERN Prog* lastp; -EXTERN int retok; -EXTERN long mnstring; -EXTERN Node* nodrat; -EXTERN Node* nodret; -EXTERN long nrathole; -EXTERN long nstatic; -EXTERN int nregion; -EXTERN long nstring; -EXTERN int nvar; -EXTERN Prog* p; -EXTERN long pc; -EXTERN Rgn region[NRGN]; -EXTERN Rgn* rgp; -EXTERN char string[NSNAME]; -EXTERN Sym* symrathole; -EXTERN Sym* symstatic; -EXTERN Var var[NVAR]; -EXTERN long* idom; -EXTERN Reg** rpo2r; -EXTERN long maxnr; -EXTERN Prog zprog; - -EXTERN uchar regused[NREG]; -EXTERN uchar aregused[NREG]; -EXTERN uchar fregused[NREG]; -EXTERN uchar regbase[I_MASK]; -EXTERN long exregoffset; -EXTERN long exaregoffset; -EXTERN long exfregoffset; -extern char* anames[]; -extern Multab multab[]; - -void cgen(Node*, int, Node*); -void lcgen(Node*, int, Node*); -void bcgen(Node*, int); -void boolgen(Node*, int, int, Node*, Node*); -void sugen(Node*, int, Node*, long); - - -void listinit(void); -int Bconv(Fmt*); -int Pconv(Fmt*); -int Aconv(Fmt*); -int Xconv(Fmt*); -int Dconv(Fmt*); -int Rconv(Fmt*); -int Sconv(Fmt*); - -void peep(void); -void excise(Reg*); -Reg* uniqp(Reg*); -Reg* uniqs(Reg*); -int findtst(Reg*, Prog*, int); -int setcc(Prog*, Prog*); -int compat(Adr*, Adr*); -int aregind(Adr*); -int asize(int); -int usedin(int, Adr*); -Reg* findccr(Reg*); -int setccr(Prog*); -Reg* findop(Reg*, int, int, int); -int regtyp(int); -int anyvar(Adr*); -int subprop(Reg*); -int copyprop(Reg*); -int copy1(Adr*, Adr*, Reg*, int); -int copyu(Prog*, Adr*, Adr*); -int copyas(Adr*, Adr*); -int tasas(Adr*, Adr*); -int copyau(Adr*, Adr*); -int copysub(Adr*, Adr*, Adr*, Prog*, int); - -ulong RtoB(int); -ulong AtoB(int); -ulong FtoB(int); -int BtoR(ulong); -int BtoA(ulong); -int BtoF(ulong); - -Reg* rega(void); -int rcmp(const void*, const void*); -void regopt(Prog*); -void addmove(Reg*, int, int, int); -Bits mkvar(Adr*, int); -void prop(Reg*, Bits, Bits); -void loopit(Reg*, long); -void synch(Reg*, Bits); -ulong allreg(ulong, Rgn*); -void paint1(Reg*, int); -ulong paint2(Reg*, int); -void paint3(Reg*, int, ulong, int); -void addreg(Adr*, int); - -void codgen(Node*, Node*); -void gen(Node*); -void noretval(int); -void usedset(Node*, int); -Node* nodconst(long); - -int swcmp(const void*, const void*); -void doswit(int, Node*); -void swit1(C1*, int, long, int, Node*); -void casf(void); -int bitload(Node*, int, int, int, Node*); -void bitstore(Node*, int, int, int, int, Node*); -long outstring(char*, long); -int doinc(Node*, int); -void setsp(void); -void adjsp(long); -int simplv(Node*); -int eval(Node*, int); -void outcode(void); -void ieeedtod(Ieee*, double); -int nodalloc(Type*, int, Node*); -int mulcon(Node*, Node*, int, Node*); -int shlcon(Node*, Node*, int, Node*); -int mulcon1(Node*, long, int, Node*); -void nullwarn(Node*, Node*); - -void tindex(Type*, Type*); -void ginit(void); -void gclean(void); -void oinit(int, int, int, int, int, int); -Prog* prg(void); -void nextpc(void); -void gargs(Node*); -void naddr(Node*, Adr*, int); -int regalloc(Type*, int); -int regaddr(int); -int regpair(int); -int regret(Type*); -void regfree(int); -void gmove(Type*, Type*, int, Node*, int, Node*); -void gopcode(int, Type*, int, Node*, int, Node*); -void asopt(void); -int relindex(int); -void gbranch(int); -void fpbranch(void); -void patch(Prog*, long); -void gpseudo(int, Sym*, int, long); -void gpseudotree(int, Sym*, Node*); - -void indx(Node*); -void bcomplex(Node*); - -/* - * com64 - */ -int com64(Node*); -void com64init(void); -void bool64(Node*); - -#pragma varargck type "A" int -#pragma varargck type "B" Bits -#pragma varargck type "D" Adr* -#pragma varargck type "N" Adr* -#pragma varargck type "P" Prog* -#pragma varargck type "S" char* -#pragma varargck type "R" int diff --git a/utils/1c/list.c b/utils/1c/list.c deleted file mode 100644 index f6bc2e62..00000000 --- a/utils/1c/list.c +++ /dev/null @@ -1,319 +0,0 @@ -#define EXTERN -#include "gc.h" - -void -listinit(void) -{ - - fmtinstall('R', Rconv); - fmtinstall('A', Aconv); - fmtinstall('D', Dconv); - fmtinstall('P', Pconv); - fmtinstall('S', Sconv); - fmtinstall('B', Bconv); -} - -int -Bconv(Fmt *fp) -{ - char str[STRINGSZ], ss[STRINGSZ], *s; - Bits bits; - int i; - - str[0] = 0; - bits = va_arg(fp->args, Bits); - while(bany(&bits)) { - i = bnum(bits); - if(str[0]) - strcat(str, " "); - if(var[i].sym == S) { - sprint(ss, "$%ld", var[i].offset); - s = ss; - } else - s = var[i].sym->name; - if(strlen(str) + strlen(s) + 1 >= STRINGSZ) - break; - strcat(str, s); - bits.b[i/32] &= ~(1L << (i%32)); - } - return fmtstrcpy(fp, str); -} - -int -Pconv(Fmt *fp) -{ - char str[STRINGSZ], s[20]; - Prog *p; - - p = va_arg(fp->args, Prog*); - sprint(str, " %A %D,%D", p->as, &p->from, &p->to); - if(p->from.field) { - sprint(s, ",%d,%d", p->to.field, p->from.field); - strcat(str, s); - } - return fmtstrcpy(fp, str); -} - -int -Aconv(Fmt *fp) -{ - int r; - - r = va_arg(fp->args, int); - return fmtstrcpy(fp, anames[r]); -} - -int -Dconv(Fmt *fp) -{ - char str[40], s[20]; - Adr *a; - int i, j; - long d; - - a = va_arg(fp->args, Adr*); - i = a->type; - j = i & I_MASK; - if(j) { - a->type = i & D_MASK; - d = a->offset; - a->offset = 0; - switch(j) { - case I_INDINC: - sprint(str, "(%D)+", a); - break; - - case I_INDDEC: - sprint(str, "-(%D)", a); - break; - - case I_INDIR: - if(a->type == D_CONST) - sprint(str, "%ld", d); - else - if(d) - sprint(str, "%ld(%D)", d, a); - else - sprint(str, "(%D)", a); - break; - - case I_ADDR: - a->offset = d; - sprint(str, "$%D", a); - break; - } - a->type = i; - a->offset = d; - goto out; - } - switch(i) { - - default: - sprint(str, "%R", i); - break; - - case D_NONE: - str[0] = 0; - break; - - case D_BRANCH: - sprint(str, "%ld(PC)", a->offset-pc); - break; - - case D_EXTERN: - sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); - break; - - case D_STATIC: - sprint(str, "%s<>+%ld(SB)", a->sym->name, a->offset); - break; - - case D_AUTO: - sprint(str, "%s-%ld(SP)", a->sym->name, -a->offset); - break; - - case D_PARAM: - sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); - break; - - case D_CONST: - sprint(str, "$%ld", a->offset); - break; - - case D_STACK: - sprint(str, "TOS+%ld", a->offset); - break; - - case D_FCONST: - sprint(str, "$%.17e", a->dval); - goto out; - - case D_SCONST: - sprint(str, "$\"%S\"", a->sval); - goto out; - } - if(a->displace) { - sprint(s, "/%ld", a->displace); - strcat(str, s); - } -out: - return fmtstrcpy(fp, str); -} - -int -Rconv(Fmt *fp) -{ - char str[20]; - int r; - - r = va_arg(fp->args, int); - if(r >= D_R0 && r < D_R0+NREG) - sprint(str, "R%d", r-D_R0); - else - if(r >= D_A0 && r < D_A0+NREG) - sprint(str, "A%d", r-D_A0); - else - if(r >= D_F0 && r < D_F0+NREG) - sprint(str, "F%d", r-D_F0); - else - switch(r) { - - default: - sprint(str, "gok(%d)", r); - break; - - case D_NONE: - sprint(str, "NONE"); - break; - - case D_TOS: - sprint(str, "TOS"); - break; - - case D_CCR: - sprint(str, "CCR"); - break; - - case D_SR: - sprint(str, "SR"); - break; - - case D_SFC: - sprint(str, "SFC"); - break; - - case D_DFC: - sprint(str, "DFC"); - break; - - case D_CACR: - sprint(str, "CACR"); - break; - - case D_USP: - sprint(str, "USP"); - break; - - case D_VBR: - sprint(str, "VBR"); - break; - - case D_CAAR: - sprint(str, "CAAR"); - break; - - case D_MSP: - sprint(str, "MSP"); - break; - - case D_ISP: - sprint(str, "ISP"); - break; - - case D_TREE: - sprint(str, "TREE"); - break; - - case D_FPCR: - sprint(str, "FPCR"); - break; - - case D_FPSR: - sprint(str, "FPSR"); - break; - - case D_FPIAR: - sprint(str, "FPIAR"); - break; - - case D_TC: - sprint(str, "TC"); - break; - - case D_ITT0: - sprint(str, "ITT0"); - break; - - case D_ITT1: - sprint(str, "ITT1"); - break; - - case D_DTT0: - sprint(str, "DTT0"); - break; - - case D_DTT1: - sprint(str, "DTT1"); - break; - - case D_MMUSR: - sprint(str, "MMUSR"); - break; - case D_URP: - sprint(str, "URP"); - break; - - case D_SRP: - sprint(str, "SRP"); - break; - } - return fmtstrcpy(fp, str); -} - -int -Sconv(Fmt *fp) -{ - int i, c; - char str[30], *p, *s; - - s = va_arg(fp->args, char*); - p = str; - for(i=0; i<sizeof(double); i++) { - c = s[i] & 0xff; - if(c != '\\' && c != '"' && isprint(c)) { - *p++ = c; - continue; - } - *p++ = '\\'; - switch(c) { - case 0: - *p++ = '0'; - continue; - case '\\': - case '"': - *p++ = c; - continue; - case '\n': - *p++ = 'n'; - continue; - case '\t': - *p++ = 't'; - continue; - } - *p++ = ((c>>6) & 7) + '0'; - *p++ = ((c>>3) & 7) + '0'; - *p++ = ((c>>0) & 7) + '0'; - } - *p = 0; - return fmtstrcpy(fp, str); -} diff --git a/utils/1c/mkfile b/utils/1c/mkfile deleted file mode 100644 index e5486b5c..00000000 --- a/utils/1c/mkfile +++ /dev/null @@ -1,29 +0,0 @@ -<../../mkconfig - -TARG=1c - -OFILES=\ - cgen.$O\ - reg.$O\ - txt.$O\ - peep.$O\ - swt.$O\ - sgen.$O\ - list.$O\ - enam.$O\ - mul.$O\ - -HFILES= gc.h\ - ../2c/2.out.h\ - ../cc/cc.h\ - -LIBS=cc bio 9 # order is important - -BIN=$ROOT/$OBJDIR/bin - -<$ROOT/mkfiles/mkone-$SHELLTYPE - -$ROOT/$OBJDIR/lib/libcc.a: - cd ../cc - mk $MKFLAGS install - mk $MKFLAGS clean diff --git a/utils/1c/mul.c b/utils/1c/mul.c deleted file mode 100644 index 65ddda2f..00000000 --- a/utils/1c/mul.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "gc.h" - -/* - * code sequences for multiply by constant - * all sequences start with leading '0'. - * if sequence starts with 'i', then the - * leading '0' is suppressed. - * '0' mov r0,r1 - * '1' sub r0,r1 - * '2' sub r1,r0 - * '3' add r0,r1 - * '4' add r1,r0 - * '5' add r0,r0 - * '6' add r1,r1 - * 'b' lsh $2,r0 - * 'c' lsh $3,r0 - * 'd'-'h' ... - * 'j' lsh $2,r1 - * 'k'-'p' ... - */ -Multab multab[] = -{ - 2, "i5", - 3, "64", - 4, "i55", - 5, "664", - 6, "645", - 7, "c2", - 9, "k4", - 10, "6645", - 11, "66364", - 12, "6455", - 13, "66464", - 14, "6d2", - 15, "d2", - 17, "l4", - 18, "6d4", - 19, "64k4", - 20, "66455", - 21, "664664", - 22, "64c2", - 23, "44c2", - 24, "64c", - 25, "63k4", - 26, "64c4", - 27, "663e2", - 28, "66e2", - 29, "63e2", - 30, "6e2", - 31, "e2", - 33, "m4", - 34, "6e4", - 35, "64l4", - 36, "66e4", - 37, "664k4", - 38, "64k45", - 39, "454c2", - 40, "664c", - 41, "663k4", - 42, "644c4", - 43, "643k4", - 44, "664c4", - 45, "640d2", - 46, "64d2", - 47, "44d2", - 48, "64d", - 49, "63l4", - 50, "64d4", - 51, "640l4", - 52, "646d4", - 53, "643d4", - 54, "6636f2", - 55, "k3f2", - 56, "kf2", - 57, "k2k4", - 58, "636f2", - 59, "663f2", - 60, "66f2", - 61, "63f2", - 62, "6f2", - 63, "f2", - 65, "n4", - 66, "6f4", - 67, "64m4", - 68, "66f4", - 69, "664l4", - 70, "64l45", - 71, "k1f4", - 72, "k4c", - 73, "k4k4", - 74, "664k45", - 75, "6640d2", - 76, "664d2", - 77, "434d2", - 78, "644d2", - 79, "454d2", - 80, "664d", - 81, "663l4", - 82, "644d4", - 83, "643l4", - 84, "664d4", - 85, "6640l4", - 86, "6634l4", - 87, "6443d4", - 88, "6646d4", - 89, "6643d4", - 90, "6406e2", - 91, "643e2", - 92, "646e2", - 93, "640e2", - 94, "64e2", - 95, "44e2", - 96, "64e", - 97, "63m4", - 98, "64e4", - 99, "640m4", - 100, "646e4", - 200, "66f364", - 300, "j40jf2", - 400, "64kg4", - 500, "66h212", - 600, "64m4c4", - 700, "j4c4d2", - 800, "64lh4", - 900, "6464g4", - 1000, "63g2c", - 1100, "j4d2p4", - 1200, "64k4f2", - 1300, "j4n4b4", - 1400, "64j4g2", - 1600, "64d4e", - 1800, "p4c2", - 2000, "63g2d", - 2100, "l4b2o4", - 2200, "k4d4p4", - 2300, "6644h2", - 2400, "j4k4f4", - 2500, "j4e2d4", - 2600, "j40n4c", - 3100, "jd12p2", - 3200, "64d4f", - 3600, "6d1p2", - 3800, "e3k3g2", - 3900, "jf20n4", - 4000, "o4e2", - 4100, "66p455", - 4200, "l4c3e2", - 4300, "l4b1f4", - 4400, "64o4d4", - 4600, "k45h2", - 4700, "k3j4g2", - 4800, "j40d2f", - 5000, "l4c3m4", - 5100, "j40h2b", - 5200, "j40n4d", - 6000, "d1o3h2", - 6100, "o1l4b2", - 6200, "ke12p2", - 6400, "64d4g", - 7200, "66e1p2", - 7400, "m3m4c2", - 7600, "l4f3c2", - 7800, "kg20n4", - 8000, "63g2f", - 8100, "m2b4p4", - 8200, "66p4c", - 8700, "66f4g2", - 8900, "l3j4g4", - 9200, "k45h25", - 9600, "j40d2g", - 9800, "k4f3d4", -}; - -int multabsize = sizeof(multab) / sizeof(multab[0]); diff --git a/utils/1c/peep.c b/utils/1c/peep.c deleted file mode 100644 index 7583da5d..00000000 --- a/utils/1c/peep.c +++ /dev/null @@ -1,1057 +0,0 @@ -#include "gc.h" - -void -peep(void) -{ - Reg *r, *r1, *r2; - Prog *p, *p1; - int t, s; -/* - * complete R structure - */ - t = 0; - for(r=firstr; r!=R; r=r1) { - r1 = r->link; - if(r1 == R) - break; - p = r->prog->link; - while(p != r1->prog) - switch(p->as) { - default: - r2 = rega(); - r->link = r2; - r2->link = r1; - - r2->prog = p; - r2->p1 = r; - r->s1 = r2; - r2->s1 = r1; - r1->p1 = r2; - - r = r2; - t++; - - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - p = p->link; - } - } - -loop1: - /* - * propigate move's by renaming - */ - t = 0; - for(r=firstr; r!=R; r=r->link) { - p = r->prog; - if(p->as == AMOVL || p->as == AFMOVEF || p->as == AFMOVED) - if(regtyp(p->from.type)) - if(anyvar(&p->to)) { - if(copyprop(r)) { - excise(r); - t++; - } else - if(subprop(r) && copyprop(r)) { - excise(r); - t++; - } - } - } - if(t) - goto loop1; - for(r=firstr; r!=R; r=r->link) { - p = r->prog; - /* - * convert (A) ... A++ into (A)++ - * and A-- ... (A) into --(A) - */ - t = aregind(&p->from); - if(t == D_NONE) - goto out1; - s = asize(p->as); - if(s == 0) - goto out1; - r1 = findop(r, t, AADDL, s); - if(r1 != R) { - if(usedin(t, &p->to)) - goto out1; - p->from.type += I_INDINC - I_INDIR; - excise(r1); - goto out1; - } - r1 = findop(r, t, ASUBL, s); - if(r1 != R) { - p->from.type += I_INDDEC - I_INDIR; - excise(r1); - } - out1: - t = aregind(&p->to); - if(t == D_NONE) - goto out2; - s = asize(p->as); - if(s == 0) - goto out2; - r1 = findop(r, t, AADDL, s); - if(r1 != R) { - p->to.type += I_INDINC - I_INDIR; - excise(r1); - goto out2; - } - r1 = findop(r, t, ASUBL, s); - if(r1 != R) { - if(usedin(t, &p->from)) - goto out2; - p->to.type += I_INDDEC - I_INDIR; - excise(r1); - } - out2: - /* - * get rid of unneeded save/restore CCR - */ - if(p->from.type == D_CCR) { - r1 = findccr(r); - if(r1 != R) { - excise(r); - excise(r1); - } - } - switch(p->as) { - case ATSTB: - case ATSTW: - case ATSTL: - if(findtst(r, r->prog, 0)) - excise(r); - } - /* - * turn TSTB (A); BLT; ORB $128,(A) into TAS (A); BLT; NOP - */ - if(p->as == ATSTB && (r1 = r->s1)) { - if((r1->prog->as == ABLT && (r2 = r1->s1)) || - (r1->prog->as == ABGE && (r2 = r1->s2))) { - p1 = r2->prog; - if(p1->as == AORB) - if(p1->from.type == D_CONST) - if(p1->from.offset == 128) - if(r1 == uniqp(r2)) - if(tasas(&p->to, &p1->to)) { - p->as = ATAS; - excise(r2); - } - } - } - } -} - -void -excise(Reg *r) -{ - - p = r->prog; - p->as = ANOP; - p->from = zprog.from; - p->to = zprog.to; -} - -Reg* -uniqp(Reg *r) -{ - Reg *r1; - - r1 = r->p1; - if(r1 == R) { - r1 = r->p2; - if(r1 == R || r1->p2link != R) - return R; - } else - if(r->p2 != R) - return R; - return r1; -} - -Reg* -uniqs(Reg *r) -{ - Reg *r1; - - r1 = r->s1; - if(r1 == R) { - r1 = r->s2; - if(r1 == R) - return R; - } else - if(r->s2 != R) - return R; - return r1; -} - -/* - * chase backward all cc setting. - * returns 1 if all set same. - */ -int -findtst(Reg *r0, Prog *rp, int n) -{ - Reg *r; - int c; - -loop: - n++; - if(n >= 10) - return 0; - for(r=r0->p2; r!=R; r=r->p2link) { - c = setcc(r->prog, rp); - if(c > 0) - continue; - if(c == 0) - return 0; - if(findtst(r, rp, n) == 0) - return 0; - } - r = r0->p1; - if(r == R) - return 1; - c = setcc(r->prog, rp); - if(c > 0) - return 1; - if(c == 0) - return 0; - r0 = r; - goto loop; -} - -/* - * tests cc - * returns -1 if no change - * returns 1 if set the same - * returns 0 if set different - */ -int -setcc(Prog *p, Prog *rp) -{ - int s; - - s = asize(rp->as); - switch(p->as) { - default: - if(debug['P']) - print("unknown setcc %A\n", p->as); - break; - - case ACMPB: - case ACMPW: - case ACMPL: - case ABSR: - return 0; - - case ABRA: - case ABGE: - case ABNE: - case ABLE: - case ABEQ: - case ABHI: - case ABLS: - case ABMI: - case ABPL: - case ABGT: - case ABLT: - case ABCC: - case ABCS: - case APEA: - case ALEA: - case ANOP: - - case AFADDD: - case AFMULD: - case AFDIVD: - case AFSUBD: - case AFADDF: - case AFMULF: - case AFDIVF: - case AFSUBF: - case AADJSP: - return -1; - - case AADDW: - case AADDL: - case ASUBW: - case ASUBL: - case ACLRL: - case ACLRW: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - goto areg; - - case AADDB: - case ASUBB: - case AANDB: - case AANDW: - case AANDL: - case AORB: - case AORW: - case AORL: - case AEORB: - case AEORW: - case AEORL: - case ALSLB: - case ALSLW: - case ALSLL: - case ALSRB: - case ALSRW: - case ALSRL: - case AASLB: - case AASLW: - case AASLL: - case AASRB: - case AASRW: - case AASRL: - case ATSTB: - case ATSTW: - case ATSTL: - case ANEGB: - case ANEGW: - case ANEGL: - case ACLRB: - if(asize(p->as) != s) - break; - if(compat(&rp->to, &p->to)) - return 1; - break; - - case AMOVW: - case AMOVL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - goto areg; - case AMOVB: - if(asize(p->as) != s) - break; - if(compat(&rp->to, &p->to)) - return 1; - if(compat(&rp->to, &p->from)) - return 1; - } - return 0; - -areg: - if((rp->to.type&D_MASK) == p->to.type) - return 0; - return -1; -} - -int -compat(Adr *a, Adr *b) -{ - int o; - - o = a->type; - if((o >= D_R0 && o < D_R0+NREG) || - (o >= D_A0 && o < D_A0+NREG)) - return o == b->type; - o &= D_MASK; - if(o >= D_A0 && o < D_A0+NREG) { - if(o != (b->type&D_MASK)) - return 0; - if(a->offset != b->offset) - return 0; - o = a->type & I_MASK; - if(o == I_INDIR) { - o = b->type & I_MASK; - if(o == I_INDIR || o == I_INDDEC) - return 1; - return 0; - } - if(o == I_INDINC) { - o = b->type & I_MASK; - if(o == I_INDIR) { - b->type += I_INDINC-I_INDIR; - return 1; - } - if(o == I_INDDEC) { - b->type += I_INDIR-I_INDDEC; - return 1; - } - return 0; - } - } - return 0; -} - -int -aregind(Adr *a) -{ - int t; - - t = a->type; - if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR)) - while(a->offset == 0) - return t & D_MASK; - return D_NONE; -} - -int -asize(int a) -{ - - switch(a) { - case AFTSTD: - case AFMOVED: - case AFADDD: - case AFSUBD: - case AFMULD: - case AFDIVD: - case AFCMPD: - case AFNEGD: - return 8; - - case AFTSTF: - case AFMOVEF: - case AFADDF: - case AFSUBF: - case AFMULF: - case AFDIVF: - case AFCMPF: - case AFNEGF: - - case ACLRL: - case ATSTL: - case AMOVL: - case AADDL: - case ASUBL: - case ACMPL: - case AANDL: - case AORL: - case AEORL: - case ALSLL: - case ALSRL: - case AASLL: - case AASRL: - case ANEGL: - return 4; - - case ACLRW: - case ATSTW: - case AMOVW: - case AADDW: - case ASUBW: - case ACMPW: - case AANDW: - case AORW: - case AEORW: - case ALSLW: - case ALSRW: - case AASLW: - case AASRW: - case ANEGW: - return 2; - - case ACLRB: - case ATSTB: - case AMOVB: - case AADDB: - case ASUBB: - case ACMPB: - case AANDB: - case AORB: - case AEORB: - case ALSLB: - case ALSRB: - case AASLB: - case AASRB: - case ANEGB: - return 1; - } - if(debug['P']) - print("unknown asize %A\n", p->as); - return 0; -} - -int -usedin(int t, Adr *a) -{ - - if((a->type&D_MASK) == t) - return 1; - return 0; -} - -Reg* -findccr(Reg *r) -{ - Prog *p; - - for(;;) { - r = uniqs(r); - if(r == R) - break; - p = r->prog; - if(p->to.type == D_CCR) - return r; - if(setccr(p)) - break; - } - return R; -} - -int -setccr(Prog *p) -{ - - switch(p->as) { - case ANOP: - return 0; - - case AADDL: - case AMOVL: - case ACLRL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - return 0; - } - return 1; -} - -Reg* -findop(Reg *r, int t, int o, int s) -{ - Prog *p; - Reg *r1; - - for(;;) { - if(o == AADDL) { - r1 = uniqs(r); - if(r1 == R) - break; - if(uniqp(r1) != r) - break; - } else { - r1 = uniqp(r); - if(r1 == R) - break; - if(uniqs(r1) != r) - break; - } - r = r1; - p = r->prog; - if(usedin(t, &p->from)) - break; - if(usedin(t, &p->to)) { - if(p->as == o) - if(p->to.type == t) - if(p->from.type == D_CONST) - if(p->from.offset == s) - return r; - break; - } - } - return R; -} - -int -regtyp(int t) -{ - - if(t >= D_R0 && t < D_R0+8) - return 1; - if(t >= D_A0 && t < D_A0+8) - return 1; - if(t >= D_F0 && t < D_F0+8) - return 1; - return 0; -} - -int -anyvar(Adr *a) -{ - - if(regtyp(a->type)) - return 1; - return 0; -} - -/* - * the idea is to substitute - * one register for another - * from one MOV to another - * MOV a, R0 - * ADD b, R0 / no use of R1 - * MOV R0, R1 - * would be converted to - * MOV a, R1 - * ADD b, R1 - * MOV R1, R0 - * hopefully, then the former or latter MOVL - * will be eliminated by copy propagation. - */ -int -subprop(Reg *r0) -{ - Prog *p; - Adr *v1, *v2; - Reg *r; - int t; - - p = r0->prog; - v1 = &p->from; - if(!regtyp(v1->type)) - return 0; - v2 = &p->to; - if(!regtyp(v2->type)) - return 0; - for(r=uniqp(r0); r!=R; r=uniqp(r)) { - if(uniqs(r) == R) - break; - p = r->prog; - switch(p->as) { - case ADIVUW: /* these set Rn and Rn+1 */ - case ADIVUL: - case ADIVSW: - case ADIVSL: - case ABSR: - return 0; - - case AFMOVED: - case AFMOVEF: - case AMOVL: - if(p->to.type == v1->type) - goto gotit; - } - if(copyau(&p->from, v2) || copyau(&p->to, v2)) - break; - if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0)) - break; - } - return 0; - -gotit: - copysub(&p->to, v1, v2, p, 1); - if(debug['P']) { - print("gotit: %D->%D\n%P", v1, v2, r->prog); - if(p->from.type == v2->type) - print(" excise"); - print("\n"); - } - if(p->from.type == v2->type) - excise(r); - for(r=uniqs(r); r!=r0; r=uniqs(r)) { - p = r->prog; - copysub(&p->from, v1, v2, p, 1); - copysub(&p->to, v1, v2, p, 1); - if(debug['P']) - print("%P\n", r->prog); - } - t = v1->type; - v1->type = v2->type; - v2->type = t; - if(debug['P']) - print("%P last\n", r->prog); - return 1; -} - -/* - * The idea is to remove redundant copies. - * v1->v2 F=0 - * (use v2 s/v2/v1/)* - * set v1 F=1 - * use v2 return fail - * ----------------- - * v1->v2 F=0 - * (use v2 s/v2/v1/)* - * set v1 F=1 - * set v2 return success - */ -int -copyprop(Reg *r0) -{ - Prog *p; - Adr *v1, *v2; - Reg *r; - - p = r0->prog; - v1 = &p->from; - v2 = &p->to; - if(copyas(v1, v2)) - return 1; - for(r=firstr; r!=R; r=r->link) - r->active = 0; - return copy1(v1, v2, r0->s1, 0); -} - -int -copy1(Adr *v1, Adr *v2, Reg *r, int f) -{ - int t; - - if(r->active) { - if(debug['P']) - print("copyret 1\n"); - return 1; - } - r->active = 1; - if(debug['P']) - print("copy %D->%D\n", v1, v2); - for(; r != R; r = r->s1) { - if(debug['P']) - print("%P", r->prog); - if(!f && uniqp(r) == R) { - f = 1; - if(debug['P']) - print("; merge; f=%d", f); - } - t = copyu(r->prog, v2, A); - switch(t) { - case 2: /* rar, cant split */ - if(debug['P']) - print("; rar return 0\n"); - return 0; - case 3: /* set */ - if(debug['P']) - print("; set; return 1\n"); - return 1; - case 1: /* used, substitute */ - case 4: /* use and set */ - if(f) { - if(debug['P']) - print("; used and f; return 0\n"); - return 0; - } - if(copyu(r->prog, v2, v1)) { - if(debug['P']) - print("; sub fail; return 0\n"); - return 0; - } - if(debug['P']) - print("; substitute"); - if(t == 4) { - if(debug['P']) - print("; used and set; return 1\n"); - return 1; - } - break; - } - if(!f) { - t = copyu(r->prog, v1, A); - if(!f && (t == 2 || t == 3 || t == 4)) { - if(debug['P']) - print("; f set used"); - f = 1; - } - } - if(debug['P']) - print("\n"); - if(r->s2) - if(!copy1(v1, v2, r->s2, f)) - return 0; - } - return 1; -} - -/* - * return - * 1 if v only used (and substitute), - * 2 if read-alter-rewrite - * 3 if set - * 4 if set and used - * 0 otherwise (not touched) - */ -int -copyu(Prog *p, Adr *v, Adr *s) -{ - int t; - - switch(p->as) { - - default: - if(debug['P']) - print("unknown op %A\n", p->as); - return 2; - - case APEA: /* rhs addr */ - if(copyas(&p->to, v)) - return 2; - goto caseread; - - case ALEA: /* lhs addr, rhs store */ - if(copyas(&p->from, v)) - return 2; - - case AMOVL: /* rhs store */ - case ACLRL: - case AFMOVEF: - case AFMOVED: - case AFMOVEB: - case AFMOVEW: - case AFMOVEL: - case ANOP: - if(copyas(&p->to, v)) { - if(s != A) - return copysub(&p->from, v, s, p, 1); - if(copyau(&p->from, v)) - return 4; - return 3; - } - goto caseread; - - case AADDL: /* rhs rar */ - case AADDW: - case AADDB: - case ASUBL: - case ASUBW: - case ASUBB: - case AANDL: - case AANDW: - case AANDB: - case AORL: - case AORW: - case AORB: - case AEORL: - case AEORW: - case AEORB: - case AASRL: - case AASRW: - case AASRB: - case AASLL: - case AASLW: - case AASLB: - case ALSRL: - case ALSRW: - case ALSRB: - case ANOTL: - case ANOTW: - case ANOTB: - case ANEGL: - case ANEGW: - case ANEGB: - case AEXTBL: - case AEXTWL: - case AEXTBW: - - case AMULSL: - case AMULUL: - - case AMOVW: /* only sets part of register */ - case AMOVB: - case ACLRW: - case ACLRB: - - case AFADDD: - case AFMULD: - case AFDIVD: - case AFSUBD: - case AFNEGD: - case AFADDF: - case AFMULF: - case AFDIVF: - case AFSUBF: - case AFNEGF: - if(copyas(&p->to, v)) - return 2; - goto caseread; - - case ADBF: /* lhs rar */ - if(copyas(&p->from, v)) - return 2; - goto caseread; - - case ACMPL: /* read only */ - case ACMPW: - case ACMPB: - case AFCMPF: - case AFCMPD: - case ATSTL: - case ATSTW: - case ATSTB: - case AFTSTF: - case AFTSTD: - caseread: - if(s != A) { - if(copysub(&p->from, v, s, p, 1)) - return 1; - return copysub(&p->to, v, s, p, 1); - } - if(copyau(&p->from, v)) - return 1; - if(copyau(&p->to, v)) - return 1; - break; - - case ABRA: /* no reference */ - case ABGE: - case ABNE: - case ABLE: - case ABEQ: - case ABHI: - case ABLS: - case ABMI: - case ABPL: - case ABGT: - case ABLT: - case ABCC: - case ABCS: - - case AFBEQ: - case AFBNE: - case AFBGT: - case AFBGE: - case AFBLE: - case AFBLT: - - case AADJSP: - case ACASEW: - break; - - case ADIVUW: /* these set Rn and Rn+1 */ - case ADIVUL: - case ADIVSW: - case ADIVSL: - t = v->type; - if(t == p->to.type || t == p->to.type+1) - return 2; - goto caseread; - - case ARTS: /* funny */ - t = v->type; - if(t == D_R0 || t == D_F0) - return 2; - if(t >= D_R0 && t < D_R0+NREG) - if(t-D_R0 > exregoffset) - return 2; - if(t >= D_A0 && t < D_A0+NREG) - if(t-D_A0 > exaregoffset) - return 2; - if(t >= D_F0 && t < D_F0+NREG) - if(t-D_F0 > exfregoffset) - return 2; - return 3; - - case ABSR: /* funny */ - t = v->type; - if(t >= D_R0 && t < D_R0+NREG) - if(t-D_R0 > exregoffset) - return 2; - if(t >= D_A0 && t < D_A0+NREG) - if(t-D_A0 > exaregoffset) - return 2; - if(t >= D_F0 && t < D_F0+NREG) - if(t-D_F0 > exfregoffset) - return 2; - if(copyau(&p->to, v)) - return 2; - return 3; - } - return 0; -} - -/* - * direct reference, - * could be set/use depending on - * semantics - */ -int -copyas(Adr *a, Adr *v) -{ - - if(a->type != v->type) - return 0; - if(regtyp(v->type)) - return 1; - if(v->type == D_AUTO || v->type == D_PARAM) { - if(v->offset == a->offset) - return 1; - return 0; - } - return 0; -} - -/* - * indirect - */ -int -tasas(Adr *a, Adr *v) -{ - int t; - - t = a->type; - if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8) - return 0; - if(v->type != t) - return 0; - if(a->displace != v->displace) - return 0; - return 1; -} - -/* - * either direct or indirect - */ -int -copyau(Adr *a, Adr *v) -{ - int t; - - if(copyas(a, v)) - return 1; - t = v->type; - if(regtyp(t)) { - if((a->type & D_MASK) == t) - return 1; - } - return 0; -} - -/* - * substitute s for v in a - * return failure to substitute - */ -int -copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f) -{ - int t; - - if(copyas(a, v)) { - t = s->type; - if(t >= D_F0 && t < D_F0+8) { - if(f) - a->type = t; - return 0; - } - if(t >= D_R0 && t < D_R0+8) { - if(f) - a->type = t; - return 0; - } - if(!(t >= D_A0 && t < D_A0+8)) - return 1; - switch(p->as) { - default: - return 1; - - case AMOVL: - case AMOVW: - case ACMPL: - case ACMPW: - break; - - case AADDL: - case AADDW: - case ASUBL: - case ASUBW: - if(a == &p->from && !regtyp(p->to.type)) - return 1; - break; - } - if(f) - a->type = t; - return 0; - } - t = v->type; - if(regtyp(t)) { - if((a->type & D_MASK) == t) { - if((s->type ^ t) & ~(NREG-1)) - return 1; - if(f) - a->type = (a->type & ~D_MASK) | s->type; - return 0; - } - return 0; - } - return 0; -} diff --git a/utils/1c/reg.c b/utils/1c/reg.c deleted file mode 100644 index ad4231c0..00000000 --- a/utils/1c/reg.c +++ /dev/null @@ -1,1221 +0,0 @@ -#include "gc.h" - -Reg* -rega(void) -{ - Reg *r; - - r = freer; - if(r == R) { - r = alloc(sizeof(*r)); - } else - freer = r->link; - - *r = zreg; - return r; -} - -int -rcmp(const void *a1, const void *a2) -{ - Rgn *p1, *p2; - int c1, c2; - - p1 = (Rgn*)a1; - p2 = (Rgn*)a2; - c1 = p2->costr; - if(p2->costa > c1) - c1 = p2->costa; - c2 = p1->costr; - if(p1->costa > c2) - c2 = p1->costa; - if(c1 -= c2) - return c1; - return p2->varno - p1->varno; -} - -void -regopt(Prog *p) -{ - Reg *r, *r1, *r2; - Prog *p1; - int i, z; - long val, initpc, npc; - ulong vreg; - Bits bit; - Var *v; - struct { - long m; - long c; - Reg* p; - } log5[6], *lp; - - firstr = R; - lastr = R; - nvar = 0; - for(z=0; z<BITS; z++) { - externs.b[z] = 0; - params.b[z] = 0; - addrs.b[z] = 0; - } - regbits = RtoB(0) | /* return reg */ - AtoB(6) | AtoB(7) | /* sp and sb */ - FtoB(0) | FtoB(1); /* floating return reg */ - for(i=0; i<NREG; i++) { - if(regused[i]) - regbits |= RtoB(i); - if(fregused[i]) - regbits |= FtoB(i); - if(aregused[i]) - regbits |= AtoB(i); - } - - /* - * pass 1 - * build aux data structure - * allocate pcs - * find use and set of variables - */ - val = 5L * 5L * 5L * 5L * 5L; - lp = log5; - for(i=0; i<5; i++) { - lp->m = val; - lp->c = 0; - lp->p = R; - val /= 5L; - lp++; - } - val = 0; - for(; p != P; p = p->link) { - switch(p->as) { - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - continue; - } - r = rega(); - if(firstr == R) { - firstr = r; - lastr = r; - } else { - lastr->link = r; - r->p1 = lastr; - lastr->s1 = r; - lastr = r; - } - r->prog = p; - r->pc = val; - val++; - - lp = log5; - for(i=0; i<5; i++) { - lp->c--; - if(lp->c <= 0) { - lp->c = lp->m; - if(lp->p != R) - lp->p->log5 = r; - lp->p = r; - (lp+1)->c = 0; - break; - } - lp++; - } - - r1 = r->p1; - if(r1 != R) - switch(r1->prog->as) { - case ABRA: - case ARTS: - case ARTE: - r->p1 = R; - r1->s1 = R; - } - - bit = mkvar(&p->from, AGOK); - if(bany(&bit)) - switch(p->as) { - case ALEA: - if(!(mvbits & B_INDIR)) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - - default: - if(mvbits & B_ADDR) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - for(z=0; z<BITS; z++) - r->use1.b[z] |= bit.b[z]; - } - - bit = mkvar(&p->to, p->as); - if(bany(&bit)) - switch(p->as) { - case ABSR: /* funny */ - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - goto def; - - case APEA: - if(!(mvbits & B_INDIR)) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - - def: - case ACMPB: case ACMPW: case ACMPL: - case AFCMPF: case AFCMPD: - case ATSTB: case ATSTW: case ATSTL: - case AFTSTF: case AFTSTD: - case ABFEXTU: case ABFEXTS: - if(mvbits & B_ADDR) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - break; - - default: - diag(Z, "reg: unknown asop: %A", p->as); - - case AADDB: case AADDW: case AADDL: - case ASUBB: case ASUBW: case ASUBL: - case AANDB: case AANDW: case AANDL: - case AORB: case AORW: case AORL: - case AEORB: case AEORW: case AEORL: - case ABFINS: - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - - case ANOP: - case AMOVB: case AMOVW: case AMOVL: - case AFMOVEB: case AFMOVEW: case AFMOVEL: - case ACLRB: case ACLRW: case ACLRL: - case AFMOVEF: case AFMOVED: - if(mvbits & B_INDIR) - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - else - for(z=0; z<BITS; z++) - r->set.b[z] |= bit.b[z]; - break; - - } - } - if(firstr == R) - return; - initpc = pc - val; - npc = val; - - /* - * pass 2 - * turn branch references to pointers - * build back pointers - */ - for(r = firstr; r != R; r = r->link) { - p = r->prog; - if(p->to.type == D_BRANCH) { - val = p->to.offset - initpc; - r1 = firstr; - while(r1 != R) { - r2 = r1->log5; - if(r2 != R && val >= r2->pc) { - r1 = r2; - continue; - } - if(r1->pc == val) - break; - r1 = r1->link; - } - if(r1 == R) { - diag(Z, "ref not found\n%L:%P", p->lineno, p); - continue; - } - if(r1 == r) { - diag(Z, "ref to self"); - continue; - } - r->s2 = r1; - r->p2link = r1->p2; - r1->p2 = r; - } - } - if(debug['R']) - print("\n%L %D\n", firstr->prog->lineno, &firstr->prog->from); - - /* - * pass 2.5 - * find looping structure - */ - for(r = firstr; r != R; r = r->link) - r->active = 0; - changer = 0; - loopit(firstr, npc); - if(debug['R'] && debug['v']) { - print("\nlooping structure:\n"); - for(r = firstr; r != R; r = r->link) { - print("%ld:%P", r->loop, r->prog); - for(z=0; z<BITS; z++) - bit.b[z] = r->use1.b[z] | - r->use2.b[z] | r->set.b[z]; - if(bany(&bit)) { - print("\t"); - if(bany(&r->use1)) - print(" u1=%B", r->use1); - if(bany(&r->use2)) - print(" u2=%B", r->use2); - if(bany(&r->set)) - print(" st=%B", r->set); - } - print("\n"); - } - } - - /* - * pass 3 - * iterate propagating usage - * back until flow graph is complete - */ -loop1: - changer = 0; - for(r = firstr; r != R; r = r->link) - r->active = 0; - for(r = firstr; r != R; r = r->link) - if(r->prog->as == ARTS) - prop(r, zbits, zbits); -loop11: - /* pick up unreachable code */ - i = 0; - for(r = firstr; r != R; r = r1) { - r1 = r->link; - if(r1 && r1->active && !r->active) { - prop(r, zbits, zbits); - i = 1; - } - } - if(i) - goto loop11; - if(changer) - goto loop1; - - /* - * pass 4 - * iterate propagating register/variable synchrony - * forward until graph is complete - */ -loop2: - changer = 0; - for(r = firstr; r != R; r = r->link) - r->active = 0; - synch(firstr, zbits); - if(changer) - goto loop2; - - - /* - * pass 5 - * isolate regions - * calculate costs (paint1) - */ - r = firstr; - if(r) { - for(z=0; z<BITS; z++) - bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & - ~(externs.b[z] | params.b[z] | addrs.b[z]); - if(bany(&bit)) { - nearln = r->prog->lineno; - warn(Z, "used and not set: %B", bit); - if(debug['R'] && !debug['w']) - print("used and not set: %B\n", bit); - - /* - * 68040 'feature': - * load of a denormalized fp will trap - */ - while(bany(&bit)) { - i = bnum(bit); - bit.b[i/32] &= ~(1L << (i%32)); - v = var + i; - if(v->type == D_AUTO) { - r->set.b[i/32] |= (1L << (i%32)); - if(typefd[v->etype]) - addmove(r, i, NREG+NREG, 1); - } - } - } - } - if(debug['R'] && debug['v']) - print("\nprop structure:\n"); - for(r = firstr; r != R; r = r->link) { - if(debug['R'] && debug['v']) - print("%P\n set = %B; rah = %B; cal = %B\n", - r->prog, r->set, r->refahead, r->calahead); - r->act = zbits; - } - rgp = region; - nregion = 0; - for(r = firstr; r != R; r = r->link) { - for(z=0; z<BITS; z++) - bit.b[z] = r->set.b[z] & - ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); - if(bany(&bit)) { - nearln = r->prog->lineno; - warn(Z, "set and not used: %B", bit); - if(debug['R']) - print("set an not used: %B\n", bit); - excise(r); - } - for(z=0; z<BITS; z++) - bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]); - while(bany(&bit)) { - i = bnum(bit); - rgp->enter = r; - rgp->varno = i; - changer = 0; - changea = 0; - if(debug['R'] && debug['v']) - print("\n"); - paint1(r, i); - bit.b[i/32] &= ~(1L<<(i%32)); - if(changer <= 0 && changea <= 0) { - if(debug['R']) - print("%L$%d.%d: %B\n", - r->prog->lineno, - changer, changea, blsh(i)); - continue; - } - rgp->costr = changer; - rgp->costa = changea; - nregion++; - if(nregion >= NRGN) { - warn(Z, "too many regions"); - goto brk; - } - rgp++; - } - } -brk: - qsort(region, nregion, sizeof(region[0]), rcmp); - - /* - * pass 6 - * determine used registers (paint2) - * replace code (paint3) - */ - rgp = region; - for(i=0; i<nregion; i++) { - bit = blsh(rgp->varno); - vreg = paint2(rgp->enter, rgp->varno); - vreg = allreg(vreg, rgp); - if(debug['R']) - print("%L$%d.%d %R: %B\n", - rgp->enter->prog->lineno, - rgp->costr, rgp->costa, - rgp->regno, - bit); - if(rgp->regno != D_NONE) - paint3(rgp->enter, rgp->varno, vreg, rgp->regno); - rgp++; - } - /* - * pass 7 - * peep-hole on basic block - */ - if(!debug['R'] || debug['P']) - peep(); - - /* - * pass 8 - * recalculate pc - */ - val = initpc; - for(r = firstr; r != R; r = r1) { - r->pc = val; - p = r->prog; - p1 = P; - r1 = r->link; - if(r1 != R) - p1 = r1->prog; - for(; p != p1; p = p->link) { - switch(p->as) { - default: - val++; - break; - - case ANOP: - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - break; - } - } - } - pc = val; - - /* - * fix up branches - */ - if(debug['R']) - if(bany(&addrs)) - print("addrs: %B\n", addrs); - - r1 = 0; /* set */ - for(r = firstr; r != R; r = r->link) { - p = r->prog; - if(p->to.type == D_BRANCH) - p->to.offset = r->s2->pc; - r1 = r; - } - - /* - * last pass - * eliminate nops - * free aux structures - */ - for(p = firstr->prog; p != P; p = p->link){ - while(p->link && p->link->as == ANOP) - p->link = p->link->link; - } - if(r1 != R) { - r1->link = freer; - freer = firstr; - } -} - -/* - * add mov b,rn - * just after r - */ -void -addmove(Reg *r, int bn, int rn, int f) -{ - Prog *p, *p1; - Var *v; - int badccr; - - badccr = 0; - p = r->prog; - p1 = p->link; - if(p1) - switch(p1->as) { - case AMOVW: - if(p1->from.type == D_CCR) - p = p1; - break; - - case ABEQ: - case ABNE: - case ABLE: - case ABLS: - case ABLT: - case ABMI: - case ABGE: - case ABPL: - case ABGT: - case ABHI: - case ABCC: - case ABCS: - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - p1->from.type = D_CCR; - p1->to.type = D_TOS; - p1->as = AMOVW; - p = p1; - badccr = 1; - } - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - v = var + bn; - p1->from.sym = v->sym; - p1->from.type = v->type; - p1->from.offset = v->offset; - p1->from.etype = v->etype; - p1->to.type = rn; - if(f) { - p1->to = p1->from; - p1->from = zprog.from; - p1->from.type = rn; - } - p1->as = opxt[OAS][v->etype]; - if(badccr) { - p = p1; - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - p1->from.type = D_TOS; - p1->to.type = D_CCR; - p1->as = AMOVW; - } - if(debug['R']) - print("%P\t.a%P\n", p, p1); -} - -Bits -mkvar(Adr *a, int as) -{ - Var *v; - int i, t, z; - long o; - Bits bit; - Sym *s; - - mvbits = 0; - t = a->type & D_MASK; - switch(t) { - - default: - if(t >= D_R0 && t < D_R0+NREG) { - regbits |= RtoB(t-D_R0); - if(as == ADIVUL || as == ADIVSL) - regbits |= RtoB(t-D_R0+1); - } - if(t >= D_A0 && t < D_A0+NREG) - regbits |= AtoB(t-D_A0); - if(t >= D_F0 && t < D_F0+NREG) - regbits |= FtoB(t-D_F0); - goto none; - - case D_EXTERN: - case D_STATIC: - case D_AUTO: - case D_PARAM: - break; - } - s = a->sym; - if(s == S) - goto none; - - if((a->type & I_MASK) == I_ADDR) - mvbits |= B_ADDR; - - o = a->offset; - v = var; - for(i=0; i<nvar; i++) { - if(s == v->sym) - if(t == v->type) - if(o == v->offset) - goto out; - v++; - } - if(s) - if(s->name[0] == '.') - goto none; - if(nvar >= NVAR) { - if(debug['w'] > 1 && s) - warn(Z, "variable not optimized: %s", s->name); - goto none; - } - i = nvar; - nvar++; - v = &var[i]; - v->sym = s; - v->offset = o; - v->etype = a->etype; - v->type = t; - if(debug['R']) - print("bit=%2d et=%2d %s (%p,%d,%ld)\n", - i, a->etype, s->name, - v->sym, v->type, v->offset); - -out: - bit = blsh(i); - if(t == D_EXTERN || t == D_STATIC) - for(z=0; z<BITS; z++) - externs.b[z] |= bit.b[z]; - if(t == D_PARAM) - for(z=0; z<BITS; z++) - params.b[z] |= bit.b[z]; - if(a->etype != v->etype || !typechlpfd[a->etype]) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; /* funny punning */ - return bit; - -none: - return zbits; -} - -void -prop(Reg *r, Bits ref, Bits cal) -{ - Reg *r1, *r2; - int z; - - for(r1 = r; r1 != R; r1 = r1->p1) { - for(z=0; z<BITS; z++) { - ref.b[z] |= r1->refahead.b[z]; - if(ref.b[z] != r1->refahead.b[z]) { - r1->refahead.b[z] = ref.b[z]; - changer++; - } - cal.b[z] |= r1->calahead.b[z]; - if(cal.b[z] != r1->calahead.b[z]) { - r1->calahead.b[z] = cal.b[z]; - changer++; - } - } - switch(r1->prog->as) { - case ABSR: - for(z=0; z<BITS; z++) { - cal.b[z] |= ref.b[z] | externs.b[z]; - ref.b[z] = 0; - } - break; - - case ATEXT: - for(z=0; z<BITS; z++) { - cal.b[z] = 0; - ref.b[z] = 0; - } - break; - - case ARTS: - for(z=0; z<BITS; z++) { - cal.b[z] = externs.b[z]; - ref.b[z] = 0; - } - } - for(z=0; z<BITS; z++) { - ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | - r1->use1.b[z] | r1->use2.b[z]; - cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]); - r1->refbehind.b[z] = ref.b[z]; - r1->calbehind.b[z] = cal.b[z]; - } - if(r1->active) - break; - r1->active = 1; - } - for(; r != r1; r = r->p1) - for(r2 = r->p2; r2 != R; r2 = r2->p2link) - prop(r2, r->refbehind, r->calbehind); -} - -/* - * find looping structure - * - * 1) find reverse postordering - * 2) find approximate dominators, - * the actual dominators if the flow graph is reducible - * otherwise, dominators plus some other non-dominators. - * See Matthew S. Hecht and Jeffrey D. Ullman, - * "Analysis of a Simple Algorithm for Global Data Flow Problems", - * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts, - * Oct. 1-3, 1973, pp. 207-217. - * 3) find all nodes with a predecessor dominated by the current node. - * such a node is a loop head. - * recursively, all preds with a greater rpo number are in the loop - */ -long -postorder(Reg *r, Reg **rpo2r, long n) -{ - Reg *r1; - - r->rpo = 1; - r1 = r->s1; - if(r1 && !r1->rpo) - n = postorder(r1, rpo2r, n); - r1 = r->s2; - if(r1 && !r1->rpo) - n = postorder(r1, rpo2r, n); - rpo2r[n] = r; - n++; - return n; -} - -long -rpolca(long *idom, long rpo1, long rpo2) -{ - long t; - - if(rpo1 == -1) - return rpo2; - while(rpo1 != rpo2){ - if(rpo1 > rpo2){ - t = rpo2; - rpo2 = rpo1; - rpo1 = t; - } - while(rpo1 < rpo2){ - t = idom[rpo2]; - if(t >= rpo2) - fatal(Z, "bad idom"); - rpo2 = t; - } - } - return rpo1; -} - -int -doms(long *idom, long r, long s) -{ - while(s > r) - s = idom[s]; - return s == r; -} - -int -loophead(long *idom, Reg *r) -{ - long src; - - src = r->rpo; - if(r->p1 != R && doms(idom, src, r->p1->rpo)) - return 1; - for(r = r->p2; r != R; r = r->p2link) - if(doms(idom, src, r->rpo)) - return 1; - return 0; -} - -void -loopmark(Reg **rpo2r, long head, Reg *r) -{ - if(r->rpo < head || r->active == head) - return; - r->active = head; - r->loop += LOOP; - if(r->p1 != R) - loopmark(rpo2r, head, r->p1); - for(r = r->p2; r != R; r = r->p2link) - loopmark(rpo2r, head, r); -} - -void -loopit(Reg *r, long nr) -{ - Reg *r1; - long i, d, me; - - if(nr > maxnr) { - rpo2r = alloc(nr * sizeof(Reg*)); - idom = alloc(nr * sizeof(long)); - maxnr = nr; - } - - d = postorder(r, rpo2r, 0); - if(d > nr) - fatal(Z, "too many reg nodes"); - nr = d; - for(i = 0; i < nr / 2; i++){ - r1 = rpo2r[i]; - rpo2r[i] = rpo2r[nr - 1 - i]; - rpo2r[nr - 1 - i] = r1; - } - for(i = 0; i < nr; i++) - rpo2r[i]->rpo = i; - - idom[0] = 0; - for(i = 0; i < nr; i++){ - r1 = rpo2r[i]; - me = r1->rpo; - d = -1; - if(r1->p1 != R && r1->p1->rpo < me) - d = r1->p1->rpo; - for(r1 = r1->p2; r1 != nil; r1 = r1->p2link) - if(r1->rpo < me) - d = rpolca(idom, d, r1->rpo); - idom[i] = d; - } - - for(i = 0; i < nr; i++){ - r1 = rpo2r[i]; - r1->loop++; - if(r1->p2 != R && loophead(idom, r1)) - loopmark(rpo2r, i, r1); - } -} - -void -synch(Reg *r, Bits dif) -{ - Reg *r1; - int z; - - for(r1 = r; r1 != R; r1 = r1->s1) { - for(z=0; z<BITS; z++) { - dif.b[z] = (dif.b[z] & - ~(~r1->refbehind.b[z] & r1->refahead.b[z])) | - r1->set.b[z] | r1->regdiff.b[z]; - if(dif.b[z] != r1->regdiff.b[z]) { - r1->regdiff.b[z] = dif.b[z]; - changer++; - } - } - if(r1->active) - break; - r1->active = 1; - for(z=0; z<BITS; z++) - dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]); - if(r1->s2 != R) - synch(r1->s2, dif); - } -} - -ulong -allreg(ulong b, Rgn *r) -{ - Var *v; - int i, j; - - v = var + r->varno; - r->regno = D_NONE; - switch(v->etype) { - - default: - diag(Z, "unknown etype"); - break; - - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - i = BtoR(~b); - j = BtoA(~b); - if(r->costa == r->costr) - if(i > j) - i = NREG; - if(j < NREG && r->costa > 0) - if(r->costa > r->costr || i >= NREG) { - r->regno = D_A0 + j; - return AtoB(j); - } - if(i < NREG && r->costr > 0) { - r->regno = D_R0 + i; - return RtoB(i); - } - break; - - case TDOUBLE: - case TFLOAT: - i = BtoF(~b); - if(i < NREG) { - r->regno = D_F0 + i; - return FtoB(i); - } - break; - } - return 0; -} - -void -paint1(Reg *r, int bn) -{ - Reg *r1; - Prog *p; - int z; - ulong bb; - int x; - - z = bn/32; - bb = 1L<<(bn%32); - if(r->act.b[z] & bb) - return; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(r1->act.b[z] & bb) - break; - r = r1; - } - if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) { - changer -= CLOAD * r->loop; - changea -= CLOAD * r->loop; - if(debug['R'] && debug['v']) - print("%ld%P\tld %B $%d.%d\n", r->loop, - r->prog, blsh(bn), changer, changea); - } - for(;;) { - r->act.b[z] |= bb; - p = r->prog; - - if(r->use1.b[z] & bb) { - changer += CREF * r->loop; - changea += CREF * r->loop; - switch(p->as) { - default: - changea = -CINF; - case AADDL: - case ASUBL: - case AMOVL: - case ACMPL: - break; - } - if(p->as == AMOVL) { - x = p->to.type; - if(x >= D_R0 && x < D_R0+NREG) - changer += r->loop; - if(x >= D_A0 && x < D_A0+NREG) - changea += r->loop; - } - if(debug['R'] && debug['v']) - print("%ld%P\tu1 %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - if((r->use2.b[z]|r->set.b[z]) & bb) { - changer += CREF * r->loop; - changea += CREF * r->loop; - switch(p->as) { - default: - changea = -CINF; - break; - case AMOVL: - case AADDL: - case ACMPL: - case ASUBL: - case ACLRL: /* can be faked */ - case ATSTL: /* can be faked */ - break; - } - if(p->as == AMOVL) { - x = p->from.type; - if(x >= D_R0 && x < D_R0+NREG) - changer += r->loop; - if(x >= D_A0 && x < D_A0+NREG) - changea += r->loop; - } - if(debug['R'] && debug['v']) - print("%ld%P\tu2 %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - if(STORE(r) & r->regdiff.b[z] & bb) { - changer -= CLOAD * r->loop; - changea -= CLOAD * r->loop; - if(debug['R'] && debug['v']) - print("%ld%P\tst %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - paint1(r1, bn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - paint1(r1, bn); - r = r->s1; - if(r == R) - break; - if(r->act.b[z] & bb) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } -} - -ulong -paint2(Reg *r, int bn) -{ - Reg *r1; - int z; - ulong bb, vreg; - - z = bn/32; - bb = 1L << (bn%32); - vreg = regbits; - if(!(r->act.b[z] & bb)) - return vreg; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(!(r1->act.b[z] & bb)) - break; - r = r1; - } - for(;;) { - r->act.b[z] &= ~bb; - - vreg |= r->regu; - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - vreg |= paint2(r1, bn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - vreg |= paint2(r1, bn); - r = r->s1; - if(r == R) - break; - if(!(r->act.b[z] & bb)) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } - return vreg; -} - -void -paint3(Reg *r, int bn, ulong rb, int rn) -{ - Reg *r1; - Prog *p; - int z; - ulong bb; - - z = bn/32; - bb = 1L << (bn%32); - if(r->act.b[z] & bb) - return; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(r1->act.b[z] & bb) - break; - r = r1; - } - if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) - addmove(r, bn, rn, 0); - for(;;) { - r->act.b[z] |= bb; - p = r->prog; - - if(r->use1.b[z] & bb) { - if(debug['R']) - print("%P", p); - addreg(&p->from, rn); - if(debug['R']) - print("\t.c%P\n", p); - } - if((r->use2.b[z]|r->set.b[z]) & bb) { - if(debug['R']) - print("%P", p); - addreg(&p->to, rn); - if(debug['R']) - print("\t.c%P\n", p); - } - if(STORE(r) & r->regdiff.b[z] & bb) - addmove(r, bn, rn, 1); - r->regu |= rb; - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - paint3(r1, bn, rb, rn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - paint3(r1, bn, rb, rn); - r = r->s1; - if(r == R) - break; - if(r->act.b[z] & bb) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } -} - -void -addreg(Adr *a, int rn) -{ - a->sym = 0; - if(rn >= D_R0 && rn < D_R0+NREG) - goto addr; - a->type = rn | (a->type & I_INDIR); - return; - -addr: - a->type = rn | (a->type & I_INDIR); -} - -/* - * bit reg - * 0-7 R0-R7 - * 8-15 A0-A7 - * 16-23 F0-F7 - */ -ulong -RtoB(int r) -{ - - if(r < 0 || r >= NREG) - return 0; - return 1L << (r + 0); -} - -int -BtoR(ulong b) -{ - - b &= 0x0000ffL; - if(b == 0) - return NREG; - return bitno(b) - 0; -} - -ulong -AtoB(int a) -{ - - if(a < 0 || a >= NREG) - return 0; - return 1L << (a + NREG); -} - -int -BtoA(ulong b) -{ - - b &= 0x00ff00L; - if(b == 0) - return NREG; - return bitno(b) - NREG; -} - -ulong -FtoB(int f) -{ - - if(f < 0 || f >= NREG) - return 0; - return 1L << (f + NREG+NREG); -} - -int -BtoF(ulong b) -{ - - b &= 0xff0000L; - if(b == 0) - return NREG; - return bitno(b) - NREG-NREG; -} diff --git a/utils/1c/sgen.c b/utils/1c/sgen.c deleted file mode 100644 index cb289eaa..00000000 --- a/utils/1c/sgen.c +++ /dev/null @@ -1,694 +0,0 @@ -#include "gc.h" - -void -codgen(Node *n, Node *nn) -{ - Prog *sp; - - argoff = 0; - inargs = 0; - for(;; nn = nn->left) { - if(nn == Z) { - diag(Z, "cant find function name"); - return; - } - if(nn->op == ONAME) - break; - } - nearln = nn->lineno; - gpseudo(ATEXT, nn->sym, D_CONST, stkoff); - sp = p; - - retok = 0; - gen(n); - if(!retok) - if(thisfn->link->etype != TVOID) - warn(Z, "no return at end of function: %s", nn->sym->name); - - noretval(3); - gbranch(ORETURN); - if(!debug['N'] || debug['R'] || debug['P']) - regopt(sp); -} - -void -gen(Node *n) -{ - Node *l; - Prog *sp, *spc, *spb; - Case *cn; - long sbc, scc; - int g, o; - -loop: - if(n == Z) - return; - nearln = n->lineno; - o = n->op; - if(debug['G']) - if(o != OLIST) - print("%L %O\n", nearln, o); - - retok = 0; - switch(o) { - - default: - complex(n); - doinc(n, PRE); - cgen(n, D_NONE, n); - doinc(n, POST); - break; - - case OLIST: - gen(n->left); - - rloop: - n = n->right; - goto loop; - - case ORETURN: - retok = 1; - complex(n); - if(n->type == T) - break; - l = n->left; - if(l == Z) { - noretval(3); - gbranch(ORETURN); - break; - } - doinc(l, PRE); - if(typesuv[n->type->etype]) { - sugen(l, D_TREE, nodret, n->type->width); - doinc(l, POST); - noretval(3); - gbranch(ORETURN); - break; - } - g = regalloc(n->type, regret(n->type)); - cgen(l, g, n); - doinc(l, POST); - if(typefd[n->type->etype]) - noretval(1); - else - noretval(2); - gbranch(ORETURN); - regfree(g); - break; - - case OLABEL: - l = n->left; - if(l) { - l->xoffset = pc; - if(l->label) - patch(l->label, pc); - } - gbranch(OGOTO); /* prevent self reference in reg */ - patch(p, pc); - goto rloop; - - case OGOTO: - retok = 1; - n = n->left; - if(n == Z) - return; - if(n->complex == 0) { - diag(Z, "label undefined: %s", n->sym->name); - return; - } - gbranch(OGOTO); - if(n->xoffset) { - patch(p, n->xoffset); - return; - } - if(n->label) - patch(n->label, pc-1); - n->label = p; - return; - - case OCASE: - l = n->left; - if(cases == C) - diag(n, "case/default outside a switch"); - if(l == Z) { - casf(); - cases->val = 0; - cases->def = 1; - cases->label = pc; - setsp();; - goto rloop; - } - complex(l); - if(l->type == T) - goto rloop; - if(l->op == OCONST) - if(typechl[l->type->etype]) { - casf(); - cases->val = l->vconst; - cases->def = 0; - cases->label = pc; - setsp(); - goto rloop; - } - diag(n, "case expression must be integer constant"); - goto rloop; - - case OSWITCH: - l = n->left; - complex(l); - doinc(l, PRE); - if(l->type == T) - break; - if(!typechl[l->type->etype]) { - diag(n, "switch expression must be integer"); - break; - } - g = regalloc(types[TLONG], D_NONE); - n->type = types[TLONG]; - cgen(l, g, n); - regfree(g); - doinc(l, POST); - setsp(); - gbranch(OGOTO); /* entry */ - sp = p; - - cn = cases; - cases = C; - casf(); - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - gen(n->right); - gbranch(OGOTO); - patch(p, breakpc); - - patch(sp, pc); - doswit(g, l); - - patch(spb, pc); - cases = cn; - breakpc = sbc; - setsp(); - break; - - case OWHILE: - case ODWHILE: - l = n->left; - gbranch(OGOTO); /* entry */ - sp = p; - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - if(n->op == OWHILE) - patch(sp, pc); - bcomplex(l); /* test */ - patch(p, breakpc); - - if(n->op == ODWHILE) - patch(sp, pc); - gen(n->right); /* body */ - gbranch(OGOTO); - patch(p, continpc); - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - break; - - case OFOR: - l = n->left; - gen(l->right->left); /* init */ - gbranch(OGOTO); /* entry */ - sp = p; - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - gen(l->right->right); /* inc */ - patch(sp, pc); - if(l->left != Z) { /* test */ - bcomplex(l->left); - patch(p, breakpc); - } - gen(n->right); /* body */ - gbranch(OGOTO); - patch(p, continpc); - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - break; - - case OCONTINUE: - if(continpc < 0) { - diag(n, "continue not in a loop"); - break; - } - gbranch(OGOTO); - patch(p, continpc); - break; - - case OBREAK: - if(breakpc < 0) { - diag(n, "break not in a loop"); - break; - } - gbranch(OGOTO); - patch(p, breakpc); - break; - - case OIF: - l = n->left; - bcomplex(l); - sp = p; - if(n->right->left != Z) - gen(n->right->left); - if(n->right->right != Z) { - gbranch(OGOTO); - patch(sp, pc); - sp = p; - gen(n->right->right); - } - patch(sp, pc); - break; - - case OSET: - case OUSED: - usedset(n->left, o); - break; - } -} - -void -usedset(Node *n, int o) -{ - if(n->op == OLIST) { - usedset(n->left, o); - usedset(n->right, o); - return; - } - complex(n); - switch(n->op) { - case OADDR: /* volatile */ - gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z); - p->as = ANOP; - break; - case ONAME: - if(o == OSET) - gopcode(OTST, types[TINT], D_NONE, Z, D_TREE, n); - else - gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z); - p->as = ANOP; - break; - } -} - -void -noretval(int n) -{ - - if(n & 1) { - gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TLONG]), Z); - p->as = ANOP; - } - if(n & 2) { - gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TDOUBLE]), Z); - p->as = ANOP; - } -} - -/* - * calculate addressability as follows - * REGISTER ==> 12 register - * NAME ==> 11 name+value(SB/SP) - * note that 10 is no longer generated - * CONST ==> 20 $value - * *(20) ==> 21 value - * &(10) ==> 12 $name+value(SB) - * &(11) ==> 1 $name+value(SP) - * (12) + (20) ==> 12 fold constants - * (1) + (20) ==> 1 fold constants - * *(12) ==> 10 back to name - * *(1) ==> 11 back to name - * - * (2,10,11) + (20) ==> 2 indirect w offset - * (2) ==> &13 - * *(10,11) ==> 13 indirect, no index - * - * (20) * (X) ==> 7 multiplier in indexing - * (X,7) + (12,1) ==> 8 adder in indexing (addresses) - * (X,7) + (10,11,2) ==> 8 adder in indexing (names) - * (8) ==> &9 index, almost addressable - * - * (X)++ ==> X fake addressability - * - * calculate complexity (number of registers) - */ -void -xcom(Node *n) -{ - Node *l, *r; - int g; - - if(n == Z) - return; - l = n->left; - r = n->right; - n->complex = 0; - n->addable = 0; - switch(n->op) { - case OCONST: - n->addable = 20; - break; - - case ONAME: - n->addable = 11; /* difference to make relocatable */ - break; - - case OREGISTER: - n->addable = 12; - break; - - case OADDR: - xcom(l); - if(l->addable == 10) - n->addable = 12; - else - if(l->addable == 11) - n->addable = 1; - break; - - case OADD: - xcom(l); - xcom(r); - if(n->type->etype != TIND) - break; - - if(l->addable == 20) - switch(r->addable) { - case 12: - case 1: - n->addable = r->addable; - goto brk; - } - if(r->addable == 20) - switch(l->addable) { - case 12: - case 1: - n->addable = l->addable; - goto brk; - } - break; - - case OIND: - xcom(l); - if(l->op == OADDR) { - l = l->left; - l->type = n->type; - *n = *l; - return; - } - switch(l->addable) { - case 20: - n->addable = 21; - break; - case 1: - n->addable = 11; - break; - case 12: - n->addable = 10; - break; - } - break; - - case OASHL: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vconst(r); - if(g >= 0 && g < 4) - n->addable = 7; - break; - - case OMUL: - case OLMUL: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - n->op = OASHL; - r->vconst = g; - if(g < 4) - n->addable = 7; - break; - } - g = vlog(l); - if(g >= 0) { - n->left = r; - n->right = l; - l = r; - r = n->right; - n->op = OASHL; - r->vconst = g; - if(g < 4) - n->addable = 7; - break; - } - break; - - case ODIV: - case OLDIV: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - if(n->op == ODIV) - n->op = OASHR; - else - n->op = OLSHR; - r->vconst = g; - } - break; - - case OSUB: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - if(vconst(l) == 0) { - n->op = ONEG; - n->left = r; - n->right = Z; - } - break; - - case OXOR: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - if(vconst(l) == -1) { - n->op = OCOM; - n->left = r; - n->right = Z; - } - break; - - case OASMUL: - case OASLMUL: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - n->op = OASASHL; - r->vconst = g; - } - goto aseae; - - case OASDIV: - case OASLDIV: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - if(n->op == OASDIV) - n->op = OASASHR; - else - n->op = OASLSHR; - r->vconst = g; - } - goto aseae; - - case OASLMOD: - case OASMOD: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - - aseae: /* hack that there are no byte/short mul/div operators */ - if(n->type->etype == TCHAR || n->type->etype == TSHORT) { - n->right = new1(OCAST, n->right, Z); - n->right->type = types[TLONG]; - n->type = types[TLONG]; - } - if(n->type->etype == TUCHAR || n->type->etype == TUSHORT) { - n->right = new1(OCAST, n->right, Z); - n->right->type = types[TULONG]; - n->type = types[TULONG]; - } - goto asop; - - case OASXOR: - case OASOR: - case OASADD: - case OASSUB: - case OASLSHR: - case OASASHR: - case OASASHL: - case OASAND: - case OAS: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - - asop: - if(l->addable > INDEXED && - l->complex < FNX && - r && r->complex < FNX) - n->addable = l->addable; - break; - - case OPOSTINC: - case OPREINC: - case OPOSTDEC: - case OPREDEC: - xcom(l); - if(typev[n->type->etype]) - break; - if(l->addable > INDEXED && - l->complex < FNX) - n->addable = l->addable; - break; - - default: - if(l != Z) - xcom(l); - if(r != Z) - xcom(r); - break; - } - -brk: - n->complex = 0; - if(n->addable >= 10) - return; - if(l != Z) - n->complex = l->complex; - if(r != Z) { - if(r->complex == n->complex) - n->complex = r->complex+1; - else - if(r->complex > n->complex) - n->complex = r->complex; - } - if(n->complex == 0) - n->complex++; - - if(com64(n)) - return; - - switch(n->op) { - - case OFUNC: - n->complex = FNX; - break; - - case OADD: - case OMUL: - case OLMUL: - case OXOR: - case OAND: - case OOR: - /* - * symmetric operators, make right side simple - * if same, put constant on left to get movq - */ - if(r->complex > l->complex || - (r->complex == l->complex && r->addable == 20)) { - n->left = r; - n->right = l; - } - break; - - case OLE: - case OLT: - case OGE: - case OGT: - case OEQ: - case ONE: - /* - * relational operators, make right side simple - * if same, put constant on left to get movq - */ - if(r->complex > l->complex || r->addable == 20) { - n->left = r; - n->right = l; - n->op = invrel[relindex(n->op)]; - } - break; - } -} - -void -bcomplex(Node *n) -{ - - complex(n); - if(n->type != T) - if(tcompat(n, T, n->type, tnot)) - n->type = T; - if(n->type != T) { - bool64(n); - doinc(n, PRE); - boolgen(n, 1, D_NONE, Z, n); - } else - gbranch(OGOTO); -} - -Node* -nodconst(long v) -{ - - return (Node*)v; -} diff --git a/utils/1c/swt.c b/utils/1c/swt.c deleted file mode 100644 index 34daeb1e..00000000 --- a/utils/1c/swt.c +++ /dev/null @@ -1,964 +0,0 @@ -#include "gc.h" - -int -swcmp(const void *a1, const void *a2) -{ - C1 *p1, *p2; - - p1 = (C1*)a1; - p2 = (C1*)a2; - if(p1->val < p2->val) - return -1; - return p1->val > p2->val; -} - -void -doswit(int g, Node *n) -{ - Case *c; - C1 *q, *iq; - long def, nc, i; - - def = 0; - nc = 0; - for(c = cases; c->link != C; c = c->link) { - if(c->def) { - if(def) - diag(n, "more than one default in switch"); - def = c->label; - continue; - } - nc++; - } - - iq = alloc(nc*sizeof(C1)); - q = iq; - for(c = cases; c->link != C; c = c->link) { - if(c->def) - continue; - q->label = c->label; - q->val = c->val; - q++; - } - qsort(iq, nc, sizeof(C1), swcmp); - if(def == 0) - def = breakpc; - for(i=0; i<nc-1; i++) - if(iq[i].val == iq[i+1].val) - diag(n, "duplicate cases in switch %ld", iq[i].val); - swit1(iq, nc, def, g, n); -} - -#define N1 4 /* ncase: always linear */ - /* else binary */ -void -swit1(C1 *q, int nc, long def, int g, Node *n) -{ - C1 *r; - int i; - long v; - Prog *sp1, *sp2; - - /* note that g and g+1 are not allocated */ - if(nc <= N1) - goto linear; - - /* - * divide and conquer - */ - i = nc / 2; - r = q+i; - v = r->val; - /* compare median */ - if(v >= -128 && v < 128) { - gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); - gopcode(OEQ, n->type, g, n, g+1, n); - } else - gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); - gbranch(OLT); - sp1 = p; - gbranch(OGT); - sp2 = p; - gbranch(OGOTO); - patch(p, r->label); - - patch(sp1, pc); - swit1(q, i, def, g, n); - - patch(sp2, pc); - swit1(r+1, nc-i-1, def, g, n); - return; - -linear: - for(i=0; i<nc; i++) { - v = q->val; - if(v >= -128 && v < 128) { - gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); - gopcode(OEQ, n->type, g+1, n, g, n); - } else - gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); - gbranch(OEQ); - patch(p, q->label); - q++; - } - gbranch(OGOTO); - patch(p, def); -} - -void -casf(void) -{ - Case *c; - - c = alloc(sizeof(*c)); - c->link = cases; - cases = c; -} - - -int -bitload(Node *b, int n1, int n2, int n3, Node *nn) -{ - int sh, g, gs; - long v; - Node *l; - Type *t; - - /* - * n1 gets adjusted/masked value - * n2 gets address of cell - * n3 gets contents of cell - */ - gs = 0; - t = tfield; - - l = b->left; - g = regalloc(t, n3); - if(n2 != D_NONE) { - lcgen(l, n2, Z); - n2 |= I_INDIR; - gmove(t, t, n2, l, g, l); - gmove(t, t, g, l, n1, l); - } else - cgen(l, g, nn); - if(b->type->shift == 0 && typeu[b->type->etype]) { - v = ~0 + (1L << b->type->nbits); - gopcode(OAND, t, D_CONST, nodconst(v), g, l); - } else { - sh = 32 - b->type->shift - b->type->nbits; - if(sh > 0) - if(sh >= 8) { - gs = regalloc(t, D_NONE); - gmove(t, t, D_CONST, nodconst(sh), gs, l); - gopcode(OASHL, t, gs, l, g, l); - if(b->type->shift) - regfree(gs); - } else - gopcode(OASHL, t, D_CONST, nodconst(sh), g, l); - sh += b->type->shift; - if(sh > 0) { - if(sh >= 8) { - if(b->type->shift) { - gs = regalloc(t, D_NONE); - gmove(t, t, D_CONST, nodconst(sh), gs, l); - } - if(typeu[b->type->etype]) - gopcode(OLSHR, t, gs, l, g, l); - else - gopcode(OASHR, t, gs, l, g, l); - regfree(gs); - } else { - if(typeu[b->type->etype]) - gopcode(OLSHR, t, D_CONST, nodconst(sh), g, l); - else - gopcode(OASHR, t, D_CONST, nodconst(sh), g, l); - } - } - } - return g; -} - -void -bitstore(Node *b, int n1, int n2, int n3, int result, Node *nn) -{ - long v; - Node *l; - Type *t; - int sh, g, gs; - - /* - * n1 has adjusted/masked value - * n2 has address of cell - * n3 has contents of cell - */ - t = tfield; - - l = b->left; - g = regalloc(t, D_NONE); - v = ~0 + (1L << b->type->nbits); - gopcode(OAND, t, D_CONST, nodconst(v), n1, l); - gmove(t, t, n1, l, g, l); - if(result != D_NONE) - gmove(t, nn->type, n1, l, result, nn); - sh = b->type->shift; - if(sh > 0) { - if(sh >= 8) { - gs = regalloc(t, D_NONE); - gmove(t, t, D_CONST, nodconst(sh), gs, l); - gopcode(OASHL, t, gs, l, g, l); - regfree(gs); - } else - gopcode(OASHL, t, D_CONST, nodconst(sh), g, l); - } - v <<= sh; - gopcode(OAND, t, D_CONST, nodconst(~v), n3, l); - gopcode(OOR, t, n3, l, g, l); - gmove(t, t, g, l, n2|I_INDIR, l); - - regfree(g); - regfree(n1); - regfree(n2); - regfree(n3); -} - -long -outstring(char *s, long n) -{ - long r; - - r = nstring; - while(n) { - string[mnstring] = *s++; - mnstring++; - nstring++; - if(mnstring >= NSNAME) { - gpseudo(ADATA, symstring, D_SCONST, 0L); - memmove(p->to.sval, string, NSNAME); - p->from.offset = nstring - NSNAME; - p->from.displace = NSNAME; - mnstring = 0; - } - n--; - } - return r; -} - -long -outlstring(ushort *s, long n) -{ - char buf[2]; - int c; - long r; - - while(nstring & 1) - outstring("", 1); - r = nstring; - while(n > 0) { - c = *s++; - if(align(0, types[TCHAR], Aarg1)) { - buf[0] = c>>8; - buf[1] = c; - } else { - buf[0] = c; - buf[1] = c>>8; - } - outstring(buf, 2); - n -= sizeof(ushort); - } - return r; -} - -int -doinc(Node *n, int f) -{ - Node *l; - int a; - -loop: - if(n == Z) - return 0; - l = n->left; - switch(n->op) { - - case OPOSTINC: - case OPOSTDEC: - if(f & POST) { - a = n->addable; - if(a >= INDEXED) { - if(f & TEST) - return 1; - n->addable = 0; - cgen(n, D_NONE, n); - n->addable = a; - } - } - break; - - case OAS: - case OASLMUL: - case OASLDIV: - case OASLMOD: - case OASMUL: - case OASDIV: - case OASMOD: - case OASXOR: - case OASOR: - case OASADD: - case OASSUB: - case OASLSHR: - case OASASHR: - case OASASHL: - case OASAND: - - case OPREINC: - case OPREDEC: - if(f & PRE) { - a = n->addable; - if(a >= INDEXED) { - if(f & TEST) - return 1; - n->addable = 0; - doinc(n, PRE); - cgen(n, D_NONE, n); - n->addable = a; - return 0; - } - } - break; - - case OFUNC: - if(f & PRE) - break; - return 0; - - case ONAME: - case OREGISTER: - case OSTRING: - case OCONST: - - case OANDAND: - case OOROR: - return 0; - - case OCOND: - return 0; - - case OCOMMA: - n = n->right; - if(f & PRE) - n = l; - goto loop; - } - if(l != Z) - if(doinc(l, f)) - return 1; - n = n->right; - goto loop; -} - -void -setsp(void) -{ - - nextpc(); - p->as = AADJSP; - p->from.type = D_CONST; - p->from.offset = 0; -} - -void -adjsp(long o) -{ - - if(o != 0) { - nextpc(); - p->as = AADJSP; - p->from.type = D_CONST; - p->from.offset = o; - argoff += o; - } -} - -int -simplv(Node *n) -{ - - if(n->addable <= INDEXED) - return 0; - while(n->op == OIND) - n = n->left; - if(n->op == ONAME) - return 1; - return 0; -} - -int -eval(Node *n, int g) -{ - - if(n->addable >= INDEXED) - return D_TREE; - g = regalloc(n->type, g); - cgen(n, g, n); - return g; -} - -void outhist(Biobuf*); -void zname(Biobuf*, Sym*, int); -void zaddr(Biobuf*, Adr*, int); -void zwrite(Biobuf*, Prog*, int, int); - -void -outcode(void) -{ - struct { Sym *sym; short type; } h[NSYM]; - Prog *p; - Sym *s; - int f, sf, st, t, sym; - Biobuf b; - - if(debug['S']) { - for(p = firstp; p != P; p = p->link) - if(p->as != ADATA && p->as != AGLOBL) - pc--; - for(p = firstp; p != P; p = p->link) { - print("%P\n", p); - if(p->as != ADATA && p->as != AGLOBL) - pc++; - } - } - f = open(outfile, OWRITE); - if(f < 0) { - diag(Z, "cant open %s", outfile); - errorexit(); - } - Binit(&b, f, OWRITE); - Bseek(&b, 0L, 2); - outhist(&b); - for(sym=0; sym<NSYM; sym++) { - h[sym].sym = S; - h[sym].type = 0; - } - sym = 1; - for(p = firstp; p != P; p = p->link) { - jackpot: - sf = 0; - s = p->from.sym; - while(s != S) { - sf = s->sym; - if(sf < 0 || sf >= NSYM) - sf = 0; - t = p->from.type & D_MASK; - if(h[sf].type == t) - if(h[sf].sym == s) - break; - s->sym = sym; - zname(&b, s, t); - h[sym].sym = s; - h[sym].type = t; - sf = sym; - sym++; - if(sym >= NSYM) - sym = 1; - break; - } - st = 0; - s = p->to.sym; - while(s != S) { - st = s->sym; - if(st < 0 || st >= NSYM) - st = 0; - t = p->to.type & D_MASK; - if(h[st].type == t) - if(h[st].sym == s) - break; - s->sym = sym; - zname(&b, s, t); - h[sym].sym = s; - h[sym].type = t; - st = sym; - sym++; - if(sym >= NSYM) - sym = 1; - if(st == sf) - goto jackpot; - break; - } - zwrite(&b, p, sf, st); - } - Bflush(&b); - close(f); - firstp = P; - lastp = P; -} - -void -zwrite(Biobuf *b, Prog *p, int sf, int st) -{ - long l; - - l = p->as; - Bputc(b, l); - Bputc(b, l>>8); - l = p->lineno; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - zaddr(b, &p->from, sf); - zaddr(b, &p->to, st); -} - -void -zname(Biobuf *b, Sym *s, int t) -{ - char *n; - ulong sig; - - if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){ - sig = sign(s); - Bputc(b, ASIGNAME); - Bputc(b, ASIGNAME>>8); - Bputc(b, sig); - Bputc(b, sig>>8); - Bputc(b, sig>>16); - Bputc(b, sig>>24); - s->sig = SIGDONE; - } - else{ - Bputc(b, ANAME); /* as */ - Bputc(b, ANAME>>8); /* as */ - } - Bputc(b, t); /* type */ - Bputc(b, s->sym); /* sym */ - n = s->name; - while(*n) { - Bputc(b, *n); - n++; - } - Bputc(b, 0); -} - -void -zaddr(Biobuf *b, Adr *a, int s) -{ - long l; - int i, t; - char *n; - Ieee e; - - t = 0; - if(a->field) - t |= T_FIELD; - if(s) - t |= T_SYM; - - switch(a->type) { - default: - if(a->offset) - t |= T_OFFSET; - if(a->displace) - t |= T_INDEX; - if(a->type & ~0xff) - t |= T_TYPE; - break; - case D_FCONST: - t |= T_FCONST; - break; - case D_SCONST: - t |= T_SCONST; - break; - } - Bputc(b, t); - - if(t & T_FIELD) { /* implies field */ - i = a->field; - Bputc(b, i); - Bputc(b, i>>8); - } - if(t & T_INDEX) { /* implies index, scale, displace */ - i = D_NONE; - Bputc(b, i); - Bputc(b, i>>8); - Bputc(b, 0); - l = a->displace; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - } - if(t & T_OFFSET) { /* implies offset */ - l = a->offset; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - } - if(t & T_SYM) /* implies sym */ - Bputc(b, s); - if(t & T_FCONST) { - ieeedtod(&e, a->dval); - l = e.l; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - l = e.h; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - return; - } - if(t & T_SCONST) { - n = a->sval; - for(i=0; i<NSNAME; i++) { - Bputc(b, *n); - n++; - } - return; - } - i = a->type; - Bputc(b, i); - if(t & T_TYPE) - Bputc(b, i>>8); -} - - - -void -outhist(Biobuf *b) -{ - Hist *h; - char *p, *q, *op, c; - Prog pg; - int n; - - pg = zprog; - pg.as = AHISTORY; - c = pathchar(); - for(h = hist; h != H; h = h->link) { - p = h->name; - op = 0; - /* on windows skip drive specifier in pathname */ - if(systemtype(Windows) && p && p[1] == ':'){ - p += 2; - c = *p; - } - if(p && p[0] != c && h->offset == 0 && pathname){ - /* on windows skip drive specifier in pathname */ - if(systemtype(Windows) && pathname[1] == ':') { - op = p; - p = pathname+2; - c = *p; - } else if(pathname[0] == c){ - op = p; - p = pathname; - } - } - while(p) { - q = utfrune(p, c); - if(q) { - n = q-p; - if(n == 0){ - n = 1; /* leading "/" */ - *p = '/'; /* don't emit "\" on windows */ - } - q++; - } else { - n = strlen(p); - q = 0; - } - if(n) { - Bputc(b, ANAME); - Bputc(b, ANAME>>8); - Bputc(b, D_FILE); - Bputc(b, 1); - Bputc(b, '<'); - Bwrite(b, p, n); - Bputc(b, 0); - } - p = q; - if(p == 0 && op) { - p = op; - op = 0; - } - } - pg.lineno = h->line; - pg.to.type = zprog.to.type; - pg.to.offset = h->offset; - if(h->offset) - pg.to.type = D_CONST; - - zwrite(b, &pg, 0, 0); - } -} - -void -ieeedtod(Ieee *ieee, double native) -{ - double fr, ho, f; - int exp; - - if(native < 0) { - ieeedtod(ieee, -native); - ieee->h |= 0x80000000L; - return; - } - if(native == 0) { - ieee->l = 0; - ieee->h = 0; - return; - } - fr = frexp(native, &exp); - f = 2097152L; /* shouldnt use fp constants here */ - fr = modf(fr*f, &ho); - ieee->h = ho; - ieee->h &= 0xfffffL; - ieee->h |= (exp+1022L) << 20; - f = 65536L; - fr = modf(fr*f, &ho); - ieee->l = ho; - ieee->l <<= 16; - ieee->l |= (long)(fr*f); -} - -int -nodalloc(Type *t, int g, Node *n) -{ - - n->type = t; - n->op = OREGISTER; - n->addable = 12; - n->complex = 0; - g = regaddr(g); - n->reg = g | I_INDIR; - n->xoffset = 0; - return g; -} - -int -mulcon(Node *n, Node *c, int result, Node *nn) -{ - long v; - - if(typefd[n->type->etype]) - return 0; - v = c->vconst; - if(mulcon1(n, v, result, nn)) - return 1; - return 0; -} - -int -shlcon(Node *n, Node *c, int result, Node *nn) -{ - long v; - - v = 1L << c->vconst; - return mulcon1(n, v, result, nn); -} - -int -mulcon1(Node *n, long v, int result, Node *nn) -{ - int g, g1, a1, a2, neg; - int o; - char code[10], *p; - - if(result == D_NONE) - return 0; - neg = 0; - if(v < 0) { - v = -v; - neg++; - } - a1 = 0; - a2 = multabsize; - for(;;) { - if(a1 >= a2) - return 0; - g1 = (a2 + a1)/2; - if(v < multab[g1].val) { - a2 = g1; - continue; - } - if(v > multab[g1].val) { - a1 = g1+1; - continue; - } - break; - } - strcpy(code, "0"); - strncat(code, multab[g1].code, sizeof(multab[0].code)); - p = code; - if(p[1] == 'i') - p += 2; - g = regalloc(n->type, result); - cgen(n, g, n); - if(neg) - gopcode(ONEG, n->type, D_NONE, n, g, n); - g1 = regalloc(n->type, D_NONE); -loop: - switch(*p) { - case 0: - regfree(g1); - gmove(n->type, nn->type, g, n, result, nn); - regfree(g); - return 1; - case '0': - o = OAS; - *p -= '0'; - goto com; - case '1': - case '2': - o = OSUB; - *p -= '1'; - goto com; - case '3': - case '4': - case '5': - case '6': - o = OADD; - *p -= '3'; - com: - a1 = g; - if(*p == 1 || *p == 3) - a1 = g1; - a2 = g; - if(*p == 0 || *p == 3) - a2 = g1; - gopcode(o, n->type, a1, n, a2, n); - p++; - break; - default: - a1 = *p++ - 'a' + 1; - a2 = g; - if(a1 > 8) { - a2 = g1; - a1 -= 8; - } - gopcode(OASHL, n->type, D_CONST, nodconst(a1), a2, n); - break; - } - goto loop; -} - -void -nullwarn(Node *l, Node *r) -{ - warn(Z, "result of operation not used"); - if(l != Z) - cgen(l, D_NONE, Z); - if(r != Z) - cgen(r, D_NONE, Z); -} - -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, D_SCONST, 0L); - p->from.offset += o+e; - p->from.displace = lw; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void -gextern(Sym *s, Node *a, long o, long w) -{ - if(a->op == OCONST && typev[a->type->etype]) { - gpseudo(ADATA, s, D_CONST, (long)(a->vconst>>32)); - p->from.offset += o; - p->from.displace = 4; - gpseudo(ADATA, s, D_CONST, (long)(a->vconst)); - p->from.offset += o + 4; - p->from.displace = 4; - return; - } - gpseudotree(ADATA, s, a); - p->from.offset += o; - p->from.displace = w; -} - -long -align(long i, Type *t, int op) -{ - long o; - Type *v; - int w; - - o = i; - w = 1; - switch(op) { - default: - diag(Z, "unknown align opcode %d", op); - break; - - case Asu2: /* padding at end of a struct */ - w = SZ_LONG; - if(packflg) - w = packflg; - break; - - case Ael1: /* initial allign of struct element */ - for(v=t; v->etype==TARRAY; v=v->link) - ; - w = ewidth[v->etype]; - if(w <= 0 || w >= SZ_SHORT) - w = SZ_SHORT; - if(packflg) - w = packflg; - break; - - case Ael2: /* width of a struct element */ - o += t->width; - break; - - case Aarg0: /* initial passbyptr argument in arg list */ - if(typesuv[t->etype]) { - o = align(o, types[TIND], Aarg1); - o = align(o, types[TIND], Aarg2); - } - break; - - case Aarg1: /* initial allign of parameter */ - w = ewidth[t->etype]; - if(w <= 0 || w >= SZ_LONG) { - w = SZ_LONG; - break; - } - o += SZ_LONG - w; /* big endian adjustment */ - w = 1; - break; - - case Aarg2: /* width of a parameter */ - o += t->width; - w = SZ_LONG; - break; - - case Aaut3: /* total allign of automatic */ - o = align(o, t, Ael1); - o = align(o, t, Ael2); - break; - } - o = round(o, w); - if(debug['A']) - print("align %s %ld %T = %ld\n", bnames[op], i, t, o); - return o; -} - -long -maxround(long max, long v) -{ - v += SZ_LONG-1; - if(v > max) - max = round(v, SZ_LONG); - return max; -} diff --git a/utils/1c/txt.c b/utils/1c/txt.c deleted file mode 100644 index e439c40c..00000000 --- a/utils/1c/txt.c +++ /dev/null @@ -1,903 +0,0 @@ -#include "gc.h" - -void -tindex(Type *tf, Type *tt) -{ - int i, j; - - j = 0; - if(tt != T) { - j = tt->etype; - if(j >= NTYPE) - j = 0; - } - i = 0; - if(tf != T) { - i = tf->etype; - if(i >= NTYPE) - if(typesu[i]) - i = j; - else - i = 0; - } - txtp = &txt[i][j]; -} - -void -ginit(void) -{ - int i, j, si, sj; - - thestring = "68000"; - thechar = '1'; - exregoffset = 7; - exaregoffset = 5; - exfregoffset = 7; - listinit(); - for(i=0; i<NREG; i++) { - regused[i] = 0; - fregused[i] = 0; - aregused[i] = 0; - } - regaddr(D_A0+6); - regaddr(D_A0+7); - for(i=0; i<sizeof(regbase); i++) - regbase[i] = D_NONE; - for(i=0; i<NREG; i++) { - regbase[D_R0+i] = D_R0+i; - regbase[D_A0+i] = D_A0+i; - regbase[D_F0+i] = D_F0+i; - } - regbase[D_TOS] = D_TOS; - - for(i=0; i<NTYPE; i++) - for(j=0; j<NTYPE; j++) { - txtp = &txt[i][j]; - txtp->movas = AGOK; - txtp->preclr = 0; - txtp->postext = AGOK; - if(!(typechlp[i] && typechlp[j])) - continue; - si = types[i]->width; - sj = types[j]->width; - if(sj < si) - txtp->preclr = -1; - if(sj > si) { - if(typeu[i]) { - txtp->preclr = 1; - } else { - if(sj == 2) - txtp->postext = AEXTBW; - else - if(sj == 4) - if(si == 1) - txtp->postext = AEXTBL; - else - txtp->postext = AEXTWL; - } - sj = si; - } - if(sj == 1) - txtp->movas = AMOVB; - if(sj == 2) - txtp->movas = AMOVW; - if(sj == 4) - txtp->movas = AMOVL; - } - - for(i=0; i<ALLOP; i++) - for(j=0; j<NTYPE; j++) - opxt[i][j] = AGOK; - oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK); - - oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED); - oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED); - oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK); - oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD); - oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD); - oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD); - oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD); - oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD); - oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK); - oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK); - oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK); - oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK); - oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK); - oinit(OOR, AORB, AORW, AORL, AGOK, AGOK); - oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK); - oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK); - oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK); - oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD); - oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK); - oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD); - oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK); - oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK); - oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK); - oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK); - oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK); - oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK); - oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK); - - nstring = 0; - mnstring = 0; - nrathole = 0; - nstatic = 0; - pc = 0; - breakpc = -1; - continpc = -1; - cases = C; - firstp = P; - lastp = P; - tfield = types[TLONG]; - - zprog.link = P; - zprog.as = AGOK; - zprog.from.type = D_NONE; - zprog.to = zprog.from; - - nodret = new(ONAME, Z, Z); - nodret->sym = slookup(".ret"); - nodret->type = types[TIND]; - nodret->etype = types[TIND]->etype; - nodret->class = CPARAM; - nodret = new(OIND, nodret, Z); - complex(nodret); - - symrathole = slookup(".rathole"); - symrathole->class = CGLOBL; - symrathole->type = typ(TARRAY, types[TCHAR]); - nodrat = new(ONAME, Z, Z); - nodrat->sym = symrathole; - nodrat->type = types[TIND]; - nodrat->etype = TVOID; - nodrat->class = CGLOBL; - complex(nodrat); - nodrat->type = symrathole->type; - - com64init(); - - symstatic = slookup(".static"); - symstatic->class = CSTATIC; - symstatic->type = typ(TARRAY, types[TLONG]); -} - -void -gclean(void) -{ - int i; - Sym *s; - - regfree(D_A0+6); - regfree(D_A0+7); - for(i=0; i<NREG; i++) { - if(regused[i]) - diag(Z, "missing R%d", i); - if(aregused[i]) - diag(Z, "missing A%d", i); - if(fregused[i]) - diag(Z, "missing F%d", i); - } - - while(mnstring) - outstring("", 1L); - symstring->type->width = nstring; - symstatic->type->width = nstatic; - symrathole->type->width = nrathole; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type == T) - continue; - if(s->type->width == 0) - continue; - if(s->class != CGLOBL && s->class != CSTATIC) - continue; - if(s->type == types[TENUM]) - continue; - gpseudo(AGLOBL, s, D_CONST, s->type->width); - pc--; - } - nextpc(); - p->as = AEND; - outcode(); -} - -void -oinit(int o, int ab, int aw, int al, int af, int ad) -{ - int i; - - i = o; - if(i >= ALLOP) { - diag(Z, "op(%d) >= ALLOP(%d)", i, ALLOP); - errorexit(); - } - opxt[i][TCHAR] = ab; - opxt[i][TUCHAR] = ab; - opxt[i][TSHORT] = aw; - opxt[i][TUSHORT] = aw; - opxt[i][TINT] = al; - opxt[i][TUINT] = al; - opxt[i][TLONG] = al; - opxt[i][TULONG] = al; - opxt[i][TIND] = al; - opxt[i][TFLOAT] = af; - opxt[i][TDOUBLE] = ad; -} - -Prog* -prg(void) -{ - Prog *p; - - p = alloc(sizeof(*p)); - *p = zprog; - return p; -} - -void -nextpc(void) -{ - - p = prg(); - pc++; - p->lineno = nearln; - if(firstp == P) { - firstp = p; - lastp = p; - return; - } - lastp->link = p; - lastp = p; -} - -void -gargs(Node *n) -{ - long s; - -loop: - if(n == Z) - return; - if(n->op == OLIST) { - gargs(n->right); - n = n->left; - goto loop; - } - s = argoff; - cgen(n, D_TOS, n); - argoff = s + n->type->width; -} - -void -naddr(Node *n, Adr *a, int x) -{ - Node *l; - long v; - - switch(n->op) { - default: - bad: - diag(n, "bad in naddr: %O", n->op); - break; - - case OADDR: - case OIND: - naddr(n->left, a, x); - goto noadd; - - case OREGISTER: - a->sym = S; - a->type = n->reg; - a->offset = n->xoffset; - a->displace = 0; - break; - - case ONAME: - a->etype = n->etype; - a->displace = 0; - a->sym = n->sym; - a->offset = n->xoffset; - a->type = D_STATIC; - if(n->class == CSTATIC) - break; - if(n->class == CEXTERN || n->class == CGLOBL) { - a->type = D_EXTERN; - break; - } - if(n->class == CAUTO) { - a->type = D_AUTO; - break; - } - if(n->class == CPARAM) { - a->type = D_PARAM; - break; - } - goto bad; - - case OCONST: - a->displace = 0; - if(typefd[n->type->etype]) { - a->type = D_FCONST; - a->dval = n->fconst; - break; - } - a->type = D_CONST; - a->offset = n->vconst; - break; - - case OADD: - l = n->left; - if(l->addable == 20) { - v = l->vconst; - naddr(n->right, a, x); - goto add; - } - l = n->right; - if(l->addable == 20) { - v = l->vconst; - naddr(n->left, a, x); - goto add; - } - goto bad; - - noadd: - v = 0; - add: - switch(n->addable) { - default: - goto bad; - case 2: - a->displace += v; - break; - case 21: - a->type &= D_MASK; - a->type |= I_INDIR; - break; - case 1: - case 12: - a->offset += v; - a->type &= D_MASK; - a->type |= I_ADDR; - break; - case 10: - case 11: - case 20: - a->type &= D_MASK; - a->type |= I_DIR; - break; - } - break; - - case OPREINC: - case OPREDEC: - case OPOSTINC: - case OPOSTDEC: - - case OAS: - case OASLMUL: - case OASLDIV: - case OASLMOD: - case OASMUL: - case OASDIV: - case OASMOD: - case OASXOR: - case OASOR: - case OASADD: - case OASSUB: - case OASLSHR: - case OASASHR: - case OASASHL: - case OASAND: - naddr(n->left, a, x); - break; - } -} - -int -regalloc(Type *t, int g) -{ - - if(t == T) - return D_NONE; - g &= D_MASK; - if(typefd[t->etype]) { - if(g >= D_F0 && g < D_F0+NREG) { - fregused[g-D_F0]++; - return g; - } - for(g=0; g<NREG; g++) - if(fregused[g] == 0) { - fregused[g]++; - return g + D_F0; - } - } else { - if(g >= D_R0 && g < D_R0+NREG) { - regused[g-D_R0]++; - return g; - } - for(g=0; g<NREG; g++) - if(regused[g] == 0) { - regused[g]++; - return g + D_R0; - } - } - diag(Z, "out of registers"); - return D_TOS; -} - -int -regaddr(int g) -{ - - if(g >= D_A0 && g < D_A0+NREG) { - aregused[g-D_A0]++; - return g; - } - for(g=0; g<NREG; g++) - if(aregused[g] == 0) { - aregused[g]++; - return g + D_A0; - } - diag(Z, "out of addr registers"); - return D_TOS; -} - -int -regpair(int g) -{ - - if(g >= D_R0+1 && g < D_R0+NREG) - if(!regused[g-D_R0-1]) { - regused[g-D_R0-1]++; - regused[g-D_R0]++; - return g-1; - } - if(g >= D_R0 && g < D_R0+NREG-1) - if(!regused[g-D_R0+1]) { - regused[g-D_R0+1]++; - regused[g-D_R0]++; - return g; - } - for(g = 0; g < NREG-1; g++) - if(!regused[g]) - if(!regused[g+1]) { - regused[g]++; - regused[g+1]++; - return g + D_R0; - } - diag(Z, "out of register pairs"); - return D_TOS; -} - -int -regret(Type *t) -{ - - if(t == T) - return D_NONE; - if(typefd[t->etype]) - return D_F0; - return D_R0; -} - -void -regfree(int g) -{ - - g &= D_MASK; - if(g == D_TOS || g == D_TREE || g == D_NONE) - return; - if(g >= D_R0 && g < D_R0+NREG) { - regused[g-D_R0]--; - return; - } - if(g >= D_A0 && g < D_A0+NREG) { - aregused[g-D_A0]--; - return; - } - if(g >= D_F0 && g < D_F0+NREG) { - fregused[g-D_F0]--; - return; - } - diag(Z, "bad in regfree: %d", g); -} - -void -gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t) -{ - int g, a, b; - Prog *p1; - - tindex(tf, tt); - if(txtp->preclr) { - if(gf >= D_R0 && gf < D_R0+NREG) - if(txtp->preclr < 0) { - gmove(tt, tt, gf, f, gt, t); - return; - } - g = regalloc(types[TLONG], gt); - if(g == gf) { - g = regalloc(types[TLONG], D_NONE); - regfree(gf); - } - if(txtp->preclr > 0) - gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z); - gopcode(OAS, tf, gf, f, g, Z); - if(g != gt) - gopcode(OAS, tt, g, Z, gt, t); - regfree(g); - return; - } - a = txtp->postext; - if(a != AGOK) { - if(gf >= D_R0 && gf < D_R0+NREG) - g = regalloc(types[TLONG], gf); - else - g = regalloc(types[TLONG], gt); - if(g != gf) - gopcode(OAS, tf, gf, f, g, Z); - nextpc(); - p->as = a; - p->to.type = g; - if(debug['g']) - print("%P\n", p); - if(g != gt) - gopcode(OAS, tt, g, Z, gt, t); - regfree(g); - return; - } - if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) || - (gf == D_TREE && gt == D_TREE && f == t)) - return; - if(typefd[tf->etype] || typefd[tt->etype]) { - if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */ - a = regalloc(types[TLONG], D_NONE); - gmove(tf, types[TLONG], gf, f, a, t); - if(tf->etype == TULONG) { - b = regalloc(types[TDOUBLE], D_NONE); - gmove(types[TLONG], tt, a, t, b, t); - gopcode(OTST, types[TLONG], D_NONE, Z, a, t); - gbranch(OGE); - p1 = p; - gopcode(OASADD, types[TDOUBLE], - D_CONST, nodconst(100), b, t); - p->from.dval = 4294967296.; - patch(p1, pc); - gmove(types[TDOUBLE], tt, b, t, gt, t); - regfree(b); - } else - gmove(types[TLONG], tt, a, t, gt, t); - regfree(a); - return; - } - if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */ - a = regalloc(types[TLONG], D_NONE); - gopcode(OAS, types[TLONG], D_FPCR, t, a, t); - gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t); - } - if(gf < D_F0 || gf >= D_F0+NREG) { - g = regalloc(types[TDOUBLE], gt); - gopcode(OFAS, tf, gf, f, g, t); - if(g != gt) - gopcode(OFAS, tt, g, t, gt, t); - regfree(g); - } else - gopcode(OFAS, tt, gf, f, gt, t); - if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */ - gopcode(OAS, types[TLONG], a, t, D_FPCR, t); - regfree(a); - } - return; - } - gopcode(OAS, tt, gf, f, gt, t); -} - -void -gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t) -{ - int i, fidx, tidx; - - if(o == OAS) - if(gf == gt) - if(gf != D_TREE || f == t) - return; - - fidx = D_NONE; - tidx = D_NONE; - i = 0; - if(ty != T) { - i = ty->etype; - if(i >= NTYPE) - i = 0; - } - nextpc(); - if(gf == D_TREE) { - naddr(f, &p->from, fidx); - } else { - p->from.type = gf; - if(gf == D_CONST) { - p->from.offset = (long)(uintptr)f; - if(typefd[i]) { - p->from.type = D_FCONST; - p->from.dval = (long)(uintptr)f; - } - } - } - p->as = opxt[o][i]; - if(gt == D_TREE) { - naddr(t, &p->to, tidx); - } else { - p->to.type = gt; - if(gt == D_CONST) - p->to.offset = (long)(uintptr)t; - } - if(o == OBIT) { - p->from.field = f->type->nbits; - p->to.field = f->type->shift; - if(p->from.field == 0) - diag(Z, "BIT zero width bit field"); - } - if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB) - asopt(); - if(debug['g']) - print("%P\n", p); - if(p->as == AGOK) - diag(Z, "GOK in gopcode: %s", onames[o]); - if(fidx != D_NONE) - regfree(fidx); - if(tidx != D_NONE) - regfree(tidx); -} - -void -asopt(void) -{ - long v; - int g; - Prog *q; - - /* - * mov $0, ... - * ==> - * clr , ... - */ - v = 0; - if(p->from.type == D_CONST) { - v = p->from.offset; - if(v == 0) { - p->from.type = D_NONE; - if(p->as == AMOVL) - p->as = ACLRL; - if(p->as == AMOVW) - p->as = ACLRW; - if(p->as == AMOVB) - p->as = ACLRB; - return; - } - } - /* - * mov ..., TOS - * ==> - * pea (...) - */ - if(p->as == AMOVL && p->to.type == D_TOS) - switch(p->from.type) { - case D_CONST: - p->from.type |= I_INDIR; - p->to = p->from; - p->from = zprog.from; - p->as = APEA; - return; - - case I_ADDR|D_EXTERN: - case I_ADDR|D_STATIC: - p->from.type &= ~I_ADDR; - p->to = p->from; - p->from = zprog.from; - p->as = APEA; - return; - } - /* - * movL $Qx, ... - * ==> - * movL $Qx,R - * movL R, ... - */ - if(p->as == AMOVL && p->from.type == D_CONST) - if(v >= -128 && v < 128) - if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) { - g = regalloc(types[TLONG], D_NONE); - q = p; - nextpc(); - p->as = AMOVL; - p->from.type = g; - p->to = q->to; - q->to = p->from; - regfree(g); - if(debug['g']) - print("%P\n", q); - return; - } -} - -void -gbranch(int o) -{ - int a; - - a = ABNE; - switch(o) { - case ORETURN: a = ARTS; break; - case OGOTO: a = ABRA; break; - case OEQ: a = ABEQ; break; - case ONE: a = ABNE; break; - case OLE: a = ABLE; break; - case OLS: a = ABLS; break; - case OLT: a = ABLT; break; - case OLO: a = ABCS; break; - case OGE: a = ABGE; break; - case OHS: a = ABCC; break; - case OGT: a = ABGT; break; - case OHI: a = ABHI; break; - case OBIT: a = ABCS; break; - case OCASE: a = ABCASE; break; - } - nextpc(); - p->from.type = D_NONE; - p->to.type = D_NONE; - p->as = a; -} - -void -fpbranch(void) -{ - int a; - - a = p->as; - switch(a) { - case ABEQ: a = AFBEQ; break; - case ABNE: a = AFBNE; break; - case ABLE: a = AFBLE; break; - case ABLT: a = AFBLT; break; - case ABGE: a = AFBGE; break; - case ABGT: a = AFBGT; break; - } - p->as = a; -} - -void -patch(Prog *op, long pc) -{ - - op->to.offset = pc; - op->to.type = D_BRANCH; -} - -void -gpseudo(int a, Sym *s, int g, long v) -{ - - nextpc(); - if(a == ADATA) - pc--; - p->as = a; - p->to.type = g; - p->to.offset = v; - p->from.sym = s; - p->from.type = D_EXTERN; - if(s->class == CSTATIC) - p->from.type = D_STATIC; -} - -void -gpseudotree(int a, Sym *s, Node *n) -{ - - nextpc(); - if(a == ADATA) - pc--; - p->as = a; - naddr(n, &p->to, D_NONE); - p->from.sym = s; - p->from.type = D_EXTERN; - if(s->class == CSTATIC) - p->from.type = D_STATIC; -} - -long -exreg(Type *t) -{ - long o; - - if(typechl[t->etype]) { - if(exregoffset <= 5) - return 0; - o = exregoffset + D_R0; - exregoffset--; - return o; - } - if(t->etype == TIND) { - if(exaregoffset <= 3) - return 0; - o = exaregoffset + D_A0; - exaregoffset--; - return o; - } - if(typefd[t->etype]) { - if(exfregoffset <= 5) - return 0; - o = exfregoffset + D_F0; - exfregoffset--; - return o; - } - return 0; -} - -schar ewidth[NTYPE] = -{ - -1, /* [TXXX] */ - SZ_CHAR, /* [TCHAR] */ - SZ_CHAR, /* [TUCHAR] */ - SZ_SHORT, /* [TSHORT] */ - SZ_SHORT, /* [TUSHORT] */ - SZ_INT, /* [TINT] */ - SZ_INT, /* [TUINT] */ - SZ_LONG, /* [TLONG] */ - SZ_LONG, /* [TULONG] */ - SZ_VLONG, /* [TVLONG] */ - SZ_VLONG, /* [TUVLONG] */ - SZ_FLOAT, /* [TFLOAT] */ - SZ_DOUBLE, /* [TDOUBLE] */ - SZ_IND, /* [TIND] */ - 0, /* [TFUNC] */ - -1, /* [TARRAY] */ - 0, /* [TVOID] */ - -1, /* [TSTRUCT] */ - -1, /* [TUNION] */ - SZ_INT, /* [TENUM] */ -}; -long ncast[NTYPE] = -{ - 0, /* [TXXX] */ - BCHAR|BUCHAR, /* [TCHAR] */ - BCHAR|BUCHAR, /* [TUCHAR] */ - BSHORT|BUSHORT, /* [TSHORT] */ - BSHORT|BUSHORT, /* [TUSHORT] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */ - BVLONG|BUVLONG, /* [TVLONG] */ - BVLONG|BUVLONG, /* [TUVLONG] */ - BFLOAT, /* [TFLOAT] */ - BDOUBLE, /* [TDOUBLE] */ - BLONG|BULONG|BIND, /* [TIND] */ - 0, /* [TFUNC] */ - 0, /* [TARRAY] */ - 0, /* [TVOID] */ - BSTRUCT, /* [TSTRUCT] */ - BUNION, /* [TUNION] */ - 0, /* [TENUM] */ -}; diff --git a/utils/1l/Nt.c b/utils/1l/Nt.c deleted file mode 100644 index 2efff499..00000000 --- a/utils/1l/Nt.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <windows.h> -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/1l/Plan9.c b/utils/1l/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/1l/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/1l/Posix.c b/utils/1l/Posix.c deleted file mode 100644 index aa5d9551..00000000 --- a/utils/1l/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fials if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} diff --git a/utils/1l/asm.c b/utils/1l/asm.c deleted file mode 100644 index 6cf02ed8..00000000 --- a/utils/1l/asm.c +++ /dev/null @@ -1,1529 +0,0 @@ -#include "l.h" - -short opa[20]; -short *op; - -long -entryvalue(void) -{ - char *a; - Sym *s; - - a = INITENTRY; - if(*a >= '0' && *a <= '9') - return atolwhex(a); - s = lookup(a, 0); - if(s->type == 0) - return INITTEXT; - if(s->type != STEXT) - diag("entry not text: %s", s->name); - return s->value; -} - -void -asmb(void) -{ - Prog *p; - long v; - int a; - short *op1; - - if(debug['v']) - Bprint(&bso, "%5.2f asmb\n", cputime()); - Bflush(&bso); - - seek(cout, HEADR, 0); - pc = INITTEXT; - curp = firstp; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - if(p->pc != pc) { - if(!debug['a']) - print("%P\n", curp); - diag("phase error %.4lux sb %.4lux in %s", p->pc, pc, TNAME); - pc = p->pc; - } - curp = p; - if(debug['a']) - Bprint(&bso, "%lux:%P\n", pc, curp); - asmins(p); - if(cbc < sizeof(opa)) - cflush(); - for(op1 = opa; op1 < op; op1++) { - a = *op1; - *cbp++ = a >> 8; - *cbp++ = a; - } - a = 2*(op - opa); - pc += a; - cbc -= a; - if(debug['a']) { - for(op1 = opa; op1 < op; op1++) - if(op1 == opa) - Bprint(&bso, "\t\t%4ux", *op1 & 0xffff); - else - Bprint(&bso, " %4ux", *op1 & 0xffff); - if(op != opa) - Bprint(&bso, "\n"); - } - } - cflush(); - switch(HEADTYPE) { - case 0: /* this is garbage */ - seek(cout, rnd(HEADR+textsize, 8192), 0); - break; - case 1: /* plan9 boot data goes into text */ - seek(cout, rnd(HEADR+textsize, INITRND), 0); - break; - case 2: /* plan 9 */ - seek(cout, HEADR+textsize, 0); - break; - case 3: /* next boot */ - seek(cout, HEADR+rnd(textsize, INITRND), 0); - break; - case 4: /* preprocess pilot */ - seek(cout, HEADR+textsize, 0); - break; - } - - if(debug['v']) - Bprint(&bso, "%5.2f datblk\n", cputime()); - Bflush(&bso); - - for(v = 0; v < datsize; v += sizeof(buf)-100) { - if(datsize-v > sizeof(buf)-100) - datblk(v, sizeof(buf)-100); - else - datblk(v, datsize-v); - } - - symsize = 0; - spsize = 0; - lcsize = 0; - relocsize = 0; - - Bflush(&bso); - - switch(HEADTYPE) { - default: - seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); - break; - case 1: /* plan9 boot data goes into text */ - seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); - break; - case 2: /* plan 9 */ - seek(cout, HEADR+textsize+datsize, 0); - break; - case 3: /* next boot */ - seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0); - break; - case 4: /* preprocess pilot */ - seek(cout, HEADR+textsize+datsize, 0); - break; - } - if(!debug['s']) { - if(debug['v']) - Bprint(&bso, "%5.2f sym\n", cputime()); - asmsym(); - } - Bflush(&bso); - if(!debug['s']) { - if(debug['v']) - Bprint(&bso, "%5.2f sp\n", cputime()); - asmsp(); - } - Bflush(&bso); - if(!debug['s']) { - if(debug['v']) - Bprint(&bso, "%5.2f pc\n", cputime()); - asmlc(); - } - Bflush(&bso); - if(!debug['s']) { - if(debug['v']) - Bprint(&bso, "%5.2f reloc\n", cputime()); - asmreloc(); - } - cflush(); - - if(debug['v']) - Bprint(&bso, "%5.2f headr\n", cputime()); - Bflush(&bso); - seek(cout, 0L, 0); - switch(HEADTYPE) { - default: - lput(0x160L<<16); /* magic and sections */ - lput(0L); /* time and date */ - lput(rnd(HEADR+textsize, 4096)+datsize); - lput(symsize); /* nsyms */ - lput((0x38L<<16)|7L); /* size of optional hdr and flags */ - lput((0413<<16)|0437L); /* magic and version */ - lput(rnd(HEADR+textsize, 4096)); /* sizes */ - lput(datsize); - lput(bsssize); - lput(entryvalue()); /* va of entry */ - lput(INITTEXT-HEADR); /* va of base of text */ - lput(INITDAT); /* va of base of data */ - lput(INITDAT+datsize); /* va of base of bss */ - lput(~0L); /* gp reg mask */ - lput(0L); - lput(0L); - lput(0L); - lput(0L); - lput(~0L); /* gp value ?? */ - break; - case 1: /* plan9 boot data goes into text */ - lput(0407); /* magic */ - lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize); /* sizes */ - lput(0); - lput(bsssize); - lput(symsize); /* nsyms */ - lput(entryvalue()); /* va of entry */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - break; - case 2: /* plan 9 */ - lput(0407); /* magic */ - lput(textsize); /* sizes */ - lput(datsize); - lput(bsssize); - lput(symsize); /* nsyms */ - lput(entryvalue()); /* va of entry */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - break; - case 3: /* next boot */ - /* header */ - lput(0xfeedfaceL); /* magic */ - lput(6); /* 68040 */ - lput(1); /* more 68040 */ - lput(5); /* file type 'boot' */ - lput(HEADTYPE); /* number commands */ - lput(HEADR-7*4); /* sizeof commands */ - lput(1); /* no undefineds */ - /* command 1 text */ - lput(1); /* command = 'segment' */ - lput(124); /* command size */ - s16put("__TEXT"); - /* botch?? entryvalue() */ - lput(INITTEXT); /* va of start */ - lput(rnd(textsize, 8192)); /* va size */ - lput(HEADR); /* file offset */ - lput(rnd(textsize, 8192)); /* file size */ - lput(7); /* max prot */ - lput(7); /* init prot */ - lput(1); /* number of sections */ - lput(0); /* flags */ - /* text section */ - s16put("__text"); - s16put("__TEXT"); - /* botch?? entryvalue() */ - lput(INITTEXT); /* va of start */ - lput(textsize); /* va size */ - lput(HEADR); /* file offset */ - lput(2); /* align */ - lput(0); /* reloff */ - lput(0); /* nreloc */ - lput(0); /* flags */ - lput(0); /* reserved1 */ - lput(0); /* reserved2 */ - /* command 1 data */ - lput(1); /* command = 'segment' */ - lput(192); /* command size */ - s16put("__DATA"); - lput(INITDAT); /* va of start */ - lput(rnd(datsize, 8192)); /* va size */ - lput(HEADR+rnd(textsize, 8192)); /* file offset */ - lput(rnd(datsize, 8192)); /* file size */ - lput(7); /* max prot */ - lput(7); /* init prot */ - lput(2); /* number of sections */ - lput(0); /* flags */ - /* data section */ - s16put("__data"); - s16put("__DATA"); - lput(INITDAT); /* va of start */ - lput(datsize); /* va size */ - lput(HEADR+rnd(textsize, 8192)); /* file offset */ - lput(2); /* align */ - lput(0); /* reloff */ - lput(0); /* nreloc */ - lput(0); /* flags */ - lput(0); /* reserved1 */ - lput(0); /* reserved2 */ - /* bss section */ - s16put("__bss"); - s16put("__DATA"); - lput(INITDAT+datsize); /* va of start */ - lput(bsssize); /* va size */ - lput(0); /* file offset */ - lput(2); /* align */ - lput(0); /* reloff */ - lput(0); /* nreloc */ - lput(1); /* flags = zero fill */ - lput(0); /* reserved1 */ - lput(0); /* reserved2 */ - /* command 2 symbol */ - lput(2); /* command = 'symbol' */ - lput(24); /* command size */ - lput(HEADR+rnd(textsize, INITRND) - +datsize); /* symoff */ - lput(symsize); /* nsyms */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - break; - case 4: /* preprocess pilot */ - lput(0407); /* magic */ - lput(textsize); /* sizes */ - lput(datsize); - lput(bsssize); - lput(symsize); /* nsyms */ - lput(entryvalue()); /* va of entry */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - lput(relocsize); /* relocation */ - break; - } - cflush(); -} - -void -asmins(Prog *p) -{ - Optab *o; - int t, a, b; - long v; - - op = opa + 1; - if(special[p->from.type]) - switch(p->from.type) { - - case D_CCR: - if(p->as != AMOVW) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x42c0 | a; /* mov from ccr */ - return; - - case D_SR: - if(p->as != AMOVW) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x40c0 | a; /* mov from sr */ - return; - - case D_USP: - if(p->as != AMOVL) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 010) { - opa[0] = 0x4e68|(a&7); /* mov usp An */ - return; - } - t = 0x800; - goto movec1; - - case D_SFC: - t = 0x000; - goto movec1; - - case D_DFC: - t = 0x001; - goto movec1; - - case D_CACR: - t = 0x002; - goto movec1; - - case D_TC: - t = 0x003; - goto movec1; - - case D_ITT0: - t = 0x004; - goto movec1; - - case D_ITT1: - t = 0x005; - goto movec1; - - case D_DTT0: - t = 0x006; - goto movec1; - - case D_DTT1: - t = 0x007; - goto movec1; - - case D_VBR: - t = 0x801; - goto movec1; - - case D_CAAR: - t = 0x802; - goto movec1; - - case D_MSP: - t = 0x803; - goto movec1; - - case D_ISP: - t = 0x804; - goto movec1; - - case D_MMUSR: - t = 0x805; - goto movec1; - - case D_URP: - t = 0x806; - goto movec1; - - case D_SRP: - t = 0x807; - goto movec1; - - movec1: - if(p->as != AMOVL) - goto bad; - opa[0] = 0x4e7a; /* mov spc Dn */ - a = asmea(p, &p->to); - b = a & 0170; - if(b == 0 || b == 010) { - *op++ = (a<<12) | t; - return; - } - goto bad; - - case D_FPCR: - t = 0xb000; - goto movec3; - - case D_FPSR: - t = 0xa800; - goto movec3; - - case D_FPIAR: - t = 0xa400; - - movec3: - if(p->as != AMOVL) - goto bad; - op++; - a = asmea(p, &p->to); - opa[0] = optab[AFMOVEL].opcode0 | a; - opa[1] = t; - return; - } - if(special[p->to.type]) - switch(p->to.type) { - - case D_CCR: - if(p->as != AMOVW) /* botch, needs and, eor etc. */ - goto bad; - a = asmea(p, &p->from); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x44c0 | a; /* mov to ccr */ - return; - - case D_SR: - if(p->as != AMOVW) /* botch, needs and, eor etc. */ - goto bad; - a = asmea(p, &p->from); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x46c0 | a; /* mov to sr */ - return; - - case D_USP: - if(p->as != AMOVL) - goto bad; - a = asmea(p, &p->from); - if((a & 0170) == 010) { - opa[0] = 0x4e60|(a&7); /* mov An usp */ - return; - } - t = 0x800; - goto movec2; - - case D_SFC: - t = 0x000; - goto movec2; - - case D_DFC: - t = 0x001; - goto movec2; - - case D_CACR: - t = 0x002; - goto movec2; - - case D_TC: - t = 0x003; - goto movec2; - - case D_ITT0: - t = 0x004; - goto movec2; - - case D_ITT1: - t = 0x005; - goto movec2; - - case D_DTT0: - t = 0x006; - goto movec2; - - case D_DTT1: - t = 0x007; - goto movec2; - - case D_VBR: - t = 0x801; - goto movec2; - - case D_CAAR: - t = 0x802; - goto movec2; - - case D_MSP: - t = 0x803; - goto movec2; - - case D_ISP: - t = 0x804; - goto movec2; - - case D_MMUSR: - t = 0x805; - goto movec2; - - case D_URP: - t = 0x806; - goto movec2; - - case D_SRP: - t = 0x807; - goto movec2; - - movec2: - if(p->as != AMOVL) - goto bad; - opa[0] = 0x4e7b; /* mov Dn spc */ - a = asmea(p, &p->from); - b = a & 0170; - if(b == 0 || b == 010) { - *op++ = (a<<12) | t; - return; - } - goto bad; - - case D_FPCR: - t = 0x9000; - goto movec4; - - case D_FPSR: - t = 0x8800; - goto movec4; - - case D_FPIAR: - t = 0x8400; - - movec4: - if(p->as != AMOVL) - goto bad; - op++; - a = asmea(p, &p->from); - opa[0] = optab[AFMOVEL].opcode0 | a; - opa[1] = t; - return; - } - - o = &optab[p->as]; - t = o->opcode0; - switch(o->optype) { - case 0: /* pseudo ops */ - if(p->as != ATEXT && p->as != ANOP) { - if(!debug['a']) - print("%P\n", p); - diag("unimplemented instruction in %s", TNAME); - return; - } - op = opa; - return; - - case 1: /* branches */ - if(p->to.type != D_BRANCH) - goto bad; - a = asmea(p, &p->to); - if(a == 071) - t = o->opcode1; - t |= a; - break; - - case 2: /* move */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 0110) { /* src quick */ - t = o->opcode1; - if((b & 0170) != 0) - goto bad; - t |= a >> 7; - t |= b << 9; - break; - } - t |= a; - t |= (b&7) << 9; - t |= (b&070) << 3; - break; - - case 3: /* add */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 0110) { /* src quick */ - t = o->opcode1; - t |= (a&01600) << 2; - t |= b; - break; - } - if((b & 0170) == 0) { /* dst Dn */ - t |= a; - t |= (b & 7) << 9; - break; - } - if((b & 0170) == 010) { /* dst An */ - if((t & 0xc0) == 0) - goto bad; - t = o->opcode2; - t |= a; - t |= (b & 7) << 9; - break; - } - if((a & 0170) == 0) { /* src Dn */ - t |= 0x100; - t |= (a & 7) << 9; - t |= b; - break; - } - if((a & 0177) == 074) { /* src immed */ - t = o->opcode3; - t |= b; - break; - } - goto bad; - - case 4: /* no operands */ - break; - - case 5: /* tst */ - t |= asmea(p, &p->to); - if((t&0170) == 010) - goto bad; - break; - - case 6: /* lea */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) != 010) - goto bad; - t |= a; - t |= (b & 7) << 9; - break; - - case 7: /* cmp */ - b = asmea(p, &p->to); - a = asmea(p, &p->from); - if((a & 0170) == 010) { /* dst An */ - t = o->opcode1; - if(t == 0) /* cmpb illegal */ - goto bad; - t |= 0xc0; - t |= b; - t |= (a & 7) << 9; - break; - } - if((b & 0177) == 074) { /* src immed */ - t = o->opcode2; - t |= a; - break; - } - if((a & 0170) == 0) { /* dst Dn */ - t |= b; - t |= (a&7) << 9; - break; - } - if((b&0170) == 030 && (a&0170) == 030) { /* (A)+,(A)+ */ - t = o->opcode3; - t |= b & 7; - t |= (a & 7) << 9; - break; - } - goto bad; - - case 8: /* svc */ - *op++ = optab[ARTS].opcode0; - break; - - case 9: /* and */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - if((b & 0170) == 0) { /* dst Dn */ - t |= a; - t |= (b&7) << 9; - break; - } - if((a & 0170) == 0) { /* src Dn */ - t = o->opcode1; - t |= b; - t |= (a&7) << 9; - break; - } - if((a & 0177) == 074) { /* src immed */ - t = o->opcode2; - t |= b; - break; - } - goto bad; - - case 10: /* eor */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - if((a & 0170) == 0) { /* src Dn */ - t |= b; - t |= (a&7) << 9; - break; - } - if((a & 0177) == 074) { /* src immed */ - t = o->opcode1; - t |= b; - break; - } - goto bad; - - case 11: /* ext */ - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - t |= b; - break; - } - goto bad; - - case 12: /* shift */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - if((a & 0177) == 0110) { /* src quick */ - t |= (a & 01600) << 2; - t |= b; - break; - } - if((a & 0170) == 0) { /* src Dn */ - t |= 0x20; - t |= a << 9; - t |= b; - break; - } - goto bad; - } - goto bad; - - case 13: /* mul, div short */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - if((a & 0170) == 010) - goto bad; - t |= a; - t |= b << 9; - break; - } - goto bad; - - case 14: /* mul, div long */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - if((a & 0170) == 010) - goto bad; - t |= a; - opa[1] |= b << 12; - opa[1] |= b+1; - break; - } - goto bad; - - case 15: /* dec and branch */ - if(p->to.type != D_BRANCH) - goto bad; - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) - goto bad; - *op++ = v; - a = asmea(p, &p->from); - if((a & 0170) != 0) - goto bad; - t |= a; - break; - - case 16: /* fmove */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 0100) { /* src Fn */ - if((b & 0170) == 0100) { /* both Fn */ - opa[1] |= (a&7) << 10; - opa[1] |= (b&7) << 7; - break; - } - t |= b; - opa[1] = o->opcode2; - opa[1] |= (a&7) << 7; - break; - } - if((b & 0170) != 0100) /* dst Fn */ - goto bad; - t |= a; - opa[1] = o->opcode3; - opa[1] |= (b&7) << 7; - break; - - case 17: /* floating ea,Fn */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) != 0100) /* dst Fn */ - goto bad; - if((a & 0170) == 0100) { /* both Fn */ - opa[1] |= (a&7) << 10; - opa[1] |= (b&7) << 7; - break; - } - t |= a; - opa[1] = o->opcode2; - opa[1] |= (b&7) << 7; - break; - - case 18: /* floating branchs */ - if(p->to.type != D_BRANCH) - goto bad; - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) - goto bad; - *op++ = v; - break; - - case 19: /* floating dec and branch */ - if(p->to.type != D_BRANCH) - goto bad; - *op++ = o->opcode1; - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) - goto bad; - *op++ = v; - a = asmea(p, &p->from); - if((a & 0170) != 0) - goto bad; - t |= a; - break; - - case 20: /* ftst ea */ - *op++ = o->opcode1; - if(p->from.type != D_NONE) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 0100) { /* Fn */ - opa[1] |= (a&7) << 10; - break; - } - t |= a; - opa[1] = o->opcode2; - break; - - case 21: /* fneg */ - *op++ = o->opcode1; - if(p->from.type == D_NONE) { - b = asmea(p, &p->to); - a = b; - } else { - a = asmea(p, &p->from); - b = asmea(p, &p->to); - } - if((b & 0170) != 0100) /* dst Fn */ - goto bad; - if((a & 0170) == 0100) { /* both Fn */ - opa[1] |= (a&7) << 10; - opa[1] |= (b&7) << 7; - break; - } - t |= a; - opa[1] = o->opcode2; - opa[1] |= (b&7) << 7; - break; - - case 22: /* floating cmp Fn,ea */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) != 0100) /* dst Fn */ - goto bad; - if((b & 0170) == 0100) { /* both Fn */ - opa[1] |= (b&7) << 10; - opa[1] |= (a&7) << 7; - break; - } - t |= b; - opa[1] = o->opcode2; - opa[1] |= (a&7) << 7; - break; - - case 23: /* word, long */ - op = opa; - a = asmea(p, &p->to); - if(a == ((7<<3)|4)) - return; - if(a == ((7<<3)|1)) { - if(p->as == AWORD) { - op = opa; - *op++ = opa[1]; - } - return; - } - if(a == ((7<<3)|0)) { - if(p->as == ALONG) { - *op++ = opa[0]; - opa[0] = 0; - } - return; - } - goto bad; - - case 24: /* bit field */ - a = ((p->to.field&31)<<6) | (p->from.field&31); - if(p->as == ABFINS) { - b = asmea(p, &p->from); - if((b&0170) != 0) - goto bad; - a |= b<<12; - *op++ = a; - a = asmea(p, &p->to); - } else { - if(p->to.type != D_NONE) { - b = asmea(p, &p->to); - if((b&0170) != 0) - goto bad; - a |= b<<12; - } - *op++ = a; - a = asmea(p, &p->from); - } - t |= a; - a &= 0170; - if(a == 010 || a == 030 || a == 040 || a == 074) - goto bad; - break; - - case 25: /* movem */ - if(p->from.type == D_CONST) { /* registers -> memory */ - asmea(p, &p->from); - a = asmea(p, &p->to); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 030) - goto bad; - t |= a; - break; - } - if(p->to.type == D_CONST) { /* memory -> registers */ - t |= 0x400; - asmea(p, &p->to); - a = asmea(p, &p->from); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 040) - goto bad; - t |= a; - break; - } - goto bad; - - case 26: /* chk */ - a = asmea(p, &p->from); - if((a&0170) == 010) - goto bad; - b = asmea(p, &p->to); - if((b&0170) != 0) - goto bad; - t |= a; - t |= b<<9; - break; - - case 27: /* btst */ - a = asmea(p, &p->from); - if(a == 074) { - t = o->opcode1; - } else - if((a&0170) != 0) - goto bad; - b = asmea(p, &p->to); - if(b == 074 || (b&0170) == 010) - goto bad; - t |= b; - break; - - case 28: /* fmovem */ - if(p->from.type == D_CONST) { /* registers -> memory */ - b = p->from.offset & 0xff; - b |= 0xf000; /* control or postinc */ - *op++ = b; - a = asmea(p, &p->to); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 030) - goto bad; - if(b == 040) - op[-1] &= ~0x1000; /* predec */ - t |= a; - break; - } - if(p->to.type == D_CONST) { /* memory -> registers */ - b = p->to.offset & 0xff; - b |= 0xd000; /* control or postinc */ - *op++ = b; - a = asmea(p, &p->from); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 040) - goto bad; - t |= a; - break; - } - goto bad; - - case 29: /* fmovemc */ - if(p->from.type == D_CONST) { /* registers -> memory */ - b = (p->from.offset & 0x7) << 10; - b |= 0xa000; - *op++ = b; - a = asmea(p, &p->to); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 030) - goto bad; - t |= a; - break; - } - if(p->to.type == D_CONST) { /* memory -> registers */ - b = (p->to.offset & 0x7) << 10; - b |= 0x8000; - *op++ = b; - a = asmea(p, &p->from); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 040) - goto bad; - t |= a; - break; - } - goto bad; - - case 30: /* trap */ - if(p->to.type == D_CONST) { - t |= p->to.offset & 0xf; - break; - } - goto bad; - - case 31: /* chk2, cmp2 */ - b = asmea(p, &p->to); - a = b & 0170; - if(a == 000 || a == 010) { - *op++ = o->opcode1 | (b << 12); - t |= asmea(p, &p->from); - break; - } - goto bad; - - case 32: /* casew */ - /* jmp (0,pc,r0.w*1) */ - casepc = p->pc; - *op++ = o->opcode1; - break; - - case 34: /* moves */ - op++; - a = asmea(p, &p->from); - b = a & 0170; - if(b == 0 || b == 010) { - opa[1] = (a << 12) | 0x800; - b = asmea(p, &p->to); - a = b & 0170; - if(a == 0 || a == 010) - goto bad; - t |= b; - break; - } - t |= a; - b = asmea(p, &p->to); - a = b & 0170; - if(a != 0 && a != 010) - goto bad; - opa[1] = (b << 12); - break; - - case 35: /* swap */ - a = asmea(p, &p->to); - if((a & 0170) == 0) { - t |= a; - break; - } - goto bad; - } - opa[0] = t; - return; - -bad: - if(!debug['a']) - print("%P\n", p); - diag("bad combination of addressing in %s", TNAME); - opa[0] = 0; -} - -int -asmea(Prog *p, Adr *a) -{ - Optab *o; - int f, t, r, i; - long v; - - t = a->type; - r = simple[t]; - v = a->offset; - if(r != 0177) { - if(v == 0) - return r; - if((r & 070) != 020) - return r; - if(v >= -32768L && v < 32768L) { - *op++ = v; - return t-D_A0-I_INDIR+050; /* d(Ax) */ - } - goto toobig; - } - f = 0; - if(a == &p->from) - f++; - o = &optab[p->as]; - switch(t) { - case D_TOS: - if(f) { - if(o->srcsp) - return (3<<3) | 7; /* (A7)+ */ - } else - if(o->dstsp) - return (4<<3) | 7; /* -(A7) */ - return (2<<3) | 7; /* (A7) */ - - case D_BRANCH: - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) { - if(p->as == ABSR || p->as == ABRA) { - v = p->pcond->pc; - *op++ = v>>16; - *op++ = v; - return (7<<3) | 1; - } - goto toobig; - } - if(v < -128 || v >= 128 || p->mark == 4) { - *op++ = v; - return 0; - } - return v & 0xff; - - case I_ADDR|D_STATIC: - case I_ADDR|D_EXTERN: - t = a->sym->type; - if(t == 0 || t == SXREF) { - diag("undefined external: %s in %s", - a->sym->name, TNAME); - a->sym->type = SDATA; - } - v = a->sym->value + a->offset; - if(t != STEXT) - v += INITDAT; - if(strcmp(a->sym->name, "a6base")) - break; - - case D_CONST: - switch(f? o->srcsp: o->dstsp) { - case 4: - *op++ = v>>16; - - case 2: - *op++ = v; - break; - - default: - diag("unknown srcsp asmea in %s", TNAME); - } - return (7<<3) | 4; - - case D_FCONST: - r = f? o->srcsp: o->dstsp; - for(i=0; i<r; i++) - ((char*)op)[i] = gnuxi(&a->ieee, i, r); - op += r/2; - return (7<<3) | 4; - - case D_QUICK: - v = a->offset & 0xff; - return 0110 | (v<<7); - - case D_STACK: - case D_AUTO: - case D_PARAM: - if(v == 0) - return (2<<3) | 7; /* (A7) */ - if(v >= -32768L && v < 32768L) { - *op++ = v; - return (5<<3) | 7; /* d(A7) */ - } - goto toobig; - - case I_INDIR|D_CONST: - if(v >= -32768L && v < 32768L) { - *op++ = v; - return (7<<3) | 0; - } - *op++ = v>>16; - *op++ = v; - return (7<<3) | 1; - - case D_STATIC: - case D_EXTERN: - t = a->sym->type; - if(t == 0 || t == SXREF) { - diag("undefined external: %s in %s", - a->sym->name, TNAME); - a->sym->type = SDATA; - } - if(t == STEXT) { - if(HEADTYPE == 4) { - v = a->sym->value + a->offset - p->pc - 2; - if(v >= -32768L && v < 32768L) { - *op++ = v; - return (7<<3) | 2; - } - goto toobig; - } - v = a->sym->value + a->offset; - *op++ = v>>16; - *op++ = v; - return (7<<3) | 1; - } - v = a->sym->value + a->offset - A6OFFSET; - if(v < -32768L || v >= 32768L) { - v += INITDAT + A6OFFSET; - if(v >= -32768L && v < 32768L) { - *op++ = v; - return (7<<3) | 0; - } - *op++ = v>>16; - *op++ = v; - return (7<<3) | 1; - } - if(v == 0) - return (2<<3) | 6; - *op++ = v; - return (5<<3) | 6; - } - if(!debug['a']) - print("%P\n", p); - diag("unknown addressing mode: %d in %s", t, TNAME); - return 0; - -toobig: - if(!debug['a']) - print("%P\n", p); - diag("addressing mode >> 2^16: %d in %s", t, TNAME); - return 0; -} - -void -lput(long l) -{ - - CPUT(l>>24) - CPUT(l>>16) - CPUT(l>>8) - CPUT(l) -} - -void -s16put(char *n) -{ - char name[16]; - int i; - - strncpy(name, n, sizeof(name)); - for(i=0; i<sizeof(name); i++) - CPUT(name[i]) -} - -void -cflush(void) -{ - int n; - - n = sizeof(buf.cbuf) - cbc; - if(n) - write(cout, buf.cbuf, n); - cbp = buf.cbuf; - cbc = sizeof(buf.cbuf); -} - -void -datblk(long s, long n) -{ - Prog *p; - char *cast; - long l, fl, j; - int i, c; - - memset(buf.dbuf, 0, n+100); - for(p = datap; p != P; p = p->link) { - curp = p; - l = p->from.sym->value + p->from.offset - s; - c = p->from.displace; - i = 0; - if(l < 0) { - if(l+c <= 0) - continue; - while(l < 0) { - l++; - i++; - } - } - if(l >= n) - continue; - for(j=l+(c-i)-1; j>=l; j--) - if(buf.dbuf[j]) { - print("%P\n", p); - diag("multiple initialization"); - break; - } - switch(p->to.type) { - case D_FCONST: - switch(c) { - default: - case 4: - fl = ieeedtof(&p->to.ieee); - cast = (char*)&fl; - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux", cast[fnuxi8[j+4]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[fnuxi8[i+4]]; - l++; - } - break; - case 8: - cast = (char*)&p->to.ieee; - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[fnuxi8[i]]; - l++; - } - break; - } - break; - - case D_SCONST: - if(debug['a'] && i == 0) { - Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = p->to.scon[i]; - l++; - } - break; - default: - fl = p->to.offset; - if(p->to.sym) { - if(p->to.sym->type == STEXT) - fl += p->to.sym->value; - if(p->to.sym->type == SDATA) - fl += p->to.sym->value + INITDAT; - if(p->to.sym->type == SBSS) - fl += p->to.sym->value + INITDAT; - } - - cast = (char*)&fl; - switch(c) { - default: - diag("bad nuxi %d %d\n%P", c, i, curp); - break; - case 1: - if(debug['a'] && i == 0) { - Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux",cast[inuxi1[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[inuxi1[i]]; - l++; - } - break; - case 2: - if(debug['a'] && i == 0) { - Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux",cast[inuxi2[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[inuxi2[i]]; - l++; - } - break; - case 4: - if(debug['a'] && i == 0) { - Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux",cast[inuxi4[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[inuxi4[i]]; - l++; - } - break; - } - break; - } - } - write(cout, buf.dbuf, n); -} - -void -asmreloc(void) -{ - Prog *p; - Sym *s1, *s2; - int c1, c2, c3; - long v; - - if(HEADTYPE != 4) - return; - for(p = datap; p != P; p = p->link) { - curp = p; - s1 = p->to.sym; - if(s1 == S) - continue; - c1 = 'D'; - c3 = p->from.displace; - s2 = p->from.sym; - v = s2->value + INITDAT; - switch(s1->type) { - default: - diag("unknown reloc %d", s1->type); - continue; - case STEXT: - c2 = 'T'; - break; - - case SDATA: - c2 = 'D'; - break; - - case SBSS: - c2 = 'B'; - break; - } - CPUT(c1); - CPUT(c2); - CPUT(c3); - lput(v); - if(debug['a']) - Bprint(&bso, "r %c%c%d %.8lux %s $%s\n", - c1, c2, c3, v, s2->name, s1->name); - relocsize += 7; - } -} - -int -gnuxi(Ieee *d, int i, int c) -{ - char *p; - long l; - - switch(c) { - default: - diag("bad nuxi %d %d\n%P", c, i, curp); - return 0; - - /* - * 2301 vax - * 0123 68k - */ - case 4: - l = ieeedtof(d); - p = (char*)&l; - i = gnuxi8[i+4]; - break; - - /* - * 67452301 vax - * 45670123 68k - */ - case 8: - p = (char*)d; - i = gnuxi8[i]; - break; - } - return p[i]; -} - -long -rnd(long v, long r) -{ - long c; - - if(r <= 0) - return v; - v += r - 1; - c = v % r; - if(c < 0) - c += r; - v -= c; - return v; -} diff --git a/utils/1l/l.h b/utils/1l/l.h deleted file mode 100644 index de8d48ff..00000000 --- a/utils/1l/l.h +++ /dev/null @@ -1,268 +0,0 @@ -#include <lib9.h> -#include <bio.h> -#include "../2c/2.out.h" - -#ifndef EXTERN -#define EXTERN extern -#endif - -#define P ((Prog*)0) -#define S ((Sym*)0) -#define TNAME (curtext?curtext->from.sym->name:noname) -#define CPUT(c)\ - { *cbp++ = c;\ - if(--cbc <= 0)\ - cflush(); } - -typedef struct Adr Adr; -typedef struct Prog Prog; -typedef struct Sym Sym; -typedef struct Auto Auto; -typedef struct Optab Optab; - -struct Adr -{ - short type; - uchar field; - union - { - struct - { - long u0displace; - long u0offset; - } s0; - char u0scon[8]; - Prog *u0cond; /* not used, but should be D_BRANCH */ - Ieee u0ieee; - } u0; - union - { - Auto* u1autom; - Sym* u1sym; - } u1; -}; - -#define displace u0.s0.u0displace -#define offset u0.s0.u0offset -#define scon u0.u0scon -#define cond u0.u0cond -#define ieee u0.u0ieee - -#define autom u1.u1autom -#define sym u1.u1sym - -struct Prog -{ - Adr from; - Adr to; - union - { - long u0stkoff; - Prog *u0forwd; - } u0; - Prog* link; - Prog* pcond; /* work on this */ - long pc; - long line; - short as; - uchar mark; /* work on these */ - uchar back; -}; - -#define stkoff u0.u0stkoff -#define forwd u0.u0forwd - -struct Auto -{ - Sym* asym; - Auto* link; - long aoffset; - short type; -}; -struct Sym -{ - char *name; - short type; - short version; - short become; - short frame; - long value; - Sym* link; -}; -struct Optab -{ - short as; - short fas; - short srcsp; - short dstsp; - ushort optype; - ushort opcode0; - ushort opcode1; - ushort opcode2; - ushort opcode3; -}; - -enum -{ - STEXT = 1, - SDATA, - SBSS, - SDATA1, - SXREF, - SAUTO, - SPARAM, - SFILE, - NHASH = 10007, - NHUNK = 100000, - MINSIZ = 4, - STRINGSZ = 200, - MAXIO = 8192, - MAXHIST = 20, /* limit of path elements for history symbols */ - A6OFFSET = 32766, -}; - -EXTERN union -{ - struct - { - char obuf[MAXIO]; /* output buffer */ - uchar ibuf[MAXIO]; /* input buffer */ - } u; - char dbuf[1]; -} buf; - -#define cbuf u.obuf -#define xbuf u.ibuf - -#pragma varargck type "A" int -#pragma varargck type "D" Adr* -#pragma varargck type "P" Prog* -#pragma varargck type "R" int -#pragma varargck type "S" char* - -EXTERN long HEADR; -EXTERN long HEADTYPE; -EXTERN long INITDAT; -EXTERN long INITRND; -EXTERN long INITTEXT; -EXTERN char* INITENTRY; /* entry point */ -EXTERN Biobuf bso; -EXTERN long bsssize; -EXTERN long casepc; -EXTERN int cbc; -EXTERN char* cbp; -EXTERN int cout; -EXTERN Auto* curauto; -EXTERN Auto* curhist; -EXTERN Prog* curp; -EXTERN Prog* curtext; -EXTERN Prog* datap; -EXTERN long datsize; -EXTERN char debug[128]; -EXTERN Prog* etextp; -EXTERN Prog* firstp; -EXTERN Prog* prog_divsl; -EXTERN Prog* prog_divul; -EXTERN Prog* prog_mull; -EXTERN Prog* prog_ccr; -EXTERN char fnuxi8[8]; -EXTERN char gnuxi8[8]; -EXTERN Sym* hash[NHASH]; -EXTERN Sym* histfrog[MAXHIST]; -EXTERN int histfrogp; -EXTERN int histgen; -EXTERN char* library[50]; -EXTERN char* libraryobj[50]; -EXTERN int libraryp; -EXTERN int xrefresolv; -EXTERN char* hunk; -EXTERN char inuxi1[1]; -EXTERN char inuxi2[2]; -EXTERN char inuxi4[4]; -EXTERN Prog* lastp; -EXTERN long lcsize; -EXTERN long relocsize; -EXTERN long ndata; -EXTERN int nerrors; -EXTERN long nhunk; -EXTERN long nsymbol; -EXTERN char* noname; -EXTERN short* op; -EXTERN char* outfile; -EXTERN long pc; -EXTERN char simple[I_MASK]; -EXTERN char special[I_MASK]; -EXTERN long spsize; -EXTERN Sym* symlist; -EXTERN long symsize; -EXTERN Prog* textp; -EXTERN long textsize; -EXTERN long thunk; -EXTERN int version; -EXTERN Prog zprg; - -extern Optab optab[]; -extern char mmsize[]; -extern char* anames[]; - -int Aconv(Fmt*); -int Dconv(Fmt*); -int Pconv(Fmt*); -int Rconv(Fmt*); -int Sconv(Fmt*); -int Xconv(Fmt*); -void addhist(long, int); -int andsize(Prog*, Adr*); -void asmb(void); -int asmea(Prog*, Adr*); -void asmins(Prog*); -void asmlc(void); -void asmsp(void); -void asmsym(void); -void asmreloc(void); -long atolwhex(char*); -Prog* brchain(Prog*); -Prog* brloop(Prog*); -void cflush(void); -Prog* copyp(Prog*); -double cputime(void); -void datblk(long, long); -void diag(char*, ...); -void dodata(void); -void doprof1(void); -void doprof2(void); -void dostkoff(void); -long entryvalue(void); -void errorexit(void); -int find1(long, int); -int find2(long, int); -void follow(void); -void gethunk(void); -int gnuxi(Ieee*, int, int); -void histtoauto(void); -double ieeedtod(Ieee*); -long ieeedtof(Ieee*); -void initmuldiv1(void); -void initmuldiv2(void); -void ldobj(int, long, char*); -void loadlib(void); -void listinit(void); -Sym* lookup(char*, int); -void lput(long); -void main(int, char*[]); -void mkfwd(void); -void* mysbrk(ulong); -void nuxiinit(void); -void objfile(char*); -void patch(void); -Prog* prg(void); -Prog* nprg(Prog*); -int relinv(int); -long reuse(Prog*, Sym*); -long rnd(long, long); -void s16put(char*); -void span(void); -void undef(void); -void xdefine(char*, int, long); -void xfol(Prog*); -int zaddr(uchar*, Adr*, Sym*[]); diff --git a/utils/1l/list.c b/utils/1l/list.c deleted file mode 100644 index f02c3efa..00000000 --- a/utils/1l/list.c +++ /dev/null @@ -1,334 +0,0 @@ -#include "l.h" - -void -listinit(void) -{ - - fmtinstall('R', Rconv); - fmtinstall('A', Aconv); - fmtinstall('D', Dconv); - fmtinstall('S', Sconv); - fmtinstall('P', Pconv); -} - -static Prog *bigP; - -int -Pconv(Fmt *fp) -{ - char str[STRINGSZ], s[20]; - Prog *p; - - p = va_arg(fp->args, Prog*); - bigP = p; - sprint(str, "(%ld) %A %D,%D", - p->line, p->as, &p->from, &p->to); - if(p->from.field) { - sprint(s, ",%d,%d", p->to.field, p->from.field); - strcat(str, s); - } - bigP = P; - return fmtstrcpy(fp, str); -} - -int -Aconv(Fmt *fp) -{ - - return fmtstrcpy(fp, anames[va_arg(fp->args, int)]); -} - -int -Dconv(Fmt *fp) -{ - char str[40], s[20]; - Adr *a; - int i, j; - long d; - - a = va_arg(fp->args, Adr*); - i = a->type; - j = i & I_MASK; - if(j) { - a->type = i & D_MASK; - d = a->offset; - a->offset = 0; - switch(j) { - case I_INDINC: - sprint(str, "(%D)+", a); - break; - - case I_INDDEC: - sprint(str, "-(%D)", a); - break; - - case I_INDIR: - if(d) - sprint(str, "%ld(%D)", d, a); - else - sprint(str, "(%D)", a); - break; - - case I_ADDR: - a->offset = d; - sprint(str, "$%D", a); - break; - } - a->type = i; - a->offset = d; - goto out; - } - switch(i) { - - default: - sprint(str, "%R", i); - break; - - case D_NONE: - str[0] = 0; - break; - - case D_BRANCH: - if(bigP != P && bigP->pcond != P) - if(a->sym != S) - sprint(str, "%lux+%s", bigP->pcond->pc, - a->sym->name); - else - sprint(str, "%lux", bigP->pcond->pc); - else - sprint(str, "%ld(PC)", a->offset); - break; - - case D_EXTERN: - sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); - break; - - case D_STATIC: - sprint(str, "%s<%d>+%ld(SB)", a->sym->name, - a->sym->version, a->offset); - break; - - case D_AUTO: - sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); - break; - - case D_PARAM: - if(a->sym) - sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); - else - sprint(str, "%ld(FP)", a->offset); - break; - - case D_CONST: - sprint(str, "$%ld", a->offset); - break; - - case D_STACK: - sprint(str, "TOS+%ld", a->offset); - break; - - case D_QUICK: - sprint(str, "$Q%ld", a->offset); - break; - - case D_FCONST: - sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); - goto out; - - case D_SCONST: - sprint(str, "$\"%S\"", a->scon); - goto out; - } - if(a->displace) { - sprint(s, "/%ld", a->displace); - strcat(str, s); - } -out: - return fmtstrcpy(fp, str); -} - -int -Rconv(Fmt *fp) -{ - char str[20]; - int r; - - r = va_arg(fp->args, int); - if(r >= D_R0 && r < D_R0+NREG) - sprint(str, "R%d", r-D_R0); - else - if(r >= D_A0 && r < D_A0+NREG) - sprint(str, "A%d", r-D_A0); - else - if(r >= D_F0 && r < D_F0+NREG) - sprint(str, "F%d", r-D_F0); - else - switch(r) { - - default: - sprint(str, "gok(%d)", r); - break; - - case D_NONE: - sprint(str, "NONE"); - break; - - case D_TOS: - sprint(str, "TOS"); - break; - - case D_CCR: - sprint(str, "CCR"); - break; - - case D_SR: - sprint(str, "SR"); - break; - - case D_SFC: - sprint(str, "SFC"); - break; - - case D_DFC: - sprint(str, "DFC"); - break; - - case D_CACR: - sprint(str, "CACR"); - break; - - case D_USP: - sprint(str, "USP"); - break; - - case D_VBR: - sprint(str, "VBR"); - break; - - case D_CAAR: - sprint(str, "CAAR"); - break; - - case D_MSP: - sprint(str, "MSP"); - break; - - case D_ISP: - sprint(str, "ISP"); - break; - - case D_FPCR: - sprint(str, "FPCR"); - break; - - case D_FPSR: - sprint(str, "FPSR"); - break; - - case D_FPIAR: - sprint(str, "FPIAR"); - break; - - case D_TREE: - sprint(str, "TREE"); - break; - - case D_TC: - sprint(str, "TC"); - break; - - case D_ITT0: - sprint(str, "ITT0"); - break; - - case D_ITT1: - sprint(str, "ITT1"); - break; - - case D_DTT0: - sprint(str, "DTT0"); - break; - - case D_DTT1: - sprint(str, "DTT1"); - break; - - case D_MMUSR: - sprint(str, "MMUSR"); - break; - case D_URP: - sprint(str, "URP"); - break; - - case D_SRP: - sprint(str, "SRP"); - break; - } - return fmtstrcpy(fp, str); -} - -int -Sconv(Fmt *fp) -{ - int i, c; - char str[30], *p, *a; - - a = va_arg(fp->args, char*); - p = str; - for(i=0; i<sizeof(double); i++) { - c = a[i] & 0xff; - if(c >= 'a' && c <= 'z' || - c >= 'A' && c <= 'Z' || - c >= '0' && c <= '9') { - *p++ = c; - continue; - } - *p++ = '\\'; - switch(c) { - default: - if(c < 040 || c >= 0177) - break; /* not portable */ - p[-1] = c; - continue; - case 0: - *p++ = 'z'; - continue; - case '\\': - case '"': - *p++ = c; - continue; - case '\n': - *p++ = 'n'; - continue; - case '\t': - *p++ = 't'; - continue; - } - *p++ = (c>>6) + '0'; - *p++ = ((c>>3) & 7) + '0'; - *p++ = (c & 7) + '0'; - } - *p = 0; - return fmtstrcpy(fp, str); -} - -void -diag(char *fmt, ...) -{ - char buf[STRINGSZ], *tn; - va_list arg; - - tn = "??none??"; - if(curtext != P && curtext->from.sym != S) - tn = curtext->from.sym->name; - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - print("%s: %s\n", tn, buf); - - nerrors++; - if(nerrors > 10) { - print("too many errors\n"); - errorexit(); - } -} diff --git a/utils/1l/mkfile b/utils/1l/mkfile deleted file mode 100644 index aafa5a70..00000000 --- a/utils/1l/mkfile +++ /dev/null @@ -1,32 +0,0 @@ -<../../mkconfig - -TARG=1l -OFILES=\ - asm.$O\ - obj.$O\ - optab.$O\ - pass.$O\ - span.$O\ - list.$O\ - enam.$O\ - $TARGMODEL.$O\ - -HFILES=\ - l.h\ - ../2c/2.out.h\ - ../include/ar.h\ - -LIBS=bio 9 -BIN=$ROOT/$OBJDIR/bin -<$ROOT/mkfiles/mkone-$SHELLTYPE - -CFLAGS= $CFLAGS -I ../include - -enam.$O: ../2c/enam.c - $CC $CFLAGS ../2c/enam.c - -%.1: %.s - 1a $stem.s - -%.1: %.c - 1c -w $stem.c diff --git a/utils/1l/obj.c b/utils/1l/obj.c deleted file mode 100644 index afc3c9e7..00000000 --- a/utils/1l/obj.c +++ /dev/null @@ -1,1380 +0,0 @@ -#define EXTERN -#include "l.h" -#include <ar.h> - -#ifndef DEFAULT -#define DEFAULT '9' -#endif - -char symname[] = SYMDEF; -char thechar = '1'; -char *thestring = "68000"; - -/* - * -H0 -T0x40004C -D0x10000000 is garbage unix - * -H1 -T0x80020000 -R4 is garbage format - * -H2 -T8224 -R8192 is plan9 format - * -H3 -Tx -Rx is next boot - * -H4 -T0 -D0 is pilot relocatable - */ - -void -main(int argc, char *argv[]) -{ - int i, c; - char *a; - - Binit(&bso, 1, OWRITE); - cout = -1; - listinit(); - memset(debug, 0, sizeof(debug)); - nerrors = 0; - outfile = "1.out"; - HEADTYPE = -1; - INITTEXT = -1; - INITDAT = -1; - INITRND = -1; - INITENTRY = 0; - - ARGBEGIN { - default: - c = ARGC(); - if(c >= 0 && c < sizeof(debug)) - debug[c]++; - break; - case 'o': /* output to (next arg) */ - outfile = ARGF(); - break; - case 'E': - a = ARGF(); - if(a) - INITENTRY = a; - break; - case 'H': - a = ARGF(); - if(a) - HEADTYPE = atolwhex(a); - break; - case 'T': - a = ARGF(); - if(a) - INITTEXT = atolwhex(a); - break; - case 'D': - a = ARGF(); - if(a) - INITDAT = atolwhex(a); - break; - case 'R': - a = ARGF(); - if(a) - INITRND = atolwhex(a); - break; - } ARGEND - - USED(argc); - - if(*argv == 0) { - diag("usage: 1l [-options] objects"); - errorexit(); - } - if(!debug['9'] && !debug['U'] && !debug['B']) - debug[DEFAULT] = 1; - if(HEADTYPE == -1) { - if(debug['U']) - HEADTYPE = 2; - if(debug['B']) - HEADTYPE = 2; - if(debug['9']) - HEADTYPE = 2; - } - if(INITDAT != -1 && INITRND == -1) - INITRND = 0; - switch(HEADTYPE) { - default: - diag("unknown -H option %d", HEADTYPE); - errorexit(); - - case 0: /* this is garbage */ - HEADR = 20L+56L; - if(INITTEXT == -1) - INITTEXT = 0x40004CL; - if(INITDAT == -1) - INITDAT = 0x10000000L; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; - if(INITRND == -1) - INITRND = 0; - break; - case 1: /* plan9 boot data goes into text */ - HEADR = 32L; - if(INITTEXT == -1) - INITTEXT = 8224; - if(INITDAT == -1) - INITDAT = 0; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; - if(INITRND == -1) - INITRND = 8192; - break; - case 2: /* plan 9 */ - HEADR = 32L; - if(INITTEXT == -1) - INITTEXT = 8224; - if(INITDAT == -1) - INITDAT = 0; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; - if(INITRND == -1) - INITRND = 8192; - break; - case 3: /* next boot */ - HEADR = 28+124+192+24; - if(INITTEXT == -1) - INITTEXT = 0x04002000; - if(INITDAT == -1) - INITDAT = 0; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; - if(INITRND == -1) - INITRND = 8192L; - break; - case 4: /* preprocess pilot */ - HEADR = 36L; - if(INITTEXT == -1) - INITTEXT = 0; - if(INITDAT == -1) - INITDAT = 0; - if(INITRND == -1) - INITRND = 0; - break; - } - if(INITDAT != 0 && INITRND != 0) - print("warning: -D0x%lux is ignored because of -R0x%lux\n", - INITDAT, INITRND); - if(debug['v']) - Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", - HEADTYPE, INITTEXT, INITDAT, INITRND); - Bflush(&bso); - for(i=1; optab[i].as; i++) - if(i != optab[i].as) { - diag("phase error in optab: %d", i); - errorexit(); - } - - zprg.link = P; - zprg.pcond = P; - zprg.back = 2; - zprg.as = AGOK; - zprg.from.type = D_NONE; - zprg.to = zprg.from; - - memset(special, 0, sizeof(special)); - special[D_CCR] = 1; - special[D_SR] = 1; - special[D_SFC] = 1; - special[D_CACR] = 1; - special[D_USP] = 1; - special[D_VBR] = 1; - special[D_CAAR] = 1; - special[D_MSP] = 1; - special[D_ISP] = 1; - special[D_DFC] = 1; - special[D_FPCR] = 1; - special[D_FPSR] = 1; - special[D_FPIAR] = 1; - special[D_TC] = 1; - special[D_ITT0] = 1; - special[D_ITT1] = 1; - special[D_DTT0] = 1; - special[D_DTT1] = 1; - special[D_MMUSR] = 1; - special[D_URP] = 1; - special[D_SRP] = 1; - memset(simple, 0177, sizeof(simple)); - for(i=0; i<8; i++) { - simple[D_R0+i] = i; - simple[D_F0+i] = i+0100; - simple[D_A0+i] = i+010; - simple[D_A0+I_INDIR+i] = i+020; - simple[D_A0+I_INDINC+i] = i+030; - simple[D_A0+I_INDDEC+i] = i+040; - } - nuxiinit(); - histgen = 0; - textp = P; - datap = P; - pc = 0; - cout = create(outfile, 1, 0775); - if(cout < 0) { - diag("cannot create %s", outfile); - errorexit(); - } - version = 0; - cbp = buf.cbuf; - cbc = sizeof(buf.cbuf); - firstp = prg(); - lastp = firstp; - - if(INITENTRY == 0) { - INITENTRY = "_main"; - if(debug['p']) - INITENTRY = "_mainp"; - if(!debug['l']) - lookup(INITENTRY, 0)->type = SXREF; - } else - lookup(INITENTRY, 0)->type = SXREF; - - initmuldiv1(); - while(*argv) - objfile(*argv++); - if(!debug['l']) - loadlib(); - firstp = firstp->link; - if(firstp == P) - errorexit(); - patch(); - if(debug['p']) - if(debug['1']) - doprof1(); - else - doprof2(); - initmuldiv2(); - follow(); - dodata(); - dostkoff(); - span(); - asmb(); - undef(); - if(debug['v']) { - Bprint(&bso, "%5.2f cpu time\n", cputime()); - Bprint(&bso, "%ld data statements\n", ndata); - Bprint(&bso, "%ld symbols\n", nsymbol); - Bprint(&bso, "%ld memory used\n", thunk); - Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); - Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); - } - Bflush(&bso); - - errorexit(); -} - -void -loadlib(void) -{ - int i; - long h; - Sym *s; - -loop: - xrefresolv = 0; - for(i=0; i<libraryp; i++) { - if(debug['v']) - Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]); - objfile(library[i]); - } - if(xrefresolv) - for(h=0; h<nelem(hash); h++) - for(s = hash[h]; s != S; s = s->link) - if(s->type == SXREF) - goto loop; -} - -void -errorexit(void) -{ - - if(nerrors) { - if(cout >= 0) - remove(outfile); - exits("error"); - } - exits(0); -} - -void -objfile(char *file) -{ - long off, esym, cnt, l; - int f, work; - Sym *s; - char magbuf[SARMAG]; - char name[100], pname[150]; - struct ar_hdr arhdr; - char *e, *start, *stop; - - if(file[0] == '-' && file[1] == 'l') { - sprint(name, "/%s/lib/lib", thestring); - strcat(name, file+2); - strcat(name, ".a"); - file = name; - } - if(debug['v']) - Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); - Bflush(&bso); - f = open(file, 0); - if(f < 0) { - diag("cannot open file: %s", file); - errorexit(); - } - l = read(f, magbuf, SARMAG); - if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ - /* load it as a regular file */ - l = seek(f, 0L, 2); - seek(f, 0L, 0); - ldobj(f, l, file); - close(f); - return; - } - - l = read(f, &arhdr, SAR_HDR); - if(l != SAR_HDR) { - diag("%s: short read on archive file symbol header", file); - goto out; - } - if(strncmp(arhdr.name, symname, strlen(symname))) { - diag("%s: first entry not symbol header", file); - goto out; - } - - esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); - off = SARMAG + SAR_HDR; - - /* - * just bang the whole symbol file into memory - */ - seek(f, off, 0); - cnt = esym - off; - start = malloc(cnt + 10); - cnt = read(f, start, cnt); - if(cnt <= 0){ - close(f); - return; - } - stop = &start[cnt]; - memset(stop, 0, 10); - - work = 1; - while(work){ - if(debug['v']) - Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); - Bflush(&bso); - work = 0; - for(e = start; e < stop; e = strchr(e+5, 0) + 1) { - s = lookup(e+5, 0); - if(s->type != SXREF) - continue; - sprint(pname, "%s(%s)", file, s->name); - if(debug['v']) - Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); - Bflush(&bso); - l = e[1] & 0xff; - l |= (e[2] & 0xff) << 8; - l |= (e[3] & 0xff) << 16; - l |= (e[4] & 0xff) << 24; - seek(f, l, 0); - l = read(f, &arhdr, SAR_HDR); - if(l != SAR_HDR) - goto bad; - if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) - goto bad; - l = atolwhex(arhdr.size); - ldobj(f, l, pname); - if(s->type == SXREF) { - diag("%s: failed to load: %s", file, s->name); - errorexit(); - } - work = 1; - xrefresolv = 1; - } - } - return; - -bad: - diag("%s: bad or out of date archive", file); -out: - close(f); -} - -int -zaddr(uchar *p, Adr *a, Sym *h[]) -{ - int c, t, i; - long l; - Sym *s; - Auto *u; - - t = p[0]; - - /* - * first try the high-time formats - */ - if(t == 0) { - a->type = p[1]; - return 2; - } - if(t == T_OFFSET) { - a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24); - a->type = p[5]; - return 6; - } - if(t == (T_OFFSET|T_SYM)) { - a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24); - s = h[p[5]]; - a->sym = s; - a->type = p[6]; - c = 7; - goto dosym; - } - if(t == T_SYM) { - s = h[p[1]]; - a->sym = s; - a->type = p[2]; - c = 3; - goto dosym; - } - if(t == (T_INDEX|T_OFFSET|T_SYM)) { - a->displace = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24); - a->offset = p[8] | (p[9]<<8) | (p[10]<<16) | (p[11]<<24); - s = h[p[12]]; - a->sym = s; - a->type = p[13]; - c = 14; - goto dosym; - } - - /* - * now do it the hard way - */ - c = 1; - if(t & T_FIELD) { - a->field = p[c] | (p[c+1]<<8); - c += 2; - } - if(t & T_INDEX) { - a->displace = p[c+3] | (p[c+4]<<8) | (p[c+5]<<16) | (p[c+6]<<24); - c += 7; - } - if(t & T_OFFSET) { - a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); - c += 4; - } - if(t & T_SYM) { - a->sym = h[p[c]]; - c += 1; - } - if(t & T_FCONST) { - a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); - a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24); - c += 8; - a->type = D_FCONST; - } else - if(t & T_SCONST) { - for(i=0; i<NSNAME; i++) - a->scon[i] = p[c+i]; - c += NSNAME; - a->type = D_SCONST; - } else - if(t & T_TYPE) { - a->type = p[c] | (p[c+1]<<8); - c += 2; - } else { - a->type = p[c]; - c++; - } - s = a->sym; - if(s == S) - return c; - -dosym: - t = a->type & D_MASK; - if(t != D_AUTO && t != D_PARAM) - return c; - l = a->offset; - for(u=curauto; u; u=u->link) { - if(u->asym == s) - if(u->type == t) { - if(u->aoffset > l) - u->aoffset = l; - return c; - } - } - - while(nhunk < sizeof(Auto)) - gethunk(); - u = (Auto*)hunk; - nhunk -= sizeof(Auto); - hunk += sizeof(Auto); - - u->link = curauto; - curauto = u; - u->asym = s; - u->aoffset = l; - u->type = t; - return c; -} - -void -addlib(char *obj) -{ - char name[1024], comp[256], *p; - int i; - - if(histfrogp <= 0) - return; - - if(histfrog[0]->name[1] == '/') { - sprint(name, ""); - i = 1; - } else - if(histfrog[0]->name[1] == '.') { - sprint(name, "."); - i = 0; - } else { - if(debug['9']) - sprint(name, "/%s/lib", thestring); - else - sprint(name, "/usr/%clib", thechar); - i = 0; - } - - for(; i<histfrogp; i++) { - snprint(comp, sizeof comp, histfrog[i]->name+1); - for(;;) { - p = strstr(comp, "$O"); - if(p == 0) - break; - memmove(p+1, p+2, strlen(p+2)+1); - p[0] = thechar; - } - for(;;) { - p = strstr(comp, "$M"); - if(p == 0) - break; - if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { - diag("library component too long"); - return; - } - memmove(p+strlen(thestring), p+2, strlen(p+2)+1); - memmove(p, thestring, strlen(thestring)); - } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { - diag("library component too long"); - return; - } - strcat(name, "/"); - strcat(name, comp); - } - for(i=0; i<libraryp; i++) - if(strcmp(name, library[i]) == 0) - return; - if(libraryp == nelem(library)){ - diag("too many autolibs; skipping %s", name); - return; - } - - p = malloc(strlen(name) + 1); - strcpy(p, name); - library[libraryp] = p; - p = malloc(strlen(obj) + 1); - strcpy(p, obj); - libraryobj[libraryp] = p; - libraryp++; -} -void -addhist(long line, int type) -{ - Auto *u; - Sym *s; - int i, j, k; - - u = malloc(sizeof(Auto)); - s = malloc(sizeof(Sym)); - s->name = malloc(2*(histfrogp+1) + 1); - - u->asym = s; - u->type = type; - u->aoffset = line; - u->link = curhist; - curhist = u; - - j = 1; - for(i=0; i<histfrogp; i++) { - k = histfrog[i]->value; - s->name[j+0] = k>>8; - s->name[j+1] = k; - j += 2; - } -} - -void -histtoauto(void) -{ - Auto *l; - - while(l = curhist) { - curhist = l->link; - l->link = curauto; - curauto = l; - } -} - -void -collapsefrog(Sym *s) -{ - int i; - - /* - * bad encoding of path components only allows - * MAXHIST components. if there is an overflow, - * first try to collapse xxx/.. - */ - for(i=1; i<histfrogp; i++) - if(strcmp(histfrog[i]->name+1, "..") == 0) { - memmove(histfrog+i-1, histfrog+i+1, - (histfrogp-i-1)*sizeof(histfrog[0])); - histfrogp--; - goto out; - } - - /* - * next try to collapse . - */ - for(i=0; i<histfrogp; i++) - if(strcmp(histfrog[i]->name+1, ".") == 0) { - memmove(histfrog+i, histfrog+i+1, - (histfrogp-i-1)*sizeof(histfrog[0])); - goto out; - } - - /* - * last chance, just truncate from front - */ - memmove(histfrog+0, histfrog+1, - (histfrogp-1)*sizeof(histfrog[0])); - -out: - histfrog[histfrogp-1] = s; -} - -uchar* -readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) -{ - int n; - - n = stop - good; - memmove(buf, good, stop - good); - stop = buf + n; - n = MAXIO - n; - if(n > max) - n = max; - n = read(f, stop, n); - if(n <= 0) - return 0; - return stop + n; -} - -void -ldobj(int f, long c, char *pn) -{ - Prog *p; - Sym *h[NSYM], *s; - int v, o, r; - long ipc, lv; - double dv; - uchar *bloc, *bsize, *stop; - - bsize = buf.xbuf; - bloc = buf.xbuf; - -newloop: - memset(h, 0, sizeof(h)); - version++; - histfrogp = 0; - ipc = pc; - -loop: - if(c <= 0) - goto eof; - r = bsize - bloc; - if(r < 100 && r < c) { /* enough for largest prog */ - bsize = readsome(f, buf.xbuf, bloc, bsize, c); - if(bsize == 0) - goto eof; - bloc = buf.xbuf; - goto loop; - } - o = bloc[0] | (bloc[1] << 8); - if(o <= AXXX || o >= ALAST) { - if(o < 0) - goto eof; - diag("%s: opcode out of range %d", pn, o); - print(" probably not a .%c file\n", thechar); - errorexit(); - } - - if(o == ANAME || o == ASIGNAME) { - if(o == ASIGNAME) { - bloc += 4; - c -= 4; - } - stop = memchr(&bloc[4], 0, bsize-&bloc[4]); - if(stop == 0){ - bsize = readsome(f, buf.xbuf, bloc, bsize, c); - if(bsize == 0) - goto eof; - bloc = buf.xbuf; - stop = memchr(&bloc[4], 0, bsize-&bloc[4]); - if(stop == 0){ - fprint(2, "%s: name too long\n", pn); - errorexit(); - } - } - v = bloc[2]; /* type */ - o = bloc[3]; /* sym */ - bloc += 4; - c -= 4; - - r = 0; - if(v == D_STATIC) - r = version; - s = lookup((char*)bloc, r); - c -= &stop[1] - bloc; - bloc = stop + 1; - - if(debug['W']) - print(" ANAME %s\n", s->name); - h[o] = s; - if((v == D_EXTERN || v == D_STATIC) && s->type == 0) - s->type = SXREF; - if(v == D_FILE) { - if(s->type != SFILE) { - histgen++; - s->type = SFILE; - s->value = histgen; - } - if(histfrogp < MAXHIST) { - histfrog[histfrogp] = s; - histfrogp++; - } else - collapsefrog(s); - } - goto loop; - } - - while(nhunk < sizeof(Prog)) - gethunk(); - p = (Prog*)hunk; - nhunk -= sizeof(Prog); - hunk += sizeof(Prog); - - p->as = o; - p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24); - p->back = 2; - r = zaddr(bloc+6, &p->from, h) + 6; - r += zaddr(bloc+r, &p->to, h); - bloc += r; - c -= r; - - if(debug['W']) - print("%P\n", p); - - switch(p->as) { - case AHISTORY: - if(p->to.offset == -1) { - addlib(pn); - histfrogp = 0; - goto loop; - } - addhist(p->line, D_FILE); /* 'z' */ - if(p->to.offset) - addhist(p->to.offset, D_FILE1); /* 'Z' */ - histfrogp = 0; - goto loop; - - case AEND: - histtoauto(); - if(curtext != P) - curtext->to.autom = curauto; - curauto = 0; - curtext = P; - if(c) - goto newloop; - return; - - case AGLOBL: - s = p->from.sym; - if(s->type == 0 || s->type == SXREF) { - s->type = SBSS; - s->value = 0; - } - if(s->type != SBSS) { - diag("%s: redefinition: %s in %s", - pn, s->name, TNAME); - s->type = SBSS; - s->value = 0; - } - if(p->to.offset > s->value) - s->value = p->to.offset; - goto loop; - - case ADATA: - p->link = datap; - datap = p; - ndata++; - goto loop; - - case AGOK: - diag("%s: unknown opcode in %s", pn, TNAME); - pc++; - goto loop; - - case ATEXT: - if(curtext != P) { - histtoauto(); - curtext->to.autom = curauto; - curauto = 0; - } - curtext = p; - lastp->link = p; - lastp = p; - p->pc = pc; - s = p->from.sym; - if(s->type != 0 && s->type != SXREF) - diag("%s: redefinition: %s", pn, s->name); - s->type = STEXT; - s->value = p->pc; - pc++; - p->pcond = P; - if(textp == P) { - textp = p; - etextp = p; - goto loop; - } - etextp->pcond = p; - etextp = p; - goto loop; - - case AJSR: - p->as = ABSR; - - case ABSR: - if(p->to.type != D_EXTERN && p->to.type != D_STATIC) - p->as = AJSR; - goto casdef; - - case AMOVL: - case AMOVB: - case AMOVW: - if(p->from.type != D_CONST) - goto casdef; - lv = p->from.offset; - if(lv >= -128 && lv < 128) - if(p->to.type >= D_R0 && p->to.type < D_R0+8) { - p->from.type = D_QUICK; - goto casdef; - } - - if(lv >= -0x7fff && lv <= 0x7fff) - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - if(p->as == AMOVL) - p->as = AMOVW; - goto casdef; - - case AADDB: - case AADDL: - case AADDW: - if(p->from.type != D_CONST) - goto casdef; - lv = p->from.offset; - if(lv < 0) { - lv = -lv; - p->from.offset = lv; - if(p->as == AADDB) - p->as = ASUBB; - else - if(p->as == AADDW) - p->as = ASUBW; - else - if(p->as == AADDL) - p->as = ASUBL; - } - if(lv > 0) - if(lv <= 8) - p->from.type = D_QUICK; - goto casdef; - - case ASUBB: - case ASUBL: - case ASUBW: - if(p->from.type != D_CONST) - goto casdef; - lv = p->from.offset; - if(lv < 0) { - lv = -lv; - p->from.offset = lv; - if(p->as == ASUBB) - p->as = AADDB; - else - if(p->as == ASUBW) - p->as = AADDW; - else - if(p->as == ASUBL) - p->as = AADDL; - } - if(lv > 0) - if(lv <= 8) - p->from.type = D_QUICK; - goto casdef; - - case AROTRB: - case AROTRL: - case AROTRW: - case AROTLB: - case AROTLL: - case AROTLW: - - case AASLB: - case AASLL: - case AASLW: - case AASRB: - case AASRL: - case AASRW: - case ALSLB: - case ALSLL: - case ALSLW: - case ALSRB: - case ALSRL: - case ALSRW: - if(p->from.type == D_CONST) - if(p->from.offset > 0) - if(p->from.offset <= 8) - p->from.type = D_QUICK; - goto casdef; - - case ATSTL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) { - p->as = ACMPW; - p->from = p->to; - p->to.type = D_CONST; - p->to.offset = 0; - } - goto casdef; - - case ACMPL: - if(p->to.type != D_CONST) - goto casdef; - lv = p->to.offset; - if(lv >= -0x7fff && lv <= 0x7fff) - if(p->from.type >= D_A0 && p->from.type < D_A0+8) - p->as = ACMPW; - goto casdef; - - case ACLRL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) { - p->as = AMOVW; - p->from.type = D_CONST; - p->from.offset = 0; - } - goto casdef; - - casdef: - default: - if(p->from.type == D_FCONST) - if(optab[p->as].fas != AXXX) { - dv = ieeedtod(&p->from.ieee); - if(dv >= -(1L<<30) && dv <= (1L<<30)) { - lv = dv; - if(lv == dv) { - p->as = optab[p->as].fas; - p->from.type = D_CONST; - p->from.offset = lv; - p->from.displace = 0; - } - } - } - if(p->to.type == D_BRANCH) - p->to.offset += ipc; - lastp->link = p; - lastp = p; - p->pc = pc; - pc++; - goto loop; - } - /* not reached */ - -eof: - diag("%s: truncated object file in %s", pn, TNAME); -} - -Sym* -lookup(char *symb, int v) -{ - Sym *s; - char *p; - long h; - int l, c; - - h = v; - for(p=symb; c = *p; p++) - h = h+h+h + c; - l = (p - symb) + 1; - if(h < 0) - h = ~h; - h %= NHASH; - for(s = hash[h]; s != S; s = s->link) - if(s->version == v) - if(memcmp(s->name, symb, l) == 0) - return s; - - while(nhunk < sizeof(Sym)) - gethunk(); - s = (Sym*)hunk; - nhunk -= sizeof(Sym); - hunk += sizeof(Sym); - - s->name = malloc(l + 1); - memmove(s->name, symb, l); - - s->link = hash[h]; - s->type = 0; - s->version = v; - s->value = 0; - hash[h] = s; - nsymbol++; - return s; -} - -Prog* -prg(void) -{ - Prog *p; - - while(nhunk < sizeof(Prog)) - gethunk(); - p = (Prog*)hunk; - nhunk -= sizeof(Prog); - hunk += sizeof(Prog); - - *p = zprg; - return p; -} - -Prog* -nprg(Prog *p) -{ - Prog *q; - - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->stkoff = p->stkoff; - q->link = p->link; - p->link = q; - return q; -} - -Prog* -copyp(Prog *q) -{ - Prog *p; - - p = prg(); - *p = *q; - return p; -} - -void -gethunk(void) -{ - char *h; - long nh; - - nh = NHUNK; - if(thunk >= 5L*NHUNK) { - nh = 5L*NHUNK; - if(thunk >= 25L*NHUNK) - nh = 25L*NHUNK; - } - h = mysbrk(nh); - if(h == (char*)-1) { - diag("out of memory"); - errorexit(); - } - hunk = h; - nhunk = nh; - thunk += nh; -} - -void -doprof1(void) -{ - Sym *s; - long n; - Prog *p, *q; - - if(debug['v']) - Bprint(&bso, "%5.2f profile 1\n", cputime()); - Bflush(&bso); - s = lookup("__mcount", 0); - n = 1; - for(p = firstp->link; p != P; p = p->link) { - if(p->as == ATEXT) { - q = prg(); - q->as = AADDL; - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - p->link = q; - q->from.type = D_CONST; - q->from.offset = 1; - q->to.type = D_EXTERN; - q->to.sym = s; - q->to.offset = n*4 + 4; - - q = prg(); - q->as = ADATA; - q->line = p->line; - q->link = datap; - datap = q; - q->from.type = D_EXTERN; - q->from.sym = s; - q->from.offset = n*4; - q->from.displace = 4; - q->to.type = D_EXTERN; - q->to.sym = p->from.sym; - n += 2; - continue; - } - } - q = prg(); - q->line = 0; - q->as = ADATA; - q->link = datap; - datap = q; - q->from.type = D_EXTERN; - q->from.sym = s; - q->from.displace = 4; - q->to.type = D_CONST; - q->to.offset = n; - s->type = SBSS; - s->value = n*4; -} - -void -doprof2(void) -{ - Sym *s2, *s4; - Prog *p, *q, *ps2, *ps4; - - if(debug['v']) - Bprint(&bso, "%5.2f profile 2\n", cputime()); - Bflush(&bso); - s2 = lookup("_profin", 0); - s4 = lookup("_profout", 0); - if(s2->type != STEXT || s4->type != STEXT) { - diag("_profin/_profout not defined"); - return; - } - - ps2 = P; - ps4 = P; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) { - if(p->from.sym == s2) { - ps2 = p; - p->from.displace = 1; - } - if(p->from.sym == s4) { - ps4 = p; - p->from.displace = 1; - } - } - } - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) { - if(p->from.displace != 0) { - for(;;) { - q = p->link; - if(q == P) - break; - if(q->as == ATEXT) - break; - p = q; - } - continue; - } - - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - p->link = q; - p = q; - p->as = ABSR; - p->to.type = D_BRANCH; - p->pcond = ps2; - p->to.sym = s2; - - continue; - } - if(p->as == ARTS) { - /* - * RTS - */ - q = prg(); - q->as = ARTS; - q->from = p->from; - q->to = p->to; - q->link = p->link; - p->link = q; - - /* - * BSR profout - */ - p->as = ABSR; - p->from = zprg.from; - p->to = zprg.to; - p->to.type = D_BRANCH; - p->pcond = ps4; - p->to.sym = s4; - - p = q; - - continue; - } - } -} - -long -reuse(Prog *r, Sym *s) -{ - Prog *p; - - - if(r == P) - return 0; - for(p = datap; p != r; p = p->link) - if(p->to.sym == s) - return p->from.offset; - return 0; -} - -void -nuxiinit(void) -{ - int i, c; - - for(i=0; i<4; i++) { - c = find1(0x01020304L, i+1); - if(i >= 2) - inuxi2[i-2] = c; - if(i >= 3) - inuxi1[i-3] = c; - inuxi4[i] = c; - fnuxi8[i] = c+4; - fnuxi8[i+4] = c; - c = find2(0x01020304L, i+1); - gnuxi8[i] = c+4; - gnuxi8[i+4] = c; - } - if(debug['v']) { - Bprint(&bso, "inuxi = "); - for(i=0; i<1; i++) - Bprint(&bso, "%d", inuxi1[i]); - Bprint(&bso, " "); - for(i=0; i<2; i++) - Bprint(&bso, "%d", inuxi2[i]); - Bprint(&bso, " "); - for(i=0; i<4; i++) - Bprint(&bso, "%d", inuxi4[i]); - Bprint(&bso, "\n[fg]nuxi = "); - for(i=0; i<8; i++) - Bprint(&bso, "%d", fnuxi8[i]); - Bprint(&bso, " "); - for(i=0; i<8; i++) - Bprint(&bso, "%d", gnuxi8[i]); - Bprint(&bso, "\n"); - } - Bflush(&bso); -} - -int -find1(long l, int c) -{ - char *p; - int i; - - p = (char*)&l; - for(i=0; i<4; i++) - if(*p++ == c) - return i; - return 0; -} - -int -find2(long l, int c) -{ - short *p; - int i; - - p = (short*)&l; - for(i=0; i<4; i+=2) { - if(((*p >> 8) & 0xff) == c) - return i; - if((*p++ & 0xff) == c) - return i+1; - } - return 0; -} - -long -ieeedtof(Ieee *e) -{ - int exp; - long v; - - if(e->h == 0) - return 0; - exp = (e->h>>20) & ((1L<<11)-1L); - exp -= (1L<<10) - 2L; - v = (e->h & 0xfffffL) << 3; - v |= (e->l >> 29) & 0x7L; - if((e->l >> 28) & 1) { - v++; - if(v & 0x800000L) { - v = (v & 0x7fffffL) >> 1; - exp++; - } - } - if(exp <= -126 || exp >= 130) - diag("double fp to single fp overflow"); - v |= ((exp + 126) & 0xffL) << 23; - v |= e->h & 0x80000000L; - return v; -} - -double -ieeedtod(Ieee *ieeep) -{ - Ieee e; - double fr; - int exp; - - if(ieeep->h & (1L<<31)) { - e.h = ieeep->h & ~(1L<<31); - e.l = ieeep->l; - return -ieeedtod(&e); - } - if(ieeep->l == 0 && ieeep->h == 0) - return 0; - fr = ieeep->l & ((1L<<16)-1L); - fr /= 1L<<16; - fr += (ieeep->l>>16) & ((1L<<16)-1L); - fr /= 1L<<16; - fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); - fr /= 1L<<21; - exp = (ieeep->h>>20) & ((1L<<11)-1L); - exp -= (1L<<10) - 2L; - return ldexp(fr, exp); -} diff --git a/utils/1l/optab.c b/utils/1l/optab.c deleted file mode 100644 index 2109b478..00000000 --- a/utils/1l/optab.c +++ /dev/null @@ -1,444 +0,0 @@ -#include "l.h" - -#define X1 0 -#define X2 0 -#define X3 0 -#define C 0xf200 - -Optab optab[] = -/* as, fas, srcsp, dstsp, optype, opcode */ -{ - { AXXX }, - { AABCD, AXXX, X1, X2, X3, 0x4e71 }, - { AADDB, AXXX, 2, 0, 3, 0xd000, 0x5000, 0, 0x0600 }, - { AADDL, AXXX, 4, 0, 3, 0xd080, 0x5080, 0xd1c0, 0x0680 }, - { AADDW, AXXX, 2, 0, 3, 0xd040, 0x5040, 0xd0c0, 0x0640 }, - { AADDXB }, - { AADDXL }, - { AADDXW }, - { AADJSP }, - { AANDB, AXXX, 2, 0, 9, 0xc000, 0xc100, 0x0200 }, - { AANDL, AXXX, 4, 0, 9, 0xc080, 0xc180, 0x0280 }, - { AANDW, AXXX, 2, 0, 9, 0xc040, 0xc140, 0x0240 }, - { AASLB, AXXX, 0, 2, 12, 0xe100 }, - { AASLL, AXXX, 0, 4, 12, 0xe180 }, - { AASLW, AXXX, 0, 2, 12, 0xe140 }, - { AASRB, AXXX, 0, 2, 12, 0xe000 }, - { AASRL, AXXX, 0, 4, 12, 0xe080 }, - { AASRW, AXXX, 0, 2, 12, 0xe040 }, - { ABCASE }, - { ABCC, AXXX, 0, 0, 1, 0x6400 }, - { ABCHG, AXXX, 2, 2, 27, 0x0140, 0x0840 }, - { ABCLR, AXXX, 2, 2, 27, 0x0180, 0x0880 }, - { ABCS, AXXX, 0, 0, 1, 0x6500 }, - { ABEQ, AXXX, 0, 0, 1, 0x6700 }, - { ABFCHG }, - { ABFCLR }, - { ABFEXTS }, - { ABFEXTU }, - { ABFFFO }, - { ABFINS }, - { ABFSET }, - { ABFTST }, - { ABGE, AXXX, 0, 0, 1, 0x6c00 }, - { ABGT, AXXX, 0, 0, 1, 0x6e00 }, - { ABHI, AXXX, 0, 0, 1, 0x6200 }, - { ABKPT }, - { ABLE, AXXX, 0, 0, 1, 0x6f00 }, - { ABLS, AXXX, 0, 0, 1, 0x6300 }, - { ABLT, AXXX, 0, 0, 1, 0x6d00 }, - { ABMI, AXXX, 0, 0, 1, 0x6b00 }, - { ABNE, AXXX, 0, 0, 1, 0x6600 }, - { ABPL, AXXX, 0, 0, 1, 0x6a00 }, - { ABRA, AXXX, 0, 0, 1, 0x6000, 0x4ec0 }, - { ABSET, AXXX, 2, 2, 27, 0x01c0, 0x08c0 }, - { ABSR, AXXX, 0, 0, 1, 0x6100, 0x4e80 }, - { ABTST, AXXX, 2, 2, 27, 0x0100, 0x0800 }, - { ABVC, AXXX, 0, 0, 1, 0x6800 }, - { ABVS, AXXX, 0, 0, 1, 0x6900 }, - { ACALLM }, - { ACAS2B }, - { ACAS2L }, - { ACAS2W }, - { ACASB }, - { ACASEW }, - { ACASL }, - { ACASW }, - { ACHK2B }, - { ACHK2L }, - { ACHK2W }, - { ACHKL, AXXX, 4, 4, 26, 0x4100 }, - { ACHKW, AXXX, 2, 2, 26, 0x4180 }, - { ACLRB, AXXX, 0, -2, 5, 0x4200 }, - { ACLRL, AXXX, 0, -4, 5, 0x4280 }, - { ACLRW, AXXX, 0, -2, 5, 0x4240 }, - { ACMP2B }, - { ACMP2L }, - { ACMP2W }, - { ACMPB, AXXX, 2, 2, 7, 0xb000, 0, 0x0c00, 0xb108 }, - { ACMPL, AXXX, 4, 4, 7, 0xb080, 0xb100, 0x0c80, 0xb188 }, - { ACMPW, AXXX, 2, 2, 7, 0xb040, 0xb080, 0x0c40, 0xb148 }, - { ADATA }, - { ADBCC, AXXX, 0, 0, 15, 0x54c8 }, - { ADBCS, AXXX, 0, 0, 15, 0x55c8 }, - { ADBEQ, AXXX, 0, 0, 15, 0x57c8 }, - { ADBF, AXXX, 0, 0, 15, 0x51c8 }, - { ADBGE, AXXX, 0, 0, 15, 0x5cc8 }, - { ADBGT, AXXX, 0, 0, 15, 0x5ec8 }, - { ADBHI, AXXX, 0, 0, 15, 0x52c8 }, - { ADBLE, AXXX, 0, 0, 15, 0x5fc8 }, - { ADBLS, AXXX, 0, 0, 15, 0x53c8 }, - { ADBLT, AXXX, 0, 0, 15, 0x5dc8 }, - { ADBMI, AXXX, 0, 0, 15, 0x5bc8 }, - { ADBNE, AXXX, 0, 0, 15, 0x56c8 }, - { ADBPL, AXXX, 0, 0, 15, 0x5ac8 }, - { ADBT, AXXX, 0, 0, 15, 0x50c8 }, - { ADBVC, AXXX, 0, 0, 15, 0x58c8 }, - { ADBVS, AXXX, 0, 0, 15, 0x59c8 }, - { ADIVSL, AXXX, 4, 0, 14, 0x4c40, 0x0800 }, - { ADIVSW, AXXX, 2, 0, 13, 0x81c0 }, - { ADIVUL, AXXX, 4, 0, 14, 0x4c40, 0x0000 }, - { ADIVUW, AXXX, 2, 0, 13, 0x80c0 }, - { AEND }, - { AEORB, AXXX, 2, 0, 10, 0xb100, 0x0a00 }, - { AEORL, AXXX, 4, 0, 10, 0xb180, 0x0a80 }, - { AEORW, AXXX, 2, 0, 10, 0xb140, 0x0a40 }, - { AEXG }, - { AEXTBL }, - { AEXTBW, AXXX, 0, 0, 11, 0x4880 }, - { AEXTWL, AXXX, 0, 0, 11, 0x48c0 }, - { AFABSB, AXXX, 2, 0, 17, C, 0x0018, 0x5818 }, - { AFABSD, AFABSL, 8, 0, 17, C, 0x0018, 0x5418 }, - { AFABSF, AFABSL, 4, 0, 17, C, 0x0018, 0x4418 }, - { AFABSL, AXXX, 4, 0, 17, C, 0x0018, 0x4018 }, - { AFABSW, AXXX, 2, 0, 17, C, 0x0018, 0x5018 }, - { AFACOSB, AXXX, 2, 0, 17, C, 0x001c, 0x581c }, - { AFACOSD, AFACOSL, 8, 0, 17, C, 0x001c, 0x541c }, - { AFACOSF, AFACOSL, 4, 0, 17, C, 0x001c, 0x441c }, - { AFACOSL, AXXX, 4, 0, 17, C, 0x001c, 0x401c }, - { AFACOSW, AXXX, 2, 0, 17, C, 0x001c, 0x501c }, - { AFADDB, AXXX, 2, 0, 17, C, 0x0022, 0x5822 }, - { AFADDD, AFADDL, 8, 0, 17, C, 0x0022, 0x5422 }, - { AFADDF, AFADDL, 4, 0, 17, C, 0x0022, 0x4422 }, - { AFADDL, AXXX, 4, 0, 17, C, 0x0022, 0x4022 }, - { AFADDW, AXXX, 2, 0, 17, C, 0x0022, 0x5022 }, - { AFASINB, AXXX, 2, 0, 17, C, 0x000c, 0x580c }, - { AFASIND, AFASINL, 8, 0, 17, C, 0x000c, 0x540c }, - { AFASINF, AFASINL, 4, 0, 17, C, 0x000c, 0x440c }, - { AFASINL, AXXX, 4, 0, 17, C, 0x000c, 0x400c }, - { AFASINW, AXXX, 2, 0, 17, C, 0x000c, 0x500c }, - { AFATANB, AXXX, 2, 0, 17, C, 0x000a, 0x580a }, - { AFATAND, AFATANL, 8, 0, 17, C, 0x000a, 0x540a }, - { AFATANF, AFATANL, 4, 0, 17, C, 0x000a, 0x440a }, - { AFATANHB, AXXX, 2, 0, 17, C, 0x000d, 0x580d }, - { AFATANHD, AFATANHL, 8, 0, 17, C, 0x000d, 0x540d }, - { AFATANHF, AFATANHL, 4, 0, 17, C, 0x000d, 0x440d }, - { AFATANHL, AXXX, 4, 0, 17, C, 0x000d, 0x400d }, - { AFATANHW, AXXX, 2, 0, 17, C, 0x000d, 0x500d }, - { AFATANL, AXXX, 4, 0, 17, C, 0x000a, 0x400a }, - { AFATANW, AXXX, 2, 0, 17, C, 0x000a, 0x500a }, - { AFBEQ, AXXX, 0, 0, 18, C+0x81 }, - { AFBF, AXXX, 0, 0, 18, C+0x8f }, - { AFBGE, AXXX, 0, 0, 18, C+0x93 }, - { AFBGT, AXXX, 0, 0, 18, C+0x92 }, - { AFBLE, AXXX, 0, 0, 18, C+0x95 }, - { AFBLT, AXXX, 0, 0, 18, C+0x94 }, - { AFBNE, AXXX, 0, 0, 18, C+0x8e }, - { AFBT, AXXX, 0, 0, 18, C+0x80 }, - { AFCMPB, AXXX, 0, 2, 22, C, 0x0038, 0x5838 }, - { AFCMPD, AFCMPL, 0, 8, 22, C, 0x0038, 0x5438 }, - { AFCMPF, AFCMPL, 0, 4, 22, C, 0x0038, 0x4438 }, - { AFCMPL, AXXX, 0, 4, 22, C, 0x0038, 0x4038 }, - { AFCMPW, AXXX, 0, 2, 22, C, 0x0038, 0x5038 }, - { AFCOSB, AXXX, 2, 0, 17, C, 0x001d, 0x581d }, - { AFCOSD, AFCOSL, 8, 0, 17, C, 0x001d, 0x541d }, - { AFCOSF, AFCOSL, 4, 0, 17, C, 0x001d, 0x441d }, - { AFCOSHB, AXXX, 2, 0, 17, C, 0x0019, 0x5819 }, - { AFCOSHD, AFCOSHL, 8, 0, 17, C, 0x0019, 0x5419 }, - { AFCOSHF, AFCOSHL, 4, 0, 17, C, 0x0019, 0x4419 }, - { AFCOSHL, AXXX, 4, 0, 17, C, 0x0019, 0x4019 }, - { AFCOSHW, AXXX, 2, 0, 17, C, 0x0019, 0x5019 }, - { AFCOSL, AXXX, 4, 0, 17, C, 0x001d, 0x401d }, - { AFCOSW, AXXX, 2, 0, 17, C, 0x001d, 0x501d }, - { AFDBEQ, AXXX, 0, 0, 19, C+0x48, 0x01 }, - { AFDBF, AXXX, 0, 0, 19, C+0x48, 0x0f }, - { AFDBGE, AXXX, 0, 0, 19, C+0x48, 0x13 }, - { AFDBGT, AXXX, 0, 0, 19, C+0x48, 0x12 }, - { AFDBLE, AXXX, 0, 0, 19, C+0x48, 0x15 }, - { AFDBLT, AXXX, 0, 0, 19, C+0x48, 0x14 }, - { AFDBNE, AXXX, 0, 0, 19, C+0x48, 0x0e }, - { AFDBT, AXXX, 0, 0, 19, C+0x48, 0x00 }, - { AFDIVB, AXXX, 2, 0, 17, C, 0x0020, 0x5820 }, - { AFDIVD, AFDIVL, 8, 0, 17, C, 0x0020, 0x5420 }, - { AFDIVF, AFDIVL, 4, 0, 17, C, 0x0020, 0x4420 }, - { AFDIVL, AXXX, 4, 0, 17, C, 0x0020, 0x4020 }, - { AFDIVW, AXXX, 2, 0, 17, C, 0x0020, 0x5020 }, - { AFETOXB, AXXX, 2, 0, 17, C, 0x0010, 0x5810 }, - { AFETOXD, AFETOXL, 8, 0, 17, C, 0x0010, 0x5410 }, - { AFETOXF, AFETOXL, 4, 0, 17, C, 0x0010, 0x4410 }, - { AFETOXL, AXXX, 4, 0, 17, C, 0x0010, 0x4010 }, - { AFETOXM1B, AXXX, 2, 0, 17, C, 0x0008, 0x5808 }, - { AFETOXM1D, AFETOXM1L, 8, 0, 17, C, 0x0008, 0x5408 }, - { AFETOXM1F, AFETOXM1L, 4, 0, 17, C, 0x0008, 0x4408 }, - { AFETOXM1L, AXXX, 4, 0, 17, C, 0x0008, 0x4008 }, - { AFETOXM1W, AXXX, 2, 0, 17, C, 0x0008, 0x5008 }, - { AFETOXW, AXXX, 2, 0, 17, C, 0x0010, 0x5010 }, - { AFGETEXPB, AXXX, 2, 0, 17, C, 0x001e, 0x581e }, - { AFGETEXPD, AFGETEXPL, 8, 0, 17, C, 0x001e, 0x541e }, - { AFGETEXPF, AFGETEXPL, 4, 0, 17, C, 0x001e, 0x441e }, - { AFGETEXPL, AXXX, 4, 0, 17, C, 0x001e, 0x401e }, - { AFGETEXPW, AXXX, 2, 0, 17, C, 0x001e, 0x501e }, - { AFGETMANB, AXXX, 2, 0, 17, C, 0x001f, 0x581f }, - { AFGETMAND, AFGETMANL, 8, 0, 17, C, 0x001f, 0x541f }, - { AFGETMANF, AFGETMANL, 4, 0, 17, C, 0x001f, 0x441f }, - { AFGETMANL, AXXX, 4, 0, 17, C, 0x001f, 0x401f }, - { AFGETMANW, AXXX, 2, 0, 17, C, 0x001f, 0x501f }, - { AFINTB, AXXX, 2, 0, 17, C, 0x0001, 0x5801 }, - { AFINTD, AFINTL, 8, 0, 17, C, 0x0001, 0x5401 }, - { AFINTF, AFINTL, 4, 0, 17, C, 0x0001, 0x4401 }, - { AFINTL, AXXX, 4, 0, 17, C, 0x0001, 0x4001 }, - { AFINTRZB, AXXX, 2, 0, 17, C, 0x0003, 0x5803 }, - { AFINTRZD, AFINTRZL, 8, 0, 17, C, 0x0003, 0x5403 }, - { AFINTRZF, AFINTRZL, 4, 0, 17, C, 0x0003, 0x4403 }, - { AFINTRZL, AXXX, 4, 0, 17, C, 0x0003, 0x4003 }, - { AFINTRZW, AXXX, 2, 0, 17, C, 0x0003, 0x5003 }, - { AFINTW, AXXX, 2, 0, 17, C, 0x0001, 0x5001 }, - { AFLOG10B, AXXX, 2, 0, 17, C, 0x0015, 0x5815 }, - { AFLOG10D, AFLOG10L, 8, 0, 17, C, 0x0015, 0x5415 }, - { AFLOG10F, AFLOG10L, 4, 0, 17, C, 0x0015, 0x4415 }, - { AFLOG10L, AXXX, 4, 0, 17, C, 0x0015, 0x4015 }, - { AFLOG10W, AXXX, 2, 0, 17, C, 0x0015, 0x5015 }, - { AFLOG2B, AXXX, 2, 0, 17, C, 0x0016, 0x5816 }, - { AFLOG2D, AFLOG2L, 8, 0, 17, C, 0x0016, 0x5416 }, - { AFLOG2F, AFLOG2L, 4, 0, 17, C, 0x0016, 0x4416 }, - { AFLOG2L, AXXX, 4, 0, 17, C, 0x0016, 0x4016 }, - { AFLOG2W, AXXX, 2, 0, 17, C, 0x0016, 0x5016 }, - { AFLOGNB, AXXX, 2, 0, 17, C, 0x0014, 0x5814 }, - { AFLOGND, AFLOGNL, 8, 0, 17, C, 0x0014, 0x5414 }, - { AFLOGNF, AFLOGNL, 4, 0, 17, C, 0x0014, 0x4414 }, - { AFLOGNL, AXXX, 4, 0, 17, C, 0x0014, 0x4014 }, - { AFLOGNP1B, AXXX, 2, 0, 17, C, 0x0006, 0x5806 }, - { AFLOGNP1D, AFLOGNP1L, 8, 0, 17, C, 0x0006, 0x5406 }, - { AFLOGNP1F, AFLOGNP1L, 4, 0, 17, C, 0x0006, 0x4406 }, - { AFLOGNP1L, AXXX, 4, 0, 17, C, 0x0006, 0x4006 }, - { AFLOGNP1W, AXXX, 2, 0, 17, C, 0x0006, 0x5006 }, - { AFLOGNW, AXXX, 2, 0, 17, C, 0x0014, 0x5014 }, - { AFMODB, AXXX, 2, 0, 17, C, 0x0021, 0x5821 }, - { AFMODD, AFMODL, 8, 0, 17, C, 0x0021, 0x5421 }, - { AFMODF, AFMODL, 4, 0, 17, C, 0x0021, 0x4421 }, - { AFMODL, AXXX, 4, 0, 17, C, 0x0021, 0x4021 }, - { AFMODW, AXXX, 2, 0, 17, C, 0x0021, 0x5021 }, - { AFMOVEB, AXXX, 2, -2, 16, C, 0x0000, 0x7800, 0x5800 }, - { AFMOVED, AFMOVEL, 8, -8, 16, C, 0x0000, 0x7400, 0x5400 }, - { AFMOVEF, AFMOVEL, 4, -4, 16, C, 0x0000, 0x6400, 0x4400 }, - { AFMOVEL, AXXX, 4, -4, 16, C, 0x0000, 0x6000, 0x4000 }, - { AFMOVEM, AXXX, 2, 2, 28, C }, - { AFMOVEMC, AXXX, 2, 2, 29, C }, - { AFMOVEW, AXXX, 2, -2, 16, C, 0x0000, 0x7000, 0x5000 }, - { AFMULB, AXXX, 2, 0, 17, C, 0x0023, 0x5823 }, - { AFMULD, AFMULL, 8, 0, 17, C, 0x0023, 0x5423 }, - { AFMULF, AFMULL, 4, 0, 17, C, 0x0023, 0x4423 }, - { AFMULL, AXXX, 4, 0, 17, C, 0x0023, 0x4023 }, - { AFMULW, AXXX, 2, 0, 17, C, 0x0023, 0x5023 }, - { AFNEGB, AXXX, 2, 0, 21, C, 0x001a, 0x581a }, - { AFNEGD, AFNEGL, 8, 0, 21, C, 0x001a, 0x541a }, - { AFNEGF, AFNEGL, 4, 0, 21, C, 0x001a, 0x441a }, - { AFNEGL, AXXX, 4, 0, 21, C, 0x001a, 0x401a }, - { AFNEGW, AXXX, 2, 0, 21, C, 0x001a, 0x501a }, - { AFREMB, AXXX, 2, 0, 17, C, 0x0025, 0x5825 }, - { AFREMD, AFREML, 8, 0, 17, C, 0x0025, 0x5425 }, - { AFREMF, AFREML, 4, 0, 17, C, 0x0025, 0x4425 }, - { AFREML, AXXX, 4, 0, 17, C, 0x0025, 0x4025 }, - { AFREMW, AXXX, 2, 0, 17, C, 0x0025, 0x5025 }, - { AFRESTORE, AXXX, 0, 2, 5, C+0x0140 }, - { AFSAVE, AXXX, 0, 2, 5, C+0x0100 }, - { AFSCALEB, AXXX, 2, 0, 17, C, 0x0026, 0x5826 }, - { AFSCALED, AFSCALEL, 8, 0, 17, C, 0x0026, 0x5426 }, - { AFSCALEF, AFSCALEL, 4, 0, 17, C, 0x0026, 0x4426 }, - { AFSCALEL, AXXX, 4, 0, 17, C, 0x0026, 0x4026 }, - { AFSCALEW, AXXX, 2, 0, 17, C, 0x0026, 0x5026 }, - { AFSEQ, AXXX, X1, X2, X3, 0xffff }, - { AFSF, AXXX, 4, X2, X3, 0xffff }, - { AFSGE, AXXX, X1, X2, X3, 0xffff }, - { AFSGT, AXXX, X1, X2, X3, 0xffff }, - { AFSINB, AXXX, 2, 0, 17, C, 0x000e, 0x580e }, - { AFSIND, AFSINL, 8, 0, 17, C, 0x000e, 0x540e }, - { AFSINF, AFSINL, 4, 0, 17, C, 0x000e, 0x440e }, - { AFSINHB, AXXX, 2, 0, 17, C, 0x0002, 0x5802 }, - { AFSINHD, AFSINHL, 8, 0, 17, C, 0x0002, 0x5402 }, - { AFSINHF, AFSINHL, 4, 0, 17, C, 0x0002, 0x4402 }, - { AFSINHL, AXXX, 4, 0, 17, C, 0x0002, 0x4002 }, - { AFSINHW, AXXX, 2, 0, 17, C, 0x0002, 0x5002 }, - { AFSINL, AXXX, 4, 0, 17, C, 0x000e, 0x400e }, - { AFSINW, AXXX, 2, 0, 17, C, 0x000e, 0x500e }, - { AFSLE, AXXX, X1, X2, X3, 0xffff }, - { AFSLT, AXXX, X1, X2, X3, 0xffff }, - { AFSNE, AXXX, X1, X2, X3, 0xffff }, - { AFSQRTB, AXXX, 2, 0, 17, C, 0x0004, 0x5804 }, - { AFSQRTD, AFSQRTL, 8, 0, 17, C, 0x0004, 0x5404 }, - { AFSQRTF, AFSQRTL, 4, 0, 17, C, 0x0004, 0x4404 }, - { AFSQRTL, AXXX, 4, 0, 17, C, 0x0004, 0x4004 }, - { AFSQRTW, AXXX, 2, 0, 17, C, 0x0004, 0x5004 }, - { AFST, AXXX, X1, X2, X3, 0xffff }, - { AFSUBB, AXXX, 2, 0, 17, C, 0x0028, 0x5828 }, - { AFSUBD, AFSUBL, 8, 0, 17, C, 0x0028, 0x5428 }, - { AFSUBF, AFSUBL, 4, 0, 17, C, 0x0028, 0x4428 }, - { AFSUBL, AXXX, 4, 0, 17, C, 0x0028, 0x4028 }, - { AFSUBW, AXXX, 2, 0, 17, C, 0x0028, 0x5028 }, - { AFTANB, AXXX, 2, 0, 17, C, 0x000f, 0x580f }, - { AFTAND, AFTANL, 8, 0, 17, C, 0x000f, 0x540f }, - { AFTANF, AFTANL, 4, 0, 17, C, 0x000f, 0x440f }, - { AFTANHB, AXXX, 2, 0, 17, C, 0x0009, 0x5809 }, - { AFTANHD, AFTANHL, 8, 0, 17, C, 0x0009, 0x5409 }, - { AFTANHF, AFTANHL, 4, 0, 17, C, 0x0009, 0x4409 }, - { AFTANHL, AXXX, 4, 0, 17, C, 0x0009, 0x4009 }, - { AFTANHW, AXXX, 2, 0, 17, C, 0x0009, 0x5009 }, - { AFTANL, AXXX, 4, 0, 17, C, 0x000f, 0x400f }, - { AFTANW, AXXX, 2, 0, 17, C, 0x000f, 0x500f }, - { AFTENTOXB, AXXX, 2, 0, 17, C, 0x0012, 0x5812 }, - { AFTENTOXD, AFTENTOXL, 8, 0, 17, C, 0x0012, 0x5412 }, - { AFTENTOXF, AFTENTOXL, 4, 0, 17, C, 0x0012, 0x4412 }, - { AFTENTOXL, AXXX, 4, 0, 17, C, 0x0012, 0x4012 }, - { AFTENTOXW, AXXX, 2, 0, 17, C, 0x0012, 0x5012 }, - { AFTSTB, AXXX, 0, 2, 20, C, 0x003a, 0x583a }, - { AFTSTD, AFTSTL, 0, 8, 20, C, 0x003a, 0x543a }, - { AFTSTF, AFTSTL, 0, 4, 20, C, 0x003a, 0x443a }, - { AFTSTL, AXXX, 0, 4, 20, C, 0x003a, 0x403a }, - { AFTSTW, AXXX, 0, 2, 20, C, 0x003a, 0x503a }, - { AFTWOTOXB, AXXX, 2, 0, 17, C, 0x0011, 0x5811 }, - { AFTWOTOXD, AFTWOTOXL, 8, 0, 17, C, 0x0011, 0x5411 }, - { AFTWOTOXF, AFTWOTOXL, 4, 0, 17, C, 0x0011, 0x4411 }, - { AFTWOTOXL, AXXX, 4, 0, 17, C, 0x0011, 0x4011 }, - { AFTWOTOXW, AXXX, 2, 0, 17, C, 0x0011, 0x5011 }, - { AGLOBL }, - { AGOK }, - { AHISTORY }, - { AILLEG, AXXX, 0, 0, 4, 0x4efc }, - { AINSTR }, - { AJMP, AXXX, 0, 0, 5, 0x4ec0 }, - { AJSR, AXXX, 0, 0, 5, 0x4e80 }, - { ALEA, AXXX, 0, 0, 6, 0x41c0 }, - { ALINKL }, - { ALINKW }, - { ALOCATE }, - { ALONG, AXXX, 0, 4, 23 }, - { ALSLB, AXXX, 0, 2, 12, 0xe108 }, - { ALSLL, AXXX, 0, 4, 12, 0xe188 }, - { ALSLW, AXXX, 0, 2, 12, 0xe148 }, - { ALSRB, AXXX, 0, 2, 12, 0xe008 }, - { ALSRL, AXXX, 0, 4, 12, 0xe088 }, - { ALSRW, AXXX, 0, 2, 12, 0xe048 }, - { AMOVB, AXXX, 2, -2, 2, 0x1000, 0x7000 }, - { AMOVEM, AXXX, 2, 2, 25, 0x48c0 }, - { AMOVEPL }, - { AMOVEPW }, - { AMOVESB }, - { AMOVESL }, - { AMOVESW, }, - { AMOVL, AXXX, 4, -4, 2, 0x2000, 0x7000 }, - { AMOVW, AXXX, 2, -2, 2, 0x3000, 0x7000 }, - { AMULSL, AXXX, 4, 0, 14, 0x4c00, 0x0800 }, - { AMULSW, AXXX, 2, 0, 13, 0xc1c0 }, - { AMULUL, AXXX, 4, 0, 14, 0x4c00, 0x0000 }, - { AMULUW, AXXX, 2, 0, 13, 0xc0c0 }, - { ANAME }, - { ANBCD }, - { ANEGB, AXXX, 0, 0, 5, 0x4400 }, - { ANEGL, AXXX, 0, 0, 5, 0x4480 }, - { ANEGW, AXXX, 0, 0, 5, 0x4440 }, - { ANEGXB }, - { ANEGXL }, - { ANEGXW }, - { ANOP }, - { ANOTB, AXXX, 0, 0, 5, 0x4600 }, - { ANOTL, AXXX, 0, 0, 5, 0x4680 }, - { ANOTW, AXXX, 0, 0, 5, 0x4640 }, - { AORB, AXXX, 2, 0, 9, 0x8000, 0x8100, 0x0000 }, - { AORL, AXXX, 4, 0, 9, 0x8080, 0x8180, 0x0080 }, - { AORW, AXXX, 2, 0, 9, 0x8040, 0x8140, 0x0040 }, - { APACK }, - { APEA, AXXX, 0, 0, 5, 0x4840 }, - { ARESET }, - { AROTLB, AXXX, 0, 2, 12, 0xe118 }, - { AROTLL, AXXX, 0, 4, 12, 0xe198 }, - { AROTLW, AXXX, 0, 2, 12, 0xe158 }, - { AROTRB, AXXX, 0, 2, 12, 0xe018 }, - { AROTRL, AXXX, 0, 4, 12, 0xe098 }, - { AROTRW, AXXX, 0, 2, 12, 0xe058 }, - { AROXLB }, - { AROXLL }, - { AROXLW }, - { AROXRB }, - { AROXRL }, - { AROXRW }, - { ARTD }, - { ARTE, AXXX, 0, 0, 4, 0x4e73 }, - { ARTM }, - { ARTR }, - { ARTS, AXXX, 0, 0, 4, 0x4e75 }, - { ASBCD }, - { ASCC }, - { ASCS }, - { ASEQ }, - { ASF }, - { ASGE }, - { ASGT }, - { ASHI }, - { ASLE }, - { ASLS }, - { ASLT }, - { ASMI }, - { ASNE }, - { ASPL }, - { AST }, - { ASTOP }, - { ASUBB, AXXX, 2, 0, 3, 0x9000, 0x5100, 0, 0x0400 }, - { ASUBL, AXXX, 4, 0, 3, 0x9080, 0x5180, 0x91c0, 0x0480 }, - { ASUBW, AXXX, 2, 0, 3, 0x9040, 0x5140, 0x90c0, 0x0440 }, - { ASUBXB }, - { ASUBXL }, - { ASUBXW }, - { ASVC }, - { ASVS }, - { ASWAP, AXXX, 0, 0, 35, 0x4840 }, - { ASYS, AXXX, 0, 2, 8, 0x4e40 }, - { ATAS, AXXX, 0, 2, 5, 0x4ac0 }, - { ATEXT }, - { ATRAP, AXXX, 0, 0, 30, 0x4e40 }, - { ATRAPCC }, - { ATRAPCS }, - { ATRAPEQ }, - { ATRAPF }, - { ATRAPGE }, - { ATRAPGT }, - { ATRAPHI }, - { ATRAPLE }, - { ATRAPLS }, - { ATRAPLT }, - { ATRAPMI }, - { ATRAPNE }, - { ATRAPPL }, - { ATRAPT }, - { ATRAPV }, - { ATRAPVC }, - { ATRAPVS }, - { ATSTB, AXXX, 0, 2, 5, 0x4a00 }, - { ATSTL, AXXX, 0, 4, 5, 0x4a80 }, - { ATSTW, AXXX, 0, 2, 5, 0x4a40 }, - { AUNLK }, - { AUNPK }, - { AWORD, AXXX, 0, 2, 23 }, - { AXXX } -}; - -char mmsize[] = -{ - /* 0 */ 0, 2, 2, 2, 2, - /* 5 */ 2, 2, 2, 4, 2, - /* 10 */ 2, 2, 2, 2, 4, - /* 15 */ 4, 4, 4, 4, 6, - /* 20 */ 4, 4, 4, 0, 4, - /* 25 */ 2, 2, 2, 2, 2, - /* 30 */ 2, 4, 4, 0, 4, - /* 35 */ 2, 0, 0, 0, 0, -}; diff --git a/utils/1l/pass.c b/utils/1l/pass.c deleted file mode 100644 index 9ab22626..00000000 --- a/utils/1l/pass.c +++ /dev/null @@ -1,673 +0,0 @@ -#include "l.h" - -void -dodata(void) -{ - int i; - Sym *s; - Prog *p; - long t, u; - - if(debug['v']) - Bprint(&bso, "%5.2f dodata\n", cputime()); - Bflush(&bso); - for(p = datap; p != P; p = p->link) { - s = p->from.sym; - if(s->type == SBSS) - s->type = SDATA; - if(s->type != SDATA) - diag("initialize non-data (%d): %s\n%P", - s->type, s->name, p); - t = p->from.offset + p->from.displace; - if(t > s->value) - diag("initialize bounds (%ld): %s\n%P", - s->value, s->name, p); - } - - /* allocate small guys */ - datsize = 0; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SDATA) - if(s->type != SBSS) - continue; - t = s->value; - if(t == 0) { - diag("%s: no size", s->name); - t = 1; - } - t = rnd(t, 4);; - s->value = t; - if(t > MINSIZ) - continue; - s->value = datsize; - datsize += t; - s->type = SDATA1; - } - - /* allocate the rest of the data */ - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SDATA) { - if(s->type == SDATA1) - s->type = SDATA; - continue; - } - t = s->value; - s->value = datsize; - datsize += t; - } - - if(debug['j']) { - /* - * pad data with bss that fits up to next - * 8k boundary, then push data to 8k - */ - u = rnd(datsize, 8192); - u -= datsize; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SBSS) - continue; - t = s->value; - if(t > u) - continue; - u -= t; - s->value = datsize; - s->type = SDATA; - datsize += t; - } - datsize += u; - } - - /* now the bss */ - bsssize = 0; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SBSS) - continue; - t = s->value; - s->value = bsssize + datsize; - bsssize += t; - } - xdefine("bdata", SDATA, 0L); - xdefine("edata", SDATA, datsize); - xdefine("end", SBSS, datsize+bsssize); -} - -Prog* -brchain(Prog *p) -{ - int i; - - for(i=0; i<20; i++) { - if(p == P || p->as != ABRA) - return p; - p = p->pcond; - } - return P; -} - -void -follow(void) -{ - Prog *p; - long o; - - if(debug['v']) - Bprint(&bso, "%5.2f follow\n", cputime()); - Bflush(&bso); - firstp = prg(); - lastp = firstp; - xfol(textp); - lastp->link = P; - firstp = firstp->link; - o = 0; /* set */ - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - - p->stkoff = -1; /* initialization for stkoff */ - if(p->as == ATEXT) { - p->stkoff = 0; - o = p->to.offset; - continue; - } - if(p->as == AADJSP && p->from.offset == 0) { - p->stkoff = o; - continue; - } - } -} - -void -xfol(Prog *p) -{ - Prog *q; - int i; - enum as a; - -loop: - if(p == P) - return; - if(p->as == ATEXT) - curtext = p; - if(p->as == ABRA) - if((q = p->pcond) != P) { - p->mark = 1; - p = q; - if(p->mark == 0) - goto loop; - } - if(p->mark) { - /* copy up to 4 instructions to avoid branch */ - for(i=0,q=p; i<4; i++,q=q->link) { - if(q == P) - break; - if(q == lastp) - break; - a = q->as; - if(a == ANOP) { - i--; - continue; - } - if(a == ABRA || a == ARTS || a == ARTE) - break; - if(q->pcond == P || q->pcond->mark) - continue; - if(a == ABSR || a == ADBF) - continue; - for(;;) { - if(p->as == ANOP) { - p = p->link; - continue; - } - q = copyp(p); - p = p->link; - q->mark = 1; - lastp->link = q; - lastp = q; - if(q->as != a || q->pcond == P || q->pcond->mark) - continue; - q->as = relinv(q->as); - p = q->pcond; - q->pcond = q->link; - q->link = p; - xfol(q->link); - p = q->link; - if(p->mark) - return; - goto loop; - } - } /* */ - q = prg(); - q->as = ABRA; - q->line = p->line; - q->to.type = D_BRANCH; - q->to.offset = p->pc; - q->pcond = p; - p = q; - } - p->mark = 1; - lastp->link = p; - lastp = p; - a = p->as; - if(a == ARTS || a == ABRA || a == ARTE) - return; - if(p->pcond != P) - if(a != ABSR) { - q = brchain(p->link); - if(q != P && q->mark) - if(a != ADBF) { - p->as = relinv(a); - p->link = p->pcond; - p->pcond = q; - } - xfol(p->link); - q = brchain(p->pcond); - if(q->mark) { - p->pcond = q; - return; - } - p = q; - goto loop; - } - p = p->link; - goto loop; -} - -int -relinv(int a) -{ - - switch(a) { - case ABEQ: return ABNE; - case ABNE: return ABEQ; - case ABLE: return ABGT; - case ABLS: return ABHI; - case ABLT: return ABGE; - case ABMI: return ABPL; - case ABGE: return ABLT; - case ABPL: return ABMI; - case ABGT: return ABLE; - case ABHI: return ABLS; - case ABCS: return ABCC; - case ABCC: return ABCS; - case AFBEQ: return AFBNE; - case AFBF: return AFBT; - case AFBGE: return AFBLT; - case AFBGT: return AFBLE; - case AFBLE: return AFBGT; - case AFBLT: return AFBGE; - case AFBNE: return AFBEQ; - case AFBT: return AFBF; - } - diag("unknown relation: %s in %s", anames[a], TNAME); - return a; -} - -void -patch(void) -{ - long c; - Prog *p, *q; - Sym *s; - long vexit; - - if(debug['v']) - Bprint(&bso, "%5.2f mkfwd\n", cputime()); - Bflush(&bso); - mkfwd(); - if(debug['v']) - Bprint(&bso, "%5.2f patch\n", cputime()); - Bflush(&bso); - s = lookup("exit", 0); - vexit = s->value; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - if((p->as == ABSR || p->as == ARTS) && p->to.sym != S) { - s = p->to.sym; - if(s->type != STEXT) { - diag("undefined: %s in %s", s->name, TNAME); - s->type = STEXT; - s->value = vexit; - } - p->to.offset = s->value; - p->to.type = D_BRANCH; - } - if(p->to.type != D_BRANCH) - continue; - c = p->to.offset; - for(q = firstp; q != P;) { - if(q->forwd != P) - if(c >= q->forwd->pc) { - q = q->forwd; - continue; - } - if(c == q->pc) - break; - q = q->link; - } - if(q == P) { - diag("branch out of range in %s\n%P", TNAME, p); - p->to.type = D_NONE; - } - p->pcond = q; - } - - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - p->mark = 0; /* initialization for follow */ - if(p->pcond != P) { - p->pcond = brloop(p->pcond); - if(p->pcond != P) - if(p->to.type == D_BRANCH) - p->to.offset = p->pcond->pc; - } - } -} - -#define LOG 5 -void -mkfwd(void) -{ - Prog *p; - int i; - long dwn[LOG], cnt[LOG]; - Prog *lst[LOG]; - - for(i=0; i<LOG; i++) { - if(i == 0) - cnt[i] = 1; else - cnt[i] = LOG * cnt[i-1]; - dwn[i] = 1; - lst[i] = P; - } - i = 0; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - i--; - if(i < 0) - i = LOG-1; - p->forwd = P; - dwn[i]--; - if(dwn[i] <= 0) { - dwn[i] = cnt[i]; - if(lst[i] != P) - lst[i]->forwd = p; - lst[i] = p; - } - } -} - -Prog* -brloop(Prog *p) -{ - int c; - Prog *q; - - c = 0; - for(q = p; q != P; q = q->pcond) { - if(q->as != ABRA) - break; - c++; - if(c >= 5000) - return P; - } - return q; -} - -void -dostkoff(void) -{ - Prog *p, *q, *qq; - long s, t; - int a; - Optab *o; - - if(debug['v']) - Bprint(&bso, "%5.2f stkoff\n", cputime()); - Bflush(&bso); - s = 0; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) { - curtext = p; - s = p->to.offset; - if(s == 0) - continue; - p = nprg(p); - p->as = AADJSP; - p->from.type = D_CONST; - p->from.offset = s; - p->stkoff = 0; - continue; - } - t = 0; - for(q = p; q != P; q = q->pcond) { - if(q->as == ATEXT) - break; - if(q->stkoff >= 0) - if(q->stkoff != s) - diag("stack offset %ld is %ld sb %ld in %s\n%P", - q->pc, q->stkoff, s, q, TNAME, p); - q->stkoff = s; - if(t++ > 100) { - diag("loop in stack offset 1: %P", p); - break; - } - } - o = &optab[p->as]; - if(p->to.type == D_TOS) - s -= o->dstsp; - if(p->from.type == D_TOS) - s -= o->srcsp; - if(p->as == AADJSP) - s += p->from.offset; - if(p->as == APEA) - s += 4; - t = 0; - for(q = p->link; q != P; q = q->pcond) { - if(q->as == ATEXT) { - q = P; - break; - } - if(q->stkoff >= 0) - break; - if(t++ > 100) { - diag("loop in stack offset 2: %P", p); - break; - } - } - if(q == P || q->stkoff == s) - continue; - if(p->as == ABRA || p->as == ARTS || p->as == ARTE) { - s = q->stkoff; - continue; - } - t = q->stkoff - s; - s = q->stkoff; - p = nprg(p); - p->as = AADJSP; - p->stkoff = s - t; - p->from.type = D_CONST; - p->from.offset = t; - } - - if(debug['v']) - Bprint(&bso, "%5.2f rewrite\n", cputime()); - Bflush(&bso); - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - a = p->from.type & D_MASK; - if(a == D_AUTO) - p->from.offset += p->stkoff; - if(a == D_PARAM) - p->from.offset += p->stkoff + 4; - a = p->to.type & D_MASK; - if(a == D_AUTO) - p->to.offset += p->stkoff; - if(a == D_PARAM) - p->to.offset += p->stkoff + 4; - switch(p->as) { - default: - continue; - - case AMOVW: - if(p->from.type != D_CCR) - continue; - a = p->to.type; - if((a < D_R0 || a > D_R0+7) && a != D_TOS) - diag("bad dest for MOVCC %P", p); - p->as = ALEA; - p->from.type = I_INDIR|(D_A0+7); - p->from.offset = -2; - p->to.type = D_A0+7; - - p = nprg(p); - p->as = ABSR; - p->to.type = D_BRANCH; - p->pcond = prog_ccr; - p->to.sym = prog_ccr->from.sym; - - if(a != D_TOS) { - p = nprg(p); - p->as = AMOVW; - p->from.type = D_TOS; - p->to.type = a; - } - continue; - - case AEXTBL: - a = p->to.type; - if(a < D_R0 || a > D_R0+7) - diag("bad dest for EXTB"); - p->as = AEXTBW; - - p = nprg(p); - p->as = AEXTWL; - p->to.type = a; - continue; - - case AMULSL: - case AMULUL: - qq = prog_mull; - goto mdcom; - case ADIVSL: - qq = prog_divsl; - goto mdcom; - case ADIVUL: - qq = prog_divul; - mdcom: - if(debug['m']) - continue; - a = p->to.type; - if(a < D_R0 || a > D_R0+7) - diag("bad dest for mul/div"); - p->as = AMOVL; - p->to.type = D_TOS; - - p = nprg(p); - p->as = AMOVL; - p->from.type = a; - p->to.type = D_TOS; - - p = nprg(p); - p->as = ABSR; - p->to.type = D_BRANCH; - p->pcond = qq; - p->to.sym = qq->from.sym; - - p = nprg(p); - p->as = AMOVL; - p->from.type = D_TOS; - p->to.type = a; - - p = nprg(p); - p->as = AMOVL; - p->from.type = D_TOS; - p->to.type = a+1; - if(qq == prog_mull) - p->to.type = a; - continue; - - case ARTS: - break; - } - if(p->stkoff == 0) - continue; - - p->as = AADJSP; - p->from.type = D_CONST; - p->from.offset = -p->stkoff; - - p = nprg(p); - p->as = ARTS; - p->stkoff = 0; - } -} - -long -atolwhex(char *s) -{ - long n; - int f; - - n = 0; - f = 0; - while(*s == ' ' || *s == '\t') - s++; - if(*s == '-' || *s == '+') { - if(*s++ == '-') - f = 1; - while(*s == ' ' || *s == '\t') - s++; - } - if(s[0]=='0' && s[1]){ - if(s[1]=='x' || s[1]=='X'){ - s += 2; - for(;;){ - if(*s >= '0' && *s <= '9') - n = n*16 + *s++ - '0'; - else if(*s >= 'a' && *s <= 'f') - n = n*16 + *s++ - 'a' + 10; - else if(*s >= 'A' && *s <= 'F') - n = n*16 + *s++ - 'A' + 10; - else - break; - } - } else - while(*s >= '0' && *s <= '7') - n = n*8 + *s++ - '0'; - } else - while(*s >= '0' && *s <= '9') - n = n*10 + *s++ - '0'; - if(f) - n = -n; - return n; -} - -void -undef(void) -{ - int i; - Sym *s; - - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) - if(s->type == SXREF) - diag("%s: not defined", s->name); -} - -void -initmuldiv1(void) -{ - lookup("_mull", 0)->type = SXREF; - lookup("_divsl", 0)->type = SXREF; - lookup("_divul", 0)->type = SXREF; - lookup("_ccr", 0)->type = SXREF; -} - -void -initmuldiv2(void) -{ - Sym *s1, *s2, *s3, *s4; - Prog *p; - - if(prog_mull != P) - return; - s1 = lookup("_mull", 0); - s2 = lookup("_divsl", 0); - s3 = lookup("_divul", 0); - s4 = lookup("_ccr", 0); - for(p = firstp; p != P; p = p->link) - if(p->as == ATEXT) { - if(p->from.sym == s1) - prog_mull = p; - if(p->from.sym == s2) - prog_divsl = p; - if(p->from.sym == s3) - prog_divul = p; - if(p->from.sym == s4) - prog_ccr = p; - } - if(prog_mull == P) { - diag("undefined: %s", s1->name); - prog_mull = curtext; - } - if(prog_divsl == P) { - diag("undefined: %s", s2->name); - prog_divsl = curtext; - } - if(prog_divul == P) { - diag("undefined: %s", s3->name); - prog_divul = curtext; - } - if(prog_ccr == P) { - diag("undefined: %s", s4->name); - prog_ccr = curtext; - } -} diff --git a/utils/1l/span.c b/utils/1l/span.c deleted file mode 100644 index d8baa362..00000000 --- a/utils/1l/span.c +++ /dev/null @@ -1,515 +0,0 @@ -#include "l.h" - -void -span(void) -{ - Prog *p, *q; - long v, c, idat; - Optab *o; - int m, n; - - xdefine("etext", STEXT, 0L); - xdefine("a6base", STEXT, 0L); - idat = INITDAT; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - n = 0; - if((q = p->pcond) != P) - if(q->back != 2) - n = 1; - p->back = n; - if(p->as == AADJSP) { - p->to.type = D_A0+7; - v = -p->from.offset; - p->from.offset = v; - if((v < -8 && v >= -32768L) || (v > 8 && v < 32768L)) { - p->as = ALEA; - p->from.type = I_INDIR | (D_A0+7); - continue; - } - p->as = AADDL; - if(v < 0) { - p->as = ASUBL; - v = -v; - p->from.offset = v; - } - if(v >= 0 && v <= 8) - p->from.type = D_QUICK; - if(v == 0) - p->as = ANOP; - } - } - n = 0; - -start: - if(debug['v']) - Bprint(&bso, "%5.2f span\n", cputime()); - Bflush(&bso); - c = INITTEXT; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - o = &optab[p->as]; - p->pc = c; - m = mmsize[o->optype]; - if(m == 0) { - if(p->as == AWORD) - m = 2; - if(p->as == ALONG) - m = 4; - p->mark = m; - c += m; - continue; - } - if(p->from.type != D_NONE) - m += andsize(p, &p->from); - if(p->to.type == D_BRANCH) { - if(p->pcond == P) - p->pcond = p; - c += m; - if(m == 2) - m |= 0100; - p->mark = m; - continue; - } - if(p->to.type != D_NONE) - m += andsize(p, &p->to); - p->mark = m; - c += m; - } - -loop: - n++; - if(debug['v']) - Bprint(&bso, "%5.2f span %d\n", cputime(), n); - Bflush(&bso); - if(n > 60) { - diag("span must be looping"); - errorexit(); - } - c = INITTEXT; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - if((m = p->mark) & 0100) { - q = p->pcond; - v = q->pc - 2; - if(p->back) - v -= c; - else - v -= p->pc; - p->pc = c; - if(v < -32768L || v >= 32768L) { - c += 6; /* only jsr and jmp can do this */ - } else - if(v < -128 || v >= 128) - c += 4; - else - if(v == 0) { - c += 4; - p->mark = 4; - } else - c += 2; - continue; - } - p->pc = c; - c += m; - } - if(c != textsize) { - textsize = c; - goto loop; - } - if(INITRND) - INITDAT = rnd(c, INITRND); - if(INITDAT != idat) { - idat = INITDAT; - goto start; - } - xdefine("etext", STEXT, c); - xdefine("a6base", STEXT, INITDAT+A6OFFSET); - if(debug['v']) - Bprint(&bso, "etext = %lux\n", c); - Bflush(&bso); - for(p = textp; p != P; p = p->pcond) - p->from.sym->value = p->pc; - textsize = c - INITTEXT; -} - -void -xdefine(char *p, int t, long v) -{ - Sym *s; - - s = lookup(p, 0); - if(s->type == 0 || s->type == SXREF) { - s->type = t; - s->value = v; - } - if(s->type == STEXT && s->value == 0) - s->value = v; -} - -int -andsize(Prog *p, Adr *ap) -{ - int t, n; - long v; - Optab *o; - - t = ap->type; - n = simple[t]; - if(n != 0177) { - v = ap->offset; - if(v == 0) - return 0; - if((n&070) != 020) /* D_INDIR */ - return 0; - if(v == 0) - return 0; - return 2; - } - if((t&I_MASK) == I_ADDR) - t = D_CONST; - switch(t) { - - default: - return 0; - - case D_STACK: - case D_AUTO: - case D_PARAM: - v = ap->offset; - if(v == 0) - return 0; - return 2; - - case I_INDIR|D_CONST: - v = ap->offset; - if(v < -32768L || v >= 32768L) - return 4; - return 2; - - case D_STATIC: - case D_EXTERN: - if(ap->sym->type == STEXT) { - if(HEADTYPE == 4) - return 2; - return 4; - } - v = ap->sym->value + ap->offset - A6OFFSET; - if(v == 0) - return 0; - if(v < -32768L || v >= 32768L) - return 4; - return 2; - - case D_CONST: - case D_FCONST: - o = &optab[p->as]; - if(ap == &(p->from)) - return o->srcsp; - return o->dstsp; - - case D_CCR: - case D_SR: - if(p->as == AMOVW) - return 0; - return 2; - - case D_USP: - t = p->from.type; - if(t >= D_A0 && t <= D_A0+8) - return 0; - t = p->to.type; - if(t >= D_A0 && t <= D_A0+8) - return 0; - - case D_SFC: - case D_DFC: - case D_CACR: - case D_VBR: - case D_CAAR: - case D_MSP: - case D_ISP: - case D_FPCR: - case D_FPSR: - case D_FPIAR: - case D_TC: - case D_ITT0: - case D_ITT1: - case D_DTT0: - case D_DTT1: - case D_MMUSR: - case D_URP: - case D_SRP: - return 2; - } -} - -void -putsymb(Sym *s, int t, long v) -{ - int i, f; - char *n; - - n = s->name; - if(t == 'f') - n++; - lput(v); - if(s->version) - t += 'a' - 'A'; - CPUT(t+0x80); /* 0x80 is variable length */ - - if(t == 'Z' || t == 'z') { - CPUT(n[0]); - for(i=1; n[i] != 0 || n[i+1] != 0; i += 2) { - CPUT(n[i]); - CPUT(n[i+1]); - } - CPUT(0); - CPUT(0); - i++; - } - else { - for(i=0; n[i]; i++) - CPUT(n[i]); - CPUT(0); - } - symsize += 4 + 1 + i + 1; - - if(debug['n']) { - if(t == 'z' || t == 'Z') { - Bprint(&bso, "%c %.8lux ", t, v); - for(i=1; n[i] != 0 || n[i+1] != 0; i+=2) { - f = ((n[i]&0xff) << 8) | (n[i+1]&0xff); - Bprint(&bso, "/%x", f); - } - Bprint(&bso, "\n"); - return; - } - if(s->version) - Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, n, s->version); - else - Bprint(&bso, "%c %.8lux %s\n", t, v, n); - } -} - -void -asmsym(void) -{ - Prog *p; - Auto *a; - Sym *s; - int h; - - s = lookup("etext", 0); - if(s->type == STEXT) - putsymb(s, 'T', s->value); - s = lookup("a6base", 0); - if(s->type == STEXT) - putsymb(s, 'D', s->value); - - for(h=0; h<NHASH; h++) - for(s=hash[h]; s!=S; s=s->link) - switch(s->type) { - case SDATA: - putsymb(s, 'D', s->value+INITDAT); - continue; - - case SBSS: - putsymb(s, 'B', s->value+INITDAT); - continue; - - case SFILE: - putsymb(s, 'f', s->value); - continue; - } - - for(p=textp; p!=P; p=p->pcond) { - s = p->from.sym; - if(s->type != STEXT) - continue; - - /* filenames first */ - for(a=p->to.autom; a; a=a->link) - if(a->type == D_FILE) - putsymb(a->asym, 'z', a->aoffset); - else - if(a->type == D_FILE1) - putsymb(a->asym, 'Z', a->aoffset); - - putsymb(s, 'T', s->value); - - /* auto and param after */ - for(a=p->to.autom; a; a=a->link) - if(a->type == D_AUTO) - putsymb(a->asym, 'a', -a->aoffset); - else - if(a->type == D_PARAM) - putsymb(a->asym, 'p', a->aoffset); - } - if(debug['v'] || debug['n']) - Bprint(&bso, "symsize = %lud\n", symsize); - Bflush(&bso); -} - -#define MINLC 2 -void -asmsp(void) -{ - long oldpc, oldsp; - Prog *p; - int s; - long v; - - oldpc = INITTEXT; - oldsp = 0; - for(p = firstp; p != P; p = p->link) { - if(p->stkoff == oldsp || p->as == ATEXT || p->as == ANOP) { - if(p->as == ATEXT) - curtext = p; - if(debug['G']) - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - continue; - } - if(debug['G']) - Bprint(&bso, "\t\t%6ld", spsize); - v = (p->pc - oldpc) / MINLC; - while(v) { - s = 127; - if(v < 127) - s = v; - CPUT(s+128); /* 129-255 +pc */ - if(debug['G']) - Bprint(&bso, " pc+%d*2(%d)", s, s+128); - v -= s; - spsize++; - } - v = p->stkoff - oldsp; - oldsp = p->stkoff; - oldpc = p->pc + MINLC; - if(v & 3 || v > 64L*4L || v < -64L*4L) { - CPUT(0); /* 0 vvvv +sp */ - lput(v); - if(debug['G']) { - if(v > 0) - Bprint(&bso, " sp+%ld*1(%d,%ld)\n", - v, 0, v); - else - Bprint(&bso, " sp%ld*1(%d,%ld)\n", - v, 0, v); - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - } - spsize += 5; - continue; - } - s = v/4; - if(s > 0) { - CPUT(0+s); /* 1-64 +sp */ - if(debug['G']) { - Bprint(&bso, " sp+%d*4(%d)\n", s, 0+s); - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - } - } else { - CPUT(64-s); /* 65-128 -sp */ - if(debug['G']) { - Bprint(&bso, " sp%d*4(%d)\n", s, 64-s); - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - } - } - spsize++; - } - while(spsize & 1) { - s = 129; - CPUT(s); - spsize++; - } - if(debug['v'] || debug['G']) - Bprint(&bso, "stsize = %ld\n", spsize); - Bflush(&bso); -} - -void -asmlc(void) -{ - long oldpc, oldlc; - Prog *p; - long v, s; - - oldpc = INITTEXT; - oldlc = 0; - for(p = firstp; p != P; p = p->link) { - if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { - if(p->as == ATEXT) - curtext = p; - if(debug['L']) - Bprint(&bso, "%6lux %P\n", - p->pc, p); - continue; - } - if(debug['L']) - Bprint(&bso, "\t\t%6ld", lcsize); - v = (p->pc - oldpc) / MINLC; - while(v) { - s = 127; - if(v < 127) - s = v; - CPUT(s+128); /* 129-255 +pc */ - if(debug['L']) - Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); - v -= s; - lcsize++; - } - s = p->line - oldlc; - oldlc = p->line; - oldpc = p->pc + MINLC; - if(s > 64 || s < -64) { - CPUT(0); /* 0 vv +lc */ - CPUT(s>>24); - CPUT(s>>16); - CPUT(s>>8); - CPUT(s); - if(debug['L']) { - if(s > 0) - Bprint(&bso, " lc+%ld(%d,%ld)\n", - s, 0, s); - else - Bprint(&bso, " lc%ld(%d,%ld)\n", - s, 0, s); - Bprint(&bso, "%6lux %P\n", - p->pc, p); - } - lcsize += 5; - continue; - } - if(s > 0) { - CPUT(0+s); /* 1-64 +lc */ - if(debug['L']) { - Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); - Bprint(&bso, "%6lux %P\n", - p->pc, p); - } - } else { - CPUT(64-s); /* 65-128 -lc */ - if(debug['L']) { - Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); - Bprint(&bso, "%6lux %P\n", - p->pc, p); - } - } - lcsize++; - } - while(lcsize & 1) { - s = 129; - CPUT(s); - lcsize++; - } - if(debug['v'] || debug['L']) - Bprint(&bso, "lcsize = %ld\n", lcsize); - Bflush(&bso); -} diff --git a/utils/2a/a.h b/utils/2a/a.h deleted file mode 100644 index 7f9987b0..00000000 --- a/utils/2a/a.h +++ /dev/null @@ -1,200 +0,0 @@ -#include <lib9.h> -#include <bio.h> -#include "../2c/2.out.h" - -#ifndef EXTERN -#define EXTERN extern -#endif - -typedef struct Sym Sym; -typedef struct Ref Ref; -typedef struct Gen Gen; -typedef struct Io Io; -typedef struct Hist Hist; -typedef struct Addr Addr; -typedef struct Gen2 Gen2; - -#define MAXALIGN 7 -#define FPCHIP 1 -#define NSYMB 500 -#define BUFSIZ 8192 -#define HISTSZ 20 -#define NINCLUDE 10 -#define NHUNK 10000 -#define EOF (-1) -#define IGN (-2) -#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff) -#define NHASH 503 -#define STRINGSZ 200 -#define NMACRO 10 - -struct Sym -{ - Sym* link; - Ref* ref; - char* macro; - long value; - ushort type; - char *name; - char sym; -}; -#define S ((Sym*)0) - -struct Ref -{ - int class; -}; - -EXTERN struct -{ - char* p; - int c; -} fi; - -struct Io -{ - Io* link; - char b[BUFSIZ]; - char* p; - short c; - short f; -}; -#define I ((Io*)0) - -EXTERN struct -{ - Sym* sym; - short type; -} h[NSYM]; - -struct Addr -{ - Sym* sym; - long offset; - short type; -}; -struct Gen -{ - Addr s0; - double dval; - char sval[8]; - long displace; - short type; - short index; - short scale; - short field; -}; -struct Gen2 -{ - Gen from; - Gen to; -}; - -struct Hist -{ - Hist* link; - char* name; - long line; - long offset; -}; -#define H ((Hist*)0) - -enum -{ - CLAST, - CMACARG, - CMACRO, - CPREPROC -}; - -EXTERN char debug[256]; -EXTERN Sym* hash[NHASH]; -EXTERN char* Dlist[30]; -EXTERN int nDlist; -EXTERN Hist* ehist; -EXTERN int newflag; -EXTERN Hist* hist; -EXTERN char* hunk; -EXTERN char* include[NINCLUDE]; -EXTERN Io* iofree; -EXTERN Io* ionext; -EXTERN Io* iostack; -EXTERN long lineno; -EXTERN int nerrors; -EXTERN long nhunk; -EXTERN int ninclude; -EXTERN Gen nullgen; -EXTERN char* outfile; -EXTERN int pass; -EXTERN char* pathname; -EXTERN long pc; -EXTERN int peekc; -EXTERN int sym; -EXTERN char symb[NSYMB]; -EXTERN int thechar; -EXTERN char* thestring; -EXTERN long thunk; -EXTERN Biobuf obuf; - -void* allocn(void*, long, long); -void errorexit(void); -void pushio(void); -void newio(void); -void newfile(char*, int); -Sym* slookup(char*); -Sym* lookup(void); -void syminit(Sym*); -long yylex(void); -int getc(void); -int getnsc(void); -void unget(int); -int escchar(int); -void cinit(void); -void pinit(char*); -void cclean(void); -int isreg(Gen*); -void outcode(int, Gen2*); -void outhist(void); -void zaddr(Gen*, int); -void zname(char*, int, int); -void ieeedtod(Ieee*, double); -int filbuf(void); -Sym* getsym(void); -void domacro(void); -void macund(void); -void macdef(void); -void macexpand(Sym*, char*); -void macinc(void); -void macprag(void); -void maclin(void); -void macif(int); -void macend(void); -void dodefine(char*); -void prfile(long); -void linehist(char*, int); -void gethunk(void); -void yyerror(char*, ...); -int yyparse(void); -void setinclude(char*); -int assemble(char*); - -enum /* keep in synch with ../cc/cc.h */ -{ - Plan9 = 1<<0, - Unix = 1<<1, - Windows = 1<<2 -}; - -/* - * system-dependent stuff from ../cc/compat.c - */ -int mywait(int*); -int mycreat(char*, int); -int systemtype(int); -int pathchar(void); -char* mygetwd(char*, int); -int myexec(char*, char*[]); -int mydup(int, int); -int myfork(void); -int mypipe(int*); -void* mysbrk(ulong); diff --git a/utils/2a/a.y b/utils/2a/a.y deleted file mode 100644 index 2a5d5c96..00000000 --- a/utils/2a/a.y +++ /dev/null @@ -1,540 +0,0 @@ -%{ -#include "a.h" -%} -%union { - Sym *sym; - long lval; - double dval; - char sval[8]; - Addr addr; - Gen gen; - Gen2 gen2; -} -%left '|' -%left '^' -%left '&' -%left '<' '>' -%left '+' '-' -%left '*' '/' '%' -%token <lval> LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5 -%token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA LTYPEB -%token <lval> LCONST LSP LSB LFP LPC LTOS LAREG LDREG LFREG LWID -%token <dval> LFCONST -%token <sval> LSCONST -%token <sym> LNAME LLAB LVAR -%type <lval> con expr scale type pointer reg offset -%type <addr> name areg xreg -%type <gen> gen rel -%type <gen2> noaddr gengen dstgen spec1 spec2 spec3 srcgen dstrel genrel -%% -prog: -| prog line - -line: - LLAB ':' - { - if($1->value != pc) - yyerror("redeclaration of %s", $1->name); - $1->value = pc; - } - line -| LNAME ':' - { - $1->type = LLAB; - $1->value = pc; - } - line -| ';' -| inst ';' -| error ';' - -inst: - LNAME '=' expr - { - $1->type = LVAR; - $1->value = $3; - } -| LVAR '=' expr - { - if($1->value != $3) - yyerror("redeclaration of %s", $1->name); - $1->value = $3; - } -| LTYPE1 gengen { outcode($1, &$2); } -| LTYPE2 noaddr { outcode($1, &$2); } -| LTYPE3 dstgen { outcode($1, &$2); } -| LTYPE4 spec1 { outcode($1, &$2); } -| LTYPE5 srcgen { outcode($1, &$2); } -| LTYPE6 dstrel { outcode($1, &$2); } -| LTYPE7 genrel { outcode($1, &$2); } -| LTYPE8 dstgen { outcode($1, &$2); } -| LTYPE8 gengen { outcode($1, &$2); } -| LTYPE9 noaddr { outcode($1, &$2); } -| LTYPE9 dstgen { outcode($1, &$2); } -| LTYPEA spec2 { outcode($1, &$2); } -| LTYPEB spec3 { outcode($1, &$2); } - -noaddr: - { - $$.from = nullgen; - $$.to = nullgen; - } -| ',' - { - $$.from = nullgen; - $$.to = nullgen; - } - -srcgen: - gen - { - $$.from = $1; - $$.to = nullgen; - } -| gen ',' - { - $$.from = $1; - $$.to = nullgen; - } - -dstgen: - gen - { - $$.from = nullgen; - $$.to = $1; - } -| ',' gen - { - $$.from = nullgen; - $$.to = $2; - } - -gengen: - gen ',' gen - { - $$.from = $1; - $$.to = $3; - } - -dstrel: - rel - { - $$.from = nullgen; - $$.to = $1; - } -| ',' rel - { - $$.from = nullgen; - $$.to = $2; - } - -genrel: - gen ',' rel - { - $$.from = $1; - $$.to = $3; - } - -spec1: /* DATA opcode */ - gen '/' con ',' gen - { - $1.displace = $3; - $$.from = $1; - $$.to = $5; - } - -spec2: /* bit field opcodes */ - gen ',' gen ',' con ',' con - { - $1.field = $7; - $3.field = $5; - $$.from = $1; - $$.to = $3; - } - -spec3: /* TEXT opcode */ - gengen -| gen ',' con ',' gen - { - $1.displace = $3; - $$.from = $1; - $$.to = $5; - } - -rel: - con '(' LPC ')' - { - $$ = nullgen; - $$.type = D_BRANCH; - $$.s0.offset = $1 + pc; - } -| LNAME offset - { - $$ = nullgen; - if(pass == 2) - yyerror("undefined label: %s", $1->name); - $$.type = D_BRANCH; - $$.s0.sym = $1; - $$.s0.offset = $2; - } -| LLAB offset - { - $$ = nullgen; - $$.type = D_BRANCH; - $$.s0.sym = $1; - $$.s0.offset = $1->value + $2; - } - -gen: - type - { - $$ = nullgen; - $$.type = $1; - } -| '$' con - { - $$ = nullgen; - $$.type = D_CONST; - $$.s0.offset = $2; - } -| '$' name - { - $$ = nullgen; - { - Addr *a; - a = &$$.s0; - *a = $2; - } - if($2.type == D_AUTO || $2.type == D_PARAM) - yyerror("constant cannot be automatic: %s", - $2.sym->name); - $$.type = $2.type | I_ADDR; - } -| '$' LSCONST - { - $$ = nullgen; - $$.type = D_SCONST; - memcpy($$.sval, $2, sizeof($$.sval)); - } -| '$' LFCONST - { - $$ = nullgen; - $$.type = D_FCONST; - $$.dval = $2; - } -| '$' '-' LFCONST - { - $$ = nullgen; - $$.type = D_FCONST; - $$.dval = -$3; - } -| LTOS '+' con - { - $$ = nullgen; - $$.type = D_STACK; - $$.s0.offset = $3; - } -| LTOS '-' con - { - $$ = nullgen; - $$.type = D_STACK; - $$.s0.offset = -$3; - } -| con - { - $$ = nullgen; - $$.type = D_CONST | I_INDIR; - $$.s0.offset = $1; - } -| '-' '(' LAREG ')' - { - $$ = nullgen; - $$.type = $3 | I_INDDEC; - } -| '(' LAREG ')' '+' - { - $$ = nullgen; - $$.type = $2 | I_INDINC; - } -| areg - { - $$ = nullgen; - $$.type = $1.type; - { - Addr *a; - a = &$$.s0; - *a = $1; - } - if(($$.type & D_MASK) == D_NONE) { - $$.index = D_NONE | I_INDEX1; - $$.scale = 0; - $$.displace = 0; - } - } -| areg xreg - { - $$ = nullgen; - $$.type = $1.type; - { - Addr *a; - a = &$$.s0; - *a = $1; - } - $$.index = $2.type | I_INDEX1; - $$.scale = $2.offset; - } -| '(' areg ')' xreg - { - $$ = nullgen; - $$.type = $2.type; - { - Addr *a; - a = &$$.s0; - *a = $2; - } - $$.index = $4.type | I_INDEX2; - $$.scale = $4.offset; - $$.displace = 0; - } -| con '(' areg ')' xreg - { - $$ = nullgen; - $$.type = $3.type; - { - Addr *a; - a = &$$.s0; - *a = $3; - } - $$.index = $5.type | I_INDEX2; - $$.scale = $5.offset; - $$.displace = $1; - } -| '(' areg ')' - { - $$ = nullgen; - $$.type = $2.type; - { - Addr *a; - a = &$$.s0; - *a = $2; - } - $$.index = D_NONE | I_INDEX3; - $$.scale = 0; - $$.displace = 0; - } -| con '(' areg ')' - { - $$ = nullgen; - $$.type = $3.type; - { - Addr *a; - a = &$$.s0; - *a = $3; - } - $$.index = D_NONE | I_INDEX3; - $$.scale = 0; - $$.displace = $1; - } -| '(' areg xreg ')' - { - $$ = nullgen; - $$.type = $2.type; - { - Addr *a; - a = &$$.s0; - *a = $2; - } - $$.index = $3.type | I_INDEX3; - $$.scale = $3.offset; - $$.displace = 0; - } -| con '(' areg xreg ')' - { - $$ = nullgen; - $$.type = $3.type; - { - Addr *a; - a = &$$.s0; - *a = $3; - } - $$.index = $4.type | I_INDEX3; - $$.scale = $4.offset; - $$.displace = $1; - } - -type: - reg -| LFREG - -xreg: - /* - * .W*1 0 - * .W*2 1 - * .W*4 2 - * .W*8 3 - * .L*1 4 - * .L*2 5 - * .L*4 6 - * .L*8 7 - */ - '(' reg LWID scale ')' - { - $$.type = $2; - $$.offset = $3+$4; - $$.sym = S; - } - -reg: - LAREG -| LDREG -| LTOS - -scale: - '*' con - { - switch($2) { - case 1: - $$ = 0; - break; - - case 2: - $$ = 1; - break; - - default: - yyerror("bad scale: %ld", $2); - - case 4: - $$ = 2; - break; - - case 8: - $$ = 3; - break; - } - } - -areg: - '(' LAREG ')' - { - $$.type = $2 | I_INDIR; - $$.sym = S; - $$.offset = 0; - } -| con '(' LAREG ')' - { - $$.type = $3 | I_INDIR; - $$.sym = S; - $$.offset = $1; - } -| '(' ')' - { - $$.type = D_NONE | I_INDIR; - $$.sym = S; - $$.offset = 0; - } -| con '(' ')' - { - $$.type = D_NONE | I_INDIR; - $$.sym = S; - $$.offset = $1; - } -| name - -name: - LNAME offset '(' pointer ')' - { - $$.type = $4; - $$.sym = $1; - $$.offset = $2; - } -| LNAME '<' '>' offset '(' LSB ')' - { - $$.type = D_STATIC; - $$.sym = $1; - $$.offset = $4; - } - -offset: - { - $$ = 0; - } -| '+' con - { - $$ = $2; - } -| '-' con - { - $$ = -$2; - } - -pointer: - LSB -| LSP -| LFP - -con: - LCONST -| LVAR - { - $$ = $1->value; - } -| '-' con - { - $$ = -$2; - } -| '+' con - { - $$ = $2; - } -| '~' con - { - $$ = ~$2; - } -| '(' expr ')' - { - $$ = $2; - } - -expr: - con -| expr '+' expr - { - $$ = $1 + $3; - } -| expr '-' expr - { - $$ = $1 - $3; - } -| expr '*' expr - { - $$ = $1 * $3; - } -| expr '/' expr - { - $$ = $1 / $3; - } -| expr '%' expr - { - $$ = $1 % $3; - } -| expr '<' '<' expr - { - $$ = $1 << $4; - } -| expr '>' '>' expr - { - $$ = $1 >> $4; - } -| expr '&' expr - { - $$ = $1 & $3; - } -| expr '^' expr - { - $$ = $1 ^ $3; - } -| expr '|' expr - { - $$ = $1 | $3; - } diff --git a/utils/2a/l.s b/utils/2a/l.s deleted file mode 100644 index 6f3cca3a..00000000 --- a/utils/2a/l.s +++ /dev/null @@ -1,479 +0,0 @@ - -/* - * Memory and machine-specific definitions. Used in C and assembler. - */ - -/* - * Sizes - */ - -#define BI2BY 8 /* bits per byte */ -#define BI2WD 32 /* bits per word */ -#define BY2WD 4 /* bytes per word */ -#define BY2PG 8192 /* bytes per page */ -#define WD2PG (BY2PG/BY2WD) /* words per page */ -#define PGSHIFT 13 /* log(BY2PG) */ -#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) -#define ICACHESIZE 0 -#define MB4 (4*1024*1024) /* Lots of things are 4Mb in size */ - -#define MAXMACH 1 /* max # cpus system can run */ - -/* - * Time - */ -#define HZ (60) /* clock frequency */ -#define MS2HZ (1000/HZ) /* millisec per clock tick */ -#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ -#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ -#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ - -/* - * SR bits - */ -#define SUPER 0x2000 -#define SPL(n) (n<<8) - -/* - * CACR - */ -#define CCLEAR 0x08 -#define CENABLE 0x01 - -/* - * Magic registers (unused in current system) - */ - -#define MACH A5 /* A5 is m-> */ -#define USER A4 /* A4 is u-> */ - -/* - * Fundamental addresses - */ - -#define USERADDR 0x80000000 -/* assuming we're in a syscall, this is the address of the Ureg structure */ -#define UREGVARSZ (23*BY2WD) /* size of variable part of Ureg */ -#define UREGADDR (USERADDR+BY2PG-(UREGVARSZ+2+4+2+(8+8+1+1)*BY2WD)) - -/* - * Devices poked during bootstrap - */ -#define TACADDR 0x40600000 -#define MOUSE 0x40200000 - -/* - * MMU - */ - -#define VAMASK 0xCFFFFFFF /* clear balu bits in address */ -#define KUSEG 0x00000000 -#define KSEG 0x80000000 - -/* - * MMU entries - */ -#define PTEVALID (1<<13) -#define PTEWRITE 0 -#define PTERONLY (1<<14) -#define PTEKERNEL (1<<15) -#define PTEUNCACHED 0 -#define INVALIDPTE 0 -#define PTEMAPMEM (1024*1024) -#define PTEPERTAB (PTEMAPMEM/BY2PG) -#define SEGMAPSIZE 16 - -#define PPN(pa) ((pa>>13)&0x1FFF) - -#define KMAP ((unsigned long *)0xD0000000) -#define UMAP ((unsigned long *)0x50000000) - -/* - * Virtual addresses - */ -#define VTAG(va) ((va>>22)&0x03F) -#define VPN(va) ((va>>13)&0x1FF) - -#define PARAM ((char*)0x40500000) -#define TLBFLUSH_ 0x01 - -/* - * Address spaces - */ - -#define UZERO KUSEG /* base of user address space */ -#define UTZERO (UZERO+BY2PG) /* first address in user text */ -#define TSTKTOP 0x10000000 /* end of new stack in sysexec */ -#define TSTKSIZ 100 -#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */ -#define KZERO KSEG /* base of kernel address space */ -#define KTZERO (KZERO+BY2PG) /* first address in kernel text */ -#define USTKSIZE (4*1024*1024) /* size of user stack */ - -#define MACHSIZE 4096 - - -#define isphys(p) ((((ulong)(p))&0xF0000000) == KSEG) -#define DBMAGIC 0xBADC0C0A - -/* - * Boot first processor - */ -TEXT start(SB), $-4 - - MOVW $(SUPER|SPL(7)), SR - MOVL $a6base(SB), A6 - MOVL $0, R0 - MOVL R0, CACR - MOVL R0, TACADDR /* zero tac counter (cause an intr?) */ - - MOVL $mach0(SB), A0 - MOVL A0, m(SB) - MOVL $0, 0(A0) - MOVL A0, A7 - ADDL $(MACHSIZE-4), A7 /* start stack under machine struct */ - MOVL $0, u(SB) - - MOVL $vectors(SB), A0 - MOVL A0, VBR - - BSR main(SB) - /* never returns */ -dead: - BRA dead - -/* - * Take first processor into user mode. Leave enough room on the stack - * for a full-sized Ureg (including long bus error format) to fit - */ - -TEXT touser(SB), $-4 - - MOVL $(USERADDR+BY2PG-UREGVARSZ), A7 - MOVW $0, -(A7) - MOVL $(UTZERO+32), -(A7) /* header is in text */ - MOVW $0, -(A7) - MOVL $(USTKTOP-6*BY2WD), A0 /* MAXSYSARG=6 */ - MOVL A0, USP - MOVW $(SUPER|SPL(0)), SR - MOVL $8, R0 - MOVL R0, CACR - RTE - -TEXT firmware(SB), $0 - - MOVL $0x40000090, A0 - JMP (A0) - -TEXT splhi(SB), $0 - - MOVL m(SB), A0 - MOVL (A7), 4(A0) - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(7)), SR - RTS - -TEXT splduart(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(5)), SR - RTS - -TEXT spllo(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(0)), SR - RTS - -TEXT splx(SB), $0 - - MOVL sr+0(FP), R0 - MOVW R0, SR - RTS - -TEXT spldone(SB), $0 - - RTS - -TEXT spl1(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(1)), SR - RTS - -TEXT flushcpucache(SB), $0 - - MOVL $(CCLEAR|CENABLE), R0 - MOVL R0, CACR - RTS - -TEXT cacrtrap(SB), $0 /* user entry point to control cache, e.g. flush */ - - MOVL R0, CACR - RTE - -TEXT setlabel(SB), $0 - - MOVL sr+0(FP), A0 - MOVL A7, (A0)+ /* stack pointer */ - MOVL (A7), (A0)+ /* pc of caller */ - MOVW SR, (A0)+ /* status register */ - CLRL R0 /* ret 0 => not returning */ - RTS - -TEXT gotolabel(SB), $0 - - MOVL p+0(FP), A0 - MOVW $(SUPER|SPL(7)), SR - MOVL (A0)+, A7 /* stack pointer */ - MOVL (A0)+, (A7) /* pc; stuff into stack frame */ - MOVW (A0)+, R0 /* status register */ - MOVW R0, SR - MOVL $1, R0 /* ret 1 => returning */ - RTS - -/* - * Test and set, as a subroutine - */ - -TEXT tas(SB), $0 - - MOVL $0, R0 - MOVL a+0(FP), A0 - TAS (A0) - BEQ tas_1 - MOVL $1, R0 -tas_1: - RTS - -/* - * Floating point - */ - -TEXT fpsave(SB), $0 - - FSAVE (fp+0(FP)) - RTS - -TEXT fprestore(SB), $0 - - FRESTORE (fp+0(FP)) - RTS - -TEXT fpregsave(SB), $0 - - FMOVEM $0xFF, (3*4)(fr+0(FP)) - FMOVEMC $0x7, (fr+0(FP)) - RTS - -TEXT fpregrestore(SB), $0 - - FMOVEMC (fr+0(FP)), $0x7 - FMOVEM (3*4)(fr+0(FP)), $0xFF - RTS - -TEXT fpcr(SB), $0 - - MOVL new+0(FP), R1 - MOVL FPCR, R0 - MOVL R1, FPCR - RTS - - -TEXT rfnote(SB), $0 - - MOVL uregp+0(FP), A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1+1)*BY2WD), A7 - RTE - -TEXT illegal(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR trap(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE - -TEXT systrap(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVL A6, ((8+6)*BY2WD)(A7) - MOVL R0, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR syscall(SB) - MOVL ((1+8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVL ((1+8+6)*BY2WD)(A7), A6 - ADDL $((1+8+8+1)*BY2WD+BY2WD), A7 - RTE - -TEXT buserror(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - PEA ((8+8+1+3)*BY2WD)(A7) - PEA 4(A7) - BSR fault68020(SB) - ADDL $8, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE - -TEXT tacintr(SB), $0 /* level 1 */ - - MOVL R0, -(A7) - MOVL TACADDR, R0 - MOVL (A7)+, R0 - RTE - -TEXT portintr(SB), $0 /* level 2 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR devportintr(SB) - BRA retintr - -TEXT dkintr(SB), $0 /* level 3 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR inconintr(SB) - BRA retintr - -TEXT mouseintr(SB), $0 /* level 4 */ - - MOVEM $0x80C2, -(A7) /* D0, A0, A1, A6 */ - MOVL $a6base(SB), A6 - MOVL $15, R0 /* mask off hex switch */ - ANDB MOUSE,R0 /* clears quadrature interrupt */ - LEA mousetab(SB)(R0.W*8), A0 - LEA mouse(SB), A1 - MOVL (A0)+, R0 - ADDL R0, (A1)+ /* dx */ - MOVL (A0), R0 - ADDL R0, (A1)+ /* dy */ - ADDL $1, (A1) /* track */ - MOVEM (A7)+, $0x4301 - RTE - -TEXT uartintr(SB), $0 /* level 5 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR duartintr(SB) - BRA retintr - -TEXT syncintr(SB), $0 /* level 6 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR clock(SB) - /* fall through */ -retintr: - BSR mousetry(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE - -GLOBL duarttimer+0(SB),$4 - -TEXT duartreadtimer+0(SB), $0 - MOVW SR, R1 /* spl7() */ - MOVW $0x2700, SR - MOVL $0x40100000, A0 - CLRL R0 - TSTB 15(A0) /* stop timer */ - MOVW 6(A0), R0 /* read hi,lo */ - TSTB 14(A0) /* restart timer */ - NOTW R0 /* timer counts down from 0xffff */ - ADDL duarttimer(SB), R0 - MOVL R0, duarttimer(SB) - MOVW R1, SR - RTS - -GLOBL mousetab(SB), $128 -DATA mousetab+ 0(SB)/4, -1 /* x down, */ -DATA mousetab+ 4(SB)/4, 1 /* y up */ -DATA mousetab+ 8(SB)/4, 0 /* x - */ -DATA mousetab+ 12(SB)/4, 1 /* y up */ -DATA mousetab+ 16(SB)/4, 1 /* x up */ -DATA mousetab+ 20(SB)/4, 1 /* y up */ -DATA mousetab+ 24(SB)/4, 0 /* x - */ -DATA mousetab+ 28(SB)/4, 1 /* y up */ -DATA mousetab+ 32(SB)/4, -1 /* x down */ -DATA mousetab+ 36(SB)/4, 0 /* y - */ -DATA mousetab+ 40(SB)/4, 0 /* x - */ -DATA mousetab+ 44(SB)/4, 0 /* y - */ -DATA mousetab+ 48(SB)/4, 1 /* x up, */ -DATA mousetab+ 52(SB)/4, 0 /* y - */ -DATA mousetab+ 56(SB)/4, 0 /* x - */ -DATA mousetab+ 60(SB)/4, 0 /* y - */ -DATA mousetab+ 64(SB)/4, -1 /* x down */ -DATA mousetab+ 68(SB)/4, -1 /* y down */ -DATA mousetab+ 72(SB)/4, 0 /* x - */ -DATA mousetab+ 76(SB)/4, -1 /* y down */ -DATA mousetab+ 80(SB)/4, 1 /* x up */ -DATA mousetab+ 84(SB)/4, -1 /* y down */ -DATA mousetab+ 88(SB)/4, 0 /* x - */ -DATA mousetab+ 92(SB)/4, -1 /* y down */ -DATA mousetab+ 96(SB)/4, -1 /* x down */ -DATA mousetab+100(SB)/4, 0 /* y - */ -DATA mousetab+104(SB)/4, 0 /* x - */ -DATA mousetab+108(SB)/4, 0 /* y - */ -DATA mousetab+112(SB)/4, 1 /* x up */ -DATA mousetab+116(SB)/4, 0 /* y - */ -DATA mousetab+120(SB)/4, 0 /* x - */ -DATA mousetab+124(SB)/4, 0 /* y - */ - -GLOBL mach0+0(SB), $MACHSIZE -GLOBL u(SB), $4 -GLOBL m(SB), $4 diff --git a/utils/2a/lex.c b/utils/2a/lex.c deleted file mode 100644 index 93ba0e2a..00000000 --- a/utils/2a/lex.c +++ /dev/null @@ -1,935 +0,0 @@ -#define EXTERN -#include "a.h" -#include "y.tab.h" -#include <ctype.h> - -void -main(int argc, char *argv[]) -{ - char *p; - int nout, nproc, status, i, c; - - thechar = '2'; - thestring = "68020"; - memset(debug, 0, sizeof(debug)); - cinit(); - outfile = 0; - include[ninclude++] = "."; - ARGBEGIN { - default: - c = ARGC(); - if(c >= 0 || c < sizeof(debug)) - debug[c] = 1; - break; - - case 'o': - outfile = ARGF(); - break; - - case 'D': - p = ARGF(); - if(p) - Dlist[nDlist++] = p; - break; - - case 'I': - p = ARGF(); - setinclude(p); - break; - } ARGEND - if(*argv == 0) { - print("usage: %ca [-options] file.s\n", thechar); - errorexit(); - } - if(argc > 1 && systemtype(Windows)){ - print("can't assemble multiple files on windows\n"); - errorexit(); - } - if(argc > 1 && !systemtype(Windows)) { - nproc = 1; - if(p = getenv("NPROC")) - nproc = atol(p); /* */ - c = 0; - nout = 0; - for(;;) { - while(nout < nproc && argc > 0) { - i = myfork(); - if(i < 0) { - i = mywait(&status); - if(i < 0) - errorexit(); - if(status) - c++; - nout--; - continue; - } - if(i == 0) { - print("%s:\n", *argv); - if(assemble(*argv)) - errorexit(); - exits(0); - } - nout++; - argc--; - argv++; - } - i = mywait(&status); - if(i < 0) { - if(c) - errorexit(); - exits(0); - } - if(status) - c++; - nout--; - } - } - if(assemble(argv[0])) - errorexit(); - exits(0); -} - -int -assemble(char *file) -{ - char ofile[100], incfile[20], *p; - int i, of; - - strcpy(ofile, file); - p = utfrrune(ofile, pathchar()); - if(p) { - include[0] = ofile; - *p++ = 0; - } else - p = ofile; - if(outfile == 0) { - outfile = p; - if(outfile){ - p = utfrrune(outfile, '.'); - if(p) - if(p[1] == 's' && p[2] == 0) - p[0] = 0; - p = utfrune(outfile, 0); - p[0] = '.'; - p[1] = thechar; - p[2] = 0; - } else - outfile = "/dev/null"; - } - p = getenv("INCLUDE"); - if(p) { - setinclude(p); - } else { - if(systemtype(Plan9)) { - sprint(incfile,"/%s/include", thestring); - setinclude(strdup(incfile)); - } - } - - of = mycreat(outfile, 0664); - if(of < 0) { - yyerror("%ca: cannot create %s", thechar, outfile); - errorexit(); - } - Binit(&obuf, of, OWRITE); - - pass = 1; - pinit(file); - for(i=0; i<nDlist; i++) - dodefine(Dlist[i]); - yyparse(); - if(nerrors) { - cclean(); - return nerrors; - } - - pass = 2; - outhist(); - pinit(file); - for(i=0; i<nDlist; i++) - dodefine(Dlist[i]); - yyparse(); - cclean(); - return nerrors; -} - -struct -{ - char *name; - ushort type; - ushort value; -} itab[] = -{ - "SP", LSP, D_AUTO, - "SB", LSB, D_EXTERN, - "FP", LFP, D_PARAM, - "PC", LPC, D_BRANCH, - "TOS", LTOS, D_TOS, - "CCR", LTOS, D_CCR, - "SR", LTOS, D_SR, - "SFC", LTOS, D_SFC, - "DFC", LTOS, D_DFC, - "CACR", LTOS, D_CACR, - "USP", LTOS, D_USP, - "VBR", LTOS, D_VBR, - "CAAR", LTOS, D_CAAR, - "MSP", LTOS, D_MSP, - "ISP", LTOS, D_ISP, - "FPCR", LTOS, D_FPCR, - "FPSR", LTOS, D_FPSR, - "FPIAR", LTOS, D_FPIAR, - "TC", LTOS, D_TC, - "ITT0", LTOS, D_ITT0, - "ITT1", LTOS, D_ITT1, - "DTT0", LTOS, D_DTT0, - "DTT1", LTOS, D_DTT1, - "MMUSR", LTOS, D_MMUSR, - "URP", LTOS, D_URP, - "SRP", LTOS, D_SRP, - - "R0", LDREG, D_R0+0, - "R1", LDREG, D_R0+1, - "R2", LDREG, D_R0+2, - "R3", LDREG, D_R0+3, - "R4", LDREG, D_R0+4, - "R5", LDREG, D_R0+5, - "R6", LDREG, D_R0+6, - "R7", LDREG, D_R0+7, - - ".W", LWID, 0, - ".L", LWID, 4, - - "A0", LAREG, D_A0+0, - "A1", LAREG, D_A0+1, - "A2", LAREG, D_A0+2, - "A3", LAREG, D_A0+3, - "A4", LAREG, D_A0+4, - "A5", LAREG, D_A0+5, - "A6", LAREG, D_A0+6, - "A7", LAREG, D_A0+7, - - "F0", LFREG, D_F0+0, - "F1", LFREG, D_F0+1, - "F2", LFREG, D_F0+2, - "F3", LFREG, D_F0+3, - "F4", LFREG, D_F0+4, - "F5", LFREG, D_F0+5, - "F6", LFREG, D_F0+6, - "F7", LFREG, D_F0+7, - - "ABCD", LTYPE1, AABCD, - "ADDB", LTYPE1, AADDB, - "ADDL", LTYPE1, AADDL, - "ADDW", LTYPE1, AADDW, - "ADDXB", LTYPE1, AADDXB, - "ADDXL", LTYPE1, AADDXL, - "ADDXW", LTYPE1, AADDXW, - "ADJSP", LTYPE5, AADJSP, - "ANDB", LTYPE1, AANDB, - "ANDL", LTYPE1, AANDL, - "ANDW", LTYPE1, AANDW, - "ASLB", LTYPE1, AASLB, - "ASLL", LTYPE1, AASLL, - "ASLW", LTYPE1, AASLW, - "ASRB", LTYPE1, AASRB, - "ASRL", LTYPE1, AASRL, - "ASRW", LTYPE1, AASRW, - "BCASE", LTYPE7, ABCASE, - "BCC", LTYPE6, ABCC, - "BCHG", LTYPE1, ABCHG, - "BCLR", LTYPE1, ABCLR, - "BCS", LTYPE6, ABCS, - "BEQ", LTYPE6, ABEQ, - "BFCHG", LTYPEA, ABFCHG, - "BFCLR", LTYPEA, ABFCLR, - "BFEXTS", LTYPEA, ABFEXTS, - "BFEXTU", LTYPEA, ABFEXTU, - "BFFFO", LTYPEA, ABFFFO, - "BFINS", LTYPEA, ABFINS, - "BFSET", LTYPEA, ABFSET, - "BFTST", LTYPEA, ABFTST, - "BGE", LTYPE6, ABGE, - "BGT", LTYPE6, ABGT, - "BHI", LTYPE6, ABHI, - "BKPT", LTYPE1, ABKPT, - "BLE", LTYPE6, ABLE, - "BLS", LTYPE6, ABLS, - "BLT", LTYPE6, ABLT, - "BMI", LTYPE6, ABMI, - "BNE", LTYPE6, ABNE, - "BPL", LTYPE6, ABPL, - "BRA", LTYPE6, ABRA, - "BSET", LTYPE1, ABSET, - "BSR", LTYPE3, ABSR, - "BTST", LTYPE1, ABTST, - "BVC", LTYPE6, ABVC, - "BVS", LTYPE6, ABVS, - "CALLM", LTYPE1, ACALLM, - "CAS2B", LTYPE1, ACAS2B, - "CAS2L", LTYPE1, ACAS2L, - "CAS2W", LTYPE1, ACAS2W, - "CASB", LTYPE1, ACASB, - "CASEW", LTYPE2, ACASEW, - "CASL", LTYPE1, ACASL, - "CASW", LTYPE1, ACASW, - "CHK2B", LTYPE1, ACHK2B, - "CHK2L", LTYPE1, ACHK2L, - "CHK2W", LTYPE1, ACHK2W, - "CHKL", LTYPE1, ACHKL, - "CHKW", LTYPE1, ACHKW, - "CLRB", LTYPE3, ACLRB, - "CLRL", LTYPE3, ACLRL, - "CLRW", LTYPE3, ACLRW, - "CMP2B", LTYPE1, ACMP2B, - "CMP2L", LTYPE1, ACMP2L, - "CMP2W", LTYPE1, ACMP2W, - "CMPB", LTYPE1, ACMPB, - "CMPL", LTYPE1, ACMPL, - "CMPW", LTYPE1, ACMPW, - "DATA", LTYPE4, ADATA, - "DBCC", LTYPE7, ADBCC, - "DBCS", LTYPE7, ADBCS, - "DBEQ", LTYPE7, ADBEQ, - "DBF", LTYPE7, ADBF, - "DBGE", LTYPE7, ADBGE, - "DBGT", LTYPE7, ADBGT, - "DBHI", LTYPE7, ADBHI, - "DBLE", LTYPE7, ADBLE, - "DBLS", LTYPE7, ADBLS, - "DBLT", LTYPE7, ADBLT, - "DBMI", LTYPE7, ADBMI, - "DBNE", LTYPE7, ADBNE, - "DBPL", LTYPE7, ADBPL, - "DBT", LTYPE7, ADBT, - "DBVC", LTYPE7, ADBVC, - "DBVS", LTYPE7, ADBVS, - "DIVSL", LTYPE1, ADIVSL, - "DIVSW", LTYPE1, ADIVSW, - "DIVUL", LTYPE1, ADIVUL, - "DIVUW", LTYPE1, ADIVUW, - "END", LTYPE2, AEND, - "EORB", LTYPE1, AEORB, - "EORL", LTYPE1, AEORL, - "EORW", LTYPE1, AEORW, - "EXG", LTYPE1, AEXG, - "EXTBL", LTYPE3, AEXTBL, - "EXTBW", LTYPE3, AEXTBW, - "EXTWL", LTYPE3, AEXTWL, - "FABSB", LTYPE1, AFABSB, - "FABSD", LTYPE1, AFABSD, - "FABSF", LTYPE1, AFABSF, - "FABSL", LTYPE1, AFABSL, - "FABSW", LTYPE1, AFABSW, - "FACOSB", LTYPE1, AFACOSB, - "FACOSD", LTYPE1, AFACOSD, - "FACOSF", LTYPE1, AFACOSF, - "FACOSL", LTYPE1, AFACOSL, - "FACOSW", LTYPE1, AFACOSW, - "FADDB", LTYPE1, AFADDB, - "FADDD", LTYPE1, AFADDD, - "FADDF", LTYPE1, AFADDF, - "FADDL", LTYPE1, AFADDL, - "FADDW", LTYPE1, AFADDW, - "FASINB", LTYPE1, AFASINB, - "FASIND", LTYPE1, AFASIND, - "FASINF", LTYPE1, AFASINF, - "FASINL", LTYPE1, AFASINL, - "FASINW", LTYPE1, AFASINW, - "FATANB", LTYPE1, AFATANB, - "FATAND", LTYPE1, AFATAND, - "FATANF", LTYPE1, AFATANF, - "FATANHB", LTYPE1, AFATANHB, - "FATANHD", LTYPE1, AFATANHD, - "FATANHF", LTYPE1, AFATANHF, - "FATANHL", LTYPE1, AFATANHL, - "FATANHW", LTYPE1, AFATANHW, - "FATANL", LTYPE1, AFATANL, - "FATANW", LTYPE1, AFATANW, - "FBEQ", LTYPE6, AFBEQ, - "FBF", LTYPE6, AFBF, - "FBGE", LTYPE6, AFBGE, - "FBGT", LTYPE6, AFBGT, - "FBLE", LTYPE6, AFBLE, - "FBLT", LTYPE6, AFBLT, - "FBNE", LTYPE6, AFBNE, - "FBT", LTYPE6, AFBT, - "FCMPB", LTYPE1, AFCMPB, - "FCMPD", LTYPE1, AFCMPD, - "FCMPF", LTYPE1, AFCMPF, - "FCMPL", LTYPE1, AFCMPL, - "FCMPW", LTYPE1, AFCMPW, - "FCOSB", LTYPE1, AFCOSB, - "FCOSD", LTYPE1, AFCOSD, - "FCOSF", LTYPE1, AFCOSF, - "FCOSHB", LTYPE1, AFCOSHB, - "FCOSHD", LTYPE1, AFCOSHD, - "FCOSHF", LTYPE1, AFCOSHF, - "FCOSHL", LTYPE1, AFCOSHL, - "FCOSHW", LTYPE1, AFCOSHW, - "FCOSL", LTYPE1, AFCOSL, - "FCOSW", LTYPE1, AFCOSW, - "FDBEQ", LTYPE7, AFDBEQ, - "FDBF", LTYPE7, AFDBF, - "FDBGE", LTYPE7, AFDBGE, - "FDBGT", LTYPE7, AFDBGT, - "FDBLE", LTYPE7, AFDBLE, - "FDBLT", LTYPE7, AFDBLT, - "FDBNE", LTYPE7, AFDBNE, - "FDBT", LTYPE7, AFDBT, - "FDIVB", LTYPE1, AFDIVB, - "FDIVD", LTYPE1, AFDIVD, - "FDIVF", LTYPE1, AFDIVF, - "FDIVL", LTYPE1, AFDIVL, - "FDIVW", LTYPE1, AFDIVW, - "FETOXB", LTYPE1, AFETOXB, - "FETOXD", LTYPE1, AFETOXD, - "FETOXF", LTYPE1, AFETOXF, - "FETOXL", LTYPE1, AFETOXL, - "FETOXM1B", LTYPE1, AFETOXM1B, - "FETOXM1D", LTYPE1, AFETOXM1D, - "FETOXM1F", LTYPE1, AFETOXM1F, - "FETOXM1L", LTYPE1, AFETOXM1L, - "FETOXM1W", LTYPE1, AFETOXM1W, - "FETOXW", LTYPE1, AFETOXW, - "FGETEXPB", LTYPE1, AFGETEXPB, - "FGETEXPD", LTYPE1, AFGETEXPD, - "FGETEXPF", LTYPE1, AFGETEXPF, - "FGETEXPL", LTYPE1, AFGETEXPL, - "FGETEXPW", LTYPE1, AFGETEXPW, - "FGETMANB", LTYPE1, AFGETMANB, - "FGETMAND", LTYPE1, AFGETMAND, - "FGETMANF", LTYPE1, AFGETMANF, - "FGETMANL", LTYPE1, AFGETMANL, - "FGETMANW", LTYPE1, AFGETMANW, - "FINTB", LTYPE1, AFINTB, - "FINTD", LTYPE1, AFINTD, - "FINTF", LTYPE1, AFINTF, - "FINTL", LTYPE1, AFINTL, - "FINTRZB", LTYPE1, AFINTRZB, - "FINTRZD", LTYPE1, AFINTRZD, - "FINTRZF", LTYPE1, AFINTRZF, - "FINTRZL", LTYPE1, AFINTRZL, - "FINTRZW", LTYPE1, AFINTRZW, - "FINTW", LTYPE1, AFINTW, - "FLOG10B", LTYPE1, AFLOG10B, - "FLOG10D", LTYPE1, AFLOG10D, - "FLOG10F", LTYPE1, AFLOG10F, - "FLOG10L", LTYPE1, AFLOG10L, - "FLOG10W", LTYPE1, AFLOG10W, - "FLOG2B", LTYPE1, AFLOG2B, - "FLOG2D", LTYPE1, AFLOG2D, - "FLOG2F", LTYPE1, AFLOG2F, - "FLOG2L", LTYPE1, AFLOG2L, - "FLOG2W", LTYPE1, AFLOG2W, - "FLOGNB", LTYPE1, AFLOGNB, - "FLOGND", LTYPE1, AFLOGND, - "FLOGNF", LTYPE1, AFLOGNF, - "FLOGNL", LTYPE1, AFLOGNL, - "FLOGNP1B", LTYPE1, AFLOGNP1B, - "FLOGNP1D", LTYPE1, AFLOGNP1D, - "FLOGNP1F", LTYPE1, AFLOGNP1F, - "FLOGNP1L", LTYPE1, AFLOGNP1L, - "FLOGNP1W", LTYPE1, AFLOGNP1W, - "FLOGNW", LTYPE1, AFLOGNW, - "FMODB", LTYPE1, AFMODB, - "FMODD", LTYPE1, AFMODD, - "FMODF", LTYPE1, AFMODF, - "FMODL", LTYPE1, AFMODL, - "FMODW", LTYPE1, AFMODW, - "FMOVEB", LTYPE1, AFMOVEB, - "FMOVED", LTYPE1, AFMOVED, - "FMOVEF", LTYPE1, AFMOVEF, - "FMOVEL", LTYPE1, AFMOVEL, - "FMOVEW", LTYPE1, AFMOVEW, - "FMULB", LTYPE1, AFMULB, - "FMULD", LTYPE1, AFMULD, - "FMULF", LTYPE1, AFMULF, - "FMULL", LTYPE1, AFMULL, - "FMULW", LTYPE1, AFMULW, - "FNEGB", LTYPE8, AFNEGB, - "FNEGD", LTYPE8, AFNEGD, - "FNEGF", LTYPE8, AFNEGF, - "FNEGL", LTYPE8, AFNEGL, - "FNEGW", LTYPE8, AFNEGW, - "FREMB", LTYPE1, AFREMB, - "FREMD", LTYPE1, AFREMD, - "FREMF", LTYPE1, AFREMF, - "FREML", LTYPE1, AFREML, - "FREMW", LTYPE1, AFREMW, - "FSCALEB", LTYPE1, AFSCALEB, - "FSCALED", LTYPE1, AFSCALED, - "FSCALEF", LTYPE1, AFSCALEF, - "FSCALEL", LTYPE1, AFSCALEL, - "FSCALEW", LTYPE1, AFSCALEW, - "FSEQ", LTYPE1, AFSEQ, - "FSF", LTYPE1, AFSF, - "FSGE", LTYPE1, AFSGE, - "FSGT", LTYPE1, AFSGT, - "FSINB", LTYPE1, AFSINB, - "FSIND", LTYPE1, AFSIND, - "FSINF", LTYPE1, AFSINF, - "FSINHB", LTYPE1, AFSINHB, - "FSINHD", LTYPE1, AFSINHD, - "FSINHF", LTYPE1, AFSINHF, - "FSINHL", LTYPE1, AFSINHL, - "FSINHW", LTYPE1, AFSINHW, - "FSINL", LTYPE1, AFSINL, - "FSINW", LTYPE1, AFSINW, - "FSLE", LTYPE1, AFSLE, - "FSLT", LTYPE1, AFSLT, - "FSNE", LTYPE1, AFSNE, - "FSQRTB", LTYPE1, AFSQRTB, - "FSQRTD", LTYPE1, AFSQRTD, - "FSQRTF", LTYPE1, AFSQRTF, - "FSQRTL", LTYPE1, AFSQRTL, - "FSQRTW", LTYPE1, AFSQRTW, - "FST", LTYPE1, AFST, - "FSUBB", LTYPE1, AFSUBB, - "FSUBD", LTYPE1, AFSUBD, - "FSUBF", LTYPE1, AFSUBF, - "FSUBL", LTYPE1, AFSUBL, - "FSUBW", LTYPE1, AFSUBW, - "FTANB", LTYPE1, AFTANB, - "FTAND", LTYPE1, AFTAND, - "FTANF", LTYPE1, AFTANF, - "FTANHB", LTYPE1, AFTANHB, - "FTANHD", LTYPE1, AFTANHD, - "FTANHF", LTYPE1, AFTANHF, - "FTANHL", LTYPE1, AFTANHL, - "FTANHW", LTYPE1, AFTANHW, - "FTANL", LTYPE1, AFTANL, - "FTANW", LTYPE1, AFTANW, - "FTENTOXB", LTYPE1, AFTENTOXB, - "FTENTOXD", LTYPE1, AFTENTOXD, - "FTENTOXF", LTYPE1, AFTENTOXF, - "FTENTOXL", LTYPE1, AFTENTOXL, - "FTENTOXW", LTYPE1, AFTENTOXW, - "FTSTB", LTYPE1, AFTSTB, - "FTSTD", LTYPE1, AFTSTD, - "FTSTF", LTYPE1, AFTSTF, - "FTSTL", LTYPE1, AFTSTL, - "FTSTW", LTYPE1, AFTSTW, - "FTWOTOXB", LTYPE1, AFTWOTOXB, - "FTWOTOXD", LTYPE1, AFTWOTOXD, - "FTWOTOXF", LTYPE1, AFTWOTOXF, - "FTWOTOXL", LTYPE1, AFTWOTOXL, - "FTWOTOXW", LTYPE1, AFTWOTOXW, - "FMOVEM", LTYPE1, AFMOVEM, - "FMOVEMC", LTYPE1, AFMOVEMC, - "FRESTORE", LTYPE3, AFRESTORE, - "FSAVE", LTYPE3, AFSAVE, - "GLOBL", LTYPE1, AGLOBL, - "GOK", LTYPE2, AGOK, - "HISTORY", LTYPE2, AHISTORY, - "ILLEG", LTYPE2, AILLEG, - "INSTR", LTYPE3, AINSTR, - "JMP", LTYPE3, AJMP, - "JSR", LTYPE3, AJSR, - "LEA", LTYPE1, ALEA, - "LINKL", LTYPE1, ALINKL, - "LINKW", LTYPE1, ALINKW, - "LOCATE", LTYPE1, ALOCATE, - "LONG", LTYPE3, ALONG, - "LSLB", LTYPE1, ALSLB, - "LSLL", LTYPE1, ALSLL, - "LSLW", LTYPE1, ALSLW, - "LSRB", LTYPE1, ALSRB, - "LSRL", LTYPE1, ALSRL, - "LSRW", LTYPE1, ALSRW, - "MOVB", LTYPE1, AMOVB, - "MOVEM", LTYPE1, AMOVEM, - "MOVEPL", LTYPE1, AMOVEPL, - "MOVEPW", LTYPE1, AMOVEPW, - "MOVESB", LTYPE1, AMOVESB, - "MOVESL", LTYPE1, AMOVESL, - "MOVESW", LTYPE1, AMOVESW, - "MOVL", LTYPE1, AMOVL, - "MOVW", LTYPE1, AMOVW, - "MULSL", LTYPE1, AMULSL, - "MULSW", LTYPE1, AMULSW, - "MULUL", LTYPE1, AMULUL, - "MULUW", LTYPE1, AMULUW, - "NAME", LTYPE1, ANAME, - "NBCD", LTYPE3, ANBCD, - "NEGB", LTYPE3, ANEGB, - "NEGL", LTYPE3, ANEGL, - "NEGW", LTYPE3, ANEGW, - "NEGXB", LTYPE3, ANEGXB, - "NEGXL", LTYPE3, ANEGXL, - "NEGXW", LTYPE3, ANEGXW, - "NOP", LTYPE9, ANOP, - "NOTB", LTYPE3, ANOTB, - "NOTL", LTYPE3, ANOTL, - "NOTW", LTYPE3, ANOTW, - "ORB", LTYPE1, AORB, - "ORL", LTYPE1, AORL, - "ORW", LTYPE1, AORW, - "PACK", LTYPE1, APACK, - "PEA", LTYPE3, APEA, - "RESET", LTYPE2, ARESET, - "ROTLB", LTYPE1, AROTLB, - "ROTLL", LTYPE1, AROTLL, - "ROTLW", LTYPE1, AROTLW, - "ROTRB", LTYPE1, AROTRB, - "ROTRL", LTYPE1, AROTRL, - "ROTRW", LTYPE1, AROTRW, - "ROXLB", LTYPE1, AROXLB, - "ROXLL", LTYPE1, AROXLL, - "ROXLW", LTYPE1, AROXLW, - "ROXRB", LTYPE1, AROXRB, - "ROXRL", LTYPE1, AROXRL, - "ROXRW", LTYPE1, AROXRW, - "RTD", LTYPE3, ARTD, - "RTE", LTYPE2, ARTE, - "RTM", LTYPE3, ARTM, - "RTR", LTYPE2, ARTR, - "RTS", LTYPE2, ARTS, - "SBCD", LTYPE1, ASBCD, - "SCC", LTYPE3, ASCC, - "SCS", LTYPE3, ASCS, - "SEQ", LTYPE3, ASEQ, - "SF", LTYPE3, ASF, - "SGE", LTYPE3, ASGE, - "SGT", LTYPE3, ASGT, - "SHI", LTYPE3, ASHI, - "SLE", LTYPE3, ASLE, - "SLS", LTYPE3, ASLS, - "SLT", LTYPE3, ASLT, - "SMI", LTYPE3, ASMI, - "SNE", LTYPE3, ASNE, - "SPL", LTYPE3, ASPL, - "ST", LTYPE3, AST, - "STOP", LTYPE3, ASTOP, - "SUBB", LTYPE1, ASUBB, - "SUBL", LTYPE1, ASUBL, - "SUBW", LTYPE1, ASUBW, - "SUBXB", LTYPE1, ASUBXB, - "SUBXL", LTYPE1, ASUBXL, - "SUBXW", LTYPE1, ASUBXW, - "SVC", LTYPE2, ASVC, - "SVS", LTYPE2, ASVS, - "SWAP", LTYPE3, ASWAP, - "SYS", LTYPE2, ASYS, - "TAS", LTYPE3, ATAS, - "TEXT", LTYPEB, ATEXT, - "TRAP", LTYPE3, ATRAP, - "TRAPCC", LTYPE2, ATRAPCC, - "TRAPCS", LTYPE2, ATRAPCS, - "TRAPEQ", LTYPE2, ATRAPEQ, - "TRAPF", LTYPE2, ATRAPF, - "TRAPGE", LTYPE2, ATRAPGE, - "TRAPGT", LTYPE2, ATRAPGT, - "TRAPHI", LTYPE2, ATRAPHI, - "TRAPLE", LTYPE2, ATRAPLE, - "TRAPLS", LTYPE2, ATRAPLS, - "TRAPLT", LTYPE2, ATRAPLT, - "TRAPMI", LTYPE2, ATRAPMI, - "TRAPNE", LTYPE2, ATRAPNE, - "TRAPPL", LTYPE2, ATRAPPL, - "TRAPT", LTYPE2, ATRAPT, - "TRAPV", LTYPE2, ATRAPV, - "TRAPVC", LTYPE2, ATRAPVC, - "TRAPVS", LTYPE2, ATRAPVS, - "TSTB", LTYPE3, ATSTB, - "TSTL", LTYPE3, ATSTL, - "TSTW", LTYPE3, ATSTW, - "UNLK", LTYPE3, AUNLK, - "UNPK", LTYPE1, AUNPK, - "WORD", LTYPE3, AWORD, - - 0 -}; - -void -cinit(void) -{ - Sym *s; - int i; - - nullgen.s0.sym = S; - nullgen.s0.offset = 0; - nullgen.type = D_NONE; - if(FPCHIP) - nullgen.dval = 0; - for(i=0; i<sizeof(nullgen.sval); i++) - nullgen.sval[i] = 0; - nullgen.displace = 0; - nullgen.type = D_NONE; - nullgen.index = D_NONE; - nullgen.scale = 0; - nullgen.field = 0; - - nerrors = 0; - iostack = I; - iofree = I; - peekc = IGN; - nhunk = 0; - for(i=0; i<NHASH; i++) - hash[i] = S; - for(i=0; itab[i].name; i++) { - s = slookup(itab[i].name); - s->type = itab[i].type; - s->value = itab[i].value; - } - - pathname = allocn(pathname, 0, 100); - if(mygetwd(pathname, 99) == 0) { - pathname = allocn(pathname, 100, 900); - if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); - } -} - -void -syminit(Sym *s) -{ - - s->type = LNAME; - s->value = 0; -} - -void -cclean(void) -{ - Gen2 g2; - - g2.from = nullgen; - g2.to = nullgen; - outcode(AEND, &g2); - Bflush(&obuf); -} - -void -zname(char *n, int t, int s) -{ - - Bputc(&obuf, ANAME); /* as */ - Bputc(&obuf, ANAME>>8); - Bputc(&obuf, t); /* type */ - Bputc(&obuf, s); /* sym */ - while(*n) { - Bputc(&obuf, *n); - n++; - } - Bputc(&obuf, 0); -} - -void -zaddr(Gen *a, int s) -{ - long l; - int i, t; - char *n; - Ieee e; - - t = 0; - if(a->field) - t |= T_FIELD; - if(a->index != D_NONE || a->displace != 0) - t |= T_INDEX; - if(a->s0.offset != 0) - t |= T_OFFSET; - if(s != 0) - t |= T_SYM; - - if(a->type == D_FCONST) - t |= T_FCONST; - else - if(a->type == D_SCONST) - t |= T_SCONST; - else - if(a->type & ~0xff) - t |= T_TYPE; - Bputc(&obuf, t); - - if(t & T_FIELD) { /* implies field */ - i = a->field; - Bputc(&obuf, i); - Bputc(&obuf, i>>8); - } - if(t & T_INDEX) { /* implies index, scale, displace */ - i = a->index; - Bputc(&obuf, i); - Bputc(&obuf, i>>8); - Bputc(&obuf, a->scale); - l = a->displace; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - } - if(t & T_OFFSET) { /* implies offset */ - l = a->s0.offset; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - } - if(t & T_SYM) /* implies sym */ - Bputc(&obuf, s); - if(t & T_FCONST) { - ieeedtod(&e, a->dval); - l = e.l; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - l = e.h; - Bputc(&obuf, l); - Bputc(&obuf, l>>8); - Bputc(&obuf, l>>16); - Bputc(&obuf, l>>24); - return; - } - if(t & T_SCONST) { - n = a->sval; - for(i=0; i<NSNAME; i++) { - Bputc(&obuf, *n); - n++; - } - return; - } - i = a->type; - Bputc(&obuf, i); - if(t & T_TYPE) - Bputc(&obuf, i>>8); -} - -void -outcode(int a, Gen2 *g2) -{ - int sf, st, t; - Sym *s; - - if(pass == 1) - goto out; - -jackpot: - sf = 0; - s = g2->from.s0.sym; - while(s != S) { - sf = s->sym; - if(sf < 0 || sf >= NSYM) - sf = 0; - t = g2->from.type & D_MASK; - if(h[sf].type == t) - if(h[sf].sym == s) - break; - zname(s->name, t, sym); - s->sym = sym; - h[sym].sym = s; - h[sym].type = t; - sf = sym; - sym++; - if(sym >= NSYM) - sym = 1; - break; - } - st = 0; - s = g2->to.s0.sym; - while(s != S) { - st = s->sym; - if(st < 0 || st >= NSYM) - st = 0; - t = g2->to.type & D_MASK; - if(h[st].type == t) - if(h[st].sym == s) - break; - zname(s->name, t, sym); - s->sym = sym; - h[sym].sym = s; - h[sym].type = t; - st = sym; - sym++; - if(sym >= NSYM) - sym = 1; - if(st == sf) - goto jackpot; - break; - } - Bputc(&obuf, a); - Bputc(&obuf, a>>8); - Bputc(&obuf, lineno); - Bputc(&obuf, lineno>>8); - Bputc(&obuf, lineno>>16); - Bputc(&obuf, lineno>>24); - zaddr(&g2->from, sf); - zaddr(&g2->to, st); - -out: - if(a != AGLOBL && a != ADATA) - pc++; -} - -void -outhist(void) -{ - Gen g; - Hist *h; - char *p, *q, *op, c; - int n; - - g = nullgen; - c = pathchar(); - for(h = hist; h != H; h = h->link) { - p = h->name; - op = 0; - /* on windows skip drive specifier in pathname */ - if(systemtype(Windows) && p && p[1] == ':'){ - p += 2; - c = *p; - } - if(p && p[0] != c && h->offset == 0 && pathname){ - /* on windows skip drive specifier in pathname */ - if(systemtype(Windows) && pathname[1] == ':') { - op = p; - p = pathname+2; - c = *p; - } else if(pathname[0] == c){ - op = p; - p = pathname; - } - } - while(p) { - q = strchr(p, c); - if(q) { - n = q-p; - if(n == 0){ - n = 1; /* leading "/" */ - *p = '/'; /* don't emit "\" on windows */ - } - q++; - } else { - n = strlen(p); - q = 0; - } - if(n) { - Bputc(&obuf, ANAME); - Bputc(&obuf, ANAME>>8); - Bputc(&obuf, D_FILE); /* type */ - Bputc(&obuf, 1); /* sym */ - Bputc(&obuf, '<'); - Bwrite(&obuf, p, n); - Bputc(&obuf, 0); - } - p = q; - if(p == 0 && op) { - p = op; - op = 0; - } - } - g.s0.offset = h->offset; - - Bputc(&obuf, AHISTORY); - Bputc(&obuf, AHISTORY>>8); - Bputc(&obuf, h->line); - Bputc(&obuf, h->line>>8); - Bputc(&obuf, h->line>>16); - Bputc(&obuf, h->line>>24); - zaddr(&nullgen, 0); - zaddr(&g, 0); - } -} - -#include "../cc/lexbody" -#include "../cc/macbody" diff --git a/utils/2a/mkfile b/utils/2a/mkfile deleted file mode 100644 index 2cf27e17..00000000 --- a/utils/2a/mkfile +++ /dev/null @@ -1,30 +0,0 @@ -<../../mkconfig - -TARG=2a - -OFILES=\ - y.tab.$O\ - lex.$O\ - -HFILES=\ - ../2c/2.out.h\ - y.tab.h\ - a.h\ - -YFILES=a.y\ - -LIBS=cc bio 9 # order is important - -BIN=$ROOT/$OBJDIR/bin - -<$ROOT/mkfiles/mkone-$SHELLTYPE - -YFLAGS=-D1 -d -CFLAGS= $CFLAGS -I../include - -lex.$O: ../cc/macbody ../cc/lexbody - -$ROOT/$OBJDIR/lib/libcc.a: - cd ../cc - mk $MKFLAGS install - mk $MKFLAGS clean diff --git a/utils/2c/2.out.h b/utils/2c/2.out.h deleted file mode 100644 index 0cf36f82..00000000 --- a/utils/2c/2.out.h +++ /dev/null @@ -1,523 +0,0 @@ -#define NSYM 50 -#define NSNAME 8 - -/* R0 is return */ -#define REGEXT 7 -/* A7 is sp A6 is sb */ -#define AREGEXT 5 -/* F0 is ret */ -#define FREGEXT 7 - -enum as -{ - AXXX = 0, - AABCD, - AADDB, - AADDL, - AADDW, - AADDXB, - AADDXL, - AADDXW, - AADJSP, - AANDB, - AANDL, - AANDW, - AASLB, - AASLL, - AASLW, - AASRB, - AASRL, - AASRW, - ABCASE, - ABCC, - ABCHG, - ABCLR, - ABCS, - ABEQ, - ABFCHG, - ABFCLR, - ABFEXTS, - ABFEXTU, - ABFFFO, - ABFINS, - ABFSET, - ABFTST, - ABGE, - ABGT, - ABHI, - ABKPT, - ABLE, - ABLS, - ABLT, - ABMI, - ABNE, - ABPL, - ABRA, - ABSET, - ABSR, - ABTST, - ABVC, - ABVS, - ACALLM, - ACAS2B, - ACAS2L, - ACAS2W, - ACASB, - ACASEW, - ACASL, - ACASW, - ACHK2B, - ACHK2L, - ACHK2W, - ACHKL, - ACHKW, - ACLRB, - ACLRL, - ACLRW, - ACMP2B, - ACMP2L, - ACMP2W, - ACMPB, - ACMPL, - ACMPW, - ADATA, - ADBCC, - ADBCS, - ADBEQ, - ADBF, - ADBGE, - ADBGT, - ADBHI, - ADBLE, - ADBLS, - ADBLT, - ADBMI, - ADBNE, - ADBPL, - ADBT, - ADBVC, - ADBVS, - ADIVSL, - ADIVSW, - ADIVUL, - ADIVUW, - AEND, - AEORB, - AEORL, - AEORW, - AEXG, - AEXTBL, - AEXTBW, - AEXTWL, - AFABSB, - AFABSD, - AFABSF, - AFABSL, - AFABSW, - AFACOSB, - AFACOSD, - AFACOSF, - AFACOSL, - AFACOSW, - AFADDB, - AFADDD, - AFADDF, - AFADDL, - AFADDW, - AFASINB, - AFASIND, - AFASINF, - AFASINL, - AFASINW, - AFATANB, - AFATAND, - AFATANF, - AFATANHB, - AFATANHD, - AFATANHF, - AFATANHL, - AFATANHW, - AFATANL, - AFATANW, - AFBEQ, - AFBF, - AFBGE, - AFBGT, - AFBLE, - AFBLT, - AFBNE, - AFBT, - AFCMPB, - AFCMPD, - AFCMPF, - AFCMPL, - AFCMPW, - AFCOSB, - AFCOSD, - AFCOSF, - AFCOSHB, - AFCOSHD, - AFCOSHF, - AFCOSHL, - AFCOSHW, - AFCOSL, - AFCOSW, - AFDBEQ, - AFDBF, - AFDBGE, - AFDBGT, - AFDBLE, - AFDBLT, - AFDBNE, - AFDBT, - AFDIVB, - AFDIVD, - AFDIVF, - AFDIVL, - AFDIVW, - AFETOXB, - AFETOXD, - AFETOXF, - AFETOXL, - AFETOXM1B, - AFETOXM1D, - AFETOXM1F, - AFETOXM1L, - AFETOXM1W, - AFETOXW, - AFGETEXPB, - AFGETEXPD, - AFGETEXPF, - AFGETEXPL, - AFGETEXPW, - AFGETMANB, - AFGETMAND, - AFGETMANF, - AFGETMANL, - AFGETMANW, - AFINTB, - AFINTD, - AFINTF, - AFINTL, - AFINTRZB, - AFINTRZD, - AFINTRZF, - AFINTRZL, - AFINTRZW, - AFINTW, - AFLOG10B, - AFLOG10D, - AFLOG10F, - AFLOG10L, - AFLOG10W, - AFLOG2B, - AFLOG2D, - AFLOG2F, - AFLOG2L, - AFLOG2W, - AFLOGNB, - AFLOGND, - AFLOGNF, - AFLOGNL, - AFLOGNP1B, - AFLOGNP1D, - AFLOGNP1F, - AFLOGNP1L, - AFLOGNP1W, - AFLOGNW, - AFMODB, - AFMODD, - AFMODF, - AFMODL, - AFMODW, - AFMOVEB, - AFMOVED, - AFMOVEF, - AFMOVEL, - AFMOVEM, - AFMOVEMC, - AFMOVEW, - AFMULB, - AFMULD, - AFMULF, - AFMULL, - AFMULW, - AFNEGB, - AFNEGD, - AFNEGF, - AFNEGL, - AFNEGW, - AFREMB, - AFREMD, - AFREMF, - AFREML, - AFREMW, - AFRESTORE, - AFSAVE, - AFSCALEB, - AFSCALED, - AFSCALEF, - AFSCALEL, - AFSCALEW, - AFSEQ, - AFSF, - AFSGE, - AFSGT, - AFSINB, - AFSIND, - AFSINF, - AFSINHB, - AFSINHD, - AFSINHF, - AFSINHL, - AFSINHW, - AFSINL, - AFSINW, - AFSLE, - AFSLT, - AFSNE, - AFSQRTB, - AFSQRTD, - AFSQRTF, - AFSQRTL, - AFSQRTW, - AFST, - AFSUBB, - AFSUBD, - AFSUBF, - AFSUBL, - AFSUBW, - AFTANB, - AFTAND, - AFTANF, - AFTANHB, - AFTANHD, - AFTANHF, - AFTANHL, - AFTANHW, - AFTANL, - AFTANW, - AFTENTOXB, - AFTENTOXD, - AFTENTOXF, - AFTENTOXL, - AFTENTOXW, - AFTSTB, - AFTSTD, - AFTSTF, - AFTSTL, - AFTSTW, - AFTWOTOXB, - AFTWOTOXD, - AFTWOTOXF, - AFTWOTOXL, - AFTWOTOXW, - AGLOBL, - AGOK, - AHISTORY, - AILLEG, - AINSTR, - AJMP, - AJSR, - ALEA, - ALINKL, - ALINKW, - ALOCATE, - ALONG, - ALSLB, - ALSLL, - ALSLW, - ALSRB, - ALSRL, - ALSRW, - AMOVB, - AMOVEM, - AMOVEPL, - AMOVEPW, - AMOVESB, - AMOVESL, - AMOVESW, - AMOVL, - AMOVW, - AMULSL, - AMULSW, - AMULUL, - AMULUW, - ANAME, - ANBCD, - ANEGB, - ANEGL, - ANEGW, - ANEGXB, - ANEGXL, - ANEGXW, - ANOP, - ANOTB, - ANOTL, - ANOTW, - AORB, - AORL, - AORW, - APACK, - APEA, - ARESET, - AROTLB, - AROTLL, - AROTLW, - AROTRB, - AROTRL, - AROTRW, - AROXLB, - AROXLL, - AROXLW, - AROXRB, - AROXRL, - AROXRW, - ARTD, - ARTE, - ARTM, - ARTR, - ARTS, - ASBCD, - ASCC, - ASCS, - ASEQ, - ASF, - ASGE, - ASGT, - ASHI, - ASLE, - ASLS, - ASLT, - ASMI, - ASNE, - ASPL, - AST, - ASTOP, - ASUBB, - ASUBL, - ASUBW, - ASUBXB, - ASUBXL, - ASUBXW, - ASVC, - ASVS, - ASWAP, - ASYS, - ATAS, - ATEXT, - ATRAP, - ATRAPCC, - ATRAPCS, - ATRAPEQ, - ATRAPF, - ATRAPGE, - ATRAPGT, - ATRAPHI, - ATRAPLE, - ATRAPLS, - ATRAPLT, - ATRAPMI, - ATRAPNE, - ATRAPPL, - ATRAPT, - ATRAPV, - ATRAPVC, - ATRAPVS, - ATSTB, - ATSTL, - ATSTW, - AUNLK, - AUNPK, - AWORD, - ASIGNAME, - - ALAST -}; - -enum -{ - NREG = 8, - - D_R0 = 0, - D_A0 = NREG, - D_F0 = D_A0+NREG, - D_NONE = D_F0+NREG, - D_TOS, - D_BRANCH, - D_STACK, - D_TREE, - D_EXTERN, - D_STATIC, - D_AUTO, - D_PARAM, - D_CONST, - D_FCONST, - D_QUICK, - - D_CCR, - D_SR, - D_SFC, - D_CACR, - D_USP, - D_VBR, - D_CAAR, - D_MSP, - D_ISP, - D_DFC, - D_FPCR, - D_FPSR, - D_FPIAR, - D_SCONST, - D_FILE, - - D_TC, /* new for 68040 */ - D_ITT0, - D_ITT1, - D_DTT0, - D_DTT1, - D_MMUSR, - D_URP, - D_SRP, - - D_FILE1, - - D_MASK = 63/(D_SRP>=63?0:1), - - I_DIR = (D_MASK+1)*0, - I_INDINC = (D_MASK+1)*1, - I_INDDEC = (D_MASK+1)*2, - I_INDIR = (D_MASK+1)*3, - I_ADDR = (D_MASK+1)*4, - - I_INDEX1 = (D_MASK+1)*1, - I_INDEX2 = (D_MASK+1)*2, - I_INDEX3 = (D_MASK+1)*3, - - I_MASK = (D_MASK+1)*7, - - T_FIELD = 1<<0, - T_INDEX = 1<<1, - T_TYPE = 1<<2, - T_OFFSET = 1<<3, - T_FCONST = 1<<4, - T_SYM = 1<<5, - T_SCONST = 1<<6 -}; - -/* - * this is the ranlib header - */ -#define SYMDEF "__.SYMDEF" - -/* - * this is the simulated IEEE floating point - */ -typedef struct ieee Ieee; -struct ieee -{ - long l; /* contains ls-man 0xffffffff */ - long h; /* contains sign 0x80000000 - exp 0x7ff00000 - ms-man 0x000fffff */ -}; diff --git a/utils/2c/Update b/utils/2c/Update deleted file mode 100644 index 65024dfe..00000000 --- a/utils/2c/Update +++ /dev/null @@ -1,7 +0,0 @@ - if(n->op == ONAME) { -< if(o == OSET) -< gopcode(OTST, tint, D_NONE, Z, D_TREE, n); -< else -< gopcode(OTST, tint, D_TREE, n, D_NONE, Z); -< p->as = ANOP; -< } diff --git a/utils/2c/cgen.c b/utils/2c/cgen.c deleted file mode 100644 index 3c1d4b3d..00000000 --- a/utils/2c/cgen.c +++ /dev/null @@ -1,1404 +0,0 @@ -#include "gc.h" - -void -cgen(Node *n, int result, Node *nn) -{ - Node *l, *r, nod; - int lg, rg, xg, yg, g, o; - long v; - Prog *p1; - - if(n == Z || n->type == T) - return; - if(typesuv[n->type->etype]) { - sugen(n, result, nn, n->type->width); - return; - } - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R\n", result); - prtree(n, "cgen"); - } - l = n->left; - r = n->right; - o = n->op; - if(n->addable >= INDEXED) { - if(result == D_NONE) { - if(nn == Z) - switch(o) { - default: - nullwarn(Z, Z); - break; - case OINDEX: - nullwarn(l, r); - break; - } - return; - } - gmove(n->type, nn->type, D_TREE, n, result, nn); - return; - } - - v = 0; /* set */ - switch(o) { - default: - diag(n, "unknown op in cgen: %O", o); - break; - - case OAS: - if(l->op == OBIT) - goto bitas; - /* - * recursive use of result - */ - if(result == D_NONE) - if(l->addable > INDEXED) - if(l->complex < FNX) { - cgen(r, D_TREE, l); - break; - } - - /* - * function calls on both sides - */ - if(l->complex >= FNX && r->complex >= FNX) { - cgen(r, D_TOS, r); - v = argoff; - lg = regaddr(result); - lcgen(l, lg, Z); - lg |= I_INDIR; - adjsp(v - argoff); - gmove(r->type, l->type, D_TOS, r, lg, l); - if(result != D_NONE) - gmove(l->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - } - - rg = D_TREE; - lg = D_TREE; - if(r->complex >= l->complex) { - /* - * right side before left - */ - if(result != D_NONE) { - rg = regalloc(n->type, result); - cgen(r, rg, n); - } else - if(r->complex >= FNX || r->addable < INDEXED) { - rg = regalloc(r->type, result); - cgen(r, rg, r); - } - if(l->addable < INDEXED) { - lg = regaddr(lg); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - } else { - /* - * left before right - */ - if(l->complex >= FNX || l->addable < INDEXED) { - lg = regaddr(lg); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - if(result != D_NONE) { - rg = regalloc(n->type, result); - cgen(r, rg, n); - } else - if(r->addable < INDEXED) { - rg = regalloc(r->type, result); - cgen(r, rg, r); - } - } - if(result != D_NONE) { - gmove(n->type, l->type, rg, r, lg, l); - gmove(n->type, nn->type, rg, r, result, nn); - } else - gmove(r->type, l->type, rg, r, lg, l); - regfree(lg); - regfree(rg); - break; - - bitas: - n = l->left; - rg = regalloc(tfield, result); - if(l->complex >= r->complex) { - lg = regaddr(D_NONE); - lcgen(n, lg, Z); - lg |= I_INDIR; - cgen(r, rg, r); - } else { - cgen(r, rg, r); - lg = regaddr(D_NONE); - lcgen(n, lg, Z); - lg |= I_INDIR; - } - g = regalloc(n->type, D_NONE); - gmove(l->type, l->type, lg, l, g, l); - bitstore(l, rg, lg, g, result, nn); - break; - - case OBIT: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - g = bitload(n, D_NONE, D_NONE, result, nn); - gopcode(OAS, nn->type, g, n, result, nn); - regfree(g); - break; - - case ODOT: - sugen(l, D_TREE, nodrat, l->type->width); - if(result != D_NONE) { - warn(n, "non-interruptable temporary"); - nod = *nodrat; - if(!r || r->op != OCONST) { - diag(n, "DOT and no offset"); - break; - } - nod.xoffset += r->vconst; - nod.type = n->type; - cgen(&nod, result, nn); - } - break; - - case OASLDIV: - case OASLMOD: - case OASDIV: - case OASMOD: - if(l->op == OBIT) - goto asbitop; - if(typefd[n->type->etype]) - goto asbinop; - rg = D_TREE; - if(l->complex >= FNX || r->complex >= FNX) { - rg = D_TOS; - cgen(r, rg, r); - v = argoff; - } else - if(r->addable < INDEXED) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - lg = D_TREE; - if(!simplv(l)) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); /* destroys register optimization */ - lg |= I_INDIR; - } - g = regpair(result); - gmove(l->type, n->type, lg, l, g, n); - if(rg == D_TOS) - adjsp(v - argoff); - gopcode(o, n->type, rg, r, g, n); - if(o == OASLMOD || o == OASMOD) - gmove(n->type, l->type, g+1, n, lg, l); - else - gmove(n->type, l->type, g, n, lg, l); - if(result != D_NONE) - if(o == OASLMOD || o == OASMOD) - gmove(n->type, nn->type, g+1, n, result, nn); - else - gmove(n->type, nn->type, g, n, result, nn); - regfree(g); - regfree(g+1); - regfree(lg); - regfree(rg); - break; - - case OASXOR: - case OASAND: - case OASOR: - if(l->op == OBIT) - goto asbitop; - if(l->complex >= FNX || - l->addable < INDEXED || - result != D_NONE || - typefd[n->type->etype]) - goto asbinop; - rg = D_TREE; - if(r->op != OCONST) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - gopcode(o, l->type, rg, r, D_TREE, l); - regfree(rg); - break; - - case OASADD: - case OASSUB: - if(l->op == OBIT || - l->complex >= FNX || - l->addable < INDEXED || - result != D_NONE || - typefd[n->type->etype]) - goto asbinop; - v = vconst(r); - if(v > 0 && v <= 8) { - gopcode(o, n->type, D_TREE, r, D_TREE, l); - break; - } - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - gopcode(o, n->type, rg, r, D_TREE, l); - regfree(rg); - break; - - case OASLSHR: - case OASASHR: - case OASASHL: - if(l->op == OBIT || - l->complex >= FNX || - l->addable < INDEXED || - result != D_NONE || - typefd[n->type->etype]) - goto asbinop; - rg = D_TREE; - v = vconst(r); - if(v <= 0 || v > 8) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - lg = regalloc(n->type, D_NONE); - cgen(l, lg, l); - gopcode(o, n->type, rg, r, lg, l); - gmove(n->type, n->type, lg, l, D_TREE, l); - regfree(lg); - regfree(rg); - break; - - case OASLMUL: - case OASMUL: - asbinop: - if(l->op == OBIT) - goto asbitop; - rg = D_TREE; - if(l->complex >= FNX || r->complex >= FNX) { - rg = D_TOS; - cgen(r, rg, r); - v = argoff; - } else - if(r->addable < INDEXED) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } else { - if(o == OASLSHR || o == OASASHR || o == OASASHL) { - v = vconst(r); - if(v <= 0 || v > 8) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - } - } - lg = D_TREE; - if(!simplv(l)) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); /* destroys register optimization */ - lg |= I_INDIR; - } - g = regalloc(n->type, result); - gmove(l->type, n->type, lg, l, g, n); - if(rg == D_TOS) - adjsp(v - argoff); - if(o == OASXOR) - if(rg == D_TREE) { - rg = regalloc(n->type, D_NONE); - cgen(r, rg, r); - } - if(o == OASXOR || o == OASLSHR || o == OASASHR || o == OASASHL) - if(rg == D_TOS) { - rg = regalloc(n->type, D_NONE); - gmove(n->type, n->type, D_TOS, n, rg, n); - } - gopcode(o, n->type, rg, r, g, n); - gmove(n->type, l->type, g, n, lg, l); - if(result != D_NONE) - gmove(n->type, nn->type, g, n, result, nn); - regfree(g); - regfree(lg); - regfree(rg); - break; - - asbitop: - rg = regaddr(D_NONE); - lg = regalloc(tfield, D_NONE); - if(l->complex >= r->complex) { - g = bitload(l, lg, rg, result, nn); - xg = regalloc(r->type, D_NONE); - cgen(r, xg, nn); - } else { - xg = regalloc(r->type, D_NONE); - cgen(r, xg, nn); - g = bitload(l, lg, rg, result, nn); - } - - if(!typefd[n->type->etype]) { - if(o == OASLDIV || o == OASDIV) { - yg = regpair(result); - gmove(tfield, n->type, g, l, yg, n); - gopcode(o, n->type, xg, r, yg, n); - gmove(n->type, tfield, yg, n, g, l); - regfree(yg); - regfree(yg+1); - - regfree(xg); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } - if(o == OASLMOD || o == OASMOD) { - yg = regpair(result); - gmove(tfield, n->type, g, l, yg, n); - gopcode(o, n->type, xg, r, yg, n); - gmove(n->type, tfield, yg+1, n, g, l); - regfree(yg); - regfree(yg+1); - - regfree(xg); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } - } - - yg = regalloc(n->type, result); - gmove(tfield, n->type, g, l, yg, n); - gopcode(o, n->type, xg, r, yg, n); - gmove(n->type, tfield, yg, n, g, l); - regfree(yg); - - regfree(xg); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - - case OCAST: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - lg = result; - if(l->complex >= FNX) - lg = regret(l->type); - lg = eval(l, lg); - if(nocast(l->type, n->type)) { - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - } - if(nocast(n->type, nn->type)) { - gmove(l->type, n->type, lg, l, result, nn); - regfree(lg); - break; - } - rg = regalloc(n->type, result); - gmove(l->type, n->type, lg, l, rg, n); - gmove(n->type, nn->type, rg, n, result, nn); - regfree(rg); - regfree(lg); - break; - - case OCOND: - doinc(l, PRE); - boolgen(l, 1, D_NONE, Z, l); - p1 = p; - - inargs++; - doinc(r->left, PRE); - cgen(r->left, result, nn); - doinc(r->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(r->right, PRE); - cgen(r->right, result, nn); - doinc(r->right, POST); - patch(p1, pc); - inargs--; - break; - - case OIND: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - lg = nodalloc(types[TIND], result, &nod); - nod.lineno = n->lineno; - if(l->op == OADD) { - if(l->left->op == OCONST) { - nod.xoffset += l->left->vconst; - l = l->right; - } else - if(l->right->op == OCONST) { - nod.xoffset += l->right->vconst; - l = l->left; - } - } - cgen(l, lg, l); - gmove(n->type, nn->type, D_TREE, &nod, result, nn); - regfree(lg); - break; - - case OFUNC: - v = argoff; - inargs++; - gargs(r); - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(result); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - inargs--; - doinc(r, POST); - doinc(l, POST); - gopcode(OFUNC, types[TCHAR], D_NONE, Z, lg, l); - regfree(lg); - if(inargs) - adjsp(v - argoff); - if(result != D_NONE) { - lg = regret(n->type); - gmove(n->type, nn->type, lg, n, result, nn); - } - break; - - case OLDIV: - case OLMOD: - case ODIV: - case OMOD: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - if(typefd[n->type->etype]) - goto binop; - if(r->addable >= INDEXED && r->complex < FNX) { - lg = regpair(result); - cgen(l, lg, l); - rg = D_TREE; - } else { - cgen(r, D_TOS, r); - v = argoff; - lg = regpair(result); - cgen(l, lg, l); - adjsp(v - argoff); - rg = D_TOS; - } - gopcode(o, n->type, rg, r, lg, l); - if(o == OMOD || o == OLMOD) - gmove(l->type, nn->type, lg+1, l, result, nn); - else - gmove(l->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(lg+1); - break; - - case OMUL: - case OLMUL: - if(l->op == OCONST) - if(mulcon(r, l, result, nn)) - break; - if(r->op == OCONST) - if(mulcon(l, r, result, nn)) - break; - if(debug['M']) - print("%L multiply\n", n->lineno); - goto binop; - - case OAND: - if(r->op == OCONST) - if(typeil[n->type->etype]) - if(l->op == OCAST) { - if(typec[l->left->type->etype]) - if(!(r->vconst & ~0xff)) { - l = l->left; - goto binop; - } - if(typeh[l->left->type->etype]) - if(!(r->vconst & ~0xffff)) { - l = l->left; - goto binop; - } - } - goto binop; - - case OADD: - if(result == D_TOS) - if(r->addable >= INDEXED) - if(l->op == OCONST) - if(typeil[l->type->etype]) { - v = l->vconst; - if(v > -32768 && v < 32768) { - rg = regaddr(D_NONE); - gmove(r->type, r->type, D_TREE, r, rg, r); - gopcode(OADDR, types[TSHORT], D_NONE, Z, rg, r); - p->to.offset = v; - p->to.type |= I_INDIR; - regfree(rg); - break; - } - } - - case OSUB: - if(result == D_TOS) - if(l->addable >= INDEXED) - if(r->op == OCONST) - if(typeil[r->type->etype]) { - v = r->vconst; - if(v > -32768 && v < 32768) { - if(n->op == OSUB) - v = -v; - lg = regaddr(D_NONE); - gmove(l->type, l->type, D_TREE, l, lg, l); - gopcode(OADDR, types[TSHORT], D_NONE, Z, lg, l); - p->to.offset = v; - p->to.type |= I_INDIR; - regfree(lg); - break; - } - } - goto binop; - - case OOR: - case OXOR: - binop: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - if(l->complex >= FNX && r->complex >= FNX) { - cgen(r, D_TOS, r); - v = argoff; - lg = regalloc(l->type, result); - cgen(l, lg, l); - adjsp(v - argoff); - if(o == OXOR) { - rg = regalloc(r->type, D_NONE); - gmove(r->type, r->type, D_TOS, r, rg, r); - gopcode(o, n->type, rg, r, lg, l); - regfree(rg); - } else - gopcode(o, n->type, D_TOS, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - } - if(l->complex >= r->complex) { - if(l->op == OADDR && (o == OADD || o == OSUB)) - lg = regaddr(result); - else - lg = regalloc(l->type, result); - cgen(l, lg, l); - rg = eval(r, D_NONE); - } else { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - lg = regalloc(l->type, result); - cgen(l, lg, l); - } - if(o == OXOR) { - if(rg == D_TREE) { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - } - if(rg == D_TOS) { - rg = regalloc(r->type, D_NONE); - gmove(r->type, r->type, D_TOS, r, rg, r); - } - } - gopcode(o, n->type, rg, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(rg); - break; - - case OASHL: - if(r->op == OCONST) - if(shlcon(l, r, result, nn)) - break; - case OLSHR: - case OASHR: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - - if(l->complex >= FNX && r->complex >= FNX) { - cgen(r, D_TOS, r); - v = argoff; - lg = regalloc(l->type, result); - cgen(l, lg, l); - adjsp(v - argoff); - rg = regalloc(r->type, D_NONE); - gopcode(OAS, r->type, D_TOS, r, rg, r); - gopcode(n->op, n->type, rg, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(rg); - break; - } - if(l->complex >= r->complex) { - lg = regalloc(l->type, result); - cgen(l, lg, l); - v = vconst(r); - if(v <= 0 || v > 8) { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - } else - rg = eval(r, D_NONE); - } else { - rg = regalloc(r->type, D_NONE); - cgen(r, rg, r); - lg = regalloc(l->type, result); - cgen(l, lg, l); - } - gopcode(o, n->type, rg, r, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - regfree(rg); - break; - - case ONEG: - case OCOM: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - lg = regalloc(l->type, result); - cgen(l, lg, l); - gopcode(o, l->type, D_NONE, Z, lg, l); - gmove(n->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - - case OADDR: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - if(l->op == OINDEX && l->scale == 4 && result != D_TOS) { - /* index scaled by 1, add is better */ - nod = *l; - nod.op = OADD; - nod.addable = 0; - cgen(&nod, result, nn); - break; - } - lcgen(l, result, nn); - break; - - case OEQ: - case ONE: - case OLE: - case OLT: - case OGE: - case OGT: - case OLO: - case OLS: - case OHI: - case OHS: - if(result == D_NONE) { - nullwarn(l, r); - break; - } - boolgen(n, 1, result, nn, Z); - break; - - case OANDAND: - case OOROR: - boolgen(n, 1, result, nn, Z); - if(result == D_NONE) - patch(p, pc); - break; - - case OCOMMA: - cgen(l, D_NONE, l); - doinc(l, POST); - doinc(r, PRE); - cgen(r, result, nn); - break; - - case ONOT: - if(result == D_NONE) { - nullwarn(l, Z); - break; - } - boolgen(n, 1, result, nn, Z); - break; - - case OPOSTINC: - case OPOSTDEC: - v = 1; - if(l->type->etype == TIND) - v = l->type->link->width; - if(o == OPOSTDEC) - v = -v; - if(l->op == OBIT) - goto bitinc; - if(nn == Z) - goto pre; - - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - if(result != D_NONE) - gmove(l->type, nn->type, lg, l, result, nn); - if(typefd[n->type->etype]) { - rg = regalloc(n->type, D_NONE); - gmove(l->type, l->type, lg, l, rg, l); - gopcode(o, n->type, D_CONST, nodconst(1), rg, l); - gmove(l->type, l->type, rg, l, lg, l); - regfree(rg); - } else { - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), lg, l); - else - gopcode(o, n->type, D_CONST, nodconst(v), lg, l); - } - regfree(lg); - break; - - case OPREINC: - case OPREDEC: - v = 1; - if(l->type->etype == TIND) - v = l->type->link->width; - if(o == OPREDEC) - v = -v; - if(l->op == OBIT) - goto bitinc; - - pre: - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(D_NONE); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - if(typefd[n->type->etype]) { - rg = regalloc(n->type, D_NONE); - gmove(l->type, l->type, lg, l, rg, l); - gopcode(o, n->type, D_CONST, nodconst(1), rg, l); - gmove(l->type, l->type, rg, l, lg, l); - regfree(rg); - } else { - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), lg, l); - else - gopcode(o, n->type, D_CONST, nodconst(v), lg, l); - } - if(result != D_NONE) - gmove(l->type, nn->type, lg, l, result, nn); - regfree(lg); - break; - - bitinc: - rg = regaddr(D_NONE); - lg = regalloc(tfield, D_NONE); - if(result != D_NONE && (o == OPOSTINC || o == OPOSTDEC)) { - g = bitload(l, lg, rg, D_NONE, nn); - if(nn != Z) - gmove(l->type, nn->type, g, l, result, nn); - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), g, n); - else - gopcode(o, n->type, D_CONST, nodconst(v), g, n); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } - g = bitload(l, lg, rg, result, nn); - if(v < 0) - gopcode(o, n->type, D_CONST, nodconst(-v), g, n); - else - gopcode(o, n->type, D_CONST, nodconst(v), g, n); - if(result != D_NONE) - gmove(l->type, nn->type, g, l, result, nn); - bitstore(l, g, rg, lg, D_NONE, nn); - break; - } -} - -void -lcgen(Node *n, int result, Node *nn) -{ - Node rn; - Prog *p1; - int lg; - - if(n == Z || n->type == T) - return; - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R\n", result); - prtree(n, "lcgen"); - } - if(nn == Z) { - nn = &rn; - nn->type = types[TIND]; - } - switch(n->op) { - case OCOMMA: - cgen(n->left, D_NONE, n->left); - doinc(n->left, POST); - doinc(n->right, PRE); - lcgen(n->right, result, nn); - break; - - case OCOND: - doinc(n->left, PRE); - boolgen(n->left, 1, D_NONE, Z, n->left); - p1 = p; - - inargs++; - doinc(n->right->left, PRE); - lcgen(n->right->left, result, nn); - doinc(n->right->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(n->right->right, PRE); - lcgen(n->right->right, result, nn); - doinc(n->right->right, POST); - patch(p1, pc); - inargs--; - break; - - case OIND: - if(n->addable >= INDEXED) { - if(result >= D_A0 && result < D_A0+NREG) { - gopcode(OADDR, types[TLONG], D_TREE, n, result, nn); - break; - } - if(result == D_TOS) { - gopcode(OADDR, types[TSHORT], D_NONE, nn, D_TREE, n); - break; - } - } - cgen(n->left, result, nn); - break; - - default: - if(n->addable < INDEXED) { - diag(n, "unknown op in lcgen: %O", n->op); - break; - } - if(result >= D_A0 && result < D_A0+NREG) { - gopcode(OADDR, types[TLONG], D_TREE, n, result, nn); - break; - } - if(result == D_TOS) { - gopcode(OADDR, types[TSHORT], D_NONE, nn, D_TREE, n); - break; - } - lg = regaddr(result); - gopcode(OADDR, types[TLONG], D_TREE, n, lg, nn); - gopcode(OAS, nn->type, lg, nn, result, nn); - regfree(lg); - break; - } -} - -void -bcgen(Node *n, int true) -{ - - boolgen(n, true, D_NONE, Z, Z); -} - -void -boolgen(Node *n, int true, int result, Node *nn, Node *post) -{ - Prog *p1, *p2; - Node *l, *r; - int lg, rg, fp, o; - long v; - - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R\n", result); - prtree(n, "boolgen"); - } - l = n->left; - r = n->right; - switch(n->op) { - - default: - lg = eval(n, result); - if(lg >= D_A0 && lg < D_A0+NREG) { - rg = regalloc(types[TLONG], D_NONE); - gopcode(OAS, types[TLONG], lg, n, rg, Z); - regfree(rg); - } else - gopcode(OTST, n->type, D_NONE, Z, lg, n); - regfree(lg); - o = ONE; - fp = typefd[n->type->etype]; - goto genbool; - - case OCONST: - fp = vconst(n); - if(!true) - fp = !fp; - gbranch(OGOTO); - if(fp) { - p1 = p; - gbranch(OGOTO); - patch(p1, pc); - } - goto com; - - case ONOT: - boolgen(l, !true, result, nn, post); - break; - - case OCOND: - doinc(l, PRE); - boolgen(l, 1, D_NONE, Z, l); - p1 = p; - - inargs++; - doinc(r->left, PRE); - boolgen(r->left, true, result, nn, r->left); - if(result != D_NONE) { - doinc(r->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(r->right, PRE); - boolgen(r->right, !true, result, nn, r->right); - doinc(r->right, POST); - patch(p1, pc); - inargs--; - break; - } - p2 = p; - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(r->right, PRE); - boolgen(r->right, !true, result, nn, r->right); - patch(p2, pc); - p2 = p; - if(doinc(post, POST|TEST)) { - lg = regalloc(types[TSHORT], D_NONE); - gopcode(OAS, types[TSHORT], D_CCR, Z, lg, Z); - doinc(post, POST); - gopcode(OAS, types[TSHORT], lg, Z, D_CCR, Z); - regfree(lg); - } - gbranch(OGOTO); - patch(p1, pc); - patch(p2, pc); - inargs--; - goto com; - - case OANDAND: - if(!true) - goto caseor; - - caseand: - doinc(l, PRE); - boolgen(l, true, D_NONE, Z, l); - p1 = p; - inargs++; - doinc(r, PRE); - boolgen(r, !true, D_NONE, Z, r); - p2 = p; - patch(p1, pc); - gbranch(OGOTO); - patch(p2, pc); - inargs--; - goto com; - - case OOROR: - if(!true) - goto caseand; - - caseor: - doinc(l, PRE); - boolgen(l, !true, D_NONE, Z, l); - p1 = p; - inargs++; - doinc(r, PRE); - boolgen(r, !true, D_NONE, Z, r); - p2 = p; - gbranch(OGOTO); - patch(p1, pc); - patch(p2, pc); - inargs--; - goto com; - - case OEQ: - case ONE: - if(vconst(l) == 0) { - if(n->op == ONE) { - boolgen(r, true, result, nn, post); - break; - } - boolgen(r, !true, result, nn, post); - break; - } - - case OLE: - case OLT: - case OGE: - case OGT: - case OHI: - case OHS: - case OLO: - case OLS: - fp = typefd[r->type->etype]; - if(l->op == OCONST) { - v = vconst(l); - if(v == 0) { /* tst instruction */ - o = invrel[relindex(n->op)]; - rg = eval(r, result); - gopcode(OTST, r->type, D_NONE, Z, rg, r); - regfree(rg); - goto genbool; - } - if(!fp) { /* cmpi and movq, saves about .5% both time and space */ - if(v < 128 && v >= -128 && - ewidth[r->type->etype] == SZ_LONG) { - rg = eval(r, result); - lg = regalloc(l->type, D_NONE); - cgen(l, lg, l); - o = n->op; - gopcode(o, l->type, lg, l, rg, r); - regfree(lg); - regfree(rg); - goto genbool; - } - o = invrel[relindex(n->op)]; - rg = eval(r, result); - gopcode(o, r->type, rg, r, D_TREE, l); - regfree(rg); - goto genbool; - } - } - lg = D_TOS; - if(r->complex < FNX) - lg = regalloc(l->type, lg); - cgen(l, lg, l); - v = argoff; - rg = eval(r, result); - if(lg == D_TOS) { - adjsp(v - argoff); - lg = regalloc(l->type, lg); - gopcode(OAS, l->type, D_TOS, l, lg, l); - } - o = n->op; - gopcode(o, l->type, lg, l, rg, r); - regfree(lg); - regfree(rg); - - genbool: - if(true) - o = comrel[relindex(o)]; - if(doinc(post, POST|TEST)) { - lg = regalloc(types[TSHORT], D_NONE); - gopcode(OAS, types[TSHORT], D_CCR, Z, lg, Z); - doinc(post, POST); - gopcode(OAS, types[TSHORT], lg, Z, D_CCR, Z); - regfree(lg); - } - gbranch(o); - if(fp) - fpbranch(); - - com: - if(result == D_NONE) - break; - p1 = p; - gopcode(OAS, nn->type, D_CONST, nodconst(1), result, nn); - gbranch(OGOTO); - p2 = p; - patch(p1, pc); - gopcode(OAS, nn->type, D_CONST, nodconst(0), result, nn); - patch(p2, pc); - break; - } -} - -void -sugen(Node *n, int result, Node *nn, long w) -{ - long s, v, o; - int lg, rg, ng; - Prog *p1; - Node *l, *r, nod; - Type *t; - - if(n == Z || n->type == T) - return; - if(debug['g']) { - if(result == D_TREE) - prtree(nn, "result"); - else - print("result = %R width = %ld\n", result, w); - prtree(n, "sugen"); - } - s = argoff; - if(result == D_TREE) { - if(nn == nodrat) - if(w > nrathole) - nrathole = w; - } - - if(n->addable >= INDEXED && n->op != OCONST) - goto copy; - switch(n->op) { - default: - diag(n, "unknown op in sugen: %O", n->op); - break; - - case OCONST: - if(n->type && typev[n->type->etype]) { - if(result == D_NONE) { - nullwarn(n->left, Z); - break; - } - - lg = regaddr(D_NONE); - if(result == D_TOS) { - adjsp(s - argoff + w); - gopcode(OADDR, types[TIND], result, nn, lg, n); - } else - if(result == D_TREE) { - lcgen(nn, lg, Z); - } else - diag(n, "unknown su result: %R", result); - - gopcode(OAS, types[TLONG], D_CONST, nodconst((long)(n->vconst>>32)), - lg|I_INDINC, n); - gopcode(OAS, types[TLONG], D_CONST, nodconst((long)(n->vconst)), - lg|I_INDINC, n); - regfree(lg); - break; - } - goto copy; - - case ODOT: - l = n->left; - sugen(l, D_TREE, nodrat, l->type->width); - if(result != D_NONE) { - warn(n, "non-interruptable temporary"); - nod = *nodrat; - r = n->right; - if(!r || r->op != OCONST) { - diag(n, "DOT and no offset"); - break; - } - nod.xoffset += r->vconst; - nod.type = n->type; - sugen(&nod, result, nn, w); - } - break; - - case OIND: - if(result == D_NONE) { - nullwarn(n->left, Z); - break; - } - goto copy; - - case OSTRUCT: - lg = nodalloc(types[TIND], result, &nod); - nod.lineno = n->lineno; - if(result == D_TREE) - lcgen(nn, lg, Z); - else - if(result == D_TOS) { - adjsp(s - argoff + w); - gopcode(OADDR, types[TIND], result, nn, lg, n); - } else - diag(n, "unknown su result: %R", result); - o = 0; - r = n->left; - for(t = n->type->link; t != T; t = t->down) { - l = r; - if(r->op == OLIST) { - l = r->left; - r = r->right; - } - nod.type = t; - if(l->complex < FNX) { - nod.xoffset = 0; - if(o != t->offset) { - gopcode(OADD, types[TIND], D_CONST, - nodconst(t->offset-o), lg, Z); - o = t->offset; - } - cgen(l, D_TREE, &nod); - continue; - } - nod.xoffset = t->offset - o; - gopcode(OAS, types[TIND], lg, Z, D_TOS, Z); - s = argoff; - if(typesuv[t->etype]) { - sugen(l, D_TREE, nodrat, t->width); - adjsp(s - argoff); - gopcode(OAS, types[TIND], D_TOS, Z, lg, Z); - warn(n, "non-interruptable temporary"); - sugen(nodrat, D_TREE, &nod, t->width); - continue; - } - rg = regalloc(t, D_NONE); - cgen(l, rg, l); - adjsp(s - argoff); - gopcode(OAS, types[TIND], D_TOS, Z, lg, Z); - gopcode(OAS, t, rg, Z, D_TREE, &nod); - regfree(rg); - } - regfree(lg); - break; - - case OAS: - if(result == D_NONE) { - sugen(n->right, D_TREE, n->left, w); - break; - } - sugen(n->right, D_TREE, nodrat, w); /* could do better */ - warn(n, "non-interruptable temporary"); - sugen(nodrat, D_TREE, n->left, w); - sugen(nodrat, result, nn, w); - break; - - case OFUNC: - if(result == D_NONE) { - sugen(n, D_TREE, nodrat, w); - break; - } - inargs++; - /* prepare zero-th arg: address of result */ - if(result == D_TOS) { - adjsp(s - argoff + w); - v = argoff; - gargs(n->right); - gopcode(OADDR, types[TSHORT], D_NONE, nn, result, nn); - p->to.type = D_STACK; - p->to.offset = argoff - v; - } else - if(result == D_TREE) { - v = argoff; - gargs(n->right); - if(nn->complex >= FNX) { - rg = regalloc(types[TIND], regret(types[TIND])); - lcgen(nn, rg, Z); - gopcode(OAS, types[TIND], rg, Z, D_TOS, Z); - regfree(rg); - } else - lcgen(nn, D_TOS, Z); - } else { - diag(n, "unknown result in FUNC sugen"); - break; - } - argoff += types[TIND]->width; - l = n->left; - lg = D_TREE; - if(l->addable < INDEXED) { - lg = regaddr(result); - lcgen(l, lg, Z); - lg |= I_INDIR; - } - inargs--; - doinc(n->right, POST); - doinc(n->left, POST); - gopcode(OFUNC, types[TCHAR], D_NONE, Z, lg, l); - regfree(lg); - if(inargs) - adjsp(v - argoff); - break; - - case OCOND: - doinc(n->left, PRE); - boolgen(n->left, 1, D_NONE, Z, n->left); - p1 = p; - - inargs++; - doinc(n->right->left, PRE); - sugen(n->right->left, result, nn, w); - doinc(n->right->left, POST); - gbranch(OGOTO); - patch(p1, pc); - p1 = p; - - doinc(n->right->right, PRE); - sugen(n->right->right, result, nn, w); - doinc(n->right->right, POST); - patch(p1, pc); - inargs--; - break; - - case OCOMMA: - cgen(n->left, D_NONE, n->left); - doinc(n->left, POST); - doinc(n->right, PRE); - sugen(n->right, result, nn, w); - break; - } - return; - -copy: - if(result == D_NONE) - return; - rg = regaddr(D_NONE); - lcgen(n, rg, Z); - - lg = regaddr(D_NONE); - if(result == D_TOS) { - adjsp(s - argoff + w); - gopcode(OADDR, types[TIND], result, nn, lg, n); - } else - if(result == D_TREE) { - if(nn->complex >= FNX) { - gopcode(OAS, types[TIND], rg, n, D_TOS, n); - s = argoff; - lcgen(nn, lg, Z); - adjsp(s - argoff); - gopcode(OAS, types[TIND], D_TOS, n, rg, n); - } else - lcgen(nn, lg, Z); - } else - diag(n, "unknown su result: %R", result); - - if(w % SZ_LONG) - diag(Z, "sucopy width not 0%%%d", SZ_LONG); - v = w / SZ_LONG; - if(v & 1) { - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - v--; - } - if(v > 6) { - ng = regalloc(types[TLONG], D_NONE); - gopcode(OAS, types[TLONG], D_CONST, nodconst(v/2-1), ng, n); - v = pc; - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - gbranch(OGT); - patch(p, v); - p->from.type = ng; - p->as = ADBF; - regfree(ng); - } else - while(v > 0) { - gopcode(OAS, types[TLONG], rg|I_INDINC, n, lg|I_INDINC, n); - v--; - } - - regfree(lg); - regfree(rg); -} diff --git a/utils/2c/enam.c b/utils/2c/enam.c deleted file mode 100644 index be6917af..00000000 --- a/utils/2c/enam.c +++ /dev/null @@ -1,425 +0,0 @@ -char *anames[] = -{ - "XXX", - "ABCD", - "ADDB", - "ADDL", - "ADDW", - "ADDXB", - "ADDXL", - "ADDXW", - "ADJSP", - "ANDB", - "ANDL", - "ANDW", - "ASLB", - "ASLL", - "ASLW", - "ASRB", - "ASRL", - "ASRW", - "BCASE", - "BCC", - "BCHG", - "BCLR", - "BCS", - "BEQ", - "BFCHG", - "BFCLR", - "BFEXTS", - "BFEXTU", - "BFFFO", - "BFINS", - "BFSET", - "BFTST", - "BGE", - "BGT", - "BHI", - "BKPT", - "BLE", - "BLS", - "BLT", - "BMI", - "BNE", - "BPL", - "BRA", - "BSET", - "BSR", - "BTST", - "BVC", - "BVS", - "CALLM", - "CAS2B", - "CAS2L", - "CAS2W", - "CASB", - "CASEW", - "CASL", - "CASW", - "CHK2B", - "CHK2L", - "CHK2W", - "CHKL", - "CHKW", - "CLRB", - "CLRL", - "CLRW", - "CMP2B", - "CMP2L", - "CMP2W", - "CMPB", - "CMPL", - "CMPW", - "DATA", - "DBCC", - "DBCS", - "DBEQ", - "DBF", - "DBGE", - "DBGT", - "DBHI", - "DBLE", - "DBLS", - "DBLT", - "DBMI", - "DBNE", - "DBPL", - "DBT", - "DBVC", - "DBVS", - "DIVSL", - "DIVSW", - "DIVUL", - "DIVUW", - "END", - "EORB", - "EORL", - "EORW", - "EXG", - "EXTBL", - "EXTBW", - "EXTWL", - "FABSB", - "FABSD", - "FABSF", - "FABSL", - "FABSW", - "FACOSB", - "FACOSD", - "FACOSF", - "FACOSL", - "FACOSW", - "FADDB", - "FADDD", - "FADDF", - "FADDL", - "FADDW", - "FASINB", - "FASIND", - "FASINF", - "FASINL", - "FASINW", - "FATANB", - "FATAND", - "FATANF", - "FATANHB", - "FATANHD", - "FATANHF", - "FATANHL", - "FATANHW", - "FATANL", - "FATANW", - "FBEQ", - "FBF", - "FBGE", - "FBGT", - "FBLE", - "FBLT", - "FBNE", - "FBT", - "FCMPB", - "FCMPD", - "FCMPF", - "FCMPL", - "FCMPW", - "FCOSB", - "FCOSD", - "FCOSF", - "FCOSHB", - "FCOSHD", - "FCOSHF", - "FCOSHL", - "FCOSHW", - "FCOSL", - "FCOSW", - "FDBEQ", - "FDBF", - "FDBGE", - "FDBGT", - "FDBLE", - "FDBLT", - "FDBNE", - "FDBT", - "FDIVB", - "FDIVD", - "FDIVF", - "FDIVL", - "FDIVW", - "FETOXB", - "FETOXD", - "FETOXF", - "FETOXL", - "FETOXM1B", - "FETOXM1D", - "FETOXM1F", - "FETOXM1L", - "FETOXM1W", - "FETOXW", - "FGETEXPB", - "FGETEXPD", - "FGETEXPF", - "FGETEXPL", - "FGETEXPW", - "FGETMANB", - "FGETMAND", - "FGETMANF", - "FGETMANL", - "FGETMANW", - "FINTB", - "FINTD", - "FINTF", - "FINTL", - "FINTRZB", - "FINTRZD", - "FINTRZF", - "FINTRZL", - "FINTRZW", - "FINTW", - "FLOG10B", - "FLOG10D", - "FLOG10F", - "FLOG10L", - "FLOG10W", - "FLOG2B", - "FLOG2D", - "FLOG2F", - "FLOG2L", - "FLOG2W", - "FLOGNB", - "FLOGND", - "FLOGNF", - "FLOGNL", - "FLOGNP1B", - "FLOGNP1D", - "FLOGNP1F", - "FLOGNP1L", - "FLOGNP1W", - "FLOGNW", - "FMODB", - "FMODD", - "FMODF", - "FMODL", - "FMODW", - "FMOVEB", - "FMOVED", - "FMOVEF", - "FMOVEL", - "FMOVEM", - "FMOVEMC", - "FMOVEW", - "FMULB", - "FMULD", - "FMULF", - "FMULL", - "FMULW", - "FNEGB", - "FNEGD", - "FNEGF", - "FNEGL", - "FNEGW", - "FREMB", - "FREMD", - "FREMF", - "FREML", - "FREMW", - "FRESTORE", - "FSAVE", - "FSCALEB", - "FSCALED", - "FSCALEF", - "FSCALEL", - "FSCALEW", - "FSEQ", - "FSF", - "FSGE", - "FSGT", - "FSINB", - "FSIND", - "FSINF", - "FSINHB", - "FSINHD", - "FSINHF", - "FSINHL", - "FSINHW", - "FSINL", - "FSINW", - "FSLE", - "FSLT", - "FSNE", - "FSQRTB", - "FSQRTD", - "FSQRTF", - "FSQRTL", - "FSQRTW", - "FST", - "FSUBB", - "FSUBD", - "FSUBF", - "FSUBL", - "FSUBW", - "FTANB", - "FTAND", - "FTANF", - "FTANHB", - "FTANHD", - "FTANHF", - "FTANHL", - "FTANHW", - "FTANL", - "FTANW", - "FTENTOXB", - "FTENTOXD", - "FTENTOXF", - "FTENTOXL", - "FTENTOXW", - "FTSTB", - "FTSTD", - "FTSTF", - "FTSTL", - "FTSTW", - "FTWOTOXB", - "FTWOTOXD", - "FTWOTOXF", - "FTWOTOXL", - "FTWOTOXW", - "GLOBL", - "GOK", - "HISTORY", - "ILLEG", - "INSTR", - "JMP", - "JSR", - "LEA", - "LINKL", - "LINKW", - "LOCATE", - "LONG", - "LSLB", - "LSLL", - "LSLW", - "LSRB", - "LSRL", - "LSRW", - "MOVB", - "MOVEM", - "MOVEPL", - "MOVEPW", - "MOVESB", - "MOVESL", - "MOVESW", - "MOVL", - "MOVW", - "MULSL", - "MULSW", - "MULUL", - "MULUW", - "NAME", - "NBCD", - "NEGB", - "NEGL", - "NEGW", - "NEGXB", - "NEGXL", - "NEGXW", - "NOP", - "NOTB", - "NOTL", - "NOTW", - "ORB", - "ORL", - "ORW", - "PACK", - "PEA", - "RESET", - "ROTLB", - "ROTLL", - "ROTLW", - "ROTRB", - "ROTRL", - "ROTRW", - "ROXLB", - "ROXLL", - "ROXLW", - "ROXRB", - "ROXRL", - "ROXRW", - "RTD", - "RTE", - "RTM", - "RTR", - "RTS", - "SBCD", - "SCC", - "SCS", - "SEQ", - "SF", - "SGE", - "SGT", - "SHI", - "SLE", - "SLS", - "SLT", - "SMI", - "SNE", - "SPL", - "ST", - "STOP", - "SUBB", - "SUBL", - "SUBW", - "SUBXB", - "SUBXL", - "SUBXW", - "SVC", - "SVS", - "SWAP", - "SYS", - "TAS", - "TEXT", - "TRAP", - "TRAPCC", - "TRAPCS", - "TRAPEQ", - "TRAPF", - "TRAPGE", - "TRAPGT", - "TRAPHI", - "TRAPLE", - "TRAPLS", - "TRAPLT", - "TRAPMI", - "TRAPNE", - "TRAPPL", - "TRAPT", - "TRAPV", - "TRAPVC", - "TRAPVS", - "TSTB", - "TSTL", - "TSTW", - "UNLK", - "UNPK", - "WORD", - "SIGNAME", - "LAST", -}; diff --git a/utils/2c/gc.h b/utils/2c/gc.h deleted file mode 100644 index 75dd85c0..00000000 --- a/utils/2c/gc.h +++ /dev/null @@ -1,357 +0,0 @@ -#include "../cc/cc.h" -#include "../2c/2.out.h" -/* - * 2c/68020 - * Motorola 68020 - */ - -#define SZ_CHAR 1 -#define SZ_SHORT 2 -#define SZ_INT 4 -#define SZ_LONG 4 -#define SZ_IND 4 -#define SZ_FLOAT 4 -#define SZ_VLONG 8 -#define SZ_DOUBLE 8 - -#define ALLOP OEND -#define NRGN 300 -#define FNX 100 -#define INDEXED 9 - -#define PRE 1 -#define POST 2 -#define TEST 4 - -typedef struct Adr Adr; -typedef struct Prog Prog; -typedef struct Txt Txt; -typedef struct Cases Case; -typedef struct Reg Reg; -typedef struct Rgn Rgn; -typedef struct Var Var; -typedef struct Multab Multab; -typedef struct C1 C1; -typedef struct Index Index; - -struct Index -{ - int o0; - int o1; -}; - -EXTERN struct -{ - Node* regtree; - Node* basetree; - short scale; -} idx; - -struct Adr -{ - long displace; - long offset; - - char sval[NSNAME]; - double dval; - - Sym* sym; - short type; - short index; - short scale; - short field; - short etype; -}; -#define A ((Adr*)0) - -struct Prog -{ - Adr from; - Adr to; - Prog* link; - long lineno; - short as; -}; -#define P ((Prog*)0) - -struct Txt -{ - short movas; - short postext; - char preclr; -}; - -struct Cases -{ - long val; - long label; - uchar def; - Case* link; -}; -#define C ((Case*)0) - -struct Var -{ - long offset; - Sym* sym; - char type; - char etype; -}; - -struct Reg -{ - long pc; - long rpo; /* reverse post ordering */ - - Bits set; - Bits use1; - Bits use2; - - Bits refbehind; - Bits refahead; - Bits calbehind; - Bits calahead; - Bits regdiff; - Bits act; - - ulong regu; - long loop; /* could be shorter */ - - Reg* log5; - long active; - - Reg* p1; - Reg* p2; - Reg* p2link; - Reg* s1; - Reg* s2; - Reg* link; - Prog* prog; -}; -#define R ((Reg*)0) - -struct Rgn -{ - Reg* enter; - short costr; - short costa; - short varno; - short regno; -}; - -struct Multab -{ - short val; - char code[6]; -}; - -struct C1 -{ - long val; - long label; -}; - -#define BLOAD(r) band(bnot(r->refbehind), r->refahead) -#define BSTORE(r) band(bnot(r->calbehind), r->calahead) -#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z]) -#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z]) - -#define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32)) - -#define CLOAD 8 -#define CREF 5 -#define CTEST 2 -#define CXREF 3 -#define CINF 1000 -#define LOOP 3 - -EXTERN Bits externs; -EXTERN Bits params; -EXTERN Bits addrs; -EXTERN ulong regbits; - -#define B_INDIR (1<<0) -#define B_ADDR (1<<1) -EXTERN int mvbits; -EXTERN int changer; -EXTERN int changea; - -EXTERN Txt txt[NTYPE][NTYPE]; -EXTERN short opxt[ALLOP][NTYPE]; -EXTERN Txt* txtp; -EXTERN int multabsize; - -EXTERN Reg* firstr; -EXTERN Reg* lastr; -EXTERN Reg zreg; -EXTERN Reg* freer; - -EXTERN long argoff; -EXTERN long breakpc; -EXTERN Case* cases; -EXTERN long continpc; -EXTERN Prog* firstp; -EXTERN Reg* firstr; -EXTERN int inargs; -EXTERN Prog* lastp; -EXTERN int retok; -EXTERN long mnstring; -EXTERN Node* nodrat; -EXTERN Node* nodret; -EXTERN long nrathole; -EXTERN long nstatic; -EXTERN int nregion; -EXTERN long nstring; -EXTERN int nvar; -EXTERN Prog* p; -EXTERN long pc; -EXTERN Rgn region[NRGN]; -EXTERN Rgn* rgp; -EXTERN char string[NSNAME]; -EXTERN Sym* symrathole; -EXTERN Sym* symstatic; -EXTERN Var var[NVAR]; -EXTERN long* idom; -EXTERN Reg** rpo2r; -EXTERN long maxnr; -EXTERN Prog zprog; - -EXTERN uchar regused[NREG]; -EXTERN uchar aregused[NREG]; -EXTERN uchar fregused[NREG]; -EXTERN uchar regbase[I_MASK]; -EXTERN long exregoffset; -EXTERN long exaregoffset; -EXTERN long exfregoffset; - -extern char* anames[]; -extern Multab multab[]; - -void cgen(Node*, int, Node*); -void lcgen(Node*, int, Node*); -void bcgen(Node*, int); -void boolgen(Node*, int, int, Node*, Node*); -void sugen(Node*, int, Node*, long); - - -void listinit(void); -int Bconv(Fmt*); -int Pconv(Fmt*); -int Aconv(Fmt*); -int Xconv(Fmt*); -int Dconv(Fmt*); -int Rconv(Fmt*); -int Sconv(Fmt*); - -void peep(void); -void excise(Reg*); -Reg* uniqp(Reg*); -Reg* uniqs(Reg*); -int findtst(Reg*, Prog*, int); -int setcc(Prog*, Prog*); -int compat(Adr*, Adr*); -int aregind(Adr*); -int asize(int); -int usedin(int, Adr*); -Reg* findccr(Reg*); -int setccr(Prog*); -Reg* findop(Reg*, int, int, int); -int regtyp(int); -int anyvar(Adr*); -int subprop(Reg*); -int copyprop(Reg*); -int copy1(Adr*, Adr*, Reg*, int); -int copyu(Prog*, Adr*, Adr*); -int copyas(Adr*, Adr*); -int tasas(Adr*, Adr*); -int copyau(Adr*, Adr*); -int copysub(Adr*, Adr*, Adr*, Prog*, int); - -ulong RtoB(int); -ulong AtoB(int); -ulong FtoB(int); -int BtoR(ulong); -int BtoA(ulong); -int BtoF(ulong); - -Reg* rega(void); -int rcmp(const void*, const void*); -void regopt(Prog*); -void addmove(Reg*, int, int, int); -Bits mkvar(Adr*, int); -void prop(Reg*, Bits, Bits); -void loopit(Reg*, long); -void synch(Reg*, Bits); -ulong allreg(ulong, Rgn*); -void paint1(Reg*, int); -ulong paint2(Reg*, int); -void paint3(Reg*, int, ulong, int); -void addreg(Adr*, int); - -void codgen(Node*, Node*); -void gen(Node*); -void usedset(Node*, int); -void noretval(int); -Node* nodconst(long); - -int swcmp(const void*, const void*); -void doswit(int, Node*); -void swit1(C1*, int, long, int, Node*); -void casf(void); -int bitload(Node*, int, int, int, Node*); -void bitstore(Node*, int, int, int, int, Node*); -long outstring(char*, long); -int doinc(Node*, int); -void setsp(void); -void adjsp(long); -int simplv(Node*); -int eval(Node*, int); -void outcode(void); -void ieeedtod(Ieee*, double); -int nodalloc(Type*, int, Node*); -int mulcon(Node*, Node*, int, Node*); -int shlcon(Node*, Node*, int, Node*); -int mulcon1(Node*, long, int, Node*); -void nullwarn(Node*, Node*); - -void tindex(Type*, Type*); -void ginit(void); -void gclean(void); -void oinit(int, int, int, int, int, int); -Prog* prg(void); -void nextpc(void); -void gargs(Node*); -void naddr(Node*, Adr*, int); -int regalloc(Type*, int); -int regaddr(int); -int regpair(int); -int regret(Type*); -void regfree(int); -void gmove(Type*, Type*, int, Node*, int, Node*); -void gopcode(int, Type*, int, Node*, int, Node*); -void asopt(void); -int relindex(int); -void gbranch(int); -void fpbranch(void); -void patch(Prog*, long); -void gpseudo(int, Sym*, int, long); -void gpseudotree(int, Sym*, Node*); - -void indx(Node*); -void bcomplex(Node*); - -/* - * com64 - */ -int com64(Node*); -void com64init(void); -void bool64(Node*); - -#pragma varargck type "A" int -#pragma varargck type "B" Bits -#pragma varargck type "D" Adr* -#pragma varargck type "N" Adr* -#pragma varargck type "P" Prog* -#pragma varargck type "S" char* -#pragma varargck type "R" int -#pragma varargck type "X" Index diff --git a/utils/2c/list.c b/utils/2c/list.c deleted file mode 100644 index 2b3cb4da..00000000 --- a/utils/2c/list.c +++ /dev/null @@ -1,384 +0,0 @@ -#define EXTERN -#include "gc.h" - -void -listinit(void) -{ - - fmtinstall('R', Rconv); - fmtinstall('A', Aconv); - fmtinstall('D', Dconv); - fmtinstall('P', Pconv); - fmtinstall('S', Sconv); - fmtinstall('X', Xconv); - fmtinstall('B', Bconv); -} - -static Index -indexv(int i, int j) -{ - Index x; - - x.o0 = i; - x.o1 = j; - return x; -} - -int -Bconv(Fmt *fp) -{ - char str[STRINGSZ], ss[STRINGSZ], *s; - Bits bits; - int i; - - str[0] = 0; - bits = va_arg(fp->args, Bits); - while(bany(&bits)) { - i = bnum(bits); - if(str[0]) - strcat(str, " "); - if(var[i].sym == S) { - sprint(ss, "$%ld", var[i].offset); - s = ss; - } else - s = var[i].sym->name; - if(strlen(str) + strlen(s) + 1 >= STRINGSZ) - break; - strcat(str, s); - bits.b[i/32] &= ~(1L << (i%32)); - } - return fmtstrcpy(fp, str); -} - -int -Pconv(Fmt *fp) -{ - char str[STRINGSZ], s[20]; - Prog *p; - - p = va_arg(fp->args, Prog*); - sprint(str, " %A %D,%D", p->as, &p->from, &p->to); - if(p->from.field) { - sprint(s, ",%d,%d", p->to.field, p->from.field); - strcat(str, s); - } - return fmtstrcpy(fp, str); -} - -int -Aconv(Fmt *fp) -{ - int r; - - r = va_arg(fp->args, int); - return fmtstrcpy(fp, anames[r]); -} - -int -Xconv(Fmt *fp) -{ - char str[20], s[10]; - Index x; - int i; - - x = va_arg(fp->args, Index); - str[0] = 0; - i = x.o0 & D_MASK; - if(i != D_NONE) { - sprint(str, "(%R.", i); - i = x.o1; - sprint(s, "%c*%c)", - "WWWWLLLL"[i], - "12481248"[i]); - strcat(str, s); - } - return fmtstrcpy(fp, str); -} - -int -Dconv(Fmt *fp) -{ - char str[40], s[20]; - Adr *a; - int i, j; - long d; - - a = va_arg(fp->args, Adr*); - i = a->index; - if(i != D_NONE) { - a->index = D_NONE; - d = a->displace; - j = a->scale; - a->displace = 0; - switch(i & I_MASK) { - default: - sprint(str, "???%ld(%D%X)", d, a, indexv(i, j)); - break; - - case I_INDEX1: - sprint(str, "%D%X", a, indexv(i, a->scale)); - break; - - case I_INDEX2: - if(d) - sprint(str, "%ld(%D)%X", d, a, indexv(i, j)); - else - sprint(str, "(%D)%X", a, indexv(i, j)); - break; - - case I_INDEX3: - if(d) - sprint(str, "%ld(%D%X)", d, a, indexv(i, j)); - else - sprint(str, "(%D%X)", a, indexv(i, j)); - break; - } - a->displace = d; - a->index = i; - goto out; - } - i = a->type; - j = i & I_MASK; - if(j) { - a->type = i & D_MASK; - d = a->offset; - a->offset = 0; - switch(j) { - case I_INDINC: - sprint(str, "(%D)+", a); - break; - - case I_INDDEC: - sprint(str, "-(%D)", a); - break; - - case I_INDIR: - if(a->type == D_CONST) - sprint(str, "%ld", d); - else - if(d) - sprint(str, "%ld(%D)", d, a); - else - sprint(str, "(%D)", a); - break; - - case I_ADDR: - a->offset = d; - sprint(str, "$%D", a); - break; - } - a->type = i; - a->offset = d; - goto out; - } - switch(i) { - - default: - sprint(str, "%R", i); - break; - - case D_NONE: - str[0] = 0; - break; - - case D_BRANCH: - sprint(str, "%ld(PC)", a->offset-pc); - break; - - case D_EXTERN: - sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); - break; - - case D_STATIC: - sprint(str, "%s<>+%ld(SB)", a->sym->name, a->offset); - break; - - case D_AUTO: - sprint(str, "%s-%ld(SP)", a->sym->name, -a->offset); - break; - - case D_PARAM: - sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); - break; - - case D_CONST: - sprint(str, "$%ld", a->offset); - break; - - case D_STACK: - sprint(str, "TOS+%ld", a->offset); - break; - - case D_FCONST: - sprint(str, "$%.17e", a->dval); - goto out; - - case D_SCONST: - sprint(str, "$\"%S\"", a->sval); - goto out; - } - if(a->displace) { - sprint(s, "/%ld", a->displace); - strcat(str, s); - } -out: - return fmtstrcpy(fp, str); -} - -int -Rconv(Fmt *fp) -{ - char str[20]; - int r; - - r = va_arg(fp->args, int); - if(r >= D_R0 && r < D_R0+NREG) - sprint(str, "R%d", r-D_R0); - else - if(r >= D_A0 && r < D_A0+NREG) - sprint(str, "A%d", r-D_A0); - else - if(r >= D_F0 && r < D_F0+NREG) - sprint(str, "F%d", r-D_F0); - else - switch(r) { - - default: - sprint(str, "gok(%d)", r); - break; - - case D_NONE: - sprint(str, "NONE"); - break; - - case D_TOS: - sprint(str, "TOS"); - break; - - case D_CCR: - sprint(str, "CCR"); - break; - - case D_SR: - sprint(str, "SR"); - break; - - case D_SFC: - sprint(str, "SFC"); - break; - - case D_DFC: - sprint(str, "DFC"); - break; - - case D_CACR: - sprint(str, "CACR"); - break; - - case D_USP: - sprint(str, "USP"); - break; - - case D_VBR: - sprint(str, "VBR"); - break; - - case D_CAAR: - sprint(str, "CAAR"); - break; - - case D_MSP: - sprint(str, "MSP"); - break; - - case D_ISP: - sprint(str, "ISP"); - break; - - case D_TREE: - sprint(str, "TREE"); - break; - - case D_FPCR: - sprint(str, "FPCR"); - break; - - case D_FPSR: - sprint(str, "FPSR"); - break; - - case D_FPIAR: - sprint(str, "FPIAR"); - break; - - case D_TC: - sprint(str, "TC"); - break; - - case D_ITT0: - sprint(str, "ITT0"); - break; - - case D_ITT1: - sprint(str, "ITT1"); - break; - - case D_DTT0: - sprint(str, "DTT0"); - break; - - case D_DTT1: - sprint(str, "DTT1"); - break; - - case D_MMUSR: - sprint(str, "MMUSR"); - break; - case D_URP: - sprint(str, "URP"); - break; - - case D_SRP: - sprint(str, "SRP"); - break; - } - return fmtstrcpy(fp, str); -} - -int -Sconv(Fmt *fp) -{ - int i, c; - char str[30], *p, *s; - - s = va_arg(fp->args, char*); - p = str; - for(i=0; i<sizeof(double); i++) { - c = s[i] & 0xff; - if(c != '\\' && c != '"' && isprint(c)) { - *p++ = c; - continue; - } - *p++ = '\\'; - switch(c) { - case 0: - *p++ = '0'; - continue; - case '\\': - case '"': - *p++ = c; - continue; - case '\n': - *p++ = 'n'; - continue; - case '\t': - *p++ = 't'; - continue; - } - *p++ = ((c>>6) & 7) + '0'; - *p++ = ((c>>3) & 7) + '0'; - *p++ = ((c>>0) & 7) + '0'; - } - *p = 0; - return fmtstrcpy(fp, str); -} diff --git a/utils/2c/mkfile b/utils/2c/mkfile deleted file mode 100644 index 7efbd5cc..00000000 --- a/utils/2c/mkfile +++ /dev/null @@ -1,30 +0,0 @@ -<../../mkconfig - -TARG=2c - -OFILES=\ - cgen.$O\ - reg.$O\ - txt.$O\ - peep.$O\ - swt.$O\ - sgen.$O\ - list.$O\ - enam.$O\ - mul.$O\ - -HFILES=\ - gc.h\ - 2.out.h\ - ../cc/cc.h\ - -LIBS=cc bio 9 # order is important - -BIN=$ROOT/$OBJDIR/bin - -<$ROOT/mkfiles/mkone-$SHELLTYPE - -$ROOT/$OBJDIR/lib/libcc.a: - cd ../cc - mk $MKFLAGS install - mk $MKFLAGS clean diff --git a/utils/2c/mul.c b/utils/2c/mul.c deleted file mode 100644 index 65ddda2f..00000000 --- a/utils/2c/mul.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "gc.h" - -/* - * code sequences for multiply by constant - * all sequences start with leading '0'. - * if sequence starts with 'i', then the - * leading '0' is suppressed. - * '0' mov r0,r1 - * '1' sub r0,r1 - * '2' sub r1,r0 - * '3' add r0,r1 - * '4' add r1,r0 - * '5' add r0,r0 - * '6' add r1,r1 - * 'b' lsh $2,r0 - * 'c' lsh $3,r0 - * 'd'-'h' ... - * 'j' lsh $2,r1 - * 'k'-'p' ... - */ -Multab multab[] = -{ - 2, "i5", - 3, "64", - 4, "i55", - 5, "664", - 6, "645", - 7, "c2", - 9, "k4", - 10, "6645", - 11, "66364", - 12, "6455", - 13, "66464", - 14, "6d2", - 15, "d2", - 17, "l4", - 18, "6d4", - 19, "64k4", - 20, "66455", - 21, "664664", - 22, "64c2", - 23, "44c2", - 24, "64c", - 25, "63k4", - 26, "64c4", - 27, "663e2", - 28, "66e2", - 29, "63e2", - 30, "6e2", - 31, "e2", - 33, "m4", - 34, "6e4", - 35, "64l4", - 36, "66e4", - 37, "664k4", - 38, "64k45", - 39, "454c2", - 40, "664c", - 41, "663k4", - 42, "644c4", - 43, "643k4", - 44, "664c4", - 45, "640d2", - 46, "64d2", - 47, "44d2", - 48, "64d", - 49, "63l4", - 50, "64d4", - 51, "640l4", - 52, "646d4", - 53, "643d4", - 54, "6636f2", - 55, "k3f2", - 56, "kf2", - 57, "k2k4", - 58, "636f2", - 59, "663f2", - 60, "66f2", - 61, "63f2", - 62, "6f2", - 63, "f2", - 65, "n4", - 66, "6f4", - 67, "64m4", - 68, "66f4", - 69, "664l4", - 70, "64l45", - 71, "k1f4", - 72, "k4c", - 73, "k4k4", - 74, "664k45", - 75, "6640d2", - 76, "664d2", - 77, "434d2", - 78, "644d2", - 79, "454d2", - 80, "664d", - 81, "663l4", - 82, "644d4", - 83, "643l4", - 84, "664d4", - 85, "6640l4", - 86, "6634l4", - 87, "6443d4", - 88, "6646d4", - 89, "6643d4", - 90, "6406e2", - 91, "643e2", - 92, "646e2", - 93, "640e2", - 94, "64e2", - 95, "44e2", - 96, "64e", - 97, "63m4", - 98, "64e4", - 99, "640m4", - 100, "646e4", - 200, "66f364", - 300, "j40jf2", - 400, "64kg4", - 500, "66h212", - 600, "64m4c4", - 700, "j4c4d2", - 800, "64lh4", - 900, "6464g4", - 1000, "63g2c", - 1100, "j4d2p4", - 1200, "64k4f2", - 1300, "j4n4b4", - 1400, "64j4g2", - 1600, "64d4e", - 1800, "p4c2", - 2000, "63g2d", - 2100, "l4b2o4", - 2200, "k4d4p4", - 2300, "6644h2", - 2400, "j4k4f4", - 2500, "j4e2d4", - 2600, "j40n4c", - 3100, "jd12p2", - 3200, "64d4f", - 3600, "6d1p2", - 3800, "e3k3g2", - 3900, "jf20n4", - 4000, "o4e2", - 4100, "66p455", - 4200, "l4c3e2", - 4300, "l4b1f4", - 4400, "64o4d4", - 4600, "k45h2", - 4700, "k3j4g2", - 4800, "j40d2f", - 5000, "l4c3m4", - 5100, "j40h2b", - 5200, "j40n4d", - 6000, "d1o3h2", - 6100, "o1l4b2", - 6200, "ke12p2", - 6400, "64d4g", - 7200, "66e1p2", - 7400, "m3m4c2", - 7600, "l4f3c2", - 7800, "kg20n4", - 8000, "63g2f", - 8100, "m2b4p4", - 8200, "66p4c", - 8700, "66f4g2", - 8900, "l3j4g4", - 9200, "k45h25", - 9600, "j40d2g", - 9800, "k4f3d4", -}; - -int multabsize = sizeof(multab) / sizeof(multab[0]); diff --git a/utils/2c/peep.c b/utils/2c/peep.c deleted file mode 100644 index 7026e628..00000000 --- a/utils/2c/peep.c +++ /dev/null @@ -1,1073 +0,0 @@ -#include "gc.h" - -void -peep(void) -{ - Reg *r, *r1, *r2; - Prog *p, *p1; - int t, s; -/* - * complete R structure - */ - t = 0; - for(r=firstr; r!=R; r=r1) { - r1 = r->link; - if(r1 == R) - break; - p = r->prog->link; - while(p != r1->prog) - switch(p->as) { - default: - r2 = rega(); - r->link = r2; - r2->link = r1; - - r2->prog = p; - r2->p1 = r; - r->s1 = r2; - r2->s1 = r1; - r1->p1 = r2; - - r = r2; - t++; - - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - p = p->link; - } - } - -loop1: - /* - * propigate move's by renaming - */ - t = 0; - for(r=firstr; r!=R; r=r->link) { - p = r->prog; - if(p->as == AMOVL || p->as == AFMOVEF || p->as == AFMOVED) - if(regtyp(p->from.type)) - if(anyvar(&p->to)) { - if(copyprop(r)) { - excise(r); - t++; - } else - if(subprop(r) && copyprop(r)) { - excise(r); - t++; - } - } - } - if(t) - goto loop1; - for(r=firstr; r!=R; r=r->link) { - p = r->prog; - /* - * convert (A) ... A++ into (A)++ - * and A-- ... (A) into --(A) - */ - t = aregind(&p->from); - if(t == D_NONE) - goto out1; - s = asize(p->as); - if(s == 0) - goto out1; - r1 = findop(r, t, AADDL, s); - if(r1 != R) { - if(usedin(t, &p->to)) - goto out1; - p->from.type += I_INDINC - I_INDIR; - excise(r1); - goto out1; - } - r1 = findop(r, t, ASUBL, s); - if(r1 != R) { - p->from.type += I_INDDEC - I_INDIR; - excise(r1); - } - out1: - t = aregind(&p->to); - if(t == D_NONE) - goto out2; - s = asize(p->as); - if(s == 0) - goto out2; - r1 = findop(r, t, AADDL, s); - if(r1 != R) { - p->to.type += I_INDINC - I_INDIR; - excise(r1); - goto out2; - } - r1 = findop(r, t, ASUBL, s); - if(r1 != R) { - if(usedin(t, &p->from)) - goto out2; - p->to.type += I_INDDEC - I_INDIR; - excise(r1); - } - out2: - /* - * get rid of unneeded save/restore CCR - */ - if(p->from.type == D_CCR) { - r1 = findccr(r); - if(r1 != R) { - excise(r); - excise(r1); - } - } - switch(p->as) { - case ATSTB: - case ATSTW: - case ATSTL: - if(findtst(r, r->prog, 0)) - excise(r); - } - /* - * turn TSTB (A); BLT; ORB $128,(A) into TAS (A); BLT; NOP - */ - if(p->as == ATSTB && (r1 = r->s1)) { - if((r1->prog->as == ABLT && (r2 = r1->s1)) || - (r1->prog->as == ABGE && (r2 = r1->s2))) { - p1 = r2->prog; - if(p1->as == AORB) - if(p1->from.type == D_CONST) - if(p1->from.offset == 128) - if(r1 == uniqp(r2)) - if(tasas(&p->to, &p1->to)) { - p->as = ATAS; - excise(r2); - } - } - } - } -} - -void -excise(Reg *r) -{ - - p = r->prog; - p->as = ANOP; - p->from = zprog.from; - p->to = zprog.to; -} - -Reg* -uniqp(Reg *r) -{ - Reg *r1; - - r1 = r->p1; - if(r1 == R) { - r1 = r->p2; - if(r1 == R || r1->p2link != R) - return R; - } else - if(r->p2 != R) - return R; - return r1; -} - -Reg* -uniqs(Reg *r) -{ - Reg *r1; - - r1 = r->s1; - if(r1 == R) { - r1 = r->s2; - if(r1 == R) - return R; - } else - if(r->s2 != R) - return R; - return r1; -} - -/* - * chase backward all cc setting. - * returns 1 if all set same. - */ -int -findtst(Reg *r0, Prog *rp, int n) -{ - Reg *r; - int c; - -loop: - n++; - if(n >= 10) - return 0; - for(r=r0->p2; r!=R; r=r->p2link) { - c = setcc(r->prog, rp); - if(c > 0) - continue; - if(c == 0) - return 0; - if(findtst(r, rp, n) == 0) - return 0; - } - r = r0->p1; - if(r == R) - return 1; - c = setcc(r->prog, rp); - if(c > 0) - return 1; - if(c == 0) - return 0; - r0 = r; - goto loop; -} - -/* - * tests cc - * returns -1 if no change - * returns 1 if set the same - * returns 0 if set different - */ -int -setcc(Prog *p, Prog *rp) -{ - int s; - - s = asize(rp->as); - switch(p->as) { - default: - if(debug['P']) - print("unknown setcc %A\n", p->as); - break; - - case ACMPB: - case ACMPW: - case ACMPL: - case ABSR: - return 0; - - case ABRA: - case ABGE: - case ABNE: - case ABLE: - case ABEQ: - case ABHI: - case ABLS: - case ABMI: - case ABPL: - case ABGT: - case ABLT: - case ABCC: - case ABCS: - case APEA: - case ALEA: - case ANOP: - - case AFADDD: - case AFMULD: - case AFDIVD: - case AFSUBD: - case AFADDF: - case AFMULF: - case AFDIVF: - case AFSUBF: - case AADJSP: - return -1; - - case AADDW: - case AADDL: - case ASUBW: - case ASUBL: - case ACLRL: - case ACLRW: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - goto areg; - - case AADDB: - case ASUBB: - case AANDB: - case AANDW: - case AANDL: - case AORB: - case AORW: - case AORL: - case AEORB: - case AEORW: - case AEORL: - case ALSLB: - case ALSLW: - case ALSLL: - case ALSRB: - case ALSRW: - case ALSRL: - case AASLB: - case AASLW: - case AASLL: - case AASRB: - case AASRW: - case AASRL: - case ATSTB: - case ATSTW: - case ATSTL: - case ANEGB: - case ANEGW: - case ANEGL: - case ACLRB: - if(asize(p->as) != s) - break; - if(compat(&rp->to, &p->to)) - return 1; - break; - - case AMOVW: - case AMOVL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - goto areg; - case AMOVB: - if(asize(p->as) != s) - break; - if(compat(&rp->to, &p->to)) - return 1; - if(compat(&rp->to, &p->from)) - return 1; - } - return 0; - -areg: - if((rp->to.type&D_MASK) == p->to.type) - return 0; - return -1; -} - -int -compat(Adr *a, Adr *b) -{ - int o; - - if(a->index != D_NONE) - return 0; - if(b->index != D_NONE) - return 0; - o = a->type; - if((o >= D_R0 && o < D_R0+NREG) || - (o >= D_A0 && o < D_A0+NREG)) - return o == b->type; - o &= D_MASK; - if(o >= D_A0 && o < D_A0+NREG) { - if(o != (b->type&D_MASK)) - return 0; - if(a->offset != b->offset) - return 0; - o = a->type & I_MASK; - if(o == I_INDIR) { - o = b->type & I_MASK; - if(o == I_INDIR || o == I_INDDEC) - return 1; - return 0; - } - if(o == I_INDINC) { - o = b->type & I_MASK; - if(o == I_INDIR) { - b->type += I_INDINC-I_INDIR; - return 1; - } - if(o == I_INDDEC) { - b->type += I_INDIR-I_INDDEC; - return 1; - } - return 0; - } - } - return 0; -} - -int -aregind(Adr *a) -{ - int t; - - t = a->type; - if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR)) - while(a->offset == 0 && a->index == D_NONE) - return t & D_MASK; - return D_NONE; -} - -int -asize(int a) -{ - - switch(a) { - case AFTSTD: - case AFMOVED: - case AFADDD: - case AFSUBD: - case AFMULD: - case AFDIVD: - case AFCMPD: - case AFNEGD: - return 8; - - case AFTSTF: - case AFMOVEF: - case AFADDF: - case AFSUBF: - case AFMULF: - case AFDIVF: - case AFCMPF: - case AFNEGF: - - case ACLRL: - case ATSTL: - case AMOVL: - case AADDL: - case ASUBL: - case ACMPL: - case AANDL: - case AORL: - case AEORL: - case ALSLL: - case ALSRL: - case AASLL: - case AASRL: - case ANEGL: - return 4; - - case ACLRW: - case ATSTW: - case AMOVW: - case AADDW: - case ASUBW: - case ACMPW: - case AANDW: - case AORW: - case AEORW: - case ALSLW: - case ALSRW: - case AASLW: - case AASRW: - case ANEGW: - return 2; - - case ACLRB: - case ATSTB: - case AMOVB: - case AADDB: - case ASUBB: - case ACMPB: - case AANDB: - case AORB: - case AEORB: - case ALSLB: - case ALSRB: - case AASLB: - case AASRB: - case ANEGB: - return 1; - } - if(debug['P']) - print("unknown asize %A\n", p->as); - return 0; -} - -int -usedin(int t, Adr *a) -{ - - if((a->type&D_MASK) == t) - return 1; - if((a->index&D_MASK) == t) - return 1; - return 0; -} - -Reg* -findccr(Reg *r) -{ - Prog *p; - - for(;;) { - r = uniqs(r); - if(r == R) - break; - p = r->prog; - if(p->to.type == D_CCR) - return r; - if(setccr(p)) - break; - } - return R; -} - -int -setccr(Prog *p) -{ - - switch(p->as) { - case ANOP: - return 0; - - case AADDL: - case AMOVL: - case ACLRL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - return 0; - } - return 1; -} - -Reg* -findop(Reg *r, int t, int o, int s) -{ - Prog *p; - Reg *r1; - - for(;;) { - if(o == AADDL) { - r1 = uniqs(r); - if(r1 == R) - break; - if(uniqp(r1) != r) - break; - } else { - r1 = uniqp(r); - if(r1 == R) - break; - if(uniqs(r1) != r) - break; - } - r = r1; - p = r->prog; - if(usedin(t, &p->from)) - break; - if(usedin(t, &p->to)) { - if(p->as == o) - if(p->to.type == t) - if(p->to.index == D_NONE) - if(p->from.type == D_CONST) - if(p->from.offset == s) - return r; - break; - } - } - return R; -} - -int -regtyp(int t) -{ - - if(t >= D_R0 && t < D_R0+8) - return 1; - if(t >= D_A0 && t < D_A0+8) - return 1; - if(t >= D_F0 && t < D_F0+8) - return 1; - return 0; -} - -int -anyvar(Adr *a) -{ - - if(regtyp(a->type)) - return 1; - return 0; -} - -/* - * the idea is to substitute - * one register for another - * from one MOV to another - * MOV a, R0 - * ADD b, R0 / no use of R1 - * MOV R0, R1 - * would be converted to - * MOV a, R1 - * ADD b, R1 - * MOV R1, R0 - * hopefully, then the former or latter MOVL - * will be eliminated by copy propagation. - */ -int -subprop(Reg *r0) -{ - Prog *p; - Adr *v1, *v2; - Reg *r; - int t; - - p = r0->prog; - v1 = &p->from; - if(!regtyp(v1->type)) - return 0; - v2 = &p->to; - if(!regtyp(v2->type)) - return 0; - for(r=uniqp(r0); r!=R; r=uniqp(r)) { - if(uniqs(r) == R) - break; - p = r->prog; - switch(p->as) { - case ADIVUW: /* these set Rn and Rn+1 */ - case ADIVUL: - case ADIVSW: - case ADIVSL: - case ABSR: - return 0; - - case AFMOVED: - case AFMOVEF: - case AMOVL: - if(p->to.type == v1->type) - goto gotit; - } - if(copyau(&p->from, v2) || copyau(&p->to, v2)) - break; - if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0)) - break; - } - return 0; - -gotit: - copysub(&p->to, v1, v2, p, 1); - if(debug['P']) { - print("gotit: %D->%D\n%P", v1, v2, r->prog); - if(p->from.type == v2->type) - print(" excise"); - print("\n"); - } - if(p->from.type == v2->type) - excise(r); - for(r=uniqs(r); r!=r0; r=uniqs(r)) { - p = r->prog; - copysub(&p->from, v1, v2, p, 1); - copysub(&p->to, v1, v2, p, 1); - if(debug['P']) - print("%P\n", r->prog); - } - t = v1->type; - v1->type = v2->type; - v2->type = t; - if(debug['P']) - print("%P last\n", r->prog); - return 1; -} - -/* - * The idea is to remove redundant copies. - * v1->v2 F=0 - * (use v2 s/v2/v1/)* - * set v1 F=1 - * use v2 return fail - * ----------------- - * v1->v2 F=0 - * (use v2 s/v2/v1/)* - * set v1 F=1 - * set v2 return success - */ -int -copyprop(Reg *r0) -{ - Prog *p; - Adr *v1, *v2; - Reg *r; - - p = r0->prog; - v1 = &p->from; - v2 = &p->to; - if(copyas(v1, v2)) - return 1; - for(r=firstr; r!=R; r=r->link) - r->active = 0; - return copy1(v1, v2, r0->s1, 0); -} - -int -copy1(Adr *v1, Adr *v2, Reg *r, int f) -{ - int t; - - if(r->active) { - if(debug['P']) - print("copyret 1\n"); - return 1; - } - r->active = 1; - if(debug['P']) - print("copy %D->%D\n", v1, v2); - for(; r != R; r = r->s1) { - if(debug['P']) - print("%P", r->prog); - if(!f && uniqp(r) == R) { - f = 1; - if(debug['P']) - print("; merge; f=%d", f); - } - t = copyu(r->prog, v2, A); - switch(t) { - case 2: /* rar, cant split */ - if(debug['P']) - print("; rar return 0\n"); - return 0; - case 3: /* set */ - if(debug['P']) - print("; set; return 1\n"); - return 1; - case 1: /* used, substitute */ - case 4: /* use and set */ - if(f) { - if(debug['P']) - print("; used and f; return 0\n"); - return 0; - } - if(copyu(r->prog, v2, v1)) { - if(debug['P']) - print("; sub fail; return 0\n"); - return 0; - } - if(debug['P']) - print("; substitute"); - if(t == 4) { - if(debug['P']) - print("; used and set; return 1\n"); - return 1; - } - break; - } - if(!f) { - t = copyu(r->prog, v1, A); - if(!f && (t == 2 || t == 3 || t == 4)) { - if(debug['P']) - print("; f set used"); - f = 1; - } - } - if(debug['P']) - print("\n"); - if(r->s2) - if(!copy1(v1, v2, r->s2, f)) - return 0; - } - return 1; -} - -/* - * return - * 1 if v only used (and substitute), - * 2 if read-alter-rewrite - * 3 if set - * 4 if set and used - * 0 otherwise (not touched) - */ -int -copyu(Prog *p, Adr *v, Adr *s) -{ - int t; - - switch(p->as) { - - default: - if(debug['P']) - print("unknown op %A\n", p->as); - return 2; - - case APEA: /* rhs addr */ - if(copyas(&p->to, v)) - return 2; - goto caseread; - - case ALEA: /* lhs addr, rhs store */ - if(copyas(&p->from, v)) - return 2; - - case AMOVL: /* rhs store */ - case ACLRL: - case AFMOVEF: - case AFMOVED: - case AFMOVEB: - case AFMOVEW: - case AFMOVEL: - case ANOP: - if(copyas(&p->to, v)) { - if(s != A) - return copysub(&p->from, v, s, p, 1); - if(copyau(&p->from, v)) - return 4; - return 3; - } - goto caseread; - - case AADDL: /* rhs rar */ - case AADDW: - case AADDB: - case ASUBL: - case ASUBW: - case ASUBB: - case AANDL: - case AANDW: - case AANDB: - case AORL: - case AORW: - case AORB: - case AEORL: - case AEORW: - case AEORB: - case AASRL: - case AASRW: - case AASRB: - case AASLL: - case AASLW: - case AASLB: - case ALSRL: - case ALSRW: - case ALSRB: - case ANOTL: - case ANOTW: - case ANOTB: - case ANEGL: - case ANEGW: - case ANEGB: - case AEXTBL: - case AEXTWL: - case AEXTBW: - - case AMULSL: - case AMULUL: - - case AMOVW: /* only sets part of register */ - case AMOVB: - case ACLRW: - case ACLRB: - - case AFADDD: - case AFMULD: - case AFDIVD: - case AFSUBD: - case AFNEGD: - case AFADDF: - case AFMULF: - case AFDIVF: - case AFSUBF: - case AFNEGF: - if(copyas(&p->to, v)) - return 2; - goto caseread; - - case ADBF: /* lhs rar */ - if(copyas(&p->from, v)) - return 2; - goto caseread; - - case ACMPL: /* read only */ - case ACMPW: - case ACMPB: - case AFCMPF: - case AFCMPD: - case ATSTL: - case ATSTW: - case ATSTB: - case AFTSTF: - case AFTSTD: - caseread: - if(s != A) { - if(copysub(&p->from, v, s, p, 1)) - return 1; - return copysub(&p->to, v, s, p, 1); - } - if(copyau(&p->from, v)) - return 1; - if(copyau(&p->to, v)) - return 1; - break; - - case ABRA: /* no reference */ - case ABGE: - case ABNE: - case ABLE: - case ABEQ: - case ABHI: - case ABLS: - case ABMI: - case ABPL: - case ABGT: - case ABLT: - case ABCC: - case ABCS: - - case AFBEQ: - case AFBNE: - case AFBGT: - case AFBGE: - case AFBLE: - case AFBLT: - - case AADJSP: - case ACASEW: - break; - - case ADIVUW: /* these set Rn and Rn+1 */ - case ADIVUL: - case ADIVSW: - case ADIVSL: - t = v->type; - if(t == p->to.type || t == p->to.type+1) - return 2; - goto caseread; - - case ARTS: /* funny */ - t = v->type; - if(t == D_R0 || t == D_F0) - return 2; - if(t >= D_R0 && t < D_R0+NREG) - if(t-D_R0 > exregoffset) - return 2; - if(t >= D_A0 && t < D_A0+NREG) - if(t-D_A0 > exaregoffset) - return 2; - if(t >= D_F0 && t < D_F0+NREG) - if(t-D_F0 > exfregoffset) - return 2; - return 3; - - case ABSR: /* funny */ - t = v->type; - if(t >= D_R0 && t < D_R0+NREG) - if(t-D_R0 > exregoffset) - return 2; - if(t >= D_A0 && t < D_A0+NREG) - if(t-D_A0 > exaregoffset) - return 2; - if(t >= D_F0 && t < D_F0+NREG) - if(t-D_F0 > exfregoffset) - return 2; - return 3; - } - return 0; -} - -/* - * direct reference, - * could be set/use depending on - * semantics - */ -int -copyas(Adr *a, Adr *v) -{ - - if(a->type != v->type) - return 0; - if(regtyp(v->type)) - return 1; - if(v->type == D_AUTO || v->type == D_PARAM) { - if(v->offset == a->offset) - return 1; - return 0; - } - return 0; -} - -/* - * indirect - */ -int -tasas(Adr *a, Adr *v) -{ - int t; - - if(a->index != D_NONE) - return 0; - if(v->index != D_NONE) - return 0; - t = a->type; - if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8) - return 0; - if(v->type != t) - return 0; - if(a->displace != v->displace) - return 0; - return 1; -} - -/* - * either direct or indirect - */ -int -copyau(Adr *a, Adr *v) -{ - int t; - - if(copyas(a, v)) - return 1; - t = v->type; - if(regtyp(t)) { - if((a->type & D_MASK) == t) - return 1; - if((a->index & D_MASK) == t) - return 1; - } - return 0; -} - -/* - * substitute s for v in a - * return failure to substitute - */ -int -copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f) -{ - int t; - - if(copyas(a, v)) { - t = s->type; - if(t >= D_F0 && t < D_F0+8) { - if(f) - a->type = t; - return 0; - } - if(t >= D_R0 && t < D_R0+8) { - if(f) - a->type = t; - return 0; - } - if(!(t >= D_A0 && t < D_A0+8)) - return 1; - switch(p->as) { - default: - return 1; - - case AMOVL: - case AMOVW: - case ACMPL: - case ACMPW: - break; - - case AADDL: - case AADDW: - case ASUBL: - case ASUBW: - if(a == &p->from && !regtyp(p->to.type)) - return 1; - break; - } - if(f) - a->type = t; - return 0; - } - t = v->type; - if(regtyp(t)) { - if((a->type & D_MASK) == t) { - if((s->type ^ t) & ~(NREG-1)) - return 1; - if(f) - a->type = (a->type & ~D_MASK) | s->type; - return 0; - } - if((a->index & D_MASK) == t) { - if(f) - a->index = (a->index & ~D_MASK) | s->type; - return 0; - } - return 0; - } - return 0; -} diff --git a/utils/2c/reg.c b/utils/2c/reg.c deleted file mode 100644 index d314096d..00000000 --- a/utils/2c/reg.c +++ /dev/null @@ -1,1275 +0,0 @@ -#include "gc.h" - -Reg* -rega(void) -{ - Reg *r; - - r = freer; - if(r == R) { - r = alloc(sizeof(*r)); - } else - freer = r->link; - - *r = zreg; - return r; -} - -int -rcmp(const void *a1, const void *a2) -{ - Rgn *p1, *p2; - int c1, c2; - - p1 = (Rgn*)a1; - p2 = (Rgn*)a2; - c1 = p2->costr; - if(p2->costa > c1) - c1 = p2->costa; - c2 = p1->costr; - if(p1->costa > c2) - c2 = p1->costa; - if(c1 -= c2) - return c1; - return p2->varno - p1->varno; -} - -void -regopt(Prog *p) -{ - Reg *r, *r1, *r2; - Prog *p1; - int i, z; - long val, initpc, npc; - ulong vreg; - Bits bit; - Var *v; - struct { - long m; - long c; - Reg* p; - } log5[6], *lp; - - firstr = R; - lastr = R; - nvar = 0; - for(z=0; z<BITS; z++) { - externs.b[z] = 0; - params.b[z] = 0; - addrs.b[z] = 0; - } - regbits = RtoB(0) | /* return reg */ - AtoB(6) | AtoB(7) | /* sp and sb */ - FtoB(0) | FtoB(1); /* floating return reg */ - for(i=0; i<NREG; i++) { - if(regused[i]) - regbits |= RtoB(i); - if(fregused[i]) - regbits |= FtoB(i); - if(aregused[i]) - regbits |= AtoB(i); - } - - /* - * pass 1 - * build aux data structure - * allocate pcs - * find use and set of variables - */ - val = 5L * 5L * 5L * 5L * 5L; - lp = log5; - for(i=0; i<5; i++) { - lp->m = val; - lp->c = 0; - lp->p = R; - val /= 5L; - lp++; - } - val = 0; - for(; p != P; p = p->link) { - switch(p->as) { - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - continue; - } - r = rega(); - if(firstr == R) { - firstr = r; - lastr = r; - } else { - lastr->link = r; - r->p1 = lastr; - lastr->s1 = r; - lastr = r; - } - r->prog = p; - r->pc = val; - val++; - - lp = log5; - for(i=0; i<5; i++) { - lp->c--; - if(lp->c <= 0) { - lp->c = lp->m; - if(lp->p != R) - lp->p->log5 = r; - lp->p = r; - (lp+1)->c = 0; - break; - } - lp++; - } - - r1 = r->p1; - if(r1 != R) - switch(r1->prog->as) { - case ABRA: - case ARTS: - case ARTE: - r->p1 = R; - r1->s1 = R; - } - - bit = mkvar(&p->from, AGOK); - if(bany(&bit)) - switch(p->as) { - case ALEA: - if(!(mvbits & B_INDIR)) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - - default: - if(mvbits & B_ADDR) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - for(z=0; z<BITS; z++) - r->use1.b[z] |= bit.b[z]; - } - - bit = mkvar(&p->to, p->as); - if(bany(&bit)) - switch(p->as) { - case ABSR: /* funny */ - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - goto def; - - case APEA: - if(!(mvbits & B_INDIR)) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - - def: - case ACMPB: case ACMPW: case ACMPL: - case AFCMPF: case AFCMPD: - case ATSTB: case ATSTW: case ATSTL: - case AFTSTF: case AFTSTD: - case ABFEXTU: case ABFEXTS: - if(mvbits & B_ADDR) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - break; - - default: - diag(Z, "reg: unknown asop: %A", p->as); - - case AADDB: case AADDW: case AADDL: - case ASUBB: case ASUBW: case ASUBL: - case AANDB: case AANDW: case AANDL: - case AORB: case AORW: case AORL: - case AEORB: case AEORW: case AEORL: - case ABFINS: - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - - case ANOP: - case AMOVB: case AMOVW: case AMOVL: - case AFMOVEB: case AFMOVEW: case AFMOVEL: - case ACLRB: case ACLRW: case ACLRL: - case AFMOVEF: case AFMOVED: - if(mvbits & B_INDIR) - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - else - for(z=0; z<BITS; z++) - r->set.b[z] |= bit.b[z]; - break; - - } - } - if(firstr == R) - return; - initpc = pc - val; - npc = val; - - /* - * pass 2 - * turn branch references to pointers - * build back pointers - */ - for(r = firstr; r != R; r = r->link) { - p = r->prog; - if(p->to.type == D_BRANCH) { - val = p->to.offset - initpc; - r1 = firstr; - while(r1 != R) { - r2 = r1->log5; - if(r2 != R && val >= r2->pc) { - r1 = r2; - continue; - } - if(r1->pc == val) - break; - r1 = r1->link; - } - if(r1 == R) { - diag(Z, "ref not found\n%L:%P", p->lineno, p); - continue; - } - if(r1 == r) { - diag(Z, "ref to self"); - continue; - } - r->s2 = r1; - r->p2link = r1->p2; - r1->p2 = r; - } - } - if(debug['R']) - print("\n%L %D\n", firstr->prog->lineno, &firstr->prog->from); - - /* - * pass 2.5 - * find looping structure - */ - for(r = firstr; r != R; r = r->link) - r->active = 0; - changer = 0; - loopit(firstr, npc); - if(debug['R'] && debug['v']) { - print("\nlooping structure:\n"); - for(r = firstr; r != R; r = r->link) { - print("%ld:%P", r->loop, r->prog); - for(z=0; z<BITS; z++) - bit.b[z] = r->use1.b[z] | - r->use2.b[z] | r->set.b[z]; - if(bany(&bit)) { - print("\t"); - if(bany(&r->use1)) - print(" u1=%B", r->use1); - if(bany(&r->use2)) - print(" u2=%B", r->use2); - if(bany(&r->set)) - print(" st=%B", r->set); - } - print("\n"); - } - } - - /* - * pass 3 - * iterate propagating usage - * back until flow graph is complete - */ -loop1: - changer = 0; - for(r = firstr; r != R; r = r->link) - r->active = 0; - for(r = firstr; r != R; r = r->link) - if(r->prog->as == ARTS) - prop(r, zbits, zbits); -loop11: - /* pick up unreachable code */ - i = 0; - for(r = firstr; r != R; r = r1) { - r1 = r->link; - if(r1 && r1->active && !r->active) { - prop(r, zbits, zbits); - i = 1; - } - } - if(i) - goto loop11; - if(changer) - goto loop1; - - /* - * pass 4 - * iterate propagating register/variable synchrony - * forward until graph is complete - */ -loop2: - changer = 0; - for(r = firstr; r != R; r = r->link) - r->active = 0; - synch(firstr, zbits); - if(changer) - goto loop2; - - - /* - * pass 5 - * isolate regions - * calculate costs (paint1) - */ - r = firstr; - if(r) { - for(z=0; z<BITS; z++) - bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & - ~(externs.b[z] | params.b[z] | addrs.b[z]); - if(bany(&bit)) { - nearln = r->prog->lineno; - warn(Z, "used and not set: %B", bit); - if(debug['R'] && !debug['w']) - print("used and not set: %B\n", bit); - - /* - * 68040 'feature': - * load of a denormalized fp will trap - */ - while(bany(&bit)) { - i = bnum(bit); - bit.b[i/32] &= ~(1L << (i%32)); - v = var + i; - if(v->type == D_AUTO) { - r->set.b[i/32] |= (1L << (i%32)); - if(typefd[v->etype]) - addmove(r, i, NREG+NREG, 1); - } - } - } - } - if(debug['R'] && debug['v']) - print("\nprop structure:\n"); - for(r = firstr; r != R; r = r->link) { - if(debug['R'] && debug['v']) - print("%P\n set = %B; rah = %B; cal = %B\n", - r->prog, r->set, r->refahead, r->calahead); - r->act = zbits; - } - rgp = region; - nregion = 0; - for(r = firstr; r != R; r = r->link) { - for(z=0; z<BITS; z++) - bit.b[z] = r->set.b[z] & - ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); - if(bany(&bit)) { - nearln = r->prog->lineno; - warn(Z, "set and not used: %B", bit); - if(debug['R']) - print("set an not used: %B\n", bit); - excise(r); - } - for(z=0; z<BITS; z++) - bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]); - while(bany(&bit)) { - i = bnum(bit); - rgp->enter = r; - rgp->varno = i; - changer = 0; - changea = 0; - if(debug['R'] && debug['v']) - print("\n"); - paint1(r, i); - bit.b[i/32] &= ~(1L<<(i%32)); - if(changer <= 0 && changea <= 0) { - if(debug['R']) - print("%L$%d.%d: %B\n", - r->prog->lineno, - changer, changea, blsh(i)); - continue; - } - rgp->costr = changer; - rgp->costa = changea; - nregion++; - if(nregion >= NRGN) { - warn(Z, "too many regions"); - goto brk; - } - rgp++; - } - } -brk: - qsort(region, nregion, sizeof(region[0]), rcmp); - - /* - * pass 6 - * determine used registers (paint2) - * replace code (paint3) - */ - rgp = region; - for(i=0; i<nregion; i++) { - bit = blsh(rgp->varno); - vreg = paint2(rgp->enter, rgp->varno); - vreg = allreg(vreg, rgp); - if(debug['R']) - print("%L$%d.%d %R: %B\n", - rgp->enter->prog->lineno, - rgp->costr, rgp->costa, - rgp->regno, - bit); - if(rgp->regno != D_NONE) - paint3(rgp->enter, rgp->varno, vreg, rgp->regno); - rgp++; - } - /* - * pass 7 - * peep-hole on basic block - */ - if(!debug['R'] || debug['P']) - peep(); - - /* - * pass 8 - * recalculate pc - */ - val = initpc; - for(r = firstr; r != R; r = r1) { - r->pc = val; - p = r->prog; - p1 = P; - r1 = r->link; - if(r1 != R) - p1 = r1->prog; - for(; p != p1; p = p->link) { - switch(p->as) { - default: - val++; - break; - - case ANOP: - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - break; - } - } - } - pc = val; - - /* - * fix up branches - */ - if(debug['R']) - if(bany(&addrs)) - print("addrs: %B\n", addrs); - - r1 = 0; /* set */ - for(r = firstr; r != R; r = r->link) { - p = r->prog; - if(p->to.type == D_BRANCH) - p->to.offset = r->s2->pc; - r1 = r; - } - - /* - * last pass - * eliminate nops - * free aux structures - */ - for(p = firstr->prog; p != P; p = p->link){ - while(p->link && p->link->as == ANOP) - p->link = p->link->link; - } - if(r1 != R) { - r1->link = freer; - freer = firstr; - } -} - -/* - * add mov b,rn - * just after r - */ -void -addmove(Reg *r, int bn, int rn, int f) -{ - Prog *p, *p1; - Var *v; - int badccr; - - badccr = 0; - p = r->prog; - p1 = p->link; - if(p1) - switch(p1->as) { - case AMOVW: - if(p1->from.type == D_CCR) - p = p1; - break; - - case ABEQ: - case ABNE: - case ABLE: - case ABLS: - case ABLT: - case ABMI: - case ABGE: - case ABPL: - case ABGT: - case ABHI: - case ABCC: - case ABCS: - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - p1->from.type = D_CCR; - p1->to.type = D_TOS; - p1->as = AMOVW; - p = p1; - badccr = 1; - } - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - v = var + bn; - p1->from.sym = v->sym; - p1->from.type = v->type; - p1->from.offset = v->offset; - p1->from.etype = v->etype; - p1->to.type = rn; - if(f) { - p1->to = p1->from; - p1->from = zprog.from; - p1->from.type = rn; - } - p1->as = opxt[OAS][v->etype]; - if(badccr) { - p = p1; - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - p1->from.type = D_TOS; - p1->to.type = D_CCR; - p1->as = AMOVW; - } - if(debug['R']) - print("%P\t.a%P\n", p, p1); -} - -Bits -mkvar(Adr *a, int as) -{ - Var *v; - int i, t, z; - long o; - Bits bit; - Sym *s; - - mvbits = 0; - t = a->type & D_MASK; - switch(t) { - - default: - if(t >= D_R0 && t < D_R0+NREG) { - regbits |= RtoB(t-D_R0); - if(as == ADIVUL || as == ADIVSL) - regbits |= RtoB(t-D_R0+1); - } - if(t >= D_A0 && t < D_A0+NREG) - regbits |= AtoB(t-D_A0); - if(t >= D_F0 && t < D_F0+NREG) - regbits |= FtoB(t-D_F0); - goto none; - - case D_EXTERN: - case D_STATIC: - case D_AUTO: - case D_PARAM: - break; - } - s = a->sym; - if(s == S) - goto none; - - if((a->type & I_MASK) == I_ADDR) - mvbits |= B_ADDR; - - switch(a->index & I_MASK) { - case I_INDEX1: - mvbits |= B_ADDR; - break; - - case I_INDEX2: - case I_INDEX3: - mvbits |= B_INDIR; - break; - } - - o = a->offset; - v = var; - for(i=0; i<nvar; i++) { - if(s == v->sym) - if(t == v->type) - if(o == v->offset) - goto out; - v++; - } - if(s) - if(s->name[0] == '.') - goto none; - if(nvar >= NVAR) { - if(debug['w'] > 1 && s) - warn(Z, "variable not optimized: %s", s->name); - goto none; - } - i = nvar; - nvar++; - v = &var[i]; - v->sym = s; - v->offset = o; - v->etype = a->etype; - v->type = t; - if(debug['R']) - print("bit=%2d et=%2d %s (%p,%d,%ld)\n", - i, a->etype, s->name, - v->sym, v->type, v->offset); - -out: - bit = blsh(i); - if(t == D_EXTERN || t == D_STATIC) - for(z=0; z<BITS; z++) - externs.b[z] |= bit.b[z]; - if(t == D_PARAM) - for(z=0; z<BITS; z++) - params.b[z] |= bit.b[z]; - if(a->etype != v->etype || !typechlpfd[a->etype]) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; /* funny punning */ - return bit; - -none: - return zbits; -} - -void -prop(Reg *r, Bits ref, Bits cal) -{ - Reg *r1, *r2; - int z; - - for(r1 = r; r1 != R; r1 = r1->p1) { - for(z=0; z<BITS; z++) { - ref.b[z] |= r1->refahead.b[z]; - if(ref.b[z] != r1->refahead.b[z]) { - r1->refahead.b[z] = ref.b[z]; - changer++; - } - cal.b[z] |= r1->calahead.b[z]; - if(cal.b[z] != r1->calahead.b[z]) { - r1->calahead.b[z] = cal.b[z]; - changer++; - } - } - switch(r1->prog->as) { - case ABSR: - for(z=0; z<BITS; z++) { - cal.b[z] |= ref.b[z] | externs.b[z]; - ref.b[z] = 0; - } - break; - - case ATEXT: - for(z=0; z<BITS; z++) { - cal.b[z] = 0; - ref.b[z] = 0; - } - break; - - case ARTS: - for(z=0; z<BITS; z++) { - cal.b[z] = externs.b[z]; - ref.b[z] = 0; - } - } - for(z=0; z<BITS; z++) { - ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | - r1->use1.b[z] | r1->use2.b[z]; - cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]); - r1->refbehind.b[z] = ref.b[z]; - r1->calbehind.b[z] = cal.b[z]; - } - if(r1->active) - break; - r1->active = 1; - } - for(; r != r1; r = r->p1) - for(r2 = r->p2; r2 != R; r2 = r2->p2link) - prop(r2, r->refbehind, r->calbehind); -} - -/* - * find looping structure - * - * 1) find reverse postordering - * 2) find approximate dominators, - * the actual dominators if the flow graph is reducible - * otherwise, dominators plus some other non-dominators. - * See Matthew S. Hecht and Jeffrey D. Ullman, - * "Analysis of a Simple Algorithm for Global Data Flow Problems", - * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts, - * Oct. 1-3, 1973, pp. 207-217. - * 3) find all nodes with a predecessor dominated by the current node. - * such a node is a loop head. - * recursively, all preds with a greater rpo number are in the loop - */ -long -postorder(Reg *r, Reg **rpo2r, long n) -{ - Reg *r1; - - r->rpo = 1; - r1 = r->s1; - if(r1 && !r1->rpo) - n = postorder(r1, rpo2r, n); - r1 = r->s2; - if(r1 && !r1->rpo) - n = postorder(r1, rpo2r, n); - rpo2r[n] = r; - n++; - return n; -} - -long -rpolca(long *idom, long rpo1, long rpo2) -{ - long t; - - if(rpo1 == -1) - return rpo2; - while(rpo1 != rpo2){ - if(rpo1 > rpo2){ - t = rpo2; - rpo2 = rpo1; - rpo1 = t; - } - while(rpo1 < rpo2){ - t = idom[rpo2]; - if(t >= rpo2) - fatal(Z, "bad idom"); - rpo2 = t; - } - } - return rpo1; -} - -int -doms(long *idom, long r, long s) -{ - while(s > r) - s = idom[s]; - return s == r; -} - -int -loophead(long *idom, Reg *r) -{ - long src; - - src = r->rpo; - if(r->p1 != R && doms(idom, src, r->p1->rpo)) - return 1; - for(r = r->p2; r != R; r = r->p2link) - if(doms(idom, src, r->rpo)) - return 1; - return 0; -} - -void -loopmark(Reg **rpo2r, long head, Reg *r) -{ - if(r->rpo < head || r->active == head) - return; - r->active = head; - r->loop += LOOP; - if(r->p1 != R) - loopmark(rpo2r, head, r->p1); - for(r = r->p2; r != R; r = r->p2link) - loopmark(rpo2r, head, r); -} - -void -loopit(Reg *r, long nr) -{ - Reg *r1; - long i, d, me; - - if(nr > maxnr) { - rpo2r = alloc(nr * sizeof(Reg*)); - idom = alloc(nr * sizeof(long)); - maxnr = nr; - } - - d = postorder(r, rpo2r, 0); - if(d > nr) - fatal(Z, "too many reg nodes"); - nr = d; - for(i = 0; i < nr / 2; i++){ - r1 = rpo2r[i]; - rpo2r[i] = rpo2r[nr - 1 - i]; - rpo2r[nr - 1 - i] = r1; - } - for(i = 0; i < nr; i++) - rpo2r[i]->rpo = i; - - idom[0] = 0; - for(i = 0; i < nr; i++){ - r1 = rpo2r[i]; - me = r1->rpo; - d = -1; - if(r1->p1 != R && r1->p1->rpo < me) - d = r1->p1->rpo; - for(r1 = r1->p2; r1 != nil; r1 = r1->p2link) - if(r1->rpo < me) - d = rpolca(idom, d, r1->rpo); - idom[i] = d; - } - - for(i = 0; i < nr; i++){ - r1 = rpo2r[i]; - r1->loop++; - if(r1->p2 != R && loophead(idom, r1)) - loopmark(rpo2r, i, r1); - } -} - -void -synch(Reg *r, Bits dif) -{ - Reg *r1; - int z; - - for(r1 = r; r1 != R; r1 = r1->s1) { - for(z=0; z<BITS; z++) { - dif.b[z] = (dif.b[z] & - ~(~r1->refbehind.b[z] & r1->refahead.b[z])) | - r1->set.b[z] | r1->regdiff.b[z]; - if(dif.b[z] != r1->regdiff.b[z]) { - r1->regdiff.b[z] = dif.b[z]; - changer++; - } - } - if(r1->active) - break; - r1->active = 1; - for(z=0; z<BITS; z++) - dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]); - if(r1->s2 != R) - synch(r1->s2, dif); - } -} - -ulong -allreg(ulong b, Rgn *r) -{ - Var *v; - int i, j; - - v = var + r->varno; - r->regno = D_NONE; - switch(v->etype) { - - default: - diag(Z, "unknown etype"); - break; - - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - i = BtoR(~b); - j = BtoA(~b); - if(r->costa == r->costr) - if(i > j) - i = NREG; - if(j < NREG && r->costa > 0) - if(r->costa > r->costr || i >= NREG) { - r->regno = D_A0 + j; - return AtoB(j); - } - if(i < NREG && r->costr > 0) { - r->regno = D_R0 + i; - return RtoB(i); - } - break; - - case TDOUBLE: - case TFLOAT: - i = BtoF(~b); - if(i < NREG) { - r->regno = D_F0 + i; - return FtoB(i); - } - break; - } - return 0; -} - -void -paint1(Reg *r, int bn) -{ - Reg *r1; - Prog *p; - int z; - ulong bb; - int x; - - z = bn/32; - bb = 1L<<(bn%32); - if(r->act.b[z] & bb) - return; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(r1->act.b[z] & bb) - break; - r = r1; - } - if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) { - changer -= CLOAD * r->loop; - changea -= CLOAD * r->loop; - if(debug['R'] && debug['v']) - print("%ld%P\tld %B $%d.%d\n", r->loop, - r->prog, blsh(bn), changer, changea); - } - for(;;) { - r->act.b[z] |= bb; - p = r->prog; - - if(r->use1.b[z] & bb) { - changer += CREF * r->loop; - changea += CREF * r->loop; - x = p->from.index; - if(x == D_NONE) { - switch(p->as) { - default: - changea = -CINF; - case AADDL: - case ASUBL: - case AMOVL: - case ACMPL: - break; - } - } else { - changer += (CXREF-CREF) * r->loop; - if(x != (I_INDEX3|D_NONE)) - changer = -CINF; - if((x&I_MASK) == I_INDEX1) - changea = -CINF; - } - if(p->as == AMOVL) { - x = p->to.type; - if(x >= D_R0 && x < D_R0+NREG) - changer += r->loop; - if(x >= D_A0 && x < D_A0+NREG) - changea += r->loop; - } - if(debug['R'] && debug['v']) - print("%ld%P\tu1 %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - if((r->use2.b[z]|r->set.b[z]) & bb) { - changer += CREF * r->loop; - changea += CREF * r->loop; - x = p->to.index; - if(x == D_NONE) - switch(p->as) { - default: - changea = -CINF; - break; - case AMOVL: - case AADDL: - case ACMPL: - case ASUBL: - case ACLRL: /* can be faked */ - case ATSTL: /* can be faked */ - break; - } - else { - changer += (CXREF-CREF) * r->loop; - if(x != (I_INDEX3|D_NONE)) - changer = -CINF; - if((x&I_MASK) == I_INDEX1) - changea = -CINF; - } - if(p->as == AMOVL) { - x = p->from.type; - if(x >= D_R0 && x < D_R0+NREG) - changer += r->loop; - if(x >= D_A0 && x < D_A0+NREG) - changea += r->loop; - } - if(debug['R'] && debug['v']) - print("%ld%P\tu2 %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - if(STORE(r) & r->regdiff.b[z] & bb) { - changer -= CLOAD * r->loop; - changea -= CLOAD * r->loop; - if(debug['R'] && debug['v']) - print("%ld%P\tst %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - paint1(r1, bn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - paint1(r1, bn); - r = r->s1; - if(r == R) - break; - if(r->act.b[z] & bb) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } -} - -ulong -paint2(Reg *r, int bn) -{ - Reg *r1; - int z; - ulong bb, vreg; - - z = bn/32; - bb = 1L << (bn%32); - vreg = regbits; - if(!(r->act.b[z] & bb)) - return vreg; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(!(r1->act.b[z] & bb)) - break; - r = r1; - } - for(;;) { - r->act.b[z] &= ~bb; - - vreg |= r->regu; - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - vreg |= paint2(r1, bn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - vreg |= paint2(r1, bn); - r = r->s1; - if(r == R) - break; - if(!(r->act.b[z] & bb)) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } - return vreg; -} - -void -paint3(Reg *r, int bn, ulong rb, int rn) -{ - Reg *r1; - Prog *p; - int z; - ulong bb; - - z = bn/32; - bb = 1L << (bn%32); - if(r->act.b[z] & bb) - return; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(r1->act.b[z] & bb) - break; - r = r1; - } - if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) - addmove(r, bn, rn, 0); - for(;;) { - r->act.b[z] |= bb; - p = r->prog; - - if(r->use1.b[z] & bb) { - if(debug['R']) - print("%P", p); - addreg(&p->from, rn); - if(debug['R']) - print("\t.c%P\n", p); - } - if((r->use2.b[z]|r->set.b[z]) & bb) { - if(debug['R']) - print("%P", p); - addreg(&p->to, rn); - if(debug['R']) - print("\t.c%P\n", p); - } - if(STORE(r) & r->regdiff.b[z] & bb) - addmove(r, bn, rn, 1); - r->regu |= rb; - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - paint3(r1, bn, rb, rn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - paint3(r1, bn, rb, rn); - r = r->s1; - if(r == R) - break; - if(r->act.b[z] & bb) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } -} - -void -addreg(Adr *a, int rn) -{ - int x; - - a->sym = 0; - x = a->index; - if(rn >= D_R0 && rn < D_R0+NREG) - goto addr; - if(x == (I_INDEX3|D_NONE)) { - a->type = rn | I_INDIR; - a->index = D_NONE; - a->offset = a->displace; - a->displace = 0; - return; - } - if(x != D_NONE) { - a->type = rn | I_INDIR; - a->index += I_INDEX1 - I_INDEX2; - a->offset = a->displace; - a->displace = 0; - return; - } - a->type = rn | (a->type & I_INDIR); - return; - -addr: - if(x == (I_INDEX3|D_NONE)) { - a->type = D_NONE|I_INDIR; - a->index += I_INDEX1 + rn - D_NONE - I_INDEX3; - a->scale = 4; /* .L*1 */ - a->offset = a->displace; - a->displace = 0; - return; - } - a->type = rn | (a->type & I_INDIR); -} - -/* - * bit reg - * 0-7 R0-R7 - * 8-15 A0-A7 - * 16-23 F0-F7 - */ -ulong -RtoB(int r) -{ - - if(r < 0 || r >= NREG) - return 0; - return 1L << (r + 0); -} - -int -BtoR(ulong b) -{ - - b &= 0x0000ffL; - if(b == 0) - return NREG; - return bitno(b) - 0; -} - -ulong -AtoB(int a) -{ - - if(a < 0 || a >= NREG) - return 0; - return 1L << (a + NREG); -} - -int -BtoA(ulong b) -{ - - b &= 0x00ff00L; - if(b == 0) - return NREG; - return bitno(b) - NREG; -} - -ulong -FtoB(int f) -{ - - if(f < 0 || f >= NREG) - return 0; - return 1L << (f + NREG+NREG); -} - -int -BtoF(ulong b) -{ - - b &= 0xff0000L; - if(b == 0) - return NREG; - return bitno(b) - NREG-NREG; -} diff --git a/utils/2c/sgen.c b/utils/2c/sgen.c deleted file mode 100644 index b4020a99..00000000 --- a/utils/2c/sgen.c +++ /dev/null @@ -1,819 +0,0 @@ -#include "gc.h" - -void -codgen(Node *n, Node *nn) -{ - Prog *sp; - - argoff = 0; - inargs = 0; - for(;; nn = nn->left) { - if(nn == Z) { - diag(Z, "cant find function name"); - return; - } - if(nn->op == ONAME) - break; - } - nearln = nn->lineno; - gpseudo(ATEXT, nn->sym, D_CONST, stkoff); - sp = p; - - retok = 0; - gen(n); - if(!retok) - if(thisfn->link->etype != TVOID) - warn(Z, "no return at end of function: %s", nn->sym->name); - - noretval(3); - gbranch(ORETURN); - if(!debug['N'] || debug['R'] || debug['P']) - regopt(sp); -} - -void -gen(Node *n) -{ - Node *l; - Prog *sp, *spc, *spb; - Case *cn; - long sbc, scc; - int g, o; - -loop: - if(n == Z) - return; - nearln = n->lineno; - o = n->op; - if(debug['G']) - if(o != OLIST) - print("%L %O\n", nearln, o); - - retok = 0; - switch(o) { - - default: - complex(n); - doinc(n, PRE); - cgen(n, D_NONE, n); - doinc(n, POST); - break; - - case OLIST: - gen(n->left); - - rloop: - n = n->right; - goto loop; - - case ORETURN: - retok = 1; - complex(n); - if(n->type == T) - break; - l = n->left; - if(l == Z) { - noretval(3); - gbranch(ORETURN); - break; - } - doinc(l, PRE); - if(typesuv[n->type->etype]) { - sugen(l, D_TREE, nodret, n->type->width); - doinc(l, POST); - noretval(3); - gbranch(ORETURN); - break; - } - g = regalloc(n->type, regret(n->type)); - cgen(l, g, n); - doinc(l, POST); - if(typefd[n->type->etype]) - noretval(1); - else - noretval(2); - gbranch(ORETURN); - regfree(g); - break; - - case OLABEL: - l = n->left; - if(l) { - l->xoffset = pc; - if(l->label) - patch(l->label, pc); - } - gbranch(OGOTO); /* prevent self reference in reg */ - patch(p, pc); - goto rloop; - - case OGOTO: - retok = 1; - n = n->left; - if(n == Z) - return; - if(n->complex == 0) { - diag(Z, "label undefined: %s", n->sym->name); - return; - } - gbranch(OGOTO); - if(n->xoffset) { - patch(p, n->xoffset); - return; - } - if(n->label) - patch(n->label, pc-1); - n->label = p; - return; - - case OCASE: - l = n->left; - if(cases == C) - diag(n, "case/default outside a switch"); - if(l == Z) { - casf(); - cases->val = 0; - cases->def = 1; - cases->label = pc; - setsp();; - goto rloop; - } - complex(l); - if(l->type == T) - goto rloop; - if(l->op == OCONST) - if(typechl[l->type->etype]) { - casf(); - cases->val = l->vconst; - cases->def = 0; - cases->label = pc; - setsp(); - goto rloop; - } - diag(n, "case expression must be integer constant"); - goto rloop; - - case OSWITCH: - l = n->left; - complex(l); - doinc(l, PRE); - if(l->type == T) - break; - if(!typechl[l->type->etype]) { - diag(n, "switch expression must be integer"); - break; - } - g = regalloc(types[TLONG], D_NONE); - n->type = types[TLONG]; - cgen(l, g, n); - regfree(g); - doinc(l, POST); - setsp(); - gbranch(OGOTO); /* entry */ - sp = p; - - cn = cases; - cases = C; - casf(); - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - gen(n->right); - gbranch(OGOTO); - patch(p, breakpc); - - patch(sp, pc); - doswit(g, l); - - patch(spb, pc); - cases = cn; - breakpc = sbc; - setsp(); - break; - - case OWHILE: - case ODWHILE: - l = n->left; - gbranch(OGOTO); /* entry */ - sp = p; - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - if(n->op == OWHILE) - patch(sp, pc); - bcomplex(l); /* test */ - patch(p, breakpc); - - if(n->op == ODWHILE) - patch(sp, pc); - gen(n->right); /* body */ - gbranch(OGOTO); - patch(p, continpc); - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - break; - - case OFOR: - l = n->left; - gen(l->right->left); /* init */ - gbranch(OGOTO); /* entry */ - sp = p; - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - gen(l->right->right); /* inc */ - patch(sp, pc); - if(l->left != Z) { /* test */ - bcomplex(l->left); - patch(p, breakpc); - } - gen(n->right); /* body */ - gbranch(OGOTO); - patch(p, continpc); - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - break; - - case OCONTINUE: - if(continpc < 0) { - diag(n, "continue not in a loop"); - break; - } - gbranch(OGOTO); - patch(p, continpc); - break; - - case OBREAK: - if(breakpc < 0) { - diag(n, "break not in a loop"); - break; - } - gbranch(OGOTO); - patch(p, breakpc); - break; - - case OIF: - l = n->left; - bcomplex(l); - sp = p; - if(n->right->left != Z) - gen(n->right->left); - if(n->right->right != Z) { - gbranch(OGOTO); - patch(sp, pc); - sp = p; - gen(n->right->right); - } - patch(sp, pc); - break; - - case OSET: - case OUSED: - usedset(n->left, o); - break; - } -} - -void -usedset(Node *n, int o) -{ - if(n->op == OLIST) { - usedset(n->left, o); - usedset(n->right, o); - return; - } - complex(n); - switch(n->op) { - case OADDR: /* volatile */ - gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z); - p->as = ANOP; - break; - case ONAME: - if(o == OSET) - gopcode(OTST, types[TINT], D_NONE, Z, D_TREE, n); - else - gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z); - p->as = ANOP; - break; - } -} - -void -noretval(int n) -{ - - if(n & 1) { - gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TLONG]), Z); - p->as = ANOP; - } - if(n & 2) { - gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TDOUBLE]), Z); - p->as = ANOP; - } -} - -/* - * calculate addressability as follows - * REGISTER ==> 12 register - * NAME ==> 10/11 name+value(SB/SP) - * CONST ==> 20 $value - * *(20) ==> 21 value - * &(10) ==> 12 $name+value(SB) - * &(11) ==> 1 $name+value(SP) - * (12) + (20) ==> 12 fold constants - * (1) + (20) ==> 1 fold constants - * *(12) ==> 10 back to name - * *(1) ==> 11 back to name - * - * (2,10,11) + (20) ==> 2 indirect w offset - * (2) ==> &13 - * *(10,11) ==> 13 indirect, no index - * - * (20) * (X) ==> 7 multiplier in indexing - * (X,7) + (12,1) ==> 8 adder in indexing (addresses) - * (X,7) + (10,11,2) ==> 8 adder in indexing (names) - * (8) ==> &9 index, almost addressable - * - * (X)++ ==> X fake addressability - * - * calculate complexity (number of registers) - */ -void -xcom(Node *n) -{ - Node *l, *r; - int g; - - if(n == Z) - return; - l = n->left; - r = n->right; - n->complex = 0; - n->addable = 0; - switch(n->op) { - case OCONST: - n->addable = 20; - break; - - case ONAME: - n->addable = 10; - if(n->class == CPARAM || n->class == CAUTO) - n->addable = 11; - break; - - case OREGISTER: - n->addable = 12; - break; - - case OADDR: - xcom(l); - if(l->addable == 10) - n->addable = 12; - else - if(l->addable == 11) - n->addable = 1; - break; - - case OADD: - xcom(l); - xcom(r); - if(n->type->etype != TIND) - break; - - if(l->addable == 20) - switch(r->addable) { - case 12: - case 1: - n->addable = r->addable; - goto brk; - case 10: - case 11: - case 2: - goto addr13; - } - if(r->addable == 20) - switch(l->addable) { - case 12: - case 1: - n->addable = l->addable; - goto brk; - case 10: - case 11: - case 2: - addr13: - n->addable = 2; - l = new1(OXXX, Z, Z); - *l = *n; - n->op = OIND; - n->left = l; - n->right = Z; - n->addable = 13; - l = new1(OXXX, Z, Z); - *l = *n; - n->op = OADDR; - n->left = l; - n->right = Z; - n->addable = 2; - goto brk; - } - - switch(r->addable) { - case 10: - case 11: - case 12: - case 1: - n->addable = 8; - } - switch(l->addable) { - case 10: - case 11: - case 12: - case 1: - n->addable = 8; - } - if(n->addable == 8) { - indx(n); - l = new1(OINDEX, idx.basetree, idx.regtree); - l->scale = idx.scale; - l->addable = 9; - l->complex = l->right->complex; - l->type = l->left->type; - n->op = OADDR; - n->left = l; - n->right = Z; - n->addable = 0; - break; - } - break; - - case OIND: - xcom(l); - if(l->op == OADDR) { - l = l->left; - l->type = n->type; - *n = *l; - return; - } - switch(l->addable) { - case 20: - n->addable = 21; - break; - case 1: - n->addable = 11; - break; - case 12: - n->addable = 10; - break; - case 10: - case 11: - case 2: - n->addable = 13; - break; - } - break; - - case OASHL: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vconst(r); - if(g >= 0 && g < 4) - n->addable = 7; - break; - - case OMUL: - case OLMUL: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - n->op = OASHL; - r->vconst = g; - if(g < 4) - n->addable = 7; - break; - } - g = vlog(l); - if(g >= 0) { - n->left = r; - n->right = l; - l = r; - r = n->right; - n->op = OASHL; - r->vconst = g; - if(g < 4) - n->addable = 7; - break; - } - break; - - case ODIV: - case OLDIV: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - if(n->op == ODIV) - n->op = OASHR; - else - n->op = OLSHR; - r->vconst = g; - } - break; - - case OSUB: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - if(vconst(l) == 0) { - n->op = ONEG; - n->left = r; - n->right = Z; - } - break; - - case OXOR: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - if(vconst(l) == -1) { - n->op = OCOM; - n->left = r; - n->right = Z; - } - break; - - case OASMUL: - case OASLMUL: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - n->op = OASASHL; - r->vconst = g; - } - goto aseae; - - case OASDIV: - case OASLDIV: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - g = vlog(r); - if(g >= 0) { - if(n->op == OASDIV) - n->op = OASASHR; - else - n->op = OASLSHR; - r->vconst = g; - } - goto aseae; - - case OASLMOD: - case OASMOD: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - - aseae: /* hack that there are no byte/short mul/div operators */ - if(n->type->etype == TCHAR || n->type->etype == TSHORT) { - n->right = new1(OCAST, n->right, Z); - n->right->type = types[TLONG]; - n->type = types[TLONG]; - } - if(n->type->etype == TUCHAR || n->type->etype == TUSHORT) { - n->right = new1(OCAST, n->right, Z); - n->right->type = types[TULONG]; - n->type = types[TULONG]; - } - goto asop; - - case OASXOR: - case OASOR: - case OASADD: - case OASSUB: - case OASLSHR: - case OASASHR: - case OASASHL: - case OASAND: - case OAS: - xcom(l); - xcom(r); - if(typev[n->type->etype]) - break; - - asop: - if(l->addable > INDEXED && - l->complex < FNX && - r && r->complex < FNX) - n->addable = l->addable; - break; - - case OPOSTINC: - case OPREINC: - case OPOSTDEC: - case OPREDEC: - xcom(l); - if(typev[n->type->etype]) - break; - if(l->addable > INDEXED && - l->complex < FNX) - n->addable = l->addable; - break; - - default: - if(l != Z) - xcom(l); - if(r != Z) - xcom(r); - break; - } - -brk: - n->complex = 0; - if(n->addable >= 10) - return; - if(l != Z) - n->complex = l->complex; - if(r != Z) { - if(r->complex == n->complex) - n->complex = r->complex+1; - else - if(r->complex > n->complex) - n->complex = r->complex; - } - if(n->complex == 0) - n->complex++; - - if(com64(n)) - return; - - switch(n->op) { - - case OFUNC: - n->complex = FNX; - break; - - case OADD: - case OMUL: - case OLMUL: - case OXOR: - case OAND: - case OOR: - /* - * symmetric operators, make right side simple - * if same, put constant on left to get movq - */ - if(r->complex > l->complex || - (r->complex == l->complex && r->addable == 20)) { - n->left = r; - n->right = l; - } - break; - - case OLE: - case OLT: - case OGE: - case OGT: - case OEQ: - case ONE: - /* - * relational operators, make right side simple - * if same, put constant on left to get movq - */ - if(r->complex > l->complex || r->addable == 20) { - n->left = r; - n->right = l; - n->op = invrel[relindex(n->op)]; - } - break; - } -} - -void -indx(Node *n) -{ - Node *l, *r; - int t; - - if(debug['x']) - prtree(n, "indx"); - t = 0; - -loop: - l = n->left; - r = n->right; - switch(r->addable) { - default: - if(t) { - diag(n, "bad indx"); - break; - } - n->right = l; - n->left = r; - t++; - goto loop; - - case 10: - case 11: - if(l->op == ONAME && r->op == ONAME) - if(l->etype == TIND) - if(r->etype != TIND) { - n->right = l; - n->left = r; - goto loop; - } - if(l->addable == 1 || l->addable == 12) { - n->right = l; - n->left = r; - goto loop; - } - - case 1: - case 12: - break; - } - if(l->addable != 7) { - idx.regtree = l; - idx.scale = 0; - } else - if(l->right->addable == 20) { - idx.regtree = l->left; - idx.scale = l->right->vconst; - } else { - idx.regtree = l->right; - idx.scale = l->left->vconst; - } - t = ewidth[idx.regtree->type->etype]; - if(t == SZ_LONG) - idx.scale += 4; - else - if(t != SZ_SHORT) - diag(n, "index not W or L"); - - idx.basetree = r; - if(debug['x']) { - print("scale = %d\n", idx.scale); - prtree(idx.regtree, "index"); - prtree(idx.basetree, "base"); - } -} - -void -bcomplex(Node *n) -{ - - complex(n); - if(n->type != T) - if(tcompat(n, T, n->type, tnot)) - n->type = T; - if(n->type != T) { - bool64(n); - doinc(n, PRE); - boolgen(n, 1, D_NONE, Z, n); - } else - gbranch(OGOTO); -} - -Node* -nodconst(long v) -{ - - return (Node*)v; -} diff --git a/utils/2c/swt.c b/utils/2c/swt.c deleted file mode 100644 index ca6895f9..00000000 --- a/utils/2c/swt.c +++ /dev/null @@ -1,1046 +0,0 @@ -#include "gc.h" - -int -swcmp(const void *a1, const void *a2) -{ - C1 *p1, *p2; - - p1 = (C1*)a1; - p2 = (C1*)a2; - if(p1->val < p2->val) - return -1; - return p1->val > p2->val; -} - -void -doswit(int g, Node *n) -{ - Case *c; - C1 *q, *iq; - long def, nc, i; - - def = 0; - nc = 0; - for(c = cases; c->link != C; c = c->link) { - if(c->def) { - if(def) - diag(n, "more than one default in switch"); - def = c->label; - continue; - } - nc++; - } - - iq = alloc(nc*sizeof(C1)); - q = iq; - for(c = cases; c->link != C; c = c->link) { - if(c->def) - continue; - q->label = c->label; - q->val = c->val; - q++; - } - qsort(iq, nc, sizeof(C1), swcmp); - if(def == 0) - def = breakpc; - for(i=0; i<nc-1; i++) - if(iq[i].val == iq[i+1].val) - diag(n, "duplicate cases in switch %ld", iq[i].val); - swit1(iq, nc, def, g, n); -} - -#define N1 4 /* ncase: always linear */ -#define N2 5 /* min ncase: direct */ -#define N3 4 /* range/ncase: direct */ - /* else binary */ -void -swit1(C1 *q, int nc, long def, int g, Node *n) -{ - C1 *r, *s; - int i, l, m, y; - long v, range; - Prog *sp1, *sp2; - - /* note that g and g+1 are not allocated */ - if(nc <= N1) - goto linear; - y = 23*nc/100 + 5; /* number of cases needed to make */ - if(y < N2) /* direct switch worthwile */ - y = N2; /* try to do better than n**2 here */ - for(m=nc; m>=y; m--) { /* m is number of cases */ - s = q+nc; - r = s-m; - for(l=nc-m; l>=0; l--) { /* l is base of contig cases */ - s--; - range = s->val - r->val; - if(range > 0 && range <= N3*m) - goto direct; - r--; - } - } - - /* - * divide and conquer - */ - i = nc / 2; - r = q+i; - v = r->val; - /* compare median */ - if(v >= -128 && v < 128) { - gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); - gopcode(OEQ, n->type, g, n, g+1, n); - } else - gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); - gbranch(OLT); - sp1 = p; - gbranch(OGT); - sp2 = p; - gbranch(OGOTO); - patch(p, r->label); - - patch(sp1, pc); - swit1(q, i, def, g, n); - - patch(sp2, pc); - swit1(r+1, nc-i-1, def, g, n); - return; - -direct: - /* compare low bound */ - v = r->val; - if(v >= -128 && v < 128) { - gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); - gopcode(OEQ, n->type, g, n, g+1, n); - } else - gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); - gbranch(OLT); - sp1 = p; - - /* compare high bound */ - v = s->val; - if(v >= -128 && v < 128) { - gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); - gopcode(OEQ, n->type, g, n, g+1, n); - } else - gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); - gbranch(OGT); - sp2 = p; - - /* switch */ - v = r->val; - gpseudo(AMOVW, symstatic, D_R0, 0L); - p->from.offset = nstatic - v*2; - p->from.index = g|I_INDEX1; - p->from.scale = 5; - nextpc(); - p->as = ACASEW; - - /* table */ - for(i=0; i<=range; i++) { - gbranch(OCASE); - if(v == r->val) { - patch(p, r->label); - r++; - } else - patch(p, def); - p->from.type = D_STATIC; - p->from.sym = symstatic; - p->from.offset = nstatic; - nstatic += types[TSHORT]->width; - v++; - } - gbranch(OGOTO); - patch(p, def); - if(r != s+1) - print("smelly direct switch\n"); - - if(l > 0) { - patch(sp1, pc); - swit1(q, l, def, g, n); - } else - patch(sp1, def); - - m += l; - if(m < nc) { - patch(sp2, pc); - swit1(q+m, nc-m, def, g, n); - } else - patch(sp2, def); - return; - - -linear: - for(i=0; i<nc; i++) { - v = q->val; - if(v >= -128 && v < 128) { - gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); - gopcode(OEQ, n->type, g+1, n, g, n); - } else - gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); - gbranch(OEQ); - patch(p, q->label); - q++; - } - gbranch(OGOTO); - patch(p, def); -} - -void -casf(void) -{ - Case *c; - - c = alloc(sizeof(*c)); - c->link = cases; - cases = c; -} - - -int -bitload(Node *b, int n1, int n2, int n3, Node *nn) -{ - int sh, g, gs; - long v; - Node *l; - Type *t; - - /* - * n1 gets adjusted/masked value - * n2 gets address of cell - * n3 gets contents of cell - */ - gs = 0; - t = tfield; - - l = b->left; - g = regalloc(t, n3); - if(n2 != D_NONE) { - lcgen(l, n2, Z); - n2 |= I_INDIR; - gmove(t, t, n2, l, g, l); - gmove(t, t, g, l, n1, l); - } else - cgen(l, g, nn); - if(b->type->shift == 0 && typeu[b->type->etype]) { - v = ~0 + (1L << b->type->nbits); - gopcode(OAND, t, D_CONST, nodconst(v), g, l); - } else { - sh = 32 - b->type->shift - b->type->nbits; - if(sh > 0) - if(sh >= 8) { - gs = regalloc(t, D_NONE); - gmove(t, t, D_CONST, nodconst(sh), gs, l); - gopcode(OASHL, t, gs, l, g, l); - if(b->type->shift) - regfree(gs); - } else - gopcode(OASHL, t, D_CONST, nodconst(sh), g, l); - sh += b->type->shift; - if(sh > 0) { - if(sh >= 8) { - if(b->type->shift) { - gs = regalloc(t, D_NONE); - gmove(t, t, D_CONST, nodconst(sh), gs, l); - } - if(typeu[b->type->etype]) - gopcode(OLSHR, t, gs, l, g, l); - else - gopcode(OASHR, t, gs, l, g, l); - regfree(gs); - } else { - if(typeu[b->type->etype]) - gopcode(OLSHR, t, D_CONST, nodconst(sh), g, l); - else - gopcode(OASHR, t, D_CONST, nodconst(sh), g, l); - } - } - } - return g; -} - -void -bitstore(Node *b, int n1, int n2, int n3, int result, Node *nn) -{ - long v; - Node *l; - Type *t; - int sh, g, gs; - - /* - * n1 has adjusted/masked value - * n2 has address of cell - * n3 has contents of cell - */ - t = tfield; - - l = b->left; - g = regalloc(t, D_NONE); - v = ~0 + (1L << b->type->nbits); - gopcode(OAND, t, D_CONST, nodconst(v), n1, l); - gmove(t, t, n1, l, g, l); - if(result != D_NONE) - gmove(t, nn->type, n1, l, result, nn); - sh = b->type->shift; - if(sh > 0) { - if(sh >= 8) { - gs = regalloc(t, D_NONE); - gmove(t, t, D_CONST, nodconst(sh), gs, l); - gopcode(OASHL, t, gs, l, g, l); - regfree(gs); - } else - gopcode(OASHL, t, D_CONST, nodconst(sh), g, l); - } - v <<= sh; - gopcode(OAND, t, D_CONST, nodconst(~v), n3, l); - gopcode(OOR, t, n3, l, g, l); - gmove(t, t, g, l, n2|I_INDIR, l); - - regfree(g); - regfree(n1); - regfree(n2); - regfree(n3); -} - -long -outstring(char *s, long n) -{ - long r; - - r = nstring; - while(n) { - string[mnstring] = *s++; - mnstring++; - nstring++; - if(mnstring >= NSNAME) { - gpseudo(ADATA, symstring, D_SCONST, 0L); - memmove(p->to.sval, string, NSNAME); - p->from.offset = nstring - NSNAME; - p->from.displace = NSNAME; - mnstring = 0; - } - n--; - } - return r; -} - -long -outlstring(ushort *s, long n) -{ - char buf[2]; - int c; - long r; - - while(nstring & 1) - outstring("", 1); - r = nstring; - while(n > 0) { - c = *s++; - if(align(0, types[TCHAR], Aarg1)) { - buf[0] = c>>8; - buf[1] = c; - } else { - buf[0] = c; - buf[1] = c>>8; - } - outstring(buf, 2); - n -= sizeof(ushort); - } - return r; -} - -int -doinc(Node *n, int f) -{ - Node *l; - int a; - -loop: - if(n == Z) - return 0; - l = n->left; - switch(n->op) { - - case OPOSTINC: - case OPOSTDEC: - if(f & POST) { - a = n->addable; - if(a >= INDEXED) { - if(f & TEST) - return 1; - n->addable = 0; - cgen(n, D_NONE, n); - n->addable = a; - } - } - break; - - case OAS: - case OASLMUL: - case OASLDIV: - case OASLMOD: - case OASMUL: - case OASDIV: - case OASMOD: - case OASXOR: - case OASOR: - case OASADD: - case OASSUB: - case OASLSHR: - case OASASHR: - case OASASHL: - case OASAND: - - case OPREINC: - case OPREDEC: - if(f & PRE) { - a = n->addable; - if(a >= INDEXED) { - if(f & TEST) - return 1; - n->addable = 0; - doinc(n, PRE); - cgen(n, D_NONE, n); - n->addable = a; - return 0; - } - } - break; - - case OFUNC: - if(f & PRE) - break; - return 0; - - case ONAME: - case OREGISTER: - case OSTRING: - case OCONST: - - case OANDAND: - case OOROR: - return 0; - - case OCOND: - return 0; - - case OCOMMA: - n = n->right; - if(f & PRE) - n = l; - goto loop; - } - if(l != Z) - if(doinc(l, f)) - return 1; - n = n->right; - goto loop; -} - -void -setsp(void) -{ - - nextpc(); - p->as = AADJSP; - p->from.type = D_CONST; - p->from.offset = 0; -} - -void -adjsp(long o) -{ - - if(o != 0) { - nextpc(); - p->as = AADJSP; - p->from.type = D_CONST; - p->from.offset = o; - argoff += o; - } -} - -int -simplv(Node *n) -{ - - if(n->addable <= INDEXED) - return 0; - while(n->op == OIND) - n = n->left; - if(n->op == ONAME) - return 1; - return 0; -} - -int -eval(Node *n, int g) -{ - - if(n->addable >= INDEXED) - return D_TREE; - g = regalloc(n->type, g); - cgen(n, g, n); - return g; -} - -void outhist(Biobuf*); -void zname(Biobuf*, Sym*, int); -void zaddr(Biobuf*, Adr*, int); -void zwrite(Biobuf*, Prog*, int, int); - -void -outcode(void) -{ - struct { Sym *sym; short type; } h[NSYM]; - Prog *p; - Sym *s; - int f, sf, st, t, sym; - Biobuf b; - - if(debug['S']) { - for(p = firstp; p != P; p = p->link) - if(p->as != ADATA && p->as != AGLOBL) - pc--; - for(p = firstp; p != P; p = p->link) { - print("%P\n", p); - if(p->as != ADATA && p->as != AGLOBL) - pc++; - } - } - f = open(outfile, OWRITE); - if(f < 0) { - diag(Z, "cant open %s", outfile); - errorexit(); - } - Binit(&b, f, OWRITE); - Bseek(&b, 0L, 2); - outhist(&b); - for(sym=0; sym<NSYM; sym++) { - h[sym].sym = S; - h[sym].type = 0; - } - sym = 1; - for(p = firstp; p != P; p = p->link) { - jackpot: - sf = 0; - s = p->from.sym; - while(s != S) { - sf = s->sym; - if(sf < 0 || sf >= NSYM) - sf = 0; - t = p->from.type & D_MASK; - if(h[sf].type == t) - if(h[sf].sym == s) - break; - s->sym = sym; - zname(&b, s, t); - h[sym].sym = s; - h[sym].type = t; - sf = sym; - sym++; - if(sym >= NSYM) - sym = 1; - break; - } - st = 0; - s = p->to.sym; - while(s != S) { - st = s->sym; - if(st < 0 || st >= NSYM) - st = 0; - t = p->to.type & D_MASK; - if(h[st].type == t) - if(h[st].sym == s) - break; - s->sym = sym; - zname(&b, s, t); - h[sym].sym = s; - h[sym].type = t; - st = sym; - sym++; - if(sym >= NSYM) - sym = 1; - if(st == sf) - goto jackpot; - break; - } - zwrite(&b, p, sf, st); - } - Bflush(&b); - close(f); - firstp = P; - lastp = P; -} - -void -zwrite(Biobuf *b, Prog *p, int sf, int st) -{ - long l; - - l = p->as; - Bputc(b, l); - Bputc(b, l>>8); - l = p->lineno; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - zaddr(b, &p->from, sf); - zaddr(b, &p->to, st); -} - -void -zname(Biobuf *b, Sym *s, int t) -{ - char *n; - ulong sig; - - if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){ - sig = sign(s); - Bputc(b, ASIGNAME); - Bputc(b, ASIGNAME>>8); - Bputc(b, sig); - Bputc(b, sig>>8); - Bputc(b, sig>>16); - Bputc(b, sig>>24); - s->sig = SIGDONE; - } - else{ - Bputc(b, ANAME); /* as */ - Bputc(b, ANAME>>8); /* as */ - } - Bputc(b, t); /* type */ - Bputc(b, s->sym); /* sym */ - n = s->name; - while(*n) { - Bputc(b, *n); - n++; - } - Bputc(b, 0); -} - -void -zaddr(Biobuf *b, Adr *a, int s) -{ - long l; - int i, t; - char *n; - Ieee e; - - t = 0; - if(a->field) - t |= T_FIELD; - if(a->index != D_NONE) - t |= T_INDEX; - if(s) - t |= T_SYM; - - switch(a->type) { - default: - if(a->offset) - t |= T_OFFSET; - if(a->displace) - t |= T_INDEX; - if(a->type & ~0xff) - t |= T_TYPE; - break; - case D_FCONST: - t |= T_FCONST; - break; - case D_SCONST: - t |= T_SCONST; - break; - } - Bputc(b, t); - - if(t & T_FIELD) { /* implies field */ - i = a->field; - Bputc(b, i); - Bputc(b, i>>8); - } - if(t & T_INDEX) { /* implies index, scale, displace */ - i = a->index; - Bputc(b, i); - Bputc(b, i>>8); - Bputc(b, a->scale); - l = a->displace; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - } - if(t & T_OFFSET) { /* implies offset */ - l = a->offset; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - } - if(t & T_SYM) /* implies sym */ - Bputc(b, s); - if(t & T_FCONST) { - ieeedtod(&e, a->dval); - l = e.l; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - l = e.h; - Bputc(b, l); - Bputc(b, l>>8); - Bputc(b, l>>16); - Bputc(b, l>>24); - return; - } - if(t & T_SCONST) { - n = a->sval; - for(i=0; i<NSNAME; i++) { - Bputc(b, *n); - n++; - } - return; - } - i = a->type; - Bputc(b, i); - if(t & T_TYPE) - Bputc(b, i>>8); -} - - - -void -outhist(Biobuf *b) -{ - Hist *h; - char *p, *q, *op, c; - Prog pg; - int n; - - pg = zprog; - pg.as = AHISTORY; - c = pathchar(); - for(h = hist; h != H; h = h->link) { - p = h->name; - op = 0; - /* on windows skip drive specifier in pathname */ - if(systemtype(Windows) && p && p[1] == ':'){ - p += 2; - c = *p; - } - if(p && p[0] != c && h->offset == 0 && pathname){ - /* on windows skip drive specifier in pathname */ - if(systemtype(Windows) && pathname[1] == ':') { - op = p; - p = pathname+2; - c = *p; - } else if(pathname[0] == c){ - op = p; - p = pathname; - } - } - while(p) { - q = utfrune(p, c); - if(q) { - n = q-p; - if(n == 0){ - n = 1; /* leading "/" */ - *p = '/'; /* don't emit "\" on windows */ - } - q++; - } else { - n = strlen(p); - q = 0; - } - if(n) { - Bputc(b, ANAME); - Bputc(b, ANAME>>8); - Bputc(b, D_FILE); - Bputc(b, 1); - Bputc(b, '<'); - Bwrite(b, p, n); - Bputc(b, 0); - } - p = q; - if(p == 0 && op) { - p = op; - op = 0; - } - } - pg.lineno = h->line; - pg.to.type = zprog.to.type; - pg.to.offset = h->offset; - if(h->offset) - pg.to.type = D_CONST; - - zwrite(b, &pg, 0, 0); - } -} - -void -ieeedtod(Ieee *ieee, double native) -{ - double fr, ho, f; - int exp; - - if(native < 0) { - ieeedtod(ieee, -native); - ieee->h |= 0x80000000L; - return; - } - if(native == 0) { - ieee->l = 0; - ieee->h = 0; - return; - } - fr = frexp(native, &exp); - f = 2097152L; /* shouldnt use fp constants here */ - fr = modf(fr*f, &ho); - ieee->h = ho; - ieee->h &= 0xfffffL; - ieee->h |= (exp+1022L) << 20; - f = 65536L; - fr = modf(fr*f, &ho); - ieee->l = ho; - ieee->l <<= 16; - ieee->l |= (long)(fr*f); -} - -int -nodalloc(Type *t, int g, Node *n) -{ - - n->type = t; - n->op = OREGISTER; - n->addable = 12; - n->complex = 0; - g = regaddr(g); - n->reg = g | I_INDIR; - n->xoffset = 0; - return g; -} - -int -mulcon(Node *n, Node *c, int result, Node *nn) -{ - long v; - - if(typefd[n->type->etype]) - return 0; - v = c->vconst; - if(mulcon1(n, v, result, nn)) - return 1; - return 0; -} - -int -shlcon(Node *n, Node *c, int result, Node *nn) -{ - long v; - - v = 1L << c->vconst; - return mulcon1(n, v, result, nn); -} - -int -mulcon1(Node *n, long v, int result, Node *nn) -{ - int g, g1, a1, a2, neg; - int o; - char code[10], *p; - - if(result == D_NONE) - return 0; - neg = 0; - if(v < 0) { - v = -v; - neg++; - } - a1 = 0; - a2 = multabsize; - for(;;) { - if(a1 >= a2) - return 0; - g1 = (a2 + a1)/2; - if(v < multab[g1].val) { - a2 = g1; - continue; - } - if(v > multab[g1].val) { - a1 = g1+1; - continue; - } - break; - } - strcpy(code, "0"); - strncat(code, multab[g1].code, sizeof(multab[0].code)); - p = code; - if(p[1] == 'i') - p += 2; - g = regalloc(n->type, result); - cgen(n, g, n); - if(neg) - gopcode(ONEG, n->type, D_NONE, n, g, n); - g1 = regalloc(n->type, D_NONE); -loop: - switch(*p) { - case 0: - regfree(g1); - gmove(n->type, nn->type, g, n, result, nn); - regfree(g); - return 1; - case '0': - o = OAS; - *p -= '0'; - goto com; - case '1': - case '2': - o = OSUB; - *p -= '1'; - goto com; - case '3': - case '4': - case '5': - case '6': - o = OADD; - *p -= '3'; - com: - a1 = g; - if(*p == 1 || *p == 3) - a1 = g1; - a2 = g; - if(*p == 0 || *p == 3) - a2 = g1; - gopcode(o, n->type, a1, n, a2, n); - p++; - break; - default: - a1 = *p++ - 'a' + 1; - a2 = g; - if(a1 > 8) { - a2 = g1; - a1 -= 8; - } - gopcode(OASHL, n->type, D_CONST, nodconst(a1), a2, n); - break; - } - goto loop; -} - -void -nullwarn(Node *l, Node *r) -{ - warn(Z, "result of operation not used"); - if(l != Z) - cgen(l, D_NONE, Z); - if(r != Z) - cgen(r, D_NONE, Z); -} - -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, D_SCONST, 0L); - p->from.offset += o+e; - p->from.displace = lw; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void -gextern(Sym *s, Node *a, long o, long w) -{ - if(a->op == OCONST && typev[a->type->etype]) { - gpseudo(ADATA, s, D_CONST, (long)(a->vconst>>32)); - p->from.offset += o; - p->from.displace = 4; - gpseudo(ADATA, s, D_CONST, (long)(a->vconst)); - p->from.offset += o + 4; - p->from.displace = 4; - return; - } - gpseudotree(ADATA, s, a); - p->from.offset += o; - p->from.displace = w; -} - -long -align(long i, Type *t, int op) -{ - long o; - Type *v; - int w; - - o = i; - w = 1; - switch(op) { - default: - diag(Z, "unknown align opcode %d", op); - break; - - case Asu2: /* padding at end of a struct */ - w = SZ_LONG; - if(packflg) - w = packflg; - break; - - case Ael1: /* initial allign of struct element */ - for(v=t; v->etype==TARRAY; v=v->link) - ; - w = ewidth[v->etype]; - if(w <= 0 || w >= SZ_SHORT) - w = SZ_SHORT; - if(packflg) - w = packflg; - break; - - case Ael2: /* width of a struct element */ - o += t->width; - break; - - case Aarg0: /* initial passbyptr argument in arg list */ - if(typesuv[t->etype]) { - o = align(o, types[TIND], Aarg1); - o = align(o, types[TIND], Aarg2); - } - break; - - case Aarg1: /* initial allign of parameter */ - w = ewidth[t->etype]; - if(w <= 0 || w >= SZ_LONG) { - w = SZ_LONG; - break; - } - o += SZ_LONG - w; /* big endian adjustment */ - w = 1; - break; - - case Aarg2: /* width of a parameter */ - o += t->width; - w = SZ_LONG; - break; - - case Aaut3: /* total allign of automatic */ - o = align(o, t, Ael1); - o = align(o, t, Ael2); - break; - } - o = round(o, w); - if(debug['A']) - print("align %s %ld %T = %ld\n", bnames[op], i, t, o); - return o; -} - -long -maxround(long max, long v) -{ - v += SZ_LONG-1; - if(v > max) - max = round(v, SZ_LONG); - return max; -} diff --git a/utils/2c/txt.c b/utils/2c/txt.c deleted file mode 100644 index 2723c6d6..00000000 --- a/utils/2c/txt.c +++ /dev/null @@ -1,940 +0,0 @@ -#include "gc.h" - -void -tindex(Type *tf, Type *tt) -{ - int i, j; - - j = 0; - if(tt != T) { - j = tt->etype; - if(j >= NTYPE) - j = 0; - } - i = 0; - if(tf != T) { - i = tf->etype; - if(i >= NTYPE) - if(typesu[i]) - i = j; - else - i = 0; - } - txtp = &txt[i][j]; -} - -void -ginit(void) -{ - int i, j, si, sj; - - thestring = "68020"; - thechar = '2'; - exregoffset = 7; - exaregoffset = 5; - exfregoffset = 7; - listinit(); - for(i=0; i<NREG; i++) { - regused[i] = 0; - fregused[i] = 0; - aregused[i] = 0; - } - regaddr(D_A0+6); - regaddr(D_A0+7); - for(i=0; i<sizeof(regbase); i++) - regbase[i] = D_NONE; - for(i=0; i<NREG; i++) { - regbase[D_R0+i] = D_R0+i; - regbase[D_A0+i] = D_A0+i; - regbase[D_F0+i] = D_F0+i; - } - regbase[D_TOS] = D_TOS; - - for(i=0; i<NTYPE; i++) - for(j=0; j<NTYPE; j++) { - txtp = &txt[i][j]; - txtp->movas = AGOK; - txtp->preclr = 0; - txtp->postext = AGOK; - if(!(typechlp[i] && typechlp[j])) - continue; - si = types[i]->width; - sj = types[j]->width; - if(sj < si) - txtp->preclr = -1; - if(sj > si) { - if(typeu[i]) { - txtp->preclr = 1; - } else { - if(sj == 2) - txtp->postext = AEXTBW; - if(sj == 4) - if(si == 1) - txtp->postext = AEXTBL; - else - txtp->postext = AEXTWL; - } - sj = si; - } - if(sj == 1) - txtp->movas = AMOVB; - if(sj == 2) - txtp->movas = AMOVW; - if(sj == 4) - txtp->movas = AMOVL; - } - - for(i=0; i<ALLOP; i++) - for(j=0; j<NTYPE; j++) - opxt[i][j] = AGOK; - oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK); - - oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED); - oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED); - oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK); - oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD); - oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD); - oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD); - oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD); - oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD); - oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD); - oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD); - oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD); - oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK); - oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK); - oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK); - oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK); - oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK); - oinit(OOR, AORB, AORW, AORL, AGOK, AGOK); - oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK); - oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK); - oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK); - oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD); - oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK); - oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD); - oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD); - oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK); - oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK); - oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK); - oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK); - oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK); - oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK); - oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK); - - nstring = 0; - mnstring = 0; - nrathole = 0; - nstatic = 0; - pc = 0; - breakpc = -1; - continpc = -1; - cases = C; - firstp = P; - lastp = P; - tfield = types[TLONG]; - - zprog.link = P; - zprog.as = AGOK; - zprog.from.type = D_NONE; - zprog.from.index = D_NONE; - zprog.to = zprog.from; - - nodret = new(ONAME, Z, Z); - nodret->sym = slookup(".ret"); - nodret->type = types[TIND]; - nodret->etype = types[TIND]->etype; - nodret->class = CPARAM; - nodret = new(OIND, nodret, Z); - complex(nodret); - - symrathole = slookup(".rathole"); - symrathole->class = CGLOBL; - symrathole->type = typ(TARRAY, types[TCHAR]); - nodrat = new(ONAME, Z, Z); - nodrat->sym = symrathole; - nodrat->type = types[TIND]; - nodrat->etype = TVOID; - nodrat->class = CGLOBL; - complex(nodrat); - nodrat->type = symrathole->type; - - com64init(); - - symstatic = slookup(".static"); - symstatic->class = CSTATIC; - symstatic->type = typ(TARRAY, types[TLONG]); -} - -void -gclean(void) -{ - int i; - Sym *s; - - regfree(D_A0+6); - regfree(D_A0+7); - for(i=0; i<NREG; i++) { - if(regused[i]) - diag(Z, "missing R%d", i); - if(aregused[i]) - diag(Z, "missing A%d", i); - if(fregused[i]) - diag(Z, "missing F%d", i); - } - - while(mnstring) - outstring("", 1L); - symstring->type->width = nstring; - symstatic->type->width = nstatic; - symrathole->type->width = nrathole; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type == T) - continue; - if(s->type->width == 0) - continue; - if(s->class != CGLOBL && s->class != CSTATIC) - continue; - if(s->type == types[TENUM]) - continue; - gpseudo(AGLOBL, s, D_CONST, s->type->width); - pc--; - } - nextpc(); - p->as = AEND; - outcode(); -} - -void -oinit(int o, int ab, int aw, int al, int af, int ad) -{ - int i; - - i = o; - if(i >= ALLOP) { - diag(Z, "op(%d) >= ALLOP(%d)", i, ALLOP); - errorexit(); - } - opxt[i][TCHAR] = ab; - opxt[i][TUCHAR] = ab; - opxt[i][TSHORT] = aw; - opxt[i][TUSHORT] = aw; - opxt[i][TINT] = al; - opxt[i][TUINT] = al; - opxt[i][TLONG] = al; - opxt[i][TULONG] = al; - opxt[i][TIND] = al; - opxt[i][TFLOAT] = af; - opxt[i][TDOUBLE] = ad; -} - -Prog* -prg(void) -{ - Prog *p; - - p = alloc(sizeof(*p)); - *p = zprog; - return p; -} - -void -nextpc(void) -{ - - p = prg(); - pc++; - p->lineno = nearln; - if(firstp == P) { - firstp = p; - lastp = p; - return; - } - lastp->link = p; - lastp = p; -} - -void -gargs(Node *n) -{ - long s; - -loop: - if(n == Z) - return; - if(n->op == OLIST) { - gargs(n->right); - n = n->left; - goto loop; - } - s = argoff; - cgen(n, D_TOS, n); - argoff = s + n->type->width; -} - -void -naddr(Node *n, Adr *a, int x) -{ - Node *l; - long v; - - switch(n->op) { - default: - bad: - diag(n, "bad in naddr: %O", n->op); - break; - - case OADDR: - case OIND: - naddr(n->left, a, x); - goto noadd; - - case OREGISTER: - a->sym = S; - a->type = n->reg; - a->offset = n->xoffset; - a->displace = 0; - break; - - case ONAME: - a->etype = n->etype; - a->displace = 0; - a->sym = n->sym; - a->offset = n->xoffset; - a->type = D_STATIC; - if(n->class == CSTATIC) - break; - if(n->class == CEXTERN || n->class == CGLOBL) { - a->type = D_EXTERN; - break; - } - if(n->class == CAUTO) { - a->type = D_AUTO; - break; - } - if(n->class == CPARAM) { - a->type = D_PARAM; - break; - } - goto bad; - - case OINDEX: - naddr(n->left, a, x); - switch(n->left->addable) { - default: - goto bad; - case 1: - case 12: - a->index = x | I_INDEX1; - a->type &= D_MASK; - break; - case 2: - case 10: - case 11: - a->index = x | I_INDEX2; - break; - } - a->scale = n->scale; - break; - - case OCONST: - a->displace = 0; - if(typefd[n->type->etype]) { - a->type = D_FCONST; - a->dval = n->fconst; - break; - } - a->type = D_CONST; - a->offset = n->vconst; - break; - - case OADD: - l = n->left; - if(l->addable == 20) { - v = l->vconst; - naddr(n->right, a, x); - goto add; - } - l = n->right; - if(l->addable == 20) { - v = l->vconst; - naddr(n->left, a, x); - goto add; - } - goto bad; - noadd: - v = 0; - add: - switch(n->addable) { - default: - goto bad; - case 2: - a->displace += v; - break; - case 21: - a->type &= D_MASK; - a->type |= I_INDIR; - break; - case 1: - case 12: - a->offset += v; - a->type &= D_MASK; - a->type |= I_ADDR; - break; - case 13: - a->index = D_NONE|I_INDEX3; - case 10: - case 11: - case 20: - a->type &= D_MASK; - a->type |= I_DIR; - break; - } - break; - - case OPREINC: - case OPREDEC: - case OPOSTINC: - case OPOSTDEC: - - case OAS: - case OASLMUL: - case OASLDIV: - case OASLMOD: - case OASMUL: - case OASDIV: - case OASMOD: - case OASXOR: - case OASOR: - case OASADD: - case OASSUB: - case OASLSHR: - case OASASHR: - case OASASHL: - case OASAND: - naddr(n->left, a, x); - break; - } -} - -int -regalloc(Type *t, int g) -{ - - if(t == T) - return D_NONE; - g &= D_MASK; - if(typefd[t->etype]) { - if(g >= D_F0 && g < D_F0+NREG) { - fregused[g-D_F0]++; - return g; - } - for(g=0; g<NREG; g++) - if(fregused[g] == 0) { - fregused[g]++; - return g + D_F0; - } - } else { - if(g >= D_R0 && g < D_R0+NREG) { - regused[g-D_R0]++; - return g; - } - for(g=0; g<NREG; g++) - if(regused[g] == 0) { - regused[g]++; - return g + D_R0; - } - } - diag(Z, "out of registers"); - return D_TOS; -} - -int -regaddr(int g) -{ - - if(g >= D_A0 && g < D_A0+NREG) { - aregused[g-D_A0]++; - return g; - } - for(g=0; g<NREG; g++) - if(aregused[g] == 0) { - aregused[g]++; - return g + D_A0; - } - diag(Z, "out of addr registers"); - return D_TOS; -} - -int -regpair(int g) -{ - - if(g >= D_R0+1 && g < D_R0+NREG) - if(!regused[g-D_R0-1]) { - regused[g-D_R0-1]++; - regused[g-D_R0]++; - return g-1; - } - if(g >= D_R0 && g < D_R0+NREG-1) - if(!regused[g-D_R0+1]) { - regused[g-D_R0+1]++; - regused[g-D_R0]++; - return g; - } - for(g = 0; g < NREG-1; g++) - if(!regused[g]) - if(!regused[g+1]) { - regused[g]++; - regused[g+1]++; - return g + D_R0; - } - diag(Z, "out of register pairs"); - return D_TOS; -} - -int -regret(Type *t) -{ - - if(t == T) - return D_NONE; - if(typefd[t->etype]) - return D_F0; - return D_R0; -} - -void -regfree(int g) -{ - - g &= D_MASK; - if(g == D_TOS || g == D_TREE || g == D_NONE) - return; - if(g >= D_R0 && g < D_R0+NREG) { - regused[g-D_R0]--; - return; - } - if(g >= D_A0 && g < D_A0+NREG) { - aregused[g-D_A0]--; - return; - } - if(g >= D_F0 && g < D_F0+NREG) { - fregused[g-D_F0]--; - return; - } - diag(Z, "bad in regfree: %d", g); -} - -void -gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t) -{ - int g, a, b; - Prog *p1; - - tindex(tf, tt); - if(txtp->preclr) { - if(gf >= D_R0 && gf < D_R0+NREG) - if(txtp->preclr < 0) { - gmove(tt, tt, gf, f, gt, t); - return; - } - g = regalloc(types[TLONG], gt); - if(g == gf) { - g = regalloc(types[TLONG], D_NONE); - regfree(gf); - } - if(txtp->preclr > 0) - gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z); - gopcode(OAS, tf, gf, f, g, Z); - if(g != gt) - gopcode(OAS, tt, g, Z, gt, t); - regfree(g); - return; - } - a = txtp->postext; - if(a != AGOK) { - if(gf >= D_R0 && gf < D_R0+NREG) - g = regalloc(types[TLONG], gf); - else - g = regalloc(types[TLONG], gt); - if(g != gf) - gopcode(OAS, tf, gf, f, g, Z); - nextpc(); - p->as = a; - p->to.type = g; - if(debug['g']) - print("%P\n", p); - if(g != gt) - gopcode(OAS, tt, g, Z, gt, t); - regfree(g); - return; - } - if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) || - (gf == D_TREE && gt == D_TREE && f == t)) - return; - if(typefd[tf->etype] || typefd[tt->etype]) { - if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */ - a = regalloc(types[TLONG], D_NONE); - gmove(tf, types[TLONG], gf, f, a, t); - if(tf->etype == TULONG) { - b = regalloc(types[TDOUBLE], D_NONE); - gmove(types[TLONG], tt, a, t, b, t); - gopcode(OTST, types[TLONG], D_NONE, Z, a, t); - gbranch(OGE); - p1 = p; - gopcode(OASADD, types[TDOUBLE], - D_CONST, nodconst(100), b, t); - p->from.dval = 4294967296.; - patch(p1, pc); - gmove(types[TDOUBLE], tt, b, t, gt, t); - regfree(b); - } else - gmove(types[TLONG], tt, a, t, gt, t); - regfree(a); - return; - } - if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */ - a = regalloc(types[TLONG], D_NONE); - gopcode(OAS, types[TLONG], D_FPCR, t, a, t); - gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t); - } - if(gf < D_F0 || gf >= D_F0+NREG) { - g = regalloc(types[TDOUBLE], gt); - gopcode(OFAS, tf, gf, f, g, t); - if(g != gt) - gopcode(OFAS, tt, g, t, gt, t); - regfree(g); - } else - gopcode(OFAS, tt, gf, f, gt, t); - if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */ - gopcode(OAS, types[TLONG], a, t, D_FPCR, t); - regfree(a); - } - return; - } - gopcode(OAS, tt, gf, f, gt, t); -} - -void -gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t) -{ - int i, fidx, tidx; - long v; - - if(o == OAS) - if(gf == gt) - if(gf != D_TREE || f == t) - return; - - fidx = D_NONE; - if(gf == D_TREE) { - if(f->op == OINDEX) { - fidx = regalloc(types[TIND], fidx); - cgen(f->right, fidx, f->right); - } - } - tidx = D_NONE; - if(gt == D_TREE) { - if(t->op == OINDEX) { - v = argoff; - tidx = regalloc(types[TIND], tidx); - cgen(t->right, tidx, t->right); - if(gf == D_TOS) - adjsp(v - argoff); - } - } - i = 0; - if(ty != T) { - i = ty->etype; - if(i >= NTYPE) - i = 0; - } - nextpc(); - if(gf == D_TREE) { - naddr(f, &p->from, fidx); - } else { - p->from.type = gf; - if(gf == D_CONST) { - p->from.offset = (long)(uintptr)f; - if(typefd[i]) { - p->from.type = D_FCONST; - p->from.dval = (long)(uintptr)f; - } - } - } - p->as = opxt[o][i]; - if(gt == D_TREE) { - naddr(t, &p->to, tidx); - } else { - p->to.type = gt; - if(gt == D_CONST) - p->to.offset = (long)(uintptr)t; - } - if(o == OBIT) { - p->from.field = f->type->nbits; - p->to.field = f->type->shift; - if(p->from.field == 0) - diag(Z, "BIT zero width bit field"); - } - if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB) - asopt(); - if(debug['g']) - print("%P\n", p); - if(p->as == AGOK) - diag(Z, "GOK in gopcode: %s", onames[o]); - if(fidx != D_NONE) - regfree(fidx); - if(tidx != D_NONE) - regfree(tidx); -} - -void -asopt(void) -{ - long v; - int g; - Prog *q; - - /* - * mov $0, ... - * ==> - * clr , ... - */ - v = 0; - if(p->from.type == D_CONST) { - v = p->from.offset; - if(v == 0) { - p->from.type = D_NONE; - if(p->as == AMOVL) - p->as = ACLRL; - if(p->as == AMOVW) - p->as = ACLRW; - if(p->as == AMOVB) - p->as = ACLRB; - return; - } - } - /* - * mov ..., TOS - * ==> - * pea (...) - */ - if(p->as == AMOVL && p->to.type == D_TOS && p->from.index == D_NONE) - switch(p->from.type) { - case D_CONST: - p->from.type |= I_INDIR; - p->to = p->from; - p->from = zprog.from; - p->as = APEA; - return; - - case I_ADDR|D_EXTERN: - case I_ADDR|D_STATIC: - p->from.type &= ~I_ADDR; - p->to = p->from; - p->from = zprog.from; - p->as = APEA; - return; - } - /* - * movL $Qx, ... - * ==> - * movL $Qx,R - * movL R, ... - */ - if(p->as == AMOVL && p->from.type == D_CONST) - if(v >= -128 && v < 128) - if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) { - g = regalloc(types[TLONG], D_NONE); - q = p; - nextpc(); - p->as = AMOVL; - p->from.type = g; - p->to = q->to; - q->to = p->from; - regfree(g); - if(debug['g']) - print("%P\n", q); - return; - } -} - -void -gbranch(int o) -{ - int a; - - a = ABNE; - switch(o) { - case ORETURN: a = ARTS; break; - case OGOTO: a = ABRA; break; - case OEQ: a = ABEQ; break; - case ONE: a = ABNE; break; - case OLE: a = ABLE; break; - case OLS: a = ABLS; break; - case OLT: a = ABLT; break; - case OLO: a = ABCS; break; - case OGE: a = ABGE; break; - case OHS: a = ABCC; break; - case OGT: a = ABGT; break; - case OHI: a = ABHI; break; - case OBIT: a = ABCS; break; - case OCASE: a = ABCASE; break; - } - nextpc(); - p->from.type = D_NONE; - p->to.type = D_NONE; - p->as = a; -} - -void -fpbranch(void) -{ - int a; - - a = p->as; - switch(a) { - case ABEQ: a = AFBEQ; break; - case ABNE: a = AFBNE; break; - case ABLE: a = AFBLE; break; - case ABLT: a = AFBLT; break; - case ABGE: a = AFBGE; break; - case ABGT: a = AFBGT; break; - } - p->as = a; -} - -void -patch(Prog *op, long pc) -{ - - op->to.offset = pc; - op->to.type = D_BRANCH; -} - -void -gpseudo(int a, Sym *s, int g, long v) -{ - - nextpc(); - if(a == ADATA) - pc--; - p->as = a; - if(g == D_TREE) - abort(); /* obsolete */ - p->to.type = g; - p->to.offset = v; - p->from.sym = s; - p->from.type = D_EXTERN; - if(s->class == CSTATIC) - p->from.type = D_STATIC; -} - -void -gpseudotree(int a, Sym *s, Node *n) -{ - nextpc(); - if(a == ADATA) - pc--; - p->as = a; - naddr(n, &p->to, D_NONE); - p->from.sym = s; - p->from.type = D_EXTERN; - if(s->class == CSTATIC) - p->from.type = D_STATIC; -} - -long -exreg(Type *t) -{ - long o; - - if(typechl[t->etype]) { - if(exregoffset <= 5) - return 0; - o = exregoffset + D_R0; - exregoffset--; - return o; - } - if(t->etype == TIND) { - if(exaregoffset <= 3) - return 0; - o = exaregoffset + D_A0; - exaregoffset--; - return o; - } - if(typefd[t->etype]) { - if(exfregoffset <= 5) - return 0; - o = exfregoffset + D_F0; - exfregoffset--; - return o; - } - return 0; -} - -schar ewidth[NTYPE] = -{ - -1, /* [TXXX] */ - SZ_CHAR, /* [TCHAR] */ - SZ_CHAR, /* [TUCHAR] */ - SZ_SHORT, /* [TSHORT] */ - SZ_SHORT, /* [TUSHORT] */ - SZ_INT, /* [TINT] */ - SZ_INT, /* [TUINT] */ - SZ_LONG, /* [TLONG] */ - SZ_LONG, /* [TULONG] */ - SZ_VLONG, /* [TVLONG] */ - SZ_VLONG, /* [TUVLONG] */ - SZ_FLOAT, /* [TFLOAT] */ - SZ_DOUBLE, /* [TDOUBLE] */ - SZ_IND, /* [TIND] */ - 0, /* [TFUNC] */ - -1, /* [TARRAY] */ - 0, /* [TVOID] */ - -1, /* [TSTRUCT] */ - -1, /* [TUNION] */ - SZ_INT, /* [TENUM] */ -}; -long ncast[NTYPE] = -{ - 0, /* [TXXX] */ - BCHAR|BUCHAR, /* [TCHAR] */ - BCHAR|BUCHAR, /* [TUCHAR] */ - BSHORT|BUSHORT, /* [TSHORT] */ - BSHORT|BUSHORT, /* [TUSHORT] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */ - BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */ - BVLONG|BUVLONG, /* [TVLONG] */ - BVLONG|BUVLONG, /* [TUVLONG] */ - BFLOAT, /* [TFLOAT] */ - BDOUBLE, /* [TDOUBLE] */ - BLONG|BULONG|BIND, /* [TIND] */ - 0, /* [TFUNC] */ - 0, /* [TARRAY] */ - 0, /* [TVOID] */ - BSTRUCT, /* [TSTRUCT] */ - BUNION, /* [TUNION] */ - 0, /* [TENUM] */ -}; diff --git a/utils/2l/Nt.c b/utils/2l/Nt.c deleted file mode 100644 index 2efff499..00000000 --- a/utils/2l/Nt.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <windows.h> -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/2l/Posix.c b/utils/2l/Posix.c deleted file mode 100644 index aa5d9551..00000000 --- a/utils/2l/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fials if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} diff --git a/utils/2l/asm.c b/utils/2l/asm.c deleted file mode 100644 index 10129e98..00000000 --- a/utils/2l/asm.c +++ /dev/null @@ -1,1569 +0,0 @@ -#include "l.h" - -short opa[20]; -short *op; - -long -entryvalue(void) -{ - char *a; - Sym *s; - - a = INITENTRY; - if(*a >= '0' && *a <= '9') - return atolwhex(a); - s = lookup(a, 0); - if(s->type == 0) - return INITTEXT; - if(s->type != STEXT) - diag("entry not text: %s", s->name); - return s->value; -} - -void -asmb(void) -{ - Prog *p; - long v; - int a; - short *op1; - - if(debug['v']) - Bprint(&bso, "%5.2f asmb\n", cputime()); - Bflush(&bso); - - seek(cout, HEADR, 0); - pc = INITTEXT; - curp = firstp; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - if(p->pc != pc) { - if(!debug['a']) - print("%P\n", curp); - diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME); - pc = p->pc; - } - curp = p; - if(debug['a']) - Bprint(&bso, "%lux:%P\n", pc, curp); - asmins(p); - if(cbc < sizeof(opa)) - cflush(); - for(op1 = opa; op1 < op; op1++) { - a = *op1; - *cbp++ = a >> 8; - *cbp++ = a; - } - a = 2*(op - opa); - pc += a; - cbc -= a; - if(debug['a']) { - for(op1 = opa; op1 < op; op1++) - if(op1 == opa) - Bprint(&bso, "\t\t%4ux", *op1 & 0xffff); - else - Bprint(&bso, " %4ux", *op1 & 0xffff); - if(op != opa) - Bprint(&bso, "\n"); - } - } - cflush(); - switch(HEADTYPE) { - case 0: /* this is garbage */ - seek(cout, rnd(HEADR+textsize, 8192), 0); - break; - case 1: /* plan9 boot data goes into text */ - seek(cout, rnd(HEADR+textsize, INITRND), 0); - break; - case 2: /* plan 9 */ - seek(cout, HEADR+textsize, 0); - break; - case 3: /* next boot */ - seek(cout, HEADR+rnd(textsize, INITRND), 0); - break; - case 4: /* preprocess pilot */ - seek(cout, HEADR+textsize, 0); - break; - } - - if(debug['v']) - Bprint(&bso, "%5.2f datblk\n", cputime()); - Bflush(&bso); - - for(v = 0; v < datsize; v += sizeof(buf)-100) { - if(datsize-v > sizeof(buf)-100) - datblk(v, sizeof(buf)-100); - else - datblk(v, datsize-v); - } - - symsize = 0; - spsize = 0; - lcsize = 0; - - Bflush(&bso); - - switch(HEADTYPE) { - default: - seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); - break; - case 1: /* plan9 boot data goes into text */ - seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); - break; - case 2: /* plan 9 */ - seek(cout, HEADR+textsize+datsize, 0); - break; - case 3: /* next boot */ - seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0); - break; - } - if(!debug['s']) { - if(debug['v']) - Bprint(&bso, "%5.2f sym\n", cputime()); - asmsym(); - } - Bflush(&bso); - if(!debug['s']) { - if(debug['v']) - Bprint(&bso, "%5.2f sp\n", cputime()); - asmsp(); - } - Bflush(&bso); - if(!debug['s']) { - if(debug['v']) - Bprint(&bso, "%5.2f pc\n", cputime()); - asmlc(); - } - cflush(); - - if(debug['v']) - Bprint(&bso, "%5.2f headr\n", cputime()); - Bflush(&bso); - seek(cout, 0L, 0); - switch(HEADTYPE) { - default: - lput(0x160L<<16); /* magic and sections */ - lput(0L); /* time and date */ - lput(rnd(HEADR+textsize, 4096)+datsize); - lput(symsize); /* nsyms */ - lput((0x38L<<16)|7L); /* size of optional hdr and flags */ - lput((0413<<16)|0437L); /* magic and version */ - lput(rnd(HEADR+textsize, 4096)); /* sizes */ - lput(datsize); - lput(bsssize); - lput(entryvalue()); /* va of entry */ - lput(INITTEXT-HEADR); /* va of base of text */ - lput(INITDAT); /* va of base of data */ - lput(INITDAT+datsize); /* va of base of bss */ - lput(~0L); /* gp reg mask */ - lput(0L); - lput(0L); - lput(0L); - lput(0L); - lput(~0L); /* gp value ?? */ - break; - case 1: /* plan9 boot data goes into text */ - lput(0407); /* magic */ - lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize); /* sizes */ - lput(0); - lput(bsssize); - lput(symsize); /* nsyms */ - lput(entryvalue()); /* va of entry */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - break; - case 2: /* plan 9 */ - lput(0407); /* magic */ - lput(textsize); /* sizes */ - lput(datsize); - lput(bsssize); - lput(symsize); /* nsyms */ - lput(entryvalue()); /* va of entry */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - break; - case 3: /* next boot */ - /* header */ - lput(0xfeedfaceL); /* magic */ - lput(6); /* 68040 */ - lput(1); /* more 68040 */ - lput(5); /* file type 'boot' */ - lput(HEADTYPE); /* number commands */ - lput(HEADR-7*4); /* sizeof commands */ - lput(1); /* no undefineds */ - /* command 1 text */ - lput(1); /* command = 'segment' */ - lput(124); /* command size */ - s16put("__TEXT"); - /* botch?? entryvalue() */ - lput(INITTEXT); /* va of start */ - lput(rnd(textsize, 8192)); /* va size */ - lput(HEADR); /* file offset */ - lput(rnd(textsize, 8192)); /* file size */ - lput(7); /* max prot */ - lput(7); /* init prot */ - lput(1); /* number of sections */ - lput(0); /* flags */ - /* text section */ - s16put("__text"); - s16put("__TEXT"); - /* botch?? entryvalue() */ - lput(INITTEXT); /* va of start */ - lput(textsize); /* va size */ - lput(HEADR); /* file offset */ - lput(2); /* align */ - lput(0); /* reloff */ - lput(0); /* nreloc */ - lput(0); /* flags */ - lput(0); /* reserved1 */ - lput(0); /* reserved2 */ - /* command 1 data */ - lput(1); /* command = 'segment' */ - lput(192); /* command size */ - s16put("__DATA"); - lput(INITDAT); /* va of start */ - lput(rnd(datsize, 8192)); /* va size */ - lput(HEADR+rnd(textsize, 8192)); /* file offset */ - lput(rnd(datsize, 8192)); /* file size */ - lput(7); /* max prot */ - lput(7); /* init prot */ - lput(2); /* number of sections */ - lput(0); /* flags */ - /* data section */ - s16put("__data"); - s16put("__DATA"); - lput(INITDAT); /* va of start */ - lput(datsize); /* va size */ - lput(HEADR+rnd(textsize, 8192)); /* file offset */ - lput(2); /* align */ - lput(0); /* reloff */ - lput(0); /* nreloc */ - lput(0); /* flags */ - lput(0); /* reserved1 */ - lput(0); /* reserved2 */ - /* bss section */ - s16put("__bss"); - s16put("__DATA"); - lput(INITDAT+datsize); /* va of start */ - lput(bsssize); /* va size */ - lput(0); /* file offset */ - lput(2); /* align */ - lput(0); /* reloff */ - lput(0); /* nreloc */ - lput(1); /* flags = zero fill */ - lput(0); /* reserved1 */ - lput(0); /* reserved2 */ - /* command 2 symbol */ - lput(2); /* command = 'symbol' */ - lput(24); /* command size */ - lput(HEADR+rnd(textsize, INITRND) - +datsize); /* symoff */ - lput(symsize); /* nsyms */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - break; - } - cflush(); -} - -void -asmins(Prog *p) -{ - Optab *o; - int t, a, b; - long v; - Prog *q; - - op = opa + 1; - if(special[p->from.type]) - switch(p->from.type) { - - case D_CCR: - if(p->as != AMOVW) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x42c0 | a; /* mov from ccr */ - return; - - case D_SR: - if(p->as != AMOVW) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x40c0 | a; /* mov from sr */ - return; - - case D_USP: - if(p->as != AMOVL) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 010) { - opa[0] = 0x4e68|(a&7); /* mov usp An */ - return; - } - t = 0x800; - goto movec1; - - case D_SFC: - t = 0x000; - goto movec1; - - case D_DFC: - t = 0x001; - goto movec1; - - case D_CACR: - t = 0x002; - goto movec1; - - case D_TC: - t = 0x003; - goto movec1; - - case D_ITT0: - t = 0x004; - goto movec1; - - case D_ITT1: - t = 0x005; - goto movec1; - - case D_DTT0: - t = 0x006; - goto movec1; - - case D_DTT1: - t = 0x007; - goto movec1; - - case D_VBR: - t = 0x801; - goto movec1; - - case D_CAAR: - t = 0x802; - goto movec1; - - case D_MSP: - t = 0x803; - goto movec1; - - case D_ISP: - t = 0x804; - goto movec1; - - case D_MMUSR: - t = 0x805; - goto movec1; - - case D_URP: - t = 0x806; - goto movec1; - - case D_SRP: - t = 0x807; - goto movec1; - - movec1: - if(p->as != AMOVL) - goto bad; - opa[0] = 0x4e7a; /* mov spc Dn */ - a = asmea(p, &p->to); - b = a & 0170; - if(b == 0 || b == 010) { - *op++ = (a<<12) | t; - return; - } - goto bad; - - case D_FPCR: - t = 0xb000; - goto movec3; - - case D_FPSR: - t = 0xa800; - goto movec3; - - case D_FPIAR: - t = 0xa400; - - movec3: - if(p->as != AMOVL) - goto bad; - op++; - a = asmea(p, &p->to); - opa[0] = optab[AFMOVEL].opcode0 | a; - opa[1] = t; - return; - } - if(special[p->to.type]) - switch(p->to.type) { - - case D_CCR: - if(p->as != AMOVW) /* botch, needs and, eor etc. */ - goto bad; - a = asmea(p, &p->from); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x44c0 | a; /* mov to ccr */ - return; - - case D_SR: - if(p->as != AMOVW) /* botch, needs and, eor etc. */ - goto bad; - a = asmea(p, &p->from); - if((a & 0170) == 010) - goto bad; - opa[0] = 0x46c0 | a; /* mov to sr */ - return; - - case D_USP: - if(p->as != AMOVL) - goto bad; - a = asmea(p, &p->from); - if((a & 0170) == 010) { - opa[0] = 0x4e60|(a&7); /* mov An usp */ - return; - } - t = 0x800; - goto movec2; - - case D_SFC: - t = 0x000; - goto movec2; - - case D_DFC: - t = 0x001; - goto movec2; - - case D_CACR: - t = 0x002; - goto movec2; - - case D_TC: - t = 0x003; - goto movec2; - - case D_ITT0: - t = 0x004; - goto movec2; - - case D_ITT1: - t = 0x005; - goto movec2; - - case D_DTT0: - t = 0x006; - goto movec2; - - case D_DTT1: - t = 0x007; - goto movec2; - - case D_VBR: - t = 0x801; - goto movec2; - - case D_CAAR: - t = 0x802; - goto movec2; - - case D_MSP: - t = 0x803; - goto movec2; - - case D_ISP: - t = 0x804; - goto movec2; - - case D_MMUSR: - t = 0x805; - goto movec2; - - case D_URP: - t = 0x806; - goto movec2; - - case D_SRP: - t = 0x807; - goto movec2; - - movec2: - if(p->as != AMOVL) - goto bad; - opa[0] = 0x4e7b; /* mov Dn spc */ - a = asmea(p, &p->from); - b = a & 0170; - if(b == 0 || b == 010) { - *op++ = (a<<12) | t; - return; - } - goto bad; - - case D_FPCR: - t = 0x9000; - goto movec4; - - case D_FPSR: - t = 0x8800; - goto movec4; - - case D_FPIAR: - t = 0x8400; - - movec4: - if(p->as != AMOVL) - goto bad; - op++; - a = asmea(p, &p->from); - opa[0] = optab[AFMOVEL].opcode0 | a; - opa[1] = t; - return; - } - - o = &optab[p->as]; - t = o->opcode0; - switch(o->optype) { - case 0: /* pseudo ops */ - if(p->as != ATEXT && p->as != ANOP) { - if(!debug['a']) - print("%P\n", p); - diag("unimplemented instruction in %s", TNAME); - return; - } - op = opa; - return; - - case 1: /* branches */ - if(p->to.type != D_BRANCH) - goto bad; - a = asmea(p, &p->to); - /* hack to turn 3-word bsr into 2-word jsr */ - if(a == 0xff && p->as == ABSR && - p->pcond->pc < 32768L && p->pcond->pc >= 0) { - op = opa + 1; - t = o->opcode1; - *op++ = p->pcond->pc; - break; - } - t |= a; - break; - - case 2: /* move */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 0110) { /* src quick */ - t = o->opcode1; - if((b & 0170) != 0) - goto bad; - t |= a >> 7; - t |= b << 9; - break; - } - t |= a; - t |= (b&7) << 9; - t |= (b&070) << 3; - break; - - case 3: /* add */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 0110) { /* src quick */ - t = o->opcode1; - t |= (a&01600) << 2; - t |= b; - break; - } - if((b & 0170) == 0) { /* dst Dn */ - t |= a; - t |= (b & 7) << 9; - break; - } - if((b & 0170) == 010) { /* dst An */ - if((t & 0xc0) == 0) - goto bad; - t = o->opcode2; - t |= a; - t |= (b & 7) << 9; - break; - } - if((a & 0170) == 0) { /* src Dn */ - t |= 0x100; - t |= (a & 7) << 9; - t |= b; - break; - } - if((a & 0177) == 074) { /* src immed */ - t = o->opcode3; - t |= b; - break; - } - goto bad; - - case 4: /* no operands */ - break; - - case 5: /* tst */ - t |= asmea(p, &p->to); - if((t&0170) == 010) - goto bad; - break; - - case 6: /* lea */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) != 010) - goto bad; - t |= a; - t |= (b & 7) << 9; - break; - - case 7: /* cmp */ - b = asmea(p, &p->to); - a = asmea(p, &p->from); - if((a & 0170) == 010) { /* dst An */ - t = o->opcode1; - if(t == 0) /* cmpb illegal */ - goto bad; - t |= 0xc0; - t |= b; - t |= (a & 7) << 9; - break; - } - if((b & 0177) == 074) { /* src immed */ - t = o->opcode2; - t |= a; - break; - } - if((a & 0170) == 0) { /* dst Dn */ - t |= b; - t |= (a&7) << 9; - break; - } - if((b&0170) == 030 && (a&0170) == 030) { /* (A)+,(A)+ */ - t = o->opcode3; - t |= b & 7; - t |= (a & 7) << 9; - break; - } - goto bad; - - case 8: /* svc */ - *op++ = optab[ARTS].opcode0; - break; - - case 9: /* and */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - if((b & 0170) == 0) { /* dst Dn */ - t |= a; - t |= (b&7) << 9; - break; - } - if((a & 0170) == 0) { /* src Dn */ - t = o->opcode1; - t |= b; - t |= (a&7) << 9; - break; - } - if((a & 0177) == 074) { /* src immed */ - t = o->opcode2; - t |= b; - break; - } - goto bad; - - case 10: /* eor */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 010) - goto bad; - if((a & 0170) == 0) { /* src Dn */ - t |= b; - t |= (a&7) << 9; - break; - } - if((a & 0177) == 074) { /* src immed */ - t = o->opcode1; - t |= b; - break; - } - goto bad; - - case 11: /* ext */ - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - t |= b; - break; - } - goto bad; - - case 12: /* shift */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - if((a & 0177) == 0110) { /* src quick */ - t |= (a & 01600) << 2; - t |= b; - break; - } - if((a & 0170) == 0) { /* src Dn */ - t |= 0x20; - t |= a << 9; - t |= b; - break; - } - goto bad; - } - goto bad; - - case 13: /* mul, div short */ - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - if((a & 0170) == 010) - goto bad; - t |= a; - t |= b << 9; - break; - } - goto bad; - - case 14: /* mul, div long */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) == 0) { /* dst Dn */ - if((a & 0170) == 010) - goto bad; - t |= a; - opa[1] |= b << 12; - opa[1] |= b+1; - break; - } - goto bad; - - case 15: /* dec and branch */ - if(p->to.type != D_BRANCH) - goto bad; - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) - goto bad; - *op++ = v; - a = asmea(p, &p->from); - if((a & 0170) != 0) - goto bad; - t |= a; - break; - - case 16: /* fmove */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) == 0100) { /* src Fn */ - if((b & 0170) == 0100) { /* both Fn */ - opa[1] |= (a&7) << 10; - opa[1] |= (b&7) << 7; - break; - } - t |= b; - opa[1] = o->opcode2; - opa[1] |= (a&7) << 7; - break; - } - if((b & 0170) != 0100) /* dst Fn */ - goto bad; - t |= a; - opa[1] = o->opcode3; - opa[1] |= (b&7) << 7; - break; - - case 17: /* floating ea,Fn */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((b & 0170) != 0100) /* dst Fn */ - goto bad; - if((a & 0170) == 0100) { /* both Fn */ - opa[1] |= (a&7) << 10; - opa[1] |= (b&7) << 7; - break; - } - t |= a; - opa[1] = o->opcode2; - opa[1] |= (b&7) << 7; - break; - - case 18: /* floating branchs */ - if(p->to.type != D_BRANCH) - goto bad; - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) - goto bad; - *op++ = v; - break; - - case 19: /* floating dec and branch */ - if(p->to.type != D_BRANCH) - goto bad; - *op++ = o->opcode1; - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) - goto bad; - *op++ = v; - a = asmea(p, &p->from); - if((a & 0170) != 0) - goto bad; - t |= a; - break; - - case 20: /* ftst ea */ - *op++ = o->opcode1; - if(p->from.type != D_NONE) - goto bad; - a = asmea(p, &p->to); - if((a & 0170) == 0100) { /* Fn */ - opa[1] |= (a&7) << 10; - break; - } - t |= a; - opa[1] = o->opcode2; - break; - - case 21: /* fneg */ - *op++ = o->opcode1; - if(p->from.type == D_NONE) { - b = asmea(p, &p->to); - a = b; - } else { - a = asmea(p, &p->from); - b = asmea(p, &p->to); - } - if((b & 0170) != 0100) /* dst Fn */ - goto bad; - if((a & 0170) == 0100) { /* both Fn */ - opa[1] |= (a&7) << 10; - opa[1] |= (b&7) << 7; - break; - } - t |= a; - opa[1] = o->opcode2; - opa[1] |= (b&7) << 7; - break; - - case 22: /* floating cmp Fn,ea */ - *op++ = o->opcode1; - a = asmea(p, &p->from); - b = asmea(p, &p->to); - if((a & 0170) != 0100) /* dst Fn */ - goto bad; - if((b & 0170) == 0100) { /* both Fn */ - opa[1] |= (b&7) << 10; - opa[1] |= (a&7) << 7; - break; - } - t |= b; - opa[1] = o->opcode2; - opa[1] |= (a&7) << 7; - break; - - case 23: /* word, long */ - op = opa; - a = asmea(p, &p->to); - if(a == ((7<<3)|4)) - return; - if(a == ((7<<3)|1)) { - if(p->as == AWORD) { - op = opa; - *op++ = opa[1]; - } - return; - } - if(a == ((7<<3)|0)) { - if(p->as == ALONG) { - *op++ = opa[0]; - opa[0] = 0; - } - return; - } - goto bad; - - case 24: /* bit field */ - a = ((p->to.field&31)<<6) | (p->from.field&31); - if(p->as == ABFINS) { - b = asmea(p, &p->from); - if((b&0170) != 0) - goto bad; - a |= b<<12; - *op++ = a; - a = asmea(p, &p->to); - } else { - if(p->to.type != D_NONE) { - b = asmea(p, &p->to); - if((b&0170) != 0) - goto bad; - a |= b<<12; - } - *op++ = a; - a = asmea(p, &p->from); - } - t |= a; - a &= 0170; - if(a == 010 || a == 030 || a == 040 || a == 074) - goto bad; - break; - - case 25: /* movem */ - if(p->from.type == D_CONST) { /* registers -> memory */ - asmea(p, &p->from); - a = asmea(p, &p->to); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 030) - goto bad; - t |= a; - break; - } - if(p->to.type == D_CONST) { /* memory -> registers */ - t |= 0x400; - asmea(p, &p->to); - a = asmea(p, &p->from); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 040) - goto bad; - t |= a; - break; - } - goto bad; - - case 26: /* chk */ - a = asmea(p, &p->from); - if((a&0170) == 010) - goto bad; - b = asmea(p, &p->to); - if((b&0170) != 0) - goto bad; - t |= a; - t |= b<<9; - break; - - case 27: /* btst */ - a = asmea(p, &p->from); - if(a == 074) { - t = o->opcode1; - } else - if((a&0170) != 0) - goto bad; - b = asmea(p, &p->to); - if(b == 074 || (b&0170) == 010) - goto bad; - t |= b; - break; - - case 28: /* fmovem */ - if(p->from.type == D_CONST) { /* registers -> memory */ - b = p->from.offset & 0xff; - b |= 0xf000; /* control or postinc */ - *op++ = b; - a = asmea(p, &p->to); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 030) - goto bad; - if(b == 040) - op[-1] &= ~0x1000; /* predec */ - t |= a; - break; - } - if(p->to.type == D_CONST) { /* memory -> registers */ - b = p->to.offset & 0xff; - b |= 0xd000; /* control or postinc */ - *op++ = b; - a = asmea(p, &p->from); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 040) - goto bad; - t |= a; - break; - } - goto bad; - - case 29: /* fmovemc */ - if(p->from.type == D_CONST) { /* registers -> memory */ - b = (p->from.offset & 0x7) << 10; - b |= 0xa000; - *op++ = b; - a = asmea(p, &p->to); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 030) - goto bad; - t |= a; - break; - } - if(p->to.type == D_CONST) { /* memory -> registers */ - b = (p->to.offset & 0x7) << 10; - b |= 0x8000; - *op++ = b; - a = asmea(p, &p->from); - if(a == 074) - goto bad; - b = a & 0170; - if(b == 000 || b == 010 || b == 040) - goto bad; - t |= a; - break; - } - goto bad; - - case 30: /* trap */ - if(p->to.type == D_CONST) { - t |= p->to.offset & 0xf; - break; - } - goto bad; - - case 31: /* chk2, cmp2 */ - b = asmea(p, &p->to); - a = b & 0170; - if(a == 000 || a == 010) { - *op++ = o->opcode1 | (b << 12); - t |= asmea(p, &p->from); - break; - } - goto bad; - - case 32: /* casew */ - /* jmp (0,pc,r0.w*1) */ - casepc = p->pc; - *op++ = o->opcode1; - break; - - case 33: /* bcase */ - q = copyp(p); - q->as = ADATA; - q->to.type = D_CONST; - q->to.offset = p->pcond->pc - casepc - 2; - q->from.displace = 2; - q->link = datap; - datap = q; - if(debug['a']) - Bprint(&bso, "%P\n", q); - op = opa; - return; - - case 34: /* moves */ - op++; - a = asmea(p, &p->from); - b = a & 0170; - if(b == 0 || b == 010) { - opa[1] = (a << 12) | 0x800; - b = asmea(p, &p->to); - a = b & 0170; - if(a == 0 || a == 010) - goto bad; - t |= b; - break; - } - t |= a; - b = asmea(p, &p->to); - a = b & 0170; - if(a != 0 && a != 010) - goto bad; - opa[1] = (b << 12); - break; - - case 35: /* swap */ - a = asmea(p, &p->to); - if((a & 0170) == 0) { - t |= a; - break; - } - goto bad; - } - opa[0] = t; - return; - -bad: - if(!debug['a']) - print("%P\n", p); - diag("bad combination of addressing in %s", TNAME); - opa[0] = 0; -} - -int -asmea(Prog *p, Adr *a) -{ - Optab *o; - int f, t, r, i; - short *top; - long v; - - if(a->index != D_NONE) - goto index; - t = a->type; - r = simple[t]; - v = a->offset; - if(r != 0177) { - if(v == 0) - return r; - if((r & 070) != 020) - return r; - if(v >= -32768L && v < 32768L) { - *op++ = v; - return t-D_A0-I_INDIR+050; /* d(Ax) */ - } - *op++ = 0x170; /* is, no indirect */ - *op++ = v>>16; - *op++ = v; - return t-D_A0-I_INDIR+060; /* (d,Ax) */ - } - f = 0; - if(a == &p->from) - f++; - o = &optab[p->as]; - switch(t) { - case D_TOS: - if(f) { - if(o->srcsp) - return (3<<3) | 7; /* (A7)+ */ - } else - if(o->dstsp) - return (4<<3) | 7; /* -(A7) */ - return (2<<3) | 7; /* (A7) */ - - case D_BRANCH: - v = p->pcond->pc - p->pc - 2; - if(v < -32768L || v >= 32768L) { - *op++ = v>>16; - *op++ = v; - return 0xff; - } - if(v < -128 || v >= 128 || p->mark == 4) { - *op++ = v; - return 0; - } - return v & 0xff; - - case I_ADDR|D_STATIC: - case I_ADDR|D_EXTERN: - t = a->sym->type; - if(t == 0 || t == SXREF) { - diag("undefined external: %s in %s", - a->sym->name, TNAME); - a->sym->type = SDATA; - } - v = a->sym->value + a->offset; - if(t != STEXT) - v += INITDAT; - - case D_CONST: - switch(f? o->srcsp: o->dstsp) { - case 4: - *op++ = v>>16; - - case 2: - *op++ = v; - break; - - default: - diag("unknown srcsp asmea in %s", TNAME); - } - return (7<<3) | 4; - - case D_FCONST: - r = f? o->srcsp: o->dstsp; - for(i=0; i<r; i++) - ((char*)op)[i] = gnuxi(&a->ieee, i, r); - op += r/2; - return (7<<3) | 4; - - case D_QUICK: - v = a->offset & 0xff; - return 0110 | (v<<7); - - case D_STACK: - case D_AUTO: - case D_PARAM: - if(v == 0) - return (2<<3) | 7; /* (A7) */ - if(v >= -32768L && v < 32768L) { - *op++ = v; - return (5<<3) | 7; /* d(A7) */ - } - *op++ = 0x170; /* is, no indirect */ - *op++ = v>>16; - *op++ = v; - return (6<<3) | 7; /* (d,A7) */ - - case I_INDIR|D_CONST: - goto adr; - - case D_STATIC: - case D_EXTERN: - t = a->sym->type; - if(t == 0 || t == SXREF) { - diag("undefined external: %s in %s", - a->sym->name, TNAME); - a->sym->type = SDATA; - } - if(t == STEXT) { - v = a->sym->value + a->offset; - *op++ = v>>16; - *op++ = v; - return (7<<3) | 1; - } - v = a->sym->value + a->offset - A6OFFSET; - if(debug['6']) { - v += INITDAT + A6OFFSET; - goto adr; - } - if(v == 0) - return (2<<3) | 6; - if(v >= -32768L && v < 32768L) { - *op++ = v; - return (5<<3) | 6; - } - v += INITDAT + A6OFFSET; - - adr: - if(v >= -32768L && v < 32768L) { - *op++ = v; - return (7<<3) | 0; - } - *op++ = v>>16; - *op++ = v; - return (7<<3) | 1; - } - if(!debug['a']) - print("%P\n", p); - diag("unknown addressing mode: %d in %s", t, TNAME); - return 0; - -index: - top = op++; - t = a->index & D_MASK; - f = (a->scale & 7) << 9; /* w/l scale */ - f |= (t & 7) << 12; /* register */ - if(t < D_R0 || t >= D_R0+8) { - if(t >= D_A0 && t < D_A0+8) { - f |= 0x8000; /* d/a */ - } else - if(t == D_NONE) - f = 0x40; /* is */ - else - goto bad; - } - - t = a->type; - r = t & 7; - v = a->offset; - if(t < (I_INDIR|D_A0) || t >= (I_INDIR|(D_A0+8))) - switch(t) { - default: - goto bad; - - case I_INDIR|D_NONE: - f |= 0x80; /* bs */ - r = 0; - break; - - case D_AUTO: - case D_PARAM: - case D_STACK: - r = 7; - break; - - case D_STATIC: - case D_EXTERN: - t = a->sym->type; - if(t == 0 || t == SXREF) { - diag("undefined external: %s in %s", - a->sym->name, TNAME); - a->sym->type = SDATA; - } - r = 6; - v += a->sym->value - A6OFFSET; - if(t == STEXT) { - f |= 0x80; /* bs */ - r = 0; - v += A6OFFSET; - goto bdlong; - } - if(debug['6']) { - f |= 0x80; /* bs */ - r = 0; - v += INITDAT + A6OFFSET; - } - } - if(v == 0) - f |= 0x10; /* bd size = null */ - else - if(v >= -32768L && v < 32768L) { - f |= 0x20; /* bd size = word */ - *op++ = v; - } else { - bdlong: - f |= 0x30; /* bd size = long */ - *op++ = v>>16; - *op++ = v; - } - v = a->displace; - t = a->index & I_MASK; - if(t != I_INDEX1) { /* non-memory index */ - if(t == I_INDEX2) - f |= 5; /* post indexing */ - else - if(t == I_INDEX3) - f |= 1; /* pre indexing */ - else - goto bad; - } - if(v != 0) { - if(v >= -32768L && v < 32768L) { - f++; /* is size = word */ - *op++ = v; - } else { - f += 2; /* is size = long */ - *op++ = v>>16; - *op++ = v; - } - } - *top = f | 0x100; - return (6<<3) | r; - -bad: - if(!debug['a']) - print("%P\n", p); - diag("bad operand in %s", TNAME); - return 0; -} - -void -lput(long l) -{ - - CPUT(l>>24) - CPUT(l>>16) - CPUT(l>>8) - CPUT(l) -} - -void -s16put(char *n) -{ - char name[16]; - int i; - - strncpy(name, n, sizeof(name)); - for(i=0; i<sizeof(name); i++) - CPUT(name[i]) -} - -void -cflush(void) -{ - int n; - - n = sizeof(buf.cbuf) - cbc; - if(n) - write(cout, buf.cbuf, n); - cbp = buf.cbuf; - cbc = sizeof(buf.cbuf); -} - -void -datblk(long s, long n) -{ - Prog *p; - char *cast; - long l, fl, j; - int i, c; - - memset(buf.dbuf, 0, n+100); - for(p = datap; p != P; p = p->link) { - curp = p; - l = p->from.sym->value + p->from.offset - s; - c = p->from.displace; - i = 0; - if(l < 0) { - if(l+c <= 0) - continue; - while(l < 0) { - l++; - i++; - } - } - if(l >= n) - continue; - for(j=l+(c-i)-1; j>=l; j--) - if(buf.dbuf[j]) { - print("%P\n", p); - diag("multiple initialization"); - break; - } - switch(p->to.type) { - case D_FCONST: - switch(c) { - default: - case 4: - fl = ieeedtof(&p->to.ieee); - cast = (char*)&fl; - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux", cast[fnuxi8[j+4]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[fnuxi8[i+4]]; - l++; - } - break; - case 8: - cast = (char*)&p->to.ieee; - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[fnuxi8[i]]; - l++; - } - break; - } - break; - - case D_SCONST: - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = p->to.scon[i]; - l++; - } - break; - default: - fl = p->to.offset; - if(p->to.sym) { - if(p->to.sym->type == STEXT) - fl += p->to.sym->value; - if(p->to.sym->type == SDATA) - fl += p->to.sym->value + INITDAT; - if(p->to.sym->type == SBSS) - fl += p->to.sym->value + INITDAT; - } - - cast = (char*)&fl; - switch(c) { - default: - diag("bad nuxi %d %d\n%P", c, i, curp); - break; - case 1: - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux",cast[inuxi1[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[inuxi1[i]]; - l++; - } - break; - case 2: - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux",cast[inuxi2[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[inuxi2[i]]; - l++; - } - break; - case 4: - if(debug['a'] && i == 0) { - Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); - for(j=0; j<c; j++) - Bprint(&bso, "%.2ux",cast[inuxi4[j]] & 0xff); - Bprint(&bso, "\n"); - } - for(; i<c; i++) { - buf.dbuf[l] = cast[inuxi4[i]]; - l++; - } - break; - } - break; - } - } - write(cout, buf.dbuf, n); -} - -int -gnuxi(Ieee *d, int i, int c) -{ - char *p; - long l; - - switch(c) { - default: - diag("bad nuxi %d %d\n%P", c, i, curp); - return 0; - - /* - * 2301 vax - * 0123 68k - */ - case 4: - l = ieeedtof(d); - p = (char*)&l; - i = gnuxi8[i+4]; - break; - - /* - * 67452301 vax - * 45670123 68k - */ - case 8: - p = (char*)d; - i = gnuxi8[i]; - break; - } - return p[i]; -} - -long -rnd(long v, long r) -{ - long c; - - if(r <= 0) - return v; - v += r - 1; - c = v % r; - if(c < 0) - c += r; - v -= c; - return v; -} diff --git a/utils/2l/l.h b/utils/2l/l.h deleted file mode 100644 index 8b03604c..00000000 --- a/utils/2l/l.h +++ /dev/null @@ -1,263 +0,0 @@ -#include <lib9.h> -#include <bio.h> -#include "../2c/2.out.h" - -#ifndef EXTERN -#define EXTERN extern -#endif - -#define P ((Prog*)0) -#define S ((Sym*)0) -#define TNAME (curtext?curtext->from.sym->name:noname) -#define CPUT(c)\ - { *cbp++ = c;\ - if(--cbc <= 0)\ - cflush(); } - -typedef struct Adr Adr; -typedef struct Prog Prog; -typedef struct Sym Sym; -typedef struct Auto Auto; -typedef struct Optab Optab; - -struct Adr -{ - short type; - short index; - union - { - struct - { - long u0displace; - long u0offset; - } s0; - char u0scon[8]; - Prog *u0cond; /* not used, but should be D_BRANCH */ - Ieee u0ieee; - } u0; - union - { - Auto* u1autom; - Sym* u1sym; - } u1; - uchar field; - uchar scale; -}; - -#define displace u0.s0.u0displace -#define offset u0.s0.u0offset -#define scon u0.u0scon -#define cond u0.u0cond -#define ieee u0.u0ieee - -#define autom u1.u1autom -#define sym u1.u1sym - -struct Prog -{ - Adr from; - Adr to; - union - { - long u0stkoff; - Prog *u0forwd; - } u0; - Prog* link; - Prog* pcond; /* work on this */ - long pc; - long line; - short as; - uchar mark; /* work on these */ - uchar back; -}; - -#define stkoff u0.u0stkoff -#define forwd u0.u0forwd - -struct Auto -{ - Sym* asym; - Auto* link; - long aoffset; - short type; -}; -struct Sym -{ - char *name; - short type; - short version; - short become; - short frame; - long value; - Sym* link; -}; -struct Optab -{ - short as; - short fas; - short srcsp; - short dstsp; - ushort optype; - ushort opcode0; - ushort opcode1; - ushort opcode2; - ushort opcode3; -}; - -enum -{ - STEXT = 1, - SDATA, - SBSS, - SDATA1, - SXREF, - SAUTO, - SPARAM, - SFILE, - NHASH = 10007, - NHUNK = 100000, - MINSIZ = 4, - STRINGSZ = 200, - MAXIO = 8192, - MAXHIST = 20, /* limit of path elements for history symbols */ - A6OFFSET = 32766 -}; - -EXTERN union -{ - struct - { - char obuf[MAXIO]; /* output buffer */ - uchar ibuf[MAXIO]; /* input buffer */ - } u; - char dbuf[1]; -} buf; - -#define cbuf u.obuf -#define xbuf u.ibuf - -EXTERN long HEADR; -EXTERN long HEADTYPE; -EXTERN long INITDAT; -EXTERN long INITRND; -EXTERN long INITTEXT; -EXTERN char* INITENTRY; /* entry point */ -EXTERN Biobuf bso; -EXTERN long bsssize; -EXTERN long casepc; -EXTERN int cbc; -EXTERN char* cbp; -EXTERN int cout; -EXTERN Auto* curauto; -EXTERN Auto* curhist; -EXTERN Prog* curp; -EXTERN Prog* curtext; -EXTERN Prog* datap; -EXTERN long datsize; -EXTERN char debug[128]; -EXTERN Prog* etextp; -EXTERN Prog* firstp; -EXTERN char fnuxi8[8]; -EXTERN char gnuxi8[8]; -EXTERN Sym* hash[NHASH]; -EXTERN Sym* histfrog[MAXHIST]; -EXTERN int histfrogp; -EXTERN int histgen; -EXTERN char* library[50]; -EXTERN char* libraryobj[50]; -EXTERN int libraryp; -EXTERN int xrefresolv; -EXTERN char* hunk; -EXTERN char inuxi1[1]; -EXTERN char inuxi2[2]; -EXTERN char inuxi4[4]; -EXTERN Prog* lastp; -EXTERN long lcsize; -EXTERN long ncase; -EXTERN long ndata; -EXTERN int nerrors; -EXTERN long nhunk; -EXTERN long nsymbol; -EXTERN char* noname; -EXTERN short* op; -EXTERN char* outfile; -EXTERN long pc; -EXTERN char simple[I_MASK]; -EXTERN char special[I_MASK]; -EXTERN long spsize; -EXTERN Sym* symlist; -EXTERN long symsize; -EXTERN Prog* textp; -EXTERN long textsize; -EXTERN long thunk; -EXTERN int version; -EXTERN Prog zprg; - -extern Optab optab[]; -extern char mmsize[]; -extern char* anames[]; - -#pragma varargck type "A" int -#pragma varargck type "D" Adr* -#pragma varargck type "P" Prog* -#pragma varargck type "R" int -#pragma varargck type "S" char* - -int Aconv(Fmt*); -int Dconv(Fmt*); -int Pconv(Fmt*); -int Rconv(Fmt*); -int Sconv(Fmt*); -int Xconv(Fmt*); -void addhist(long, int); -int andsize(Prog*, Adr*); -Prog* appendp(Prog*); -void asmb(void); -int asmea(Prog*, Adr*); -void asmins(Prog*); -void asmlc(void); -void asmsp(void); -void asmsym(void); -long atolwhex(char*); -Prog* brchain(Prog*); -Prog* brloop(Prog*); -void cflush(void); -Prog* copyp(Prog*); -double cputime(void); -void datblk(long, long); -void diag(char*, ...); -void dodata(void); -void doprof1(void); -void doprof2(void); -void dostkoff(void); -long entryvalue(void); -void errorexit(void); -int find1(long, int); -int find2(long, int); -void follow(void); -void gethunk(void); -int gnuxi(Ieee*, int, int); -void histtoauto(void); -double ieeedtod(Ieee*); -long ieeedtof(Ieee*); -void ldobj(int, long, char*); -void loadlib(void); -void listinit(void); -Sym* lookup(char*, int); -void lput(long); -void main(int, char*[]); -void mkfwd(void); -void* mysbrk(ulong); -void nuxiinit(void); -void objfile(char*); -void patch(void); -Prog* prg(void); -int relinv(int); -long reuse(Prog*, Sym*); -long rnd(long, long); -void s16put(char*); -void span(void); -void undef(void); -void xdefine(char*, int, long); -void xfol(Prog*); -int zaddr(uchar*, Adr*, Sym*[]); diff --git a/utils/2l/list.c b/utils/2l/list.c deleted file mode 100644 index 1ebf488e..00000000 --- a/utils/2l/list.c +++ /dev/null @@ -1,395 +0,0 @@ -#include "l.h" - -void -listinit(void) -{ - - fmtinstall('R', Rconv); - fmtinstall('A', Aconv); - fmtinstall('D', Dconv); - fmtinstall('S', Sconv); - fmtinstall('P', Pconv); -} - -static Prog *bigP; - -int -Pconv(Fmt *fp) -{ - char str[STRINGSZ], s[20]; - Prog *p; - - p = va_arg(fp->args, Prog*); - bigP = p; - sprint(str, "(%ld) %A %D,%D", - p->line, p->as, &p->from, &p->to); - if(p->from.field) { - sprint(s, ",%d,%d", p->to.field, p->from.field); - strcat(str, s); - } - bigP = P; - return fmtstrcpy(fp, str); -} - -int -Aconv(Fmt *fp) -{ - - return fmtstrcpy(fp, anames[va_arg(fp->args, int)]); -} - -int -Xconv(Fmt *fp) -{ - char str[20], s[10]; - int i0, i1; - - str[0] = 0; - i0 = va_arg(fp->args, int) & D_MASK; - i1 = va_arg(fp->args, int); - if(i0 != D_NONE) { - sprint(str, "(%R.", i0); - sprint(s, "%c*%c)", - "WWWWLLLL"[i1], - "12481248"[i1]); - strcat(str, s); - } - return fmtstrcpy(fp, str); -} - -int -Dconv(Fmt *fp) -{ - char str[40], s[20]; - Adr *a; - int i, j; - long d; - - a = va_arg(fp->args, Adr*); - i = a->index; - if(i != D_NONE) { - a->index = D_NONE; - d = a->displace; - a->displace = 0; - switch(i & I_MASK) { - default: - sprint(str, "???%ld(%D)", d, a); - break; - - case I_INDEX1: - sprint(str, "%D", a); - break; - - case I_INDEX2: - if(d) - sprint(str, "%ld(%D)", d, a); - else - sprint(str, "(%D)", a); - break; - - case I_INDEX3: - if(d) - sprint(str, "%ld(%D", d, a); - else - sprint(str, "(%D", a); - break; - } - - if(i != D_NONE) { - j = a->scale & 7; - sprint(strchr(str,0), "(%R.", i); - sprint(strchr(str,0), "%c*%c)", - "WWWWLLLL"[j], - "12481248"[j]); - } - if((i & I_MASK) == I_INDEX3) - strcat(str, ")"); - a->displace = d; - a->index = i; - goto out; - } - i = a->type; - j = i & I_MASK; - if(j) { - a->type = i & D_MASK; - d = a->offset; - a->offset = 0; - switch(j) { - case I_INDINC: - sprint(str, "(%D)+", a); - break; - - case I_INDDEC: - sprint(str, "-(%D)", a); - break; - - case I_INDIR: - if(d) - sprint(str, "%ld(%D)", d, a); - else - sprint(str, "(%D)", a); - break; - - case I_ADDR: - a->offset = d; - sprint(str, "$%D", a); - break; - } - a->type = i; - a->offset = d; - goto out; - } - switch(i) { - - default: - sprint(str, "%R", i); - break; - - case D_NONE: - str[0] = 0; - break; - - case D_BRANCH: - if(bigP != P && bigP->pcond != P) - if(a->sym != S) - sprint(str, "%lux+%s", bigP->pcond->pc, - a->sym->name); - else - sprint(str, "%lux", bigP->pcond->pc); - else - sprint(str, "%ld(PC)", a->offset); - break; - - case D_EXTERN: - sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); - break; - - case D_STATIC: - sprint(str, "%s<%d>+%ld(SB)", a->sym->name, - a->sym->version, a->offset); - break; - - case D_AUTO: - sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); - break; - - case D_PARAM: - if(a->sym) - sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); - else - sprint(str, "%ld(FP)", a->offset); - break; - - case D_CONST: - sprint(str, "$%ld", a->offset); - break; - - case D_STACK: - sprint(str, "TOS+%ld", a->offset); - break; - - case D_QUICK: - sprint(str, "$Q%ld", a->offset); - break; - - case D_FCONST: - sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); - goto out; - - case D_SCONST: - sprint(str, "$\"%S\"", a->scon); - goto out; - } - if(a->displace) { - sprint(s, "/%ld", a->displace); - strcat(str, s); - } -out: - return fmtstrcpy(fp, str); -} - -int -Rconv(Fmt *fp) -{ - char str[20]; - int r; - - r = va_arg(fp->args, int); - if(r >= D_R0 && r < D_R0+NREG) - sprint(str, "R%d", r-D_R0); - else - if(r >= D_A0 && r < D_A0+NREG) - sprint(str, "A%d", r-D_A0); - else - if(r >= D_F0 && r < D_F0+NREG) - sprint(str, "F%d", r-D_F0); - else - switch(r) { - - default: - sprint(str, "gok(%d)", r); - break; - - case D_NONE: - sprint(str, "NONE"); - break; - - case D_TOS: - sprint(str, "TOS"); - break; - - case D_CCR: - sprint(str, "CCR"); - break; - - case D_SR: - sprint(str, "SR"); - break; - - case D_SFC: - sprint(str, "SFC"); - break; - - case D_DFC: - sprint(str, "DFC"); - break; - - case D_CACR: - sprint(str, "CACR"); - break; - - case D_USP: - sprint(str, "USP"); - break; - - case D_VBR: - sprint(str, "VBR"); - break; - - case D_CAAR: - sprint(str, "CAAR"); - break; - - case D_MSP: - sprint(str, "MSP"); - break; - - case D_ISP: - sprint(str, "ISP"); - break; - - case D_FPCR: - sprint(str, "FPCR"); - break; - - case D_FPSR: - sprint(str, "FPSR"); - break; - - case D_FPIAR: - sprint(str, "FPIAR"); - break; - - case D_TREE: - sprint(str, "TREE"); - break; - - case D_TC: - sprint(str, "TC"); - break; - - case D_ITT0: - sprint(str, "ITT0"); - break; - - case D_ITT1: - sprint(str, "ITT1"); - break; - - case D_DTT0: - sprint(str, "DTT0"); - break; - - case D_DTT1: - sprint(str, "DTT1"); - break; - - case D_MMUSR: - sprint(str, "MMUSR"); - break; - case D_URP: - sprint(str, "URP"); - break; - - case D_SRP: - sprint(str, "SRP"); - break; - } - return fmtstrcpy(fp, str); -} - -int -Sconv(Fmt *fp) -{ - int i, c; - char str[30], *p, *a; - - a = va_arg(fp->args, char*); - p = str; - for(i=0; i<sizeof(double); i++) { - c = a[i] & 0xff; - if(c >= 'a' && c <= 'z' || - c >= 'A' && c <= 'Z' || - c >= '0' && c <= '9') { - *p++ = c; - continue; - } - *p++ = '\\'; - switch(c) { - default: - if(c < 040 || c >= 0177) - break; /* not portable */ - p[-1] = c; - continue; - case 0: - *p++ = 'z'; - continue; - case '\\': - case '"': - *p++ = c; - continue; - case '\n': - *p++ = 'n'; - continue; - case '\t': - *p++ = 't'; - continue; - } - *p++ = (c>>6) + '0'; - *p++ = ((c>>3) & 7) + '0'; - *p++ = (c & 7) + '0'; - } - *p = 0; - return fmtstrcpy(fp, str); -} - -void -diag(char *fmt, ...) -{ - char buf[STRINGSZ], *tn; - va_list arg; - - tn = "??none??"; - if(curtext != P && curtext->from.sym != S) - tn = curtext->from.sym->name; - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - print("%s: %s\n", tn, buf); - - nerrors++; - if(nerrors > 10) { - print("too many errors\n"); - errorexit(); - } -} diff --git a/utils/2l/mkfile b/utils/2l/mkfile deleted file mode 100644 index c52b5ce7..00000000 --- a/utils/2l/mkfile +++ /dev/null @@ -1,26 +0,0 @@ -<../../mkconfig - -TARG=2l -OFILES=\ - asm.$O\ - obj.$O\ - optab.$O\ - pass.$O\ - span.$O\ - list.$O\ - enam.$O\ - $TARGMODEL.$O\ - -HFILES=\ - l.h\ - ../2c/2.out.h\ - ../include/ar.h\ - -LIBS=bio 9 -BIN=$ROOT/$OBJDIR/bin -<$ROOT/mkfiles/mkone-$SHELLTYPE - -CFLAGS= $CFLAGS -I ../include - -enam.$O: ../2c/enam.c - $CC $CFLAGS ../2c/enam.c diff --git a/utils/2l/optab.c b/utils/2l/optab.c deleted file mode 100644 index 9f4527b7..00000000 --- a/utils/2l/optab.c +++ /dev/null @@ -1,444 +0,0 @@ -#include "l.h" - -#define X1 0 -#define X2 0 -#define X3 0 -#define C 0xf200 - -Optab optab[] = -/* as, fas, srcsp, dstsp, optype, opcode */ -{ - { AXXX }, - { AABCD, AXXX, X1, X2, X3, 0x4e71 }, - { AADDB, AXXX, 2, 0, 3, 0xd000, 0x5000, 0, 0x0600 }, - { AADDL, AXXX, 4, 0, 3, 0xd080, 0x5080, 0xd1c0, 0x0680 }, - { AADDW, AXXX, 2, 0, 3, 0xd040, 0x5040, 0xd0c0, 0x0640 }, - { AADDXB }, - { AADDXL }, - { AADDXW }, - { AADJSP }, - { AANDB, AXXX, 2, 0, 9, 0xc000, 0xc100, 0x0200 }, - { AANDL, AXXX, 4, 0, 9, 0xc080, 0xc180, 0x0280 }, - { AANDW, AXXX, 2, 0, 9, 0xc040, 0xc140, 0x0240 }, - { AASLB, AXXX, 0, 2, 12, 0xe100 }, - { AASLL, AXXX, 0, 4, 12, 0xe180 }, - { AASLW, AXXX, 0, 2, 12, 0xe140 }, - { AASRB, AXXX, 0, 2, 12, 0xe000 }, - { AASRL, AXXX, 0, 4, 12, 0xe080 }, - { AASRW, AXXX, 0, 2, 12, 0xe040 }, - { ABCASE, AXXX, 0, 0, 33 }, - { ABCC, AXXX, 0, 0, 1, 0x6400 }, - { ABCHG, AXXX, 2, 2, 27, 0x0140, 0x0840 }, - { ABCLR, AXXX, 2, 2, 27, 0x0180, 0x0880 }, - { ABCS, AXXX, 0, 0, 1, 0x6500 }, - { ABEQ, AXXX, 0, 0, 1, 0x6700 }, - { ABFCHG, AXXX, 0, 0, 24, 0xeac0 }, - { ABFCLR, AXXX, 0, 0, 24, 0xecc0 }, - { ABFEXTS, AXXX, 0, 0, 24, 0xebc0 }, - { ABFEXTU, AXXX, 0, 0, 24, 0xe9c0 }, - { ABFFFO, AXXX, 0, 0, 24, 0xedc0 }, - { ABFINS, AXXX, 0, 0, 24, 0xefc0 }, - { ABFSET, AXXX, 0, 0, 24, 0xeec0 }, - { ABFTST, AXXX, 0, 0, 24, 0xe8c0 }, - { ABGE, AXXX, 0, 0, 1, 0x6c00 }, - { ABGT, AXXX, 0, 0, 1, 0x6e00 }, - { ABHI, AXXX, 0, 0, 1, 0x6200 }, - { ABKPT }, - { ABLE, AXXX, 0, 0, 1, 0x6f00 }, - { ABLS, AXXX, 0, 0, 1, 0x6300 }, - { ABLT, AXXX, 0, 0, 1, 0x6d00 }, - { ABMI, AXXX, 0, 0, 1, 0x6b00 }, - { ABNE, AXXX, 0, 0, 1, 0x6600 }, - { ABPL, AXXX, 0, 0, 1, 0x6a00 }, - { ABRA, AXXX, 0, 0, 1, 0x6000 }, - { ABSET, AXXX, 2, 2, 27, 0x01c0, 0x08c0 }, - { ABSR, AXXX, 0, 0, 1, 0x6100, 0x4eb8 }, - { ABTST, AXXX, 2, 2, 27, 0x0100, 0x0800 }, - { ABVC, AXXX, 0, 0, 1, 0x6800 }, - { ABVS, AXXX, 0, 0, 1, 0x6900 }, - { ACALLM }, - { ACAS2B }, - { ACAS2L }, - { ACAS2W }, - { ACASB }, - { ACASEW, AXXX, 0, 0, 32, 0x4efb, 0 }, - { ACASL }, - { ACASW }, - { ACHK2B, AXXX, 2, 0, 31, 0x00c0, 0x0800 }, - { ACHK2L, AXXX, 4, 0, 31, 0x04c0, 0x0800 }, - { ACHK2W, AXXX, 2, 0, 31, 0x02c0, 0x0800 }, - { ACHKL, AXXX, 4, 4, 26, 0x4100 }, - { ACHKW, AXXX, 2, 2, 26, 0x4180 }, - { ACLRB, AXXX, 0, -2, 5, 0x4200 }, - { ACLRL, AXXX, 0, -4, 5, 0x4280 }, - { ACLRW, AXXX, 0, -2, 5, 0x4240 }, - { ACMP2B, AXXX, 2, 0, 31, 0x00c0, 0x0000 }, - { ACMP2L, AXXX, 4, 0, 31, 0x04c0, 0x0000 }, - { ACMP2W, AXXX, 2, 0, 31, 0x02c0, 0x0000 }, - { ACMPB, AXXX, 2, 2, 7, 0xb000, 0, 0x0c00, 0xb108 }, - { ACMPL, AXXX, 4, 4, 7, 0xb080, 0xb100, 0x0c80, 0xb188 }, - { ACMPW, AXXX, 2, 2, 7, 0xb040, 0xb080, 0x0c40, 0xb148 }, - { ADATA }, - { ADBCC, AXXX, 0, 0, 15, 0x54c8 }, - { ADBCS, AXXX, 0, 0, 15, 0x55c8 }, - { ADBEQ, AXXX, 0, 0, 15, 0x57c8 }, - { ADBF, AXXX, 0, 0, 15, 0x51c8 }, - { ADBGE, AXXX, 0, 0, 15, 0x5cc8 }, - { ADBGT, AXXX, 0, 0, 15, 0x5ec8 }, - { ADBHI, AXXX, 0, 0, 15, 0x52c8 }, - { ADBLE, AXXX, 0, 0, 15, 0x5fc8 }, - { ADBLS, AXXX, 0, 0, 15, 0x53c8 }, - { ADBLT, AXXX, 0, 0, 15, 0x5dc8 }, - { ADBMI, AXXX, 0, 0, 15, 0x5bc8 }, - { ADBNE, AXXX, 0, 0, 15, 0x56c8 }, - { ADBPL, AXXX, 0, 0, 15, 0x5ac8 }, - { ADBT, AXXX, 0, 0, 15, 0x50c8 }, - { ADBVC, AXXX, 0, 0, 15, 0x58c8 }, - { ADBVS, AXXX, 0, 0, 15, 0x59c8 }, - { ADIVSL, AXXX, 4, 0, 14, 0x4c40, 0x0800 }, - { ADIVSW, AXXX, 2, 0, 13, 0x81c0 }, - { ADIVUL, AXXX, 4, 0, 14, 0x4c40, 0x0000 }, - { ADIVUW, AXXX, 2, 0, 13, 0x80c0 }, - { AEND }, - { AEORB, AXXX, 2, 0, 10, 0xb100, 0x0a00 }, - { AEORL, AXXX, 4, 0, 10, 0xb180, 0x0a80 }, - { AEORW, AXXX, 2, 0, 10, 0xb140, 0x0a40 }, - { AEXG }, - { AEXTBL, AXXX, 0, 0, 11, 0x49c0 }, - { AEXTBW, AXXX, 0, 0, 11, 0x4880 }, - { AEXTWL, AXXX, 0, 0, 11, 0x48c0 }, - { AFABSB, AXXX, 2, 0, 17, C, 0x0018, 0x5818 }, - { AFABSD, AFABSL, 8, 0, 17, C, 0x0018, 0x5418 }, - { AFABSF, AFABSL, 4, 0, 17, C, 0x0018, 0x4418 }, - { AFABSL, AXXX, 4, 0, 17, C, 0x0018, 0x4018 }, - { AFABSW, AXXX, 2, 0, 17, C, 0x0018, 0x5018 }, - { AFACOSB, AXXX, 2, 0, 17, C, 0x001c, 0x581c }, - { AFACOSD, AFACOSL, 8, 0, 17, C, 0x001c, 0x541c }, - { AFACOSF, AFACOSL, 4, 0, 17, C, 0x001c, 0x441c }, - { AFACOSL, AXXX, 4, 0, 17, C, 0x001c, 0x401c }, - { AFACOSW, AXXX, 2, 0, 17, C, 0x001c, 0x501c }, - { AFADDB, AXXX, 2, 0, 17, C, 0x0022, 0x5822 }, - { AFADDD, AFADDL, 8, 0, 17, C, 0x0022, 0x5422 }, - { AFADDF, AFADDL, 4, 0, 17, C, 0x0022, 0x4422 }, - { AFADDL, AXXX, 4, 0, 17, C, 0x0022, 0x4022 }, - { AFADDW, AXXX, 2, 0, 17, C, 0x0022, 0x5022 }, - { AFASINB, AXXX, 2, 0, 17, C, 0x000c, 0x580c }, - { AFASIND, AFASINL, 8, 0, 17, C, 0x000c, 0x540c }, - { AFASINF, AFASINL, 4, 0, 17, C, 0x000c, 0x440c }, - { AFASINL, AXXX, 4, 0, 17, C, 0x000c, 0x400c }, - { AFASINW, AXXX, 2, 0, 17, C, 0x000c, 0x500c }, - { AFATANB, AXXX, 2, 0, 17, C, 0x000a, 0x580a }, - { AFATAND, AFATANL, 8, 0, 17, C, 0x000a, 0x540a }, - { AFATANF, AFATANL, 4, 0, 17, C, 0x000a, 0x440a }, - { AFATANHB, AXXX, 2, 0, 17, C, 0x000d, 0x580d }, - { AFATANHD, AFATANHL, 8, 0, 17, C, 0x000d, 0x540d }, - { AFATANHF, AFATANHL, 4, 0, 17, C, 0x000d, 0x440d }, - { AFATANHL, AXXX, 4, 0, 17, C, 0x000d, 0x400d }, - { AFATANHW, AXXX, 2, 0, 17, C, 0x000d, 0x500d }, - { AFATANL, AXXX, 4, 0, 17, C, 0x000a, 0x400a }, - { AFATANW, AXXX, 2, 0, 17, C, 0x000a, 0x500a }, - { AFBEQ, AXXX, 0, 0, 18, C+0x81 }, - { AFBF, AXXX, 0, 0, 18, C+0x8f }, - { AFBGE, AXXX, 0, 0, 18, C+0x93 }, - { AFBGT, AXXX, 0, 0, 18, C+0x92 }, - { AFBLE, AXXX, 0, 0, 18, C+0x95 }, - { AFBLT, AXXX, 0, 0, 18, C+0x94 }, - { AFBNE, AXXX, 0, 0, 18, C+0x8e }, - { AFBT, AXXX, 0, 0, 18, C+0x80 }, - { AFCMPB, AXXX, 0, 2, 22, C, 0x0038, 0x5838 }, - { AFCMPD, AFCMPL, 0, 8, 22, C, 0x0038, 0x5438 }, - { AFCMPF, AFCMPL, 0, 4, 22, C, 0x0038, 0x4438 }, - { AFCMPL, AXXX, 0, 4, 22, C, 0x0038, 0x4038 }, - { AFCMPW, AXXX, 0, 2, 22, C, 0x0038, 0x5038 }, - { AFCOSB, AXXX, 2, 0, 17, C, 0x001d, 0x581d }, - { AFCOSD, AFCOSL, 8, 0, 17, C, 0x001d, 0x541d }, - { AFCOSF, AFCOSL, 4, 0, 17, C, 0x001d, 0x441d }, - { AFCOSHB, AXXX, 2, 0, 17, C, 0x0019, 0x5819 }, - { AFCOSHD, AFCOSHL, 8, 0, 17, C, 0x0019, 0x5419 }, - { AFCOSHF, AFCOSHL, 4, 0, 17, C, 0x0019, 0x4419 }, - { AFCOSHL, AXXX, 4, 0, 17, C, 0x0019, 0x4019 }, - { AFCOSHW, AXXX, 2, 0, 17, C, 0x0019, 0x5019 }, - { AFCOSL, AXXX, 4, 0, 17, C, 0x001d, 0x401d }, - { AFCOSW, AXXX, 2, 0, 17, C, 0x001d, 0x501d }, - { AFDBEQ, AXXX, 0, 0, 19, C+0x48, 0x01 }, - { AFDBF, AXXX, 0, 0, 19, C+0x48, 0x0f }, - { AFDBGE, AXXX, 0, 0, 19, C+0x48, 0x13 }, - { AFDBGT, AXXX, 0, 0, 19, C+0x48, 0x12 }, - { AFDBLE, AXXX, 0, 0, 19, C+0x48, 0x15 }, - { AFDBLT, AXXX, 0, 0, 19, C+0x48, 0x14 }, - { AFDBNE, AXXX, 0, 0, 19, C+0x48, 0x0e }, - { AFDBT, AXXX, 0, 0, 19, C+0x48, 0x00 }, - { AFDIVB, AXXX, 2, 0, 17, C, 0x0020, 0x5820 }, - { AFDIVD, AFDIVL, 8, 0, 17, C, 0x0020, 0x5420 }, - { AFDIVF, AFDIVL, 4, 0, 17, C, 0x0020, 0x4420 }, - { AFDIVL, AXXX, 4, 0, 17, C, 0x0020, 0x4020 }, - { AFDIVW, AXXX, 2, 0, 17, C, 0x0020, 0x5020 }, - { AFETOXB, AXXX, 2, 0, 17, C, 0x0010, 0x5810 }, - { AFETOXD, AFETOXL, 8, 0, 17, C, 0x0010, 0x5410 }, - { AFETOXF, AFETOXL, 4, 0, 17, C, 0x0010, 0x4410 }, - { AFETOXL, AXXX, 4, 0, 17, C, 0x0010, 0x4010 }, - { AFETOXM1B, AXXX, 2, 0, 17, C, 0x0008, 0x5808 }, - { AFETOXM1D, AFETOXM1L, 8, 0, 17, C, 0x0008, 0x5408 }, - { AFETOXM1F, AFETOXM1L, 4, 0, 17, C, 0x0008, 0x4408 }, - { AFETOXM1L, AXXX, 4, 0, 17, C, 0x0008, 0x4008 }, - { AFETOXM1W, AXXX, 2, 0, 17, C, 0x0008, 0x5008 }, - { AFETOXW, AXXX, 2, 0, 17, C, 0x0010, 0x5010 }, - { AFGETEXPB, AXXX, 2, 0, 17, C, 0x001e, 0x581e }, - { AFGETEXPD, AFGETEXPL, 8, 0, 17, C, 0x001e, 0x541e }, - { AFGETEXPF, AFGETEXPL, 4, 0, 17, C, 0x001e, 0x441e }, - { AFGETEXPL, AXXX, 4, 0, 17, C, 0x001e, 0x401e }, - { AFGETEXPW, AXXX, 2, 0, 17, C, 0x001e, 0x501e }, - { AFGETMANB, AXXX, 2, 0, 17, C, 0x001f, 0x581f }, - { AFGETMAND, AFGETMANL, 8, 0, 17, C, 0x001f, 0x541f }, - { AFGETMANF, AFGETMANL, 4, 0, 17, C, 0x001f, 0x441f }, - { AFGETMANL, AXXX, 4, 0, 17, C, 0x001f, 0x401f }, - { AFGETMANW, AXXX, 2, 0, 17, C, 0x001f, 0x501f }, - { AFINTB, AXXX, 2, 0, 17, C, 0x0001, 0x5801 }, - { AFINTD, AFINTL, 8, 0, 17, C, 0x0001, 0x5401 }, - { AFINTF, AFINTL, 4, 0, 17, C, 0x0001, 0x4401 }, - { AFINTL, AXXX, 4, 0, 17, C, 0x0001, 0x4001 }, - { AFINTRZB, AXXX, 2, 0, 17, C, 0x0003, 0x5803 }, - { AFINTRZD, AFINTRZL, 8, 0, 17, C, 0x0003, 0x5403 }, - { AFINTRZF, AFINTRZL, 4, 0, 17, C, 0x0003, 0x4403 }, - { AFINTRZL, AXXX, 4, 0, 17, C, 0x0003, 0x4003 }, - { AFINTRZW, AXXX, 2, 0, 17, C, 0x0003, 0x5003 }, - { AFINTW, AXXX, 2, 0, 17, C, 0x0001, 0x5001 }, - { AFLOG10B, AXXX, 2, 0, 17, C, 0x0015, 0x5815 }, - { AFLOG10D, AFLOG10L, 8, 0, 17, C, 0x0015, 0x5415 }, - { AFLOG10F, AFLOG10L, 4, 0, 17, C, 0x0015, 0x4415 }, - { AFLOG10L, AXXX, 4, 0, 17, C, 0x0015, 0x4015 }, - { AFLOG10W, AXXX, 2, 0, 17, C, 0x0015, 0x5015 }, - { AFLOG2B, AXXX, 2, 0, 17, C, 0x0016, 0x5816 }, - { AFLOG2D, AFLOG2L, 8, 0, 17, C, 0x0016, 0x5416 }, - { AFLOG2F, AFLOG2L, 4, 0, 17, C, 0x0016, 0x4416 }, - { AFLOG2L, AXXX, 4, 0, 17, C, 0x0016, 0x4016 }, - { AFLOG2W, AXXX, 2, 0, 17, C, 0x0016, 0x5016 }, - { AFLOGNB, AXXX, 2, 0, 17, C, 0x0014, 0x5814 }, - { AFLOGND, AFLOGNL, 8, 0, 17, C, 0x0014, 0x5414 }, - { AFLOGNF, AFLOGNL, 4, 0, 17, C, 0x0014, 0x4414 }, - { AFLOGNL, AXXX, 4, 0, 17, C, 0x0014, 0x4014 }, - { AFLOGNP1B, AXXX, 2, 0, 17, C, 0x0006, 0x5806 }, - { AFLOGNP1D, AFLOGNP1L, 8, 0, 17, C, 0x0006, 0x5406 }, - { AFLOGNP1F, AFLOGNP1L, 4, 0, 17, C, 0x0006, 0x4406 }, - { AFLOGNP1L, AXXX, 4, 0, 17, C, 0x0006, 0x4006 }, - { AFLOGNP1W, AXXX, 2, 0, 17, C, 0x0006, 0x5006 }, - { AFLOGNW, AXXX, 2, 0, 17, C, 0x0014, 0x5014 }, - { AFMODB, AXXX, 2, 0, 17, C, 0x0021, 0x5821 }, - { AFMODD, AFMODL, 8, 0, 17, C, 0x0021, 0x5421 }, - { AFMODF, AFMODL, 4, 0, 17, C, 0x0021, 0x4421 }, - { AFMODL, AXXX, 4, 0, 17, C, 0x0021, 0x4021 }, - { AFMODW, AXXX, 2, 0, 17, C, 0x0021, 0x5021 }, - { AFMOVEB, AXXX, 2, -2, 16, C, 0x0000, 0x7800, 0x5800 }, - { AFMOVED, AFMOVEL, 8, -8, 16, C, 0x0000, 0x7400, 0x5400 }, - { AFMOVEF, AFMOVEL, 4, -4, 16, C, 0x0000, 0x6400, 0x4400 }, - { AFMOVEL, AXXX, 4, -4, 16, C, 0x0000, 0x6000, 0x4000 }, - { AFMOVEM, AXXX, 2, 2, 28, C }, - { AFMOVEMC, AXXX, 2, 2, 29, C }, - { AFMOVEW, AXXX, 2, -2, 16, C, 0x0000, 0x7000, 0x5000 }, - { AFMULB, AXXX, 2, 0, 17, C, 0x0023, 0x5823 }, - { AFMULD, AFMULL, 8, 0, 17, C, 0x0023, 0x5423 }, - { AFMULF, AFMULL, 4, 0, 17, C, 0x0023, 0x4423 }, - { AFMULL, AXXX, 4, 0, 17, C, 0x0023, 0x4023 }, - { AFMULW, AXXX, 2, 0, 17, C, 0x0023, 0x5023 }, - { AFNEGB, AXXX, 2, 0, 21, C, 0x001a, 0x581a }, - { AFNEGD, AFNEGL, 8, 0, 21, C, 0x001a, 0x541a }, - { AFNEGF, AFNEGL, 4, 0, 21, C, 0x001a, 0x441a }, - { AFNEGL, AXXX, 4, 0, 21, C, 0x001a, 0x401a }, - { AFNEGW, AXXX, 2, 0, 21, C, 0x001a, 0x501a }, - { AFREMB, AXXX, 2, 0, 17, C, 0x0025, 0x5825 }, - { AFREMD, AFREML, 8, 0, 17, C, 0x0025, 0x5425 }, - { AFREMF, AFREML, 4, 0, 17, C, 0x0025, 0x4425 }, - { AFREML, AXXX, 4, 0, 17, C, 0x0025, 0x4025 }, - { AFREMW, AXXX, 2, 0, 17, C, 0x0025, 0x5025 }, - { AFRESTORE, AXXX, 0, 2, 5, C+0x0140 }, - { AFSAVE, AXXX, 0, 2, 5, C+0x0100 }, - { AFSCALEB, AXXX, 2, 0, 17, C, 0x0026, 0x5826 }, - { AFSCALED, AFSCALEL, 8, 0, 17, C, 0x0026, 0x5426 }, - { AFSCALEF, AFSCALEL, 4, 0, 17, C, 0x0026, 0x4426 }, - { AFSCALEL, AXXX, 4, 0, 17, C, 0x0026, 0x4026 }, - { AFSCALEW, AXXX, 2, 0, 17, C, 0x0026, 0x5026 }, - { AFSEQ, AXXX, X1, X2, X3, 0xffff }, - { AFSF, AXXX, 4, X2, X3, 0xffff }, - { AFSGE, AXXX, X1, X2, X3, 0xffff }, - { AFSGT, AXXX, X1, X2, X3, 0xffff }, - { AFSINB, AXXX, 2, 0, 17, C, 0x000e, 0x580e }, - { AFSIND, AFSINL, 8, 0, 17, C, 0x000e, 0x540e }, - { AFSINF, AFSINL, 4, 0, 17, C, 0x000e, 0x440e }, - { AFSINHB, AXXX, 2, 0, 17, C, 0x0002, 0x5802 }, - { AFSINHD, AFSINHL, 8, 0, 17, C, 0x0002, 0x5402 }, - { AFSINHF, AFSINHL, 4, 0, 17, C, 0x0002, 0x4402 }, - { AFSINHL, AXXX, 4, 0, 17, C, 0x0002, 0x4002 }, - { AFSINHW, AXXX, 2, 0, 17, C, 0x0002, 0x5002 }, - { AFSINL, AXXX, 4, 0, 17, C, 0x000e, 0x400e }, - { AFSINW, AXXX, 2, 0, 17, C, 0x000e, 0x500e }, - { AFSLE, AXXX, X1, X2, X3, 0xffff }, - { AFSLT, AXXX, X1, X2, X3, 0xffff }, - { AFSNE, AXXX, X1, X2, X3, 0xffff }, - { AFSQRTB, AXXX, 2, 0, 17, C, 0x0004, 0x5804 }, - { AFSQRTD, AFSQRTL, 8, 0, 17, C, 0x0004, 0x5404 }, - { AFSQRTF, AFSQRTL, 4, 0, 17, C, 0x0004, 0x4404 }, - { AFSQRTL, AXXX, 4, 0, 17, C, 0x0004, 0x4004 }, - { AFSQRTW, AXXX, 2, 0, 17, C, 0x0004, 0x5004 }, - { AFST, AXXX, X1, X2, X3, 0xffff }, - { AFSUBB, AXXX, 2, 0, 17, C, 0x0028, 0x5828 }, - { AFSUBD, AFSUBL, 8, 0, 17, C, 0x0028, 0x5428 }, - { AFSUBF, AFSUBL, 4, 0, 17, C, 0x0028, 0x4428 }, - { AFSUBL, AXXX, 4, 0, 17, C, 0x0028, 0x4028 }, - { AFSUBW, AXXX, 2, 0, 17, C, 0x0028, 0x5028 }, - { AFTANB, AXXX, 2, 0, 17, C, 0x000f, 0x580f }, - { AFTAND, AFTANL, 8, 0, 17, C, 0x000f, 0x540f }, - { AFTANF, AFTANL, 4, 0, 17, C, 0x000f, 0x440f }, - { AFTANHB, AXXX, 2, 0, 17, C, 0x0009, 0x5809 }, - { AFTANHD, AFTANHL, 8, 0, 17, C, 0x0009, 0x5409 }, - { AFTANHF, AFTANHL, 4, 0, 17, C, 0x0009, 0x4409 }, - { AFTANHL, AXXX, 4, 0, 17, C, 0x0009, 0x4009 }, - { AFTANHW, AXXX, 2, 0, 17, C, 0x0009, 0x5009 }, - { AFTANL, AXXX, 4, 0, 17, C, 0x000f, 0x400f }, - { AFTANW, AXXX, 2, 0, 17, C, 0x000f, 0x500f }, - { AFTENTOXB, AXXX, 2, 0, 17, C, 0x0012, 0x5812 }, - { AFTENTOXD, AFTENTOXL, 8, 0, 17, C, 0x0012, 0x5412 }, - { AFTENTOXF, AFTENTOXL, 4, 0, 17, C, 0x0012, 0x4412 }, - { AFTENTOXL, AXXX, 4, 0, 17, C, 0x0012, 0x4012 }, - { AFTENTOXW, AXXX, 2, 0, 17, C, 0x0012, 0x5012 }, - { AFTSTB, AXXX, 0, 2, 20, C, 0x003a, 0x583a }, - { AFTSTD, AFTSTL, 0, 8, 20, C, 0x003a, 0x543a }, - { AFTSTF, AFTSTL, 0, 4, 20, C, 0x003a, 0x443a }, - { AFTSTL, AXXX, 0, 4, 20, C, 0x003a, 0x403a }, - { AFTSTW, AXXX, 0, 2, 20, C, 0x003a, 0x503a }, - { AFTWOTOXB, AXXX, 2, 0, 17, C, 0x0011, 0x5811 }, - { AFTWOTOXD, AFTWOTOXL, 8, 0, 17, C, 0x0011, 0x5411 }, - { AFTWOTOXF, AFTWOTOXL, 4, 0, 17, C, 0x0011, 0x4411 }, - { AFTWOTOXL, AXXX, 4, 0, 17, C, 0x0011, 0x4011 }, - { AFTWOTOXW, AXXX, 2, 0, 17, C, 0x0011, 0x5011 }, - { AGLOBL }, - { AGOK }, - { AHISTORY }, - { AILLEG, AXXX, 0, 0, 4, 0x4efc }, - { AINSTR }, - { AJMP, AXXX, 0, 0, 5, 0x4ec0 }, - { AJSR, AXXX, 0, 0, 5, 0x4e80 }, - { ALEA, AXXX, 0, 0, 6, 0x41c0 }, - { ALINKL }, - { ALINKW }, - { ALOCATE }, - { ALONG, AXXX, 0, 4, 23 }, - { ALSLB, AXXX, 0, 2, 12, 0xe108 }, - { ALSLL, AXXX, 0, 4, 12, 0xe188 }, - { ALSLW, AXXX, 0, 2, 12, 0xe148 }, - { ALSRB, AXXX, 0, 2, 12, 0xe008 }, - { ALSRL, AXXX, 0, 4, 12, 0xe088 }, - { ALSRW, AXXX, 0, 2, 12, 0xe048 }, - { AMOVB, AXXX, 2, -2, 2, 0x1000, 0x7000 }, - { AMOVEM, AXXX, 2, 2, 25, 0x48c0 }, - { AMOVEPL }, - { AMOVEPW }, - { AMOVESB, AXXX, 2, -2, 34, 0xe00 }, - { AMOVESL, AXXX, 4, -4, 34, 0xe80 }, - { AMOVESW, AXXX, 2, -2, 34, 0xe40 }, - { AMOVL, AXXX, 4, -4, 2, 0x2000, 0x7000 }, - { AMOVW, AXXX, 2, -2, 2, 0x3000, 0x7000 }, - { AMULSL, AXXX, 4, 0, 14, 0x4c00, 0x0800 }, - { AMULSW, AXXX, 2, 0, 13, 0xc1c0 }, - { AMULUL, AXXX, 4, 0, 14, 0x4c00, 0x0000 }, - { AMULUW, AXXX, 2, 0, 13, 0xc0c0 }, - { ANAME }, - { ANBCD }, - { ANEGB, AXXX, 0, 0, 5, 0x4400 }, - { ANEGL, AXXX, 0, 0, 5, 0x4480 }, - { ANEGW, AXXX, 0, 0, 5, 0x4440 }, - { ANEGXB }, - { ANEGXL }, - { ANEGXW }, - { ANOP }, - { ANOTB, AXXX, 0, 0, 5, 0x4600 }, - { ANOTL, AXXX, 0, 0, 5, 0x4680 }, - { ANOTW, AXXX, 0, 0, 5, 0x4640 }, - { AORB, AXXX, 2, 0, 9, 0x8000, 0x8100, 0x0000 }, - { AORL, AXXX, 4, 0, 9, 0x8080, 0x8180, 0x0080 }, - { AORW, AXXX, 2, 0, 9, 0x8040, 0x8140, 0x0040 }, - { APACK }, - { APEA, AXXX, 0, 0, 5, 0x4840 }, - { ARESET }, - { AROTLB, AXXX, 0, 2, 12, 0xe118 }, - { AROTLL, AXXX, 0, 4, 12, 0xe198 }, - { AROTLW, AXXX, 0, 2, 12, 0xe158 }, - { AROTRB, AXXX, 0, 2, 12, 0xe018 }, - { AROTRL, AXXX, 0, 4, 12, 0xe098 }, - { AROTRW, AXXX, 0, 2, 12, 0xe058 }, - { AROXLB }, - { AROXLL }, - { AROXLW }, - { AROXRB }, - { AROXRL }, - { AROXRW }, - { ARTD }, - { ARTE, AXXX, 0, 0, 4, 0x4e73 }, - { ARTM }, - { ARTR }, - { ARTS, AXXX, 0, 0, 4, 0x4e75 }, - { ASBCD }, - { ASCC }, - { ASCS }, - { ASEQ }, - { ASF }, - { ASGE }, - { ASGT }, - { ASHI }, - { ASLE }, - { ASLS }, - { ASLT }, - { ASMI }, - { ASNE }, - { ASPL }, - { AST }, - { ASTOP }, - { ASUBB, AXXX, 2, 0, 3, 0x9000, 0x5100, 0, 0x0400 }, - { ASUBL, AXXX, 4, 0, 3, 0x9080, 0x5180, 0x91c0, 0x0480 }, - { ASUBW, AXXX, 2, 0, 3, 0x9040, 0x5140, 0x90c0, 0x0440 }, - { ASUBXB }, - { ASUBXL }, - { ASUBXW }, - { ASVC }, - { ASVS }, - { ASWAP, AXXX, 0, 0, 35, 0x4840 }, - { ASYS, AXXX, 0, 2, 8, 0x4e40 }, - { ATAS, AXXX, 0, 2, 5, 0x4ac0 }, - { ATEXT }, - { ATRAP, AXXX, 0, 0, 30, 0x4e40 }, - { ATRAPCC, AXXX, 0, 0, 4, 0x54fc }, - { ATRAPCS, AXXX, 0, 0, 4, 0x55fc }, - { ATRAPEQ, AXXX, 0, 0, 4, 0x57fc }, - { ATRAPF, AXXX, 0, 0, 4, 0x51fc }, - { ATRAPGE, AXXX, 0, 0, 4, 0x5cfc }, - { ATRAPGT, AXXX, 0, 0, 4, 0x5efc }, - { ATRAPHI, AXXX, 0, 0, 4, 0x52fc }, - { ATRAPLE, AXXX, 0, 0, 4, 0x5ffc }, - { ATRAPLS, AXXX, 0, 0, 4, 0x53fc }, - { ATRAPLT, AXXX, 0, 0, 4, 0x5dfc }, - { ATRAPMI, AXXX, 0, 0, 4, 0x5bfc }, - { ATRAPNE, AXXX, 0, 0, 4, 0x56fc }, - { ATRAPPL, AXXX, 0, 0, 4, 0x5afc }, - { ATRAPT, AXXX, 0, 0, 4, 0x50fc }, - { ATRAPV, AXXX, 0, 0, 4, 0x4e76 }, - { ATRAPVC, AXXX, 0, 0, 4, 0x58fc }, - { ATRAPVS, AXXX, 0, 0, 4, 0x59fc }, - { ATSTB, AXXX, 0, 2, 5, 0x4a00 }, - { ATSTL, AXXX, 0, 4, 5, 0x4a80 }, - { ATSTW, AXXX, 0, 2, 5, 0x4a40 }, - { AUNLK }, - { AUNPK }, - { AWORD, AXXX, 0, 2, 23 }, - { AXXX } -}; - -char mmsize[] = -{ - /* 0 */ 0, 2, 2, 2, 2, - /* 5 */ 2, 2, 2, 4, 2, - /* 10 */ 2, 2, 2, 2, 4, - /* 15 */ 4, 4, 4, 4, 6, - /* 20 */ 4, 4, 4, 0, 4, - /* 25 */ 2, 2, 2, 2, 2, - /* 30 */ 2, 4, 4, 0, 4, - /* 35 */ 2, 0, 0, 0, 0, -}; diff --git a/utils/2l/pass.c b/utils/2l/pass.c deleted file mode 100644 index d429494e..00000000 --- a/utils/2l/pass.c +++ /dev/null @@ -1,538 +0,0 @@ -#include "l.h" - -void -dodata(void) -{ - int i; - Sym *s; - Prog *p; - long t, u; - - if(debug['v']) - Bprint(&bso, "%5.2f dodata\n", cputime()); - Bflush(&bso); - for(p = datap; p != P; p = p->link) { - s = p->from.sym; - if(s->type == SBSS) - s->type = SDATA; - if(s->type != SDATA) - diag("initialize non-data (%d): %s\n%P", - s->type, s->name, p); - t = p->from.offset + p->from.displace; - if(t > s->value) - diag("initialize bounds (%ld): %s\n%P", - s->value, s->name, p); - } - - /* allocate small guys */ - datsize = 0; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SDATA) - if(s->type != SBSS) - continue; - t = s->value; - if(t == 0) { - diag("%s: no size", s->name); - t = 1; - } - t = rnd(t, 4);; - s->value = t; - if(t > MINSIZ) - continue; - s->value = datsize; - datsize += t; - s->type = SDATA1; - } - - /* allocate the rest of the data */ - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SDATA) { - if(s->type == SDATA1) - s->type = SDATA; - continue; - } - t = s->value; - s->value = datsize; - datsize += t; - } - - if(debug['j']) { - /* - * pad data with bss that fits up to next - * 8k boundary, then push data to 8k - */ - u = rnd(datsize, 8192); - u -= datsize; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SBSS) - continue; - t = s->value; - if(t > u) - continue; - u -= t; - s->value = datsize; - s->type = SDATA; - datsize += t; - } - datsize += u; - } - - /* now the bss */ - bsssize = 0; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type != SBSS) - continue; - t = s->value; - s->value = bsssize + datsize; - bsssize += t; - } - xdefine("bdata", SDATA, 0L); - xdefine("edata", SDATA, datsize); - xdefine("end", SBSS, datsize+bsssize); -} - -Prog* -brchain(Prog *p) -{ - int i; - - for(i=0; i<20; i++) { - if(p == P || p->as != ABRA) - return p; - p = p->pcond; - } - return P; -} - -void -follow(void) -{ - Prog *p; - long o; - Sym *s; - - if(debug['v']) - Bprint(&bso, "%5.2f follow\n", cputime()); - Bflush(&bso); - firstp = prg(); - lastp = firstp; - xfol(textp); - lastp->link = P; - firstp = firstp->link; - o = 0; /* set */ - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - if(p->as == ABCASE) { /* initialization for dodata */ - s = p->from.sym; - if(s->type == SBSS) - s->type = SDATA; - if(s->type != SDATA) - diag("BCASE of non-data: %s in %s\n%P", - s->name, TNAME, p); - } - - p->stkoff = -1; /* initialization for stkoff */ - if(p->as == ATEXT) { - p->stkoff = 0; - o = p->to.offset; - continue; - } - if(p->as == AADJSP && p->from.offset == 0) { - p->stkoff = o; - continue; - } - } -} - -void -xfol(Prog *p) -{ - Prog *q; - int i; - enum as a; - -loop: - if(p == P) - return; - if(p->as == ATEXT) - curtext = p; - if(p->as == ABRA) - if((q = p->pcond) != P) { - p->mark = 1; - p = q; - if(p->mark == 0) - goto loop; - } - if(p->mark) { - /* copy up to 4 instructions to avoid branch */ - for(i=0,q=p; i<4; i++,q=q->link) { - if(q == P) - break; - if(q == lastp) - break; - a = q->as; - if(a == ANOP) { - i--; - continue; - } - if(a == ABRA || a == ARTS || a == ARTE) - break; - if(q->pcond == P || q->pcond->mark) - continue; - if(a == ABSR || a == ABCASE || a == ADBF) - continue; - for(;;) { - if(p->as == ANOP) { - p = p->link; - continue; - } - q = copyp(p); - p = p->link; - q->mark = 1; - lastp->link = q; - lastp = q; - if(q->as != a || q->pcond == P || q->pcond->mark) - continue; - q->as = relinv(q->as); - p = q->pcond; - q->pcond = q->link; - q->link = p; - xfol(q->link); - p = q->link; - if(p->mark) - return; - goto loop; - } - } /* */ - q = prg(); - q->as = ABRA; - q->line = p->line; - q->to.type = D_BRANCH; - q->to.offset = p->pc; - q->pcond = p; - p = q; - } - p->mark = 1; - lastp->link = p; - lastp = p; - a = p->as; - if(a == ARTS || a == ABRA || a == ARTE) - return; - if(p->pcond != P) - if(a != ABSR) { - q = brchain(p->link); - if(q != P && q->mark) - if(a != ABCASE && a != ADBF) { - p->as = relinv(a); - p->link = p->pcond; - p->pcond = q; - } - xfol(p->link); - q = brchain(p->pcond); - if(q->mark) { - p->pcond = q; - return; - } - p = q; - goto loop; - } - p = p->link; - goto loop; -} - -int -relinv(int a) -{ - - switch(a) { - case ABEQ: return ABNE; - case ABNE: return ABEQ; - case ABLE: return ABGT; - case ABLS: return ABHI; - case ABLT: return ABGE; - case ABMI: return ABPL; - case ABGE: return ABLT; - case ABPL: return ABMI; - case ABGT: return ABLE; - case ABHI: return ABLS; - case ABCS: return ABCC; - case ABCC: return ABCS; - case AFBEQ: return AFBNE; - case AFBF: return AFBT; - case AFBGE: return AFBLT; - case AFBGT: return AFBLE; - case AFBLE: return AFBGT; - case AFBLT: return AFBGE; - case AFBNE: return AFBEQ; - case AFBT: return AFBF; - } - diag("unknown relation: %s in %s", anames[a], TNAME); - return a; -} - -void -patch(void) -{ - long c; - Prog *p, *q; - Sym *s; - long vexit; - - if(debug['v']) - Bprint(&bso, "%5.2f mkfwd\n", cputime()); - Bflush(&bso); - mkfwd(); - if(debug['v']) - Bprint(&bso, "%5.2f patch\n", cputime()); - Bflush(&bso); - s = lookup("exit", 0); - vexit = s->value; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - if((p->as == ABSR || p->as == ARTS) && p->to.sym != S) { - s = p->to.sym; - if(s->type != STEXT) { - diag("undefined: %s in %s", s->name, TNAME); - s->type = STEXT; - s->value = vexit; - } - p->to.offset = s->value; - p->to.type = D_BRANCH; - } - if(p->to.type != D_BRANCH) - continue; - c = p->to.offset; - for(q = firstp; q != P;) { - if(q->forwd != P) - if(c >= q->forwd->pc) { - q = q->forwd; - continue; - } - if(c == q->pc) - break; - q = q->link; - } - if(q == P) { - diag("branch out of range in %s\n%P", TNAME, p); - p->to.type = D_NONE; - } - p->pcond = q; - } - - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - p->mark = 0; /* initialization for follow */ - if(p->pcond != P) { - p->pcond = brloop(p->pcond); - if(p->pcond != P) - if(p->to.type == D_BRANCH) - p->to.offset = p->pcond->pc; - } - } -} - -#define LOG 5 -void -mkfwd(void) -{ - Prog *p; - int i; - long dwn[LOG], cnt[LOG]; - Prog *lst[LOG]; - - for(i=0; i<LOG; i++) { - if(i == 0) - cnt[i] = 1; else - cnt[i] = LOG * cnt[i-1]; - dwn[i] = 1; - lst[i] = P; - } - i = 0; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - i--; - if(i < 0) - i = LOG-1; - p->forwd = P; - dwn[i]--; - if(dwn[i] <= 0) { - dwn[i] = cnt[i]; - if(lst[i] != P) - lst[i]->forwd = p; - lst[i] = p; - } - } -} - -Prog* -brloop(Prog *p) -{ - int c; - Prog *q; - - c = 0; - for(q = p; q != P; q = q->pcond) { - if(q->as != ABRA) - break; - c++; - if(c >= 5000) - return P; - } - return q; -} - -void -dostkoff(void) -{ - Prog *p, *q; - long s, t; - int a; - Optab *o; - - if(debug['v']) - Bprint(&bso, "%5.2f stkoff\n", cputime()); - Bflush(&bso); - s = 0; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) { - curtext = p; - s = p->to.offset; - if(s == 0) - continue; - p = appendp(p); - p->as = AADJSP; - p->from.type = D_CONST; - p->from.offset = s; - p->stkoff = 0; - continue; - } - for(q = p; q != P; q = q->pcond) { - if(q->as == ATEXT) - break; - if(q->stkoff >= 0) - if(q->stkoff != s) - diag("stack offset %ld is %ld sb %ld in %s\n%P", - q->pc, q->stkoff, s, q, TNAME, p); - q->stkoff = s; - } - o = &optab[p->as]; - if(p->to.type == D_TOS) - s -= o->dstsp; - if(p->from.type == D_TOS) - s -= o->srcsp; - if(p->as == AADJSP) - s += p->from.offset; - if(p->as == APEA) - s += 4; - for(q = p->link; q != P; q = q->pcond) { - if(q->as == ATEXT) { - q = P; - break; - } - if(q->stkoff >= 0) - break; - } - if(q == P || q->stkoff == s) - continue; - if(p->as == ABRA || p->as == ARTS || p->as == ARTE) { - s = q->stkoff; - continue; - } - if(p->link->as == ABCASE) - diag("BCASE with stack offset in %s", TNAME); - t = q->stkoff - s; - s = q->stkoff; - p = appendp(p); - p->as = AADJSP; - p->stkoff = s - t; - p->from.type = D_CONST; - p->from.offset = t; - } - - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - a = p->from.type & D_MASK; - if(a == D_AUTO) - p->from.offset += p->stkoff; - if(a == D_PARAM) - p->from.offset += p->stkoff + 4; - a = p->to.type & D_MASK; - if(a == D_AUTO) - p->to.offset += p->stkoff; - if(a == D_PARAM) - p->to.offset += p->stkoff + 4; - if(p->as != ARTS) - continue; - if(p->stkoff == 0) - continue; - q = p; - p = appendp(p); - p->as = ARTS; - p->stkoff = 0; - - q->as = AADJSP; - q->from.type = D_CONST; - q->from.offset = -q->stkoff; - } -} - -long -atolwhex(char *s) -{ - long n; - int f; - - n = 0; - f = 0; - while(*s == ' ' || *s == '\t') - s++; - if(*s == '-' || *s == '+') { - if(*s++ == '-') - f = 1; - while(*s == ' ' || *s == '\t') - s++; - } - if(s[0]=='0' && s[1]){ - if(s[1]=='x' || s[1]=='X'){ - s += 2; - for(;;){ - if(*s >= '0' && *s <= '9') - n = n*16 + *s++ - '0'; - else if(*s >= 'a' && *s <= 'f') - n = n*16 + *s++ - 'a' + 10; - else if(*s >= 'A' && *s <= 'F') - n = n*16 + *s++ - 'A' + 10; - else - break; - } - } else - while(*s >= '0' && *s <= '7') - n = n*8 + *s++ - '0'; - } else - while(*s >= '0' && *s <= '9') - n = n*10 + *s++ - '0'; - if(f) - n = -n; - return n; -} - -void -undef(void) -{ - int i; - Sym *s; - - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) - if(s->type == SXREF) - diag("%s: not defined", s->name); -} diff --git a/utils/2l/span.c b/utils/2l/span.c deleted file mode 100644 index 45fc23ad..00000000 --- a/utils/2l/span.c +++ /dev/null @@ -1,551 +0,0 @@ -#include "l.h" - -void -span(void) -{ - Prog *p, *q; - long v, c, idat; - Optab *o; - int m, n; - - xdefine("etext", STEXT, 0L); - xdefine("a6base", STEXT, 0L); - idat = INITDAT; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - n = 0; - if((q = p->pcond) != P) - if(q->back != 2) - n = 1; - p->back = n; - if(p->as == AADJSP) { - p->to.type = D_A0+7; - v = -p->from.offset; - p->from.offset = v; - if((v < -8 && v >= -32768L) || (v > 8 && v < 32768L)) { - p->as = ALEA; - p->from.type = I_INDIR | (D_A0+7); - continue; - } - p->as = AADDL; - if(v < 0) { - p->as = ASUBL; - v = -v; - p->from.offset = v; - } - if(v >= 0 && v <= 8) - p->from.type = D_QUICK; - if(v == 0) - p->as = ANOP; - } - } - n = 0; - -start: - if(debug['v']) - Bprint(&bso, "%5.2f span\n", cputime()); - Bflush(&bso); - c = INITTEXT; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - o = &optab[p->as]; - p->pc = c; - m = mmsize[o->optype]; - if(m == 0) { - if(p->as == AWORD) - m = 2; - if(p->as == ALONG) - m = 4; - p->mark = m; - c += m; - continue; - } - if(p->from.type != D_NONE) - m += andsize(p, &p->from); - if(p->to.type == D_BRANCH) { - if(p->pcond == P) - p->pcond = p; - c += m; - if(m == 2) - m |= 0100; - p->mark = m; - continue; - } - if(p->to.type != D_NONE) - m += andsize(p, &p->to); - p->mark = m; - c += m; - } - -loop: - n++; - if(debug['v']) - Bprint(&bso, "%5.2f span %d\n", cputime(), n); - Bflush(&bso); - if(n > 60) { - diag("span must be looping"); - errorexit(); - } - c = INITTEXT; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) - curtext = p; - if((m = p->mark) & 0100) { - q = p->pcond; - v = q->pc - 2; - if(p->back) - v -= c; - else - v -= p->pc; - p->pc = c; - if(v < -32768L || v >= 32768L) { - if(p->as == ABSR && q->pc < 32768L && q->pc >= 0) - c += 4; - else - c += 6; - } else - if(v < -128 || v >= 128) - c += 4; - else - if(v == 0) { - c += 4; - p->mark = 4; - } else - c += 2; - continue; - } - p->pc = c; - c += m; - } - if(c != textsize) { - textsize = c; - goto loop; - } - if(INITRND) - INITDAT = rnd(c, INITRND); - if(INITDAT != idat) { - idat = INITDAT; - goto start; - } - xdefine("etext", STEXT, c); - xdefine("a6base", STEXT, INITDAT+A6OFFSET); - if(debug['v']) - Bprint(&bso, "etext = %lux\n", c); - Bflush(&bso); - for(p = textp; p != P; p = p->pcond) - p->from.sym->value = p->pc; - textsize = c - INITTEXT; -} - -void -xdefine(char *p, int t, long v) -{ - Sym *s; - - s = lookup(p, 0); - if(s->type == 0 || s->type == SXREF) { - s->type = t; - s->value = v; - } - if(s->type == STEXT && s->value == 0) - s->value = v; -} - -int -andsize(Prog *p, Adr *ap) -{ - int t, n; - long v; - Optab *o; - - t = ap->type; - if(ap->index != D_NONE) { - n = 2; - v = ap->displace; - if(v != 0) { - n += 2; - if(v < -32768L || v >= 32768L) - n += 2; - } - switch(t) { - default: - v = ap->offset; - break; - - case D_STATIC: - case D_EXTERN: - if(ap->sym->type == STEXT) - return n+4; /* see below */ - v = ap->sym->value + ap->offset - A6OFFSET; - if(debug['6']) - v += INITDAT + A6OFFSET; - } - if(v != 0) { - n += 2; - if(v < -32768L || v >= 32768L) - n += 2; - } - return n; - } - n = simple[t]; - if(n != 0177) { - v = ap->offset; - if(v == 0) - return 0; - if((n&070) != 020) /* D_INDIR */ - return 0; - if(v == 0) - return 0; - if(v < -32768L || v >= 32768L) - return 6; /* switch to index1 mode */ - return 2; - } - if((t&I_MASK) == I_ADDR) - t = D_CONST; - switch(t) { - - default: - return 0; - - case D_STACK: - case D_AUTO: - case D_PARAM: - v = ap->offset; - if(v == 0) - return 0; - if(v < -32768L || v >= 32768L) - return 6; /* switch to index1 mode */ - return 2; - - case I_INDIR|D_CONST: - v = ap->offset; - goto adr; - - case D_STATIC: - case D_EXTERN: - if(ap->sym->type == STEXT) - return 4; /* too slow to get back into namelist */ - v = ap->sym->value + ap->offset - A6OFFSET; - if(debug['6']) { - v += INITDAT + A6OFFSET; - goto adr; - } - if(v == 0) - return 0; - - adr: - if(v < -32768L || v >= 32768L) - return 4; - return 2; - - case D_CONST: - case D_FCONST: - o = &optab[p->as]; - if(ap == &(p->from)) - return o->srcsp; - return o->dstsp; - - case D_CCR: - case D_SR: - if(p->as == AMOVW) - return 0; - return 2; - - case D_USP: - t = p->from.type; - if(t >= D_A0 && t <= D_A0+8) - return 0; - t = p->to.type; - if(t >= D_A0 && t <= D_A0+8) - return 0; - - case D_SFC: - case D_DFC: - case D_CACR: - case D_VBR: - case D_CAAR: - case D_MSP: - case D_ISP: - case D_FPCR: - case D_FPSR: - case D_FPIAR: - case D_TC: - case D_ITT0: - case D_ITT1: - case D_DTT0: - case D_DTT1: - case D_MMUSR: - case D_URP: - case D_SRP: - return 2; - } -} - -void -putsymb(Sym *s, int t, long v) -{ - int i, f; - char *n; - - n = s->name; - if(t == 'f') - n++; - lput(v); - if(s->version) - t += 'a' - 'A'; - CPUT(t+0x80); /* 0x80 is variable length */ - - if(t == 'Z' || t == 'z') { - CPUT(n[0]); - for(i=1; n[i] != 0 || n[i+1] != 0; i += 2) { - CPUT(n[i]); - CPUT(n[i+1]); - } - CPUT(0); - CPUT(0); - i++; - } - else { - for(i=0; n[i]; i++) - CPUT(n[i]); - CPUT(0); - } - symsize += 4 + 1 + i + 1; - - if(debug['n']) { - if(t == 'z' || t == 'Z') { - Bprint(&bso, "%c %.8lux ", t, v); - for(i=1; n[i] != 0 || n[i+1] != 0; i+=2) { - f = ((n[i]&0xff) << 8) | (n[i+1]&0xff); - Bprint(&bso, "/%x", f); - } - Bprint(&bso, "\n"); - return; - } - if(s->version) - Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, n, s->version); - else - Bprint(&bso, "%c %.8lux %s\n", t, v, n); - } -} - -void -asmsym(void) -{ - Prog *p; - Auto *a; - Sym *s; - int h; - - s = lookup("etext", 0); - if(s->type == STEXT) - putsymb(s, 'T', s->value); - s = lookup("a6base", 0); - if(s->type == STEXT) - putsymb(s, 'D', s->value); - - for(h=0; h<NHASH; h++) - for(s=hash[h]; s!=S; s=s->link) - switch(s->type) { - case SDATA: - putsymb(s, 'D', s->value+INITDAT); - continue; - - case SBSS: - putsymb(s, 'B', s->value+INITDAT); - continue; - - case SFILE: - putsymb(s, 'f', s->value); - continue; - } - - for(p=textp; p!=P; p=p->pcond) { - s = p->from.sym; - if(s->type != STEXT) - continue; - - /* filenames first */ - for(a=p->to.autom; a; a=a->link) - if(a->type == D_FILE) - putsymb(a->asym, 'z', a->aoffset); - else - if(a->type == D_FILE1) - putsymb(a->asym, 'Z', a->aoffset); - - putsymb(s, 'T', s->value); - - /* auto and param after */ - for(a=p->to.autom; a; a=a->link) - if(a->type == D_AUTO) - putsymb(a->asym, 'a', -a->aoffset); - else - if(a->type == D_PARAM) - putsymb(a->asym, 'p', a->aoffset); - } - if(debug['v'] || debug['n']) - Bprint(&bso, "symsize = %lud\n", symsize); - Bflush(&bso); -} - -#define MINLC 2 -void -asmsp(void) -{ - long oldpc, oldsp; - Prog *p; - int s; - long v; - - oldpc = INITTEXT; - oldsp = 0; - for(p = firstp; p != P; p = p->link) { - if(p->stkoff == oldsp || p->as == ATEXT || p->as == ANOP) { - if(p->as == ATEXT) - curtext = p; - if(debug['G']) - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - continue; - } - if(debug['G']) - Bprint(&bso, "\t\t%6ld", spsize); - v = (p->pc - oldpc) / MINLC; - while(v) { - s = 127; - if(v < 127) - s = v; - CPUT(s+128); /* 129-255 +pc */ - if(debug['G']) - Bprint(&bso, " pc+%d*2(%d)", s, s+128); - v -= s; - spsize++; - } - v = p->stkoff - oldsp; - oldsp = p->stkoff; - oldpc = p->pc + MINLC; - if(v & 3 || v > 64L*4L || v < -64L*4L) { - CPUT(0); /* 0 vvvv +sp */ - lput(v); - if(debug['G']) { - if(v > 0) - Bprint(&bso, " sp+%ld*1(%d,%ld)\n", - v, 0, v); - else - Bprint(&bso, " sp%ld*1(%d,%ld)\n", - v, 0, v); - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - } - spsize += 5; - continue; - } - s = v/4; - if(s > 0) { - CPUT(0+s); /* 1-64 +sp */ - if(debug['G']) { - Bprint(&bso, " sp+%d*4(%d)\n", s, 0+s); - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - } - } else { - CPUT(64-s); /* 65-128 -sp */ - if(debug['G']) { - Bprint(&bso, " sp%d*4(%d)\n", s, 64-s); - Bprint(&bso, "%6lux %4ld%P\n", - p->pc, p->stkoff, p); - } - } - spsize++; - } - while(spsize & 1) { - s = 129; - CPUT(s); - spsize++; - } - if(debug['v'] || debug['G']) - Bprint(&bso, "stsize = %ld\n", spsize); - Bflush(&bso); -} - -void -asmlc(void) -{ - long oldpc, oldlc; - Prog *p; - long v, s; - - oldpc = INITTEXT; - oldlc = 0; - for(p = firstp; p != P; p = p->link) { - if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { - if(p->as == ATEXT) - curtext = p; - if(debug['L']) - Bprint(&bso, "%6lux %P\n", - p->pc, p); - continue; - } - if(debug['L']) - Bprint(&bso, "\t\t%6ld", lcsize); - v = (p->pc - oldpc) / MINLC; - while(v) { - s = 127; - if(v < 127) - s = v; - CPUT(s+128); /* 129-255 +pc */ - if(debug['L']) - Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); - v -= s; - lcsize++; - } - s = p->line - oldlc; - oldlc = p->line; - oldpc = p->pc + MINLC; - if(s > 64 || s < -64) { - CPUT(0); /* 0 vv +lc */ - CPUT(s>>24); - CPUT(s>>16); - CPUT(s>>8); - CPUT(s); - if(debug['L']) { - if(s > 0) - Bprint(&bso, " lc+%ld(%d,%ld)\n", - s, 0, s); - else - Bprint(&bso, " lc%ld(%d,%ld)\n", - s, 0, s); - Bprint(&bso, "%6lux %P\n", - p->pc, p); - } - lcsize += 5; - continue; - } - if(s > 0) { - CPUT(0+s); /* 1-64 +lc */ - if(debug['L']) { - Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); - Bprint(&bso, "%6lux %P\n", - p->pc, p); - } - } else { - CPUT(64-s); /* 65-128 -lc */ - if(debug['L']) { - Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); - Bprint(&bso, "%6lux %P\n", - p->pc, p); - } - } - lcsize++; - } - while(lcsize & 1) { - s = 129; - CPUT(s); - lcsize++; - } - if(debug['v'] || debug['L']) - Bprint(&bso, "lcsize = %ld\n", lcsize); - Bflush(&bso); -} diff --git a/utils/5a/a.h b/utils/5a/a.h index 23d19347..62d8760d 100644 --- a/utils/5a/a.h +++ b/utils/5a/a.h @@ -174,9 +174,9 @@ int mywait(int*); int mycreat(char*, int); int systemtype(int); int pathchar(void); +int myfork(void); char* mygetwd(char*, int); int myexec(char*, char*[]); int mydup(int, int); -int myfork(void); int mypipe(int*); void* mysbrk(ulong); diff --git a/utils/5a/lex.c b/utils/5a/lex.c index 2802f4f8..0d93b413 100644 --- a/utils/5a/lex.c +++ b/utils/5a/lex.c @@ -311,6 +311,11 @@ struct "MOVWD", LTYPE3, AMOVWD, "MOVWF", LTYPE3, AMOVWF, + "LDREX", LTYPE3, ALDREX, + "LDREXD", LTYPE3, ALDREXD, + "STREX", LTYPE9, ASTREX, + "STREXD", LTYPE9, ASTREXD, + /* "ABSF", LTYPEI, AABSF, "ABSD", LTYPEI, AABSD, @@ -326,6 +331,8 @@ struct "NRMD", LTYPEI, ANRMD, */ + "SQRTF", LTYPEI, ASQRTF, + "SQRTD", LTYPEI, ASQRTD, "CMPF", LTYPEL, ACMPF, "CMPD", LTYPEL, ACMPD, "ADDF", LTYPEK, AADDF, @@ -417,10 +424,10 @@ cinit(void) } pathname = allocn(pathname, 0, 100); - if(mygetwd(pathname, 99) == 0) { + if(getwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); - if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + if(getwd(pathname, 999) == 0) + strcpy(pathname, "/?"); } } diff --git a/utils/5c/5.out.h b/utils/5c/5.out.h index dad2c336..a618f8f1 100644 --- a/utils/5c/5.out.h +++ b/utils/5c/5.out.h @@ -25,6 +25,7 @@ #define NFREG 8 #define FREGRET 0 #define FREGEXT 7 +#define FREGTMP 15 /* compiler allocates register variables F0 up */ /* compiler allocates external registers F7 down */ @@ -92,6 +93,8 @@ enum as AMULD, ADIVF, ADIVD, +// ASQRTF, +// ASQRTD, ASRL, ASRA, @@ -143,6 +146,16 @@ enum as ASIGNAME, + /* moved here to preserve values of older identifiers */ + ASQRTF, + ASQRTD, + + ALDREX, + ASTREX, + + ALDREXD, + ASTREXD, + ALAST, }; @@ -173,7 +186,8 @@ enum as #define D_SHIFT (D_NONE+19) #define D_FPCR (D_NONE+20) -#define D_REGREG (D_NONE+21) +#define D_REGREG (D_NONE+21) +#define D_ADDR (D_NONE+22) /* name */ #define D_EXTERN (D_NONE+3) diff --git a/utils/5c/enam.c b/utils/5c/enam.c index 989b2760..e5ea0b84 100644 --- a/utils/5c/enam.c +++ b/utils/5c/enam.c @@ -94,5 +94,11 @@ char* anames[] = "BXRET", "DWORD", "SIGNAME", + "SQRTF", + "SQRTD", + "LDREX", + "STREX", + "LDREXD", + "STREXD", "LAST", }; diff --git a/utils/5c/gc.h b/utils/5c/gc.h index fa93cd0a..b9382a00 100644 --- a/utils/5c/gc.h +++ b/utils/5c/gc.h @@ -3,7 +3,7 @@ /* * 5c/arm - * Arm 7500 + * Arm */ #define SZ_CHAR 1 #define SZ_SHORT 2 @@ -59,7 +59,7 @@ struct Prog struct Case { Case* link; - long val; + vlong val; long label; char def; char isv; @@ -68,7 +68,7 @@ struct Case struct C1 { - long val; + vlong val; long label; }; @@ -265,7 +265,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void swit2(C1*, int, long, Node*, Node*); @@ -276,7 +276,6 @@ long outstring(char*, long); int mulcon(Node*, Node*); Multab* mulcon0(long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); @@ -297,7 +296,7 @@ int Rconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); Bits mkvar(Adr*, int); diff --git a/utils/5c/list.c b/utils/5c/list.c index d50f07db..c7276dd8 100644 --- a/utils/5c/list.c +++ b/utils/5c/list.c @@ -98,7 +98,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/5c/peep.c b/utils/5c/peep.c index 25e5a118..9d4a2da2 100644 --- a/utils/5c/peep.c +++ b/utils/5c/peep.c @@ -1069,7 +1069,7 @@ copyu(Prog *p, Adr *v, Adr *s) if(v->type == D_REG) { if(v->reg <= REGEXT && v->reg > exregoffset) return 2; - if(v->reg == REGARG) + if(v->reg == (uchar)REGARG) return 2; } if(v->type == D_FREG) @@ -1087,11 +1087,10 @@ copyu(Prog *p, Adr *v, Adr *s) case ATEXT: /* funny */ if(v->type == D_REG) - if(v->reg == REGARG) + if(v->reg == (uchar)REGARG) return 3; return 0; } - /* not reached */ } int diff --git a/utils/5c/reg.c b/utils/5c/reg.c index 43c78712..ab1005ba 100644 --- a/utils/5c/reg.c +++ b/utils/5c/reg.c @@ -18,7 +18,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; @@ -1125,7 +1125,7 @@ RtoB(int r) int BtoR(long b) { - b &= 0x01fcL; + b &= 0x01fcL; // excluded R9 and R10 for extern registers if(b == 0) return 0; return bitno(b); diff --git a/utils/5c/swt.c b/utils/5c/swt.c index ccc63ee7..6e0b8d51 100644 --- a/utils/5c/swt.c +++ b/utils/5c/swt.c @@ -25,8 +25,8 @@ swit2(C1 *q, int nc, long def, Node *n, Node *tn) } if(nc < 5) { for(i=0; i<nc; i++) { - if(debug['W']) - print("case = %.8lux\n", q->val); + if(debug['K']) + print("case = %.8llux\n", q->val); gopcode(OEQ, nodconst(q->val), n, Z); patch(p, q->label); q++; @@ -38,16 +38,16 @@ swit2(C1 *q, int nc, long def, Node *n, Node *tn) i = nc / 2; r = q+i; - if(debug['W']) - print("case > %.8lux\n", r->val); + if(debug['K']) + print("case > %.8llux\n", r->val); gopcode(OGT, nodconst(r->val), n, Z); sp = p; gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */ patch(p, r->label); swit2(q, i, def, n, tn); - if(debug['W']) - print("case < %.8lux\n", r->val); + if(debug['K']) + print("case < %.8llux\n", r->val); patch(sp, pc); swit2(r+1, nc-i-1, def, n, tn); return; @@ -59,8 +59,8 @@ direct: gopcode(OCASE, nodconst((q+nc-1)->val - v), n, Z); patch(p, def); for(i=0; i<nc; i++) { - if(debug['W']) - print("case = %.8lux\n", q->val); + if(debug['K']) + print("case = %.8llux\n", q->val); while(q->val != v) { nextpc(); p->as = ABCASE; @@ -269,23 +269,6 @@ loop: } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0)); - p->from.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { @@ -579,7 +562,7 @@ align(long i, Type *t, int op) w = packflg; break; - case Ael1: /* initial allign of struct element */ + case Ael1: /* initial align of struct element */ for(v=t; v->etype==TARRAY; v=v->link) ; w = ewidth[v->etype]; @@ -600,7 +583,7 @@ align(long i, Type *t, int op) } break; - case Aarg1: /* initial allign of parameter */ + case Aarg1: /* initial align of parameter */ w = ewidth[t->etype]; if(w <= 0 || w >= SZ_LONG) { w = SZ_LONG; @@ -614,7 +597,7 @@ align(long i, Type *t, int op) w = SZ_LONG; break; - case Aaut3: /* total allign of automatic */ + case Aaut3: /* total align of automatic */ o = align(o, t, Ael2); o = align(o, t, Ael1); w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */ diff --git a/utils/5c/txt.c b/utils/5c/txt.c index f97eb61a..fadf5938 100644 --- a/utils/5c/txt.c +++ b/utils/5c/txt.c @@ -1,5 +1,7 @@ #include "gc.h" +static char resvreg[nelem(reg)]; + void ginit(void) { @@ -80,6 +82,16 @@ ginit(void) com64init(); memset(reg, 0, sizeof(reg)); + /* don't allocate */ + reg[REGTMP] = 1; + reg[REGSB] = 1; + reg[REGSP] = 1; + reg[REGLINK] = 1; + reg[REGPC] = 1; + /* keep two external registers */ + reg[REGEXT] = 1; + reg[REGEXT-1] = 1; + memmove(resvreg, reg, sizeof(reg)); } void @@ -89,10 +101,10 @@ gclean(void) Sym *s; for(i=0; i<NREG; i++) - if(reg[i]) + if(reg[i] && !resvreg[i]) diag(Z, "reg %d left allocated", i); for(i=NREG; i<NREG+NFREG; i++) - if(reg[i]) + if(reg[i] && !resvreg[i]) diag(Z, "freg %d left allocated", i-NREG); while(mnstring) outstring("", 1L); @@ -283,7 +295,7 @@ regalloc(Node *n, Node *tn, Node *o) for(i=REGRET+1; i<NREG; i++) { if(j >= NREG) j = REGRET+1; - if(reg[j] == 0) { + if(reg[j] == 0 && resvreg[j] == 0) { i = j; goto out; } @@ -319,7 +331,7 @@ err: return; out: reg[i]++; -/* lasti++; *** StrongARM does register forwarding */ + lasti++; if(lasti >= 5) lasti = 0; nodreg(n, tn, i); @@ -549,7 +561,8 @@ void gmove(Node *f, Node *t) { int ft, tt, a; - Node nod; + Node nod, nod1; + Prog *p1; ft = f->type->etype; tt = t->type->etype; @@ -678,21 +691,58 @@ gmove(Node *f, Node *t) } break; case TUINT: - case TINT: case TULONG: + if(tt == TFLOAT || tt == TDOUBLE) { + // ugly and probably longer than necessary, + // but vfp has a single instruction for this, + // so hopefully it won't last long. + // + // tmp = f + // tmp1 = tmp & 0x80000000 + // tmp ^= tmp1 + // t = float(int32(tmp)) + // if(tmp1) + // t += 2147483648. + // + regalloc(&nod, f, Z); + regalloc(&nod1, f, Z); + gins(AMOVW, f, &nod); + gins(AMOVW, &nod, &nod1); + gins(AAND, nodconst(0x80000000), &nod1); + gins(AEOR, &nod1, &nod); + if(tt == TFLOAT) + gins(AMOVWF, &nod, t); + else + gins(AMOVWD, &nod, t); + gins(ACMP, nodconst(0), Z); + raddr(&nod1, p); + gins(ABEQ, Z, Z); + regfree(&nod); + regfree(&nod1); + p1 = p; + regalloc(&nod, t, Z); + if(tt == TFLOAT) { + gins(AMOVF, nodfconst(2147483648.), &nod); + gins(AADDF, &nod, t); + } else { + gins(AMOVD, nodfconst(2147483648.), &nod); + gins(AADDD, &nod, t); + } + regfree(&nod); + patch(p1, pc); + return; + } + // fall through + + case TINT: case TLONG: case TIND: switch(tt) { case TDOUBLE: - case TVLONG: gins(AMOVWD, f, t); - if(ft == TULONG) { - } return; case TFLOAT: gins(AMOVWF, f, t); - if(ft == TULONG) { - } return; case TINT: case TUINT: @@ -710,7 +760,6 @@ gmove(Node *f, Node *t) case TSHORT: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVH, f, &nod); gins(AMOVWD, &nod, t); @@ -740,7 +789,6 @@ gmove(Node *f, Node *t) case TUSHORT: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVHU, f, &nod); gins(AMOVWD, &nod, t); @@ -770,7 +818,6 @@ gmove(Node *f, Node *t) case TCHAR: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVB, f, &nod); gins(AMOVWD, &nod, t); @@ -800,7 +847,6 @@ gmove(Node *f, Node *t) case TUCHAR: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVBU, f, &nod); gins(AMOVWD, &nod, t); @@ -1015,7 +1061,8 @@ gopcode(int o, Node *f1, Node *f2, Node *t) nextpc(); p->as = a; naddr(f1, &p->from); - if(a == ACMP && f1->op == OCONST && p->from.offset < 0) { + if(a == ACMP && f1->op == OCONST && p->from.offset < 0 && + p->from.offset != 0x80000000) { p->as = ACMN; p->from.offset = -p->from.offset; } @@ -1185,9 +1232,12 @@ exreg(Type *t) long o; if(typechlp[t->etype]) { - if(exregoffset <= REGEXT-4) + if(exregoffset <= REGEXT-2) return 0; o = exregoffset; + if(reg[o] && !resvreg[o]) + return 0; + resvreg[o] = reg[o] = 1; exregoffset--; return o; } @@ -1195,6 +1245,9 @@ exreg(Type *t) if(exfregoffset <= NFREG-1) return 0; o = exfregoffset + NREG; + if(reg[o] && !resvreg[o]) + return 0; + resvreg[o] = reg[o] = 1; exfregoffset--; return o; } diff --git a/utils/5coff/coff.c b/utils/5coff/coff.c index 7a057ea5..1b552016 100644 --- a/utils/5coff/coff.c +++ b/utils/5coff/coff.c @@ -482,7 +482,6 @@ coffsym(void) bf = defsym(DOTBF, STEXT, 0); ef = defsym(DOTEF, STEXT, 0); for(p = firstp; p != P; p = p->link){ - setarch(p); if(p->as != ATEXT){ if(p->line != 0) lno = lineno(p->line); @@ -593,7 +592,6 @@ cofflc(void) /* opc = INITTEXT; */ olc = 0; for(p = firstp; p != P; p = p->link){ - setarch(p); if(p->as == ATEXT){ curtext = p; s = p->from.sym; diff --git a/utils/5l/Nt.c b/utils/5l/Nt.c deleted file mode 100644 index 73c6f795..00000000 --- a/utils/5l/Nt.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <windows.h> -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/5l/Plan9.c b/utils/5l/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/5l/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/5l/Posix.c b/utils/5l/Posix.c deleted file mode 100644 index 0da0ee0c..00000000 --- a/utils/5l/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fails if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} diff --git a/utils/5l/asm.c b/utils/5l/asm.c index 66a7f0c6..53d51c45 100644 --- a/utils/5l/asm.c +++ b/utils/5l/asm.c @@ -43,7 +43,6 @@ asmb(void) seek(cout, OFFSET, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { - setarch(p); if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; @@ -57,16 +56,9 @@ asmb(void) } curp = p; o = oplook(p); /* could probably avoid this call */ - if(thumb) - thumbasmout(p, o); - else - asmout(p, o); + asmout(p, o); pc += o->size; } - while(pc-INITTEXT < textsize) { - cput(0); - pc++; - } if(debug['a']) Bprint(&bso, "\n"); @@ -88,10 +80,12 @@ asmb(void) case 1: case 2: case 5: + case 7: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; case 3: + case 6: /* no header, padded segments */ OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; @@ -108,7 +102,6 @@ asmb(void) else datblk(t, datsize-t, 0); } - cflush(); symsize = 0; lcsize = 0; @@ -128,9 +121,12 @@ asmb(void) seek(cout, OFFSET, 0); break; case 3: + case 6: /* no header, padded segments */ OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; + case 7: + break; } if(!debug['s']) asmsym(); @@ -139,8 +135,6 @@ asmb(void) Bflush(&bso); if(!debug['s']) asmlc(); - if(!debug['s']) - asmthumbmap(); if(dlm) asmdyn(); cflush(); @@ -151,7 +145,6 @@ asmb(void) cflush(); } - curtext = P; if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); @@ -159,6 +152,7 @@ asmb(void) seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ + case 6: /* no header, padded segments */ break; case 1: /* aif for risc os */ lputl(0xe1a00000); /* NOP - decompress code */ @@ -221,16 +215,12 @@ asmb(void) lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ break; + case 7: /* elf */ + debug['S'] = 1; /* symbol table */ + elf32(ARM, ELFDATA2LSB, 0, nil); + break; } cflush(); - if(debug['c']){ - print("textsize=%ld\n", textsize); - print("datsize=%ld\n", datsize); - print("bsssize=%ld\n", bsssize); - print("symsize=%ld\n", symsize); - print("lcsize=%ld\n", lcsize); - print("total=%ld\n", textsize+datsize+bsssize+symsize+lcsize); - } } void @@ -254,16 +244,6 @@ cput(int c) cflush(); } -/* -void -cput(long c) -{ - *cbp++ = c; - if(--cbc <= 0) - cflush(); -} -*/ - void wput(long l) { @@ -277,11 +257,11 @@ wput(long l) } void -hput(long l) +wputl(long l) { - cbp[0] = l>>8; - cbp[1] = l; + cbp[0] = l; + cbp[1] = l>>8; cbp += 2; cbc -= 2; if(cbc <= 0) @@ -317,11 +297,24 @@ lputl(long l) } void +llput(vlong v) +{ + lput(v>>32); + lput(v); +} + +void +llputl(vlong v) +{ + lputl(v); + lputl(v>>32); +} + +void cflush(void) { int n; - /* no bug if cbc < 0 since obuf(cbuf) followed by ibuf in buf! */ n = sizeof(buf.cbuf) - cbc; if(n) write(cout, buf.cbuf, n); @@ -463,16 +456,15 @@ asmlc(void) oldpc = INITTEXT; oldlc = 0; for(p = firstp; p != P; p = p->link) { - setarch(p); if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { if(p->as == ATEXT) curtext = p; - if(debug['L']) + if(debug['V']) Bprint(&bso, "%6lux %P\n", p->pc, p); continue; } - if(debug['L']) + if(debug['V']) Bprint(&bso, "\t\t%6ld", lcsize); v = (p->pc - oldpc) / MINLC; while(v) { @@ -480,7 +472,7 @@ asmlc(void) if(v < 127) s = v; cput(s+128); /* 129-255 +pc */ - if(debug['L']) + if(debug['V']) Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); v -= s; lcsize++; @@ -494,7 +486,7 @@ asmlc(void) cput(s>>16); cput(s>>8); cput(s); - if(debug['L']) { + if(debug['V']) { if(s > 0) Bprint(&bso, " lc+%ld(%d,%ld)\n", s, 0, s); @@ -509,14 +501,14 @@ asmlc(void) } if(s > 0) { cput(0+s); /* 1-64 +lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); Bprint(&bso, "%6lux %P\n", p->pc, p); } } else { cput(64-s); /* 65-128 -lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); Bprint(&bso, "%6lux %P\n", p->pc, p); @@ -529,62 +521,11 @@ asmlc(void) cput(s); lcsize++; } - if(debug['v'] || debug['L']) + if(debug['v'] || debug['V']) Bprint(&bso, "lcsize = %ld\n", lcsize); Bflush(&bso); } -static void -outt(long f, long l) -{ - if(debug['L']) - Bprint(&bso, "tmap: %lux-%lux\n", f, l); - lput(f); - lput(l); -} - -void -asmthumbmap(void) -{ - long pc, lastt; - Prog *p; - - if(!seenthumb) - return; - pc = 0; - lastt = -1; - for(p = firstp; p != P; p = p->link){ - pc = p->pc - INITTEXT; - if(p->as == ATEXT){ - setarch(p); - if(thumb){ - if(p->from.sym->foreign){ // 8 bytes of ARM first - if(lastt >= 0){ - outt(lastt, pc-1); - lastt = -1; - } - pc += 8; - } - if(lastt < 0) - lastt = pc; - } - else{ - if(p->from.sym->foreign){ // 4 bytes of THUMB first - if(lastt < 0) - lastt = pc; - pc += 4; - } - if(lastt >= 0){ - outt(lastt, pc-1); - lastt = -1; - } - } - } - } - if(lastt >= 0) - outt(lastt, pc+1); -} - void datblk(long s, long n, int str) { @@ -661,25 +602,14 @@ datblk(long s, long n, int str) switch(v->type) { case SUNDEF: ckoff(v, d); - d += v->value; - break; case STEXT: case SLEAF: - d += v->value; -#ifdef CALLEEBX - d += fnpinc(v); -#else - if(v->thumb) - d++; // T bit -#endif - break; case SSTRING: - d += v->value; + d += p->to.sym->value; break; case SDATA: case SBSS: - d += v->value + INITDAT; - break; + d += p->to.sym->value + INITDAT; } if(dlm) dynreloc(v, a+INITDAT, 1); @@ -728,8 +658,6 @@ PP = p; o4 = 0; o5 = 0; o6 = 0; - armsize += o->size; -if(debug['P']) print("%ulx: %P type %d\n", (ulong)(p->pc), p, o->type); switch(o->type) { default: diag("unknown asm %d", o->type); @@ -737,7 +665,6 @@ if(debug['P']) print("%ulx: %P type %d\n", (ulong)(p->pc), p, o->type); break; case 0: /* pseudo ops */ -if(debug['G']) print("%ulx: %s: arm %d %d %d %d\n", (ulong)(p->pc), p->from.sym->name, p->from.sym->thumb, p->from.sym->foreign, p->from.sym->fnptr, p->from.sym->used); break; case 1: /* op R,[R],R */ @@ -807,10 +734,6 @@ if(debug['G']) print("%ulx: %s: arm %d %d %d %d\n", (ulong)(p->pc), p->from.sym- } else if(p->cond != P) v = (p->cond->pc - pc) - 8; -#ifdef CALLEEBX - if(p->as == ABL) - v += fninc(p->to.sym); -#endif o1 = opbra(p->as, p->scond); o1 |= (v >> 2) & 0xffffff; break; @@ -1237,6 +1160,7 @@ if(debug['G']) print("%ulx: %s: arm %d %d %d %d\n", (ulong)(p->pc), p->from.sym- o1 |= rf | (rt<<12); break; + /* old arm 7500 fp using coproc 1 (1<<8) */ case 56: /* move to FP[CS]R */ o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4); o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12); @@ -1417,49 +1341,58 @@ if(debug['G']) print("%ulx: %s: arm %d %d %d %d\n", (ulong)(p->pc), p->from.sym- else if(p->as == AMOVH) o2 ^= (1<<6); break; - case 74: /* bx $I */ -#ifdef CALLEEBX - diag("bx $i case (arm)"); -#endif - if(!seenthumb) - diag("ABX $I and seenthumb==0"); - v = p->cond->pc; - if(p->to.sym->thumb) - v |= 1; // T bit - o1 = olr(8, REGPC, REGTMP, p->scond&C_SCOND); // mov 8(PC), Rtmp - o2 = oprrr(AADD, p->scond) | immrot(8) | (REGPC<<16) | (REGLINK<<12); // add 8,PC, LR - o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // bx Rtmp - o4 = opbra(AB, 14); // B over o6 - o5 = v; - break; - case 75: /* bx O(R) */ - aclass(&p->to); - if(instoffset != 0) - diag("non-zero offset in ABX"); -/* - o1 = oprrr(AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR - o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R -*/ - // p->to.reg may be REGLINK - o1 = oprrr(AADD, p->scond); - o1 |= immrot(instoffset); - o1 |= p->to.reg << 16; - o1 |= REGTMP << 12; - o2 = oprrr(AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR - o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // BX Rtmp + + /* VFP ops: */ + case 74: /* vfp floating point arith */ + o1 = opvfprrr(p->as, p->scond); + rf = p->from.reg; + if(p->from.type == D_FCONST) { + diag("invalid floating-point immediate\n%P", p); + rf = 0; + } + rt = p->to.reg; + r = p->reg; + if(r == NREG) + r = rt; + o1 |= rt<<12; + if(((o1>>20)&0xf) == 0xb) + o1 |= rf<<0; + else + o1 |= r<<16 | rf<<0; break; - case 76: /* bx O(R) when returning from fn*/ - if(!seenthumb) - diag("ABXRET and seenthumb==0"); - aclass(&p->to); -// print("ARM BXRET %d(R%d)\n", instoffset, p->to.reg); - if(instoffset != 0) - diag("non-zero offset in ABXRET"); - // o1 = olr(instoffset, p->to.reg, REGTMP, p->scond); // mov O(R), Rtmp - o1 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R + case 75: /* vfp floating point compare */ + o1 = opvfprrr(p->as, p->scond); + rf = p->from.reg; + if(p->from.type == D_FCONST) { + if(p->from.ieee->h != 0 || p->from.ieee->l != 0) + diag("invalid floating-point immediate\n%P", p); + o1 |= 1<<16; + rf = 0; + } + rt = p->reg; + o1 |= rt<<12 | rf<<0; + o2 = 0x0ef1fa10; /* MRS APSR_nzcv, FPSCR */ + o2 |= (p->scond & C_SCOND) << 28; + break; + case 76: /* vfp floating point fix and float */ + o1 = opvfprrr(p->as, p->scond); + rf = p->from.reg; + rt = p->to.reg; + if(p->from.type == D_REG) { + o2 = o1 | rt<<12 | rt<<0; + o1 = 0x0e000a10; /* VMOV F,R */ + o1 |= (p->scond & C_SCOND) << 28 | rt<<16 | rf<<12; + } else { + o1 |= FREGTMP<<12 | rf<<0; + o2 = 0x0e100a10; /* VMOV R,F */ + o2 |= (p->scond & C_SCOND) << 28 | FREGTMP<<16 | rt<<12; + } break; } + if(debug['a'] > 1) + Bprint(&bso, "%2d ", o->type); + v = p->pc; switch(o->size) { default: @@ -1556,6 +1489,7 @@ oprrr(int a, int sc) case ASRA: return o | (0xd<<21) | (2<<5); case ASWI: return o | (0xf<<24); + /* old arm 7500 fp using coproc 1 (1<<8) */ case AADDD: return o | (0xe<<24) | (0x0<<20) | (1<<8) | (1<<7); case AADDF: return o | (0xe<<24) | (0x0<<20) | (1<<8); case AMULD: return o | (0xe<<24) | (0x1<<20) | (1<<8) | (1<<7); @@ -1583,6 +1517,40 @@ oprrr(int a, int sc) } long +opvfprrr(int a, int sc) +{ + long o; + + o = (sc & C_SCOND) << 28; + if(sc & (C_SBIT|C_PBIT|C_WBIT)) + diag(".S/.P/.W on vfp instruction"); + o |= 0xe<<24; + switch(a) { + case AMOVWD: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x8<<16 | 1<<7; + case AMOVWF: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x8<<16 | 1<<7; + case AMOVDW: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0xD<<16 | 1<<7; + case AMOVFW: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0xD<<16 | 1<<7; + case AMOVFD: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x7<<16 | 1<<7; + case AMOVDF: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x7<<16 | 1<<7; + case AMOVF: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x0<<16 | 0<<7; + case AMOVD: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x0<<16 | 0<<7; + case ACMPF: return o | 0xa<<8 | 0xb<<20 | 1<<6 | 0x4<<16 | 0<<7; + case ACMPD: return o | 0xb<<8 | 0xb<<20 | 1<<6 | 0x4<<16 | 0<<7; + case AADDF: return o | 0xa<<8 | 0x3<<20; + case AADDD: return o | 0xb<<8 | 0x3<<20; + case ASUBF: return o | 0xa<<8 | 0x3<<20 | 1<<6; + case ASUBD: return o | 0xb<<8 | 0x3<<20 | 1<<6; + case AMULF: return o | 0xa<<8 | 0x2<<20; + case AMULD: return o | 0xb<<8 | 0x2<<20; + case ADIVF: return o | 0xa<<8 | 0x8<<20; + case ADIVD: return o | 0xb<<8 | 0x8<<20; + } + diag("bad vfp rrr %d", a); + prasm(curp); + return 0; +} + +long opbra(int a, int sc) { @@ -1637,7 +1605,7 @@ olr(long v, int b, int r, int sc) o ^= 1 << 23; } if(v >= (1<<12)) - diag("literal span too large: %d (R%d)\n%P", v, b, PP); + diag("literal span too large: %ld (R%d)\n%P", v, b, PP); o |= v; o |= b << 16; o |= r << 12; @@ -1662,7 +1630,7 @@ olhr(long v, int b, int r, int sc) o ^= 1 << 23; } if(v >= (1<<8)) - diag("literal span too large: %d (R%d)\n%P", v, b, PP); + diag("literal span too large: %ld (R%d)\n%P", v, b, PP); o |= (v&0xf)|((v>>4)<<8)|(1<<22); o |= b << 16; o |= r << 12; @@ -1717,10 +1685,45 @@ olhrr(int i, int b, int r, int sc) } long +ovfpmem(int a, int r, long v, int b, int sc, Prog *p) +{ + long o; + + if(sc & (C_SBIT|C_PBIT|C_WBIT)) + diag(".S/.P/.W on VLDR/VSTR instruction"); + o = (sc & C_SCOND) << 28; + o |= 0xd<<24 | (1<<23); + if(v < 0) { + v = -v; + o ^= 1 << 23; + } + if(v & 3) + diag("odd offset for floating point op: %ld\n%P", v, p); + else if(v >= (1<<10)) + diag("literal span too large: %ld\n%P", v, p); + o |= (v>>2) & 0xFF; + o |= b << 16; + o |= r << 12; + switch(a) { + default: + diag("bad fst %A", a); + case AMOVD: + o |= 0xb<<8; + break; + case AMOVF: + o |= 0xa<<8; + break; + } + return o; +} + +long ofsr(int a, int r, long v, int b, int sc, Prog *p) { long o; + if(vfp) + return ovfpmem(a, r, v, b, sc, p); if(sc & C_SBIT) diag(".S on FLDR/FSTR instruction"); o = (sc & C_SCOND) << 28; @@ -1734,9 +1737,9 @@ ofsr(int a, int r, long v, int b, int sc, Prog *p) o ^= 1 << 23; } if(v & 3) - diag("odd offset for floating point op: %d\n%P", v, p); + diag("odd offset for floating point op: %ld\n%P", v, p); else if(v >= (1<<10)) - diag("literal span too large: %d\n%P", v, p); + diag("literal span too large: %ld\n%P", v, p); o |= (v>>2) & 0xFF; o |= b << 16; o |= r << 12; @@ -1792,6 +1795,8 @@ chipfloat(Ieee *e) Ieee *p; int n; + if(vfp) + return -1; for(n = sizeof(chipfloats)/sizeof(chipfloats[0]); --n >= 0;){ p = &chipfloats[n]; if(p->l == e->l && p->h == e->h) diff --git a/utils/5l/l.h b/utils/5l/l.h index a7c322be..bd734f1e 100644 --- a/utils/5l/l.h +++ b/utils/5l/l.h @@ -1,13 +1,17 @@ #include <lib9.h> #include <bio.h> #include "../5c/5.out.h" +#include "../8l/elf.h" #ifndef EXTERN #define EXTERN extern #endif -/* do not undefine this - code will be removed eventually */ -#define CALLEEBX +#define LIBNAMELEN 300 + +void addlibpath(char*); +int fileexists(char*); +char* findlib(char*); typedef struct Adr Adr; typedef struct Sym Sym; @@ -17,11 +21,9 @@ typedef struct Optab Optab; typedef struct Oprang Oprang; typedef uchar Opcross[32][2][32]; typedef struct Count Count; -typedef struct Use Use; #define P ((Prog*)0) #define S ((Sym*)0) -#define U ((Use*)0) #define TNAME (curtext&&curtext->from.sym?curtext->from.sym->name:noname) struct Adr @@ -68,7 +70,6 @@ struct Prog uchar as; uchar scond; uchar reg; - uchar align; }; #define regused u0.u0regused #define forwd u0.u0forwd @@ -81,14 +82,10 @@ struct Sym short become; short frame; uchar subtype; + uchar used; ushort file; long value; long sig; - uchar used; - uchar thumb; // thumb code - uchar foreign; // called by arm if thumb, by thumb if arm - uchar fnptr; // used as fn ptr - Use* use; Sym* link; }; @@ -122,12 +119,6 @@ struct Count long count; long outof; }; -struct Use -{ - Prog* p; /* use */ - Prog* ct; /* curtext */ - Use* link; -}; enum { @@ -141,7 +132,6 @@ enum SCONST, SSTRING, SUNDEF, - SREMOVED, SIMPORT, SEXPORT, @@ -150,6 +140,7 @@ enum LTO = 1<<1, LPOOL = 1<<2, V4 = 1<<3, /* arm v4 arch */ + VFP = 1<<4, /* arm vfpv3 floating point */ C_NONE = 0, C_REG, @@ -162,22 +153,17 @@ enum C_RCON, /* 0xff rotated */ C_NCON, /* ~RCON */ C_SCON, /* 0xffff */ - C_BCON, /* thumb */ C_LCON, C_FCON, - C_GCON, /* thumb */ C_RACON, - C_SACON, /* thumb */ C_LACON, - C_GACON, /* thumb */ C_RECON, C_LECON, C_SBRA, C_LBRA, - C_GBRA, /* thumb */ C_HAUTO, /* halfword insn offset (-0xff to 0xff) */ C_FAUTO, /* float insn offset (0 to 0x3fc, word aligned) */ @@ -198,12 +184,6 @@ enum C_ROREG, C_SROREG, /* both S and R */ C_LOREG, - C_GOREG, /* thumb */ - - C_PC, - C_SP, - C_HREG, - C_OFFPC, /* thumb */ C_ADDR, /* relocatable address */ @@ -240,9 +220,6 @@ EXTERN union #define cbuf u.obuf #define xbuf u.ibuf -#define setarch(p) if((p)->as==ATEXT) thumb=(p)->reg&ALLTHUMBS -#define setthumb(p) if((p)->as==ATEXT) seenthumb|=(p)->reg&ALLTHUMBS - #ifndef COFFCVT EXTERN long HEADR; /* length of header */ @@ -250,6 +227,7 @@ EXTERN int HEADTYPE; /* type of header */ EXTERN long INITDAT; /* data location */ EXTERN long INITRND; /* data round above text location */ EXTERN long INITTEXT; /* text location */ +EXTERN long INITTEXTP; /* text location (physical) */ EXTERN char* INITENTRY; /* entry point */ EXTERN long autosize; EXTERN Biobuf bso; @@ -289,7 +267,6 @@ EXTERN long nhunk; EXTERN long instoffset; EXTERN Opcross opcross[8]; EXTERN Oprang oprange[ALAST]; -EXTERN Oprang thumboprange[ALAST]; EXTERN char* outfile; EXTERN long pc; EXTERN uchar repop[ALAST]; @@ -302,9 +279,7 @@ EXTERN char xcmp[C_GOK+1][C_GOK+1]; EXTERN Prog zprg; EXTERN int dtype; EXTERN int armv4; -EXTERN int thumb; -EXTERN int seenthumb; -EXTERN int armsize; +EXTERN int vfp; EXTERN int doexp, dlm; EXTERN int imports, nimports; @@ -316,7 +291,6 @@ EXTERN Prog undefp; extern char* anames[]; extern Optab optab[]; -extern Optab thumboptab[]; void addpool(Prog*, Adr*); EXTERN Prog* blitrl; @@ -329,12 +303,15 @@ EXTERN Prog* prog_mod; EXTERN Prog* prog_modu; #pragma varargck type "A" int +#pragma varargck type "A" uint #pragma varargck type "C" int #pragma varargck type "D" Adr* #pragma varargck type "N" Adr* #pragma varargck type "P" Prog* #pragma varargck type "S" char* +#pragma varargck argpos diag 1 + int Aconv(Fmt*); int Cconv(Fmt*); int Dconv(Fmt*); @@ -342,20 +319,17 @@ int Nconv(Fmt*); int Pconv(Fmt*); int Sconv(Fmt*); int aclass(Adr*); -int thumbaclass(Adr*, Prog*); void addhist(long, int); +void addlibpath(char*); void append(Prog*, Prog*); void asmb(void); void asmdyn(void); void asmlc(void); -void asmthumbmap(void); void asmout(Prog*, Optab*); -void thumbasmout(Prog*, Optab*); void asmsym(void); long atolwhex(char*); Prog* brloop(Prog*); void buildop(void); -void thumbbuildop(void); void buildrep(int, int); void cflush(void); void ckoff(Sym*, long); @@ -374,11 +348,12 @@ long entryvalue(void); void errorexit(void); void exchange(Prog*); void export(void); +int fileexists(char*); int find1(long, int); +char* findlib(char*); void follow(void); void gethunk(void); void histtoauto(void); -void hputl(int); double ieeedtod(Ieee*); long ieeedtof(Ieee*); void import(void); @@ -388,7 +363,8 @@ void loadlib(void); void listinit(void); Sym* lookup(char*, int); void cput(int); -void hput(long); +void llput(vlong); +void llputl(vlong); void lput(long); void lputl(long); void mkfwd(void); @@ -397,10 +373,11 @@ void names(void); void nocache(Prog*); void nuxiinit(void); void objfile(char*); -int ocmp(const void*, const void*); +int ocmp(void*, void*); long opirr(int); Optab* oplook(Prog*); long oprrr(int, int); +long opvfprrr(int, int); long olr(long, int, int, int); long olhr(long, int, int, int); long olrr(int, int, int, int); @@ -426,6 +403,7 @@ void strnput(char*, int); void undef(void); void undefsym(Sym*); void wput(long); +void wputl(long); void xdefine(char*, int, long); void xfol(Prog*); void zerosig(char*); @@ -433,12 +411,5 @@ void noops(void); long immrot(ulong); long immaddr(long); long opbra(int, int); -int brextra(Prog*); -int isbranch(Prog*); -int fnpinc(Sym *); -int fninc(Sym *); -void thumbcount(void); -void reachable(void); -void fnptrs(void); #endif diff --git a/utils/5l/list.c b/utils/5l/list.c index 5d2e7b49..173f3031 100644 --- a/utils/5l/list.c +++ b/utils/5l/list.c @@ -56,14 +56,6 @@ Pconv(Fmt *fp) sprint(str, "(%ld) %A%C %D/%d,%D", p->line, a, p->scond, &p->from, p->reg, &p->to); break; - - case AWORD: - sprint(str, "WORD %ld", p->to.offset); - break; - - case ADWORD: - sprint(str, "DWORD %ld %ld", p->from.offset, p->to.offset); - break; } return fmtstrcpy(fp, str); } @@ -75,7 +67,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/5l/mkfile b/utils/5l/mkfile index 4be81d08..75fa0678 100644 --- a/utils/5l/mkfile +++ b/utils/5l/mkfile @@ -12,7 +12,7 @@ OFILES=\ span.$O\ enam.$O\ $TARGMODEL.$O\ - thumb.$O\ + elf.$O\ HFILES=\ l.h\ @@ -21,7 +21,7 @@ HFILES=\ LIBS=bio 9 # order is important -CFLAGS=$CFLAGS -I../include +CFLAGS=$CFLAGS -I../include -I. BIN=$ROOT/$OBJDIR/bin @@ -30,3 +30,8 @@ BIN=$ROOT/$OBJDIR/bin enam.$O: ../5c/enam.c $CC $CFLAGS ../5c/enam.c +elf.$O: ../ld/elf.c + $CC $CFLAGS ../ld/elf.c + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/5l/noop.c b/utils/5l/noop.c index 08ef6dbe..e68c08f6 100644 --- a/utils/5l/noop.c +++ b/utils/5l/noop.c @@ -5,76 +5,11 @@ static Sym* sym_divu; static Sym* sym_mod; static Sym* sym_modu; -static void setdiv(int); - -static Prog * -movrr(Prog *q, int rs, int rd, Prog *p) -{ - if(q == nil) - q = prg(); - q->as = AMOVW; - q->line = p->line; - q->from.type = D_REG; - q->from.reg = rs; - q->to.type = D_REG; - q->to.reg = rd; - q->link = p->link; - return q; -} - -static Prog * -fnret(Prog *q, int rs, int foreign, Prog *p) -{ - q = movrr(q, rs, REGPC, p); - if(foreign){ // BX rs - q->as = ABXRET; - q->from.type = D_NONE; - q->from.reg = NREG; - q->to.reg = rs; - } - return q; -} - -static Prog * -aword(long w, Prog *p) -{ - Prog *q; - - q = prg(); - q->as = AWORD; - q->line = p->line; - q->from.type = D_NONE; - q->reg = NREG; - q->to.type = D_CONST; - q->to.offset = w; - q->link = p->link; - p->link = q; - return q; -} - -static Prog * -adword(long w1, long w2, Prog *p) -{ - Prog *q; - - q = prg(); - q->as = ADWORD; - q->line = p->line; - q->from.type = D_CONST; - q->from.offset = w1; - q->reg = NREG; - q->to.type = D_CONST; - q->to.offset = w2; - q->link = p->link; - p->link = q; - return q; -} - void noops(void) { - Prog *p, *q, *q1, *q2; - int o, curframe, curbecome, maxbecome, foreign; + Prog *p, *q, *q1; + int o, curframe, curbecome, maxbecome; /* * find leaf subroutines @@ -96,7 +31,6 @@ noops(void) q = P; for(p = firstp; p != P; p = p->link) { - setarch(p); /* find out how much arg space is used in this TEXT */ if(p->to.type == D_OREG && p->to.reg == REGSP) @@ -134,7 +68,6 @@ noops(void) initdiv(); if(curtext != P) curtext->mark &= ~LEAF; - setdiv(p->as); continue; case ANOP: @@ -144,7 +77,6 @@ noops(void) continue; case ABL: - case ABX: if(curtext != P) curtext->mark &= ~LEAF; @@ -193,13 +125,11 @@ noops(void) curtext = 0; for(p = firstp; p != P; p = p->link) { - setarch(p); switch(p->as) { case ATEXT: curtext = p; break; case ABL: - // case ABX: if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) { o = maxbecome - curtext->from.sym->frame; if(o <= 0) @@ -219,7 +149,6 @@ noops(void) } for(p = firstp; p != P; p = p->link) { - setarch(p); o = p->as; switch(o) { case ATEXT: @@ -238,16 +167,7 @@ noops(void) Bflush(&bso); curtext->mark |= LEAF; } -#ifdef CALLEEBX - if(p->from.sym->foreign){ - if(thumb) - // don't allow literal pool to seperate these - p = adword(0xe28f7001, 0xe12fff17, p); // arm add 1, pc, r7 and bx r7 - // p = aword(0xe12fff17, aword(0xe28f7001, p)); // arm add 1, pc, r7 and bx r7 - else - p = aword(0x4778, p); // thumb bx pc and 2 bytes padding - } -#endif + if(curtext->mark & LEAF) { if(curtext->from.sym) curtext->from.sym->type = SLEAF; @@ -271,36 +191,6 @@ noops(void) #endif } - if(thumb){ - if(!(curtext->mark & LEAF)){ - q = movrr(nil, REGLINK, REGTMPT-1, p); - p->link = q; - q1 = prg(); - q1->as = AMOVW; - q1->line = p->line; - q1->from.type = D_REG; - q1->from.reg = REGTMPT-1; - q1->to.type = D_OREG; - q1->to.name = D_NONE; - q1->to.reg = REGSP; - q1->to.offset = 0; - q1->link = q->link; - q->link = q1; - } - if(autosize){ - q2 = prg(); - q2->as = ASUB; - q2->line = p->line; - q2->from.type = D_CONST; - q2->from.offset = autosize; - q2->to.type = D_REG; - q2->to.reg = REGSP; - q2->link = p->link; - p->link = q2; - } - break; - } - q1 = prg(); q1->as = AMOVW; q1->scond |= C_WBIT; @@ -310,24 +200,18 @@ noops(void) q1->to.type = D_OREG; q1->to.offset = -autosize; q1->to.reg = REGSP; + q1->link = p->link; p->link = q1; break; case ARET: nocache(p); - foreign = seenthumb && curtext->from.sym != S && (curtext->from.sym->foreign || curtext->from.sym->fnptr); -// print("%s %d %d\n", curtext->from.sym->name, curtext->from.sym->foreign, curtext->from.sym->fnptr); if(p->from.type == D_CONST) goto become; if(curtext->mark & LEAF) { if(!autosize) { - if(thumb){ - p = fnret(p, REGLINK, foreign, p); - break; - } -// if(foreign) print("ABXRET 1 %s\n", curtext->from.sym->name); - p->as = foreign ? ABXRET : AB; + p->as = AB; p->from = zprg.from; p->to.type = D_OREG; p->to.offset = 0; @@ -341,13 +225,9 @@ noops(void) p->from.offset = autosize; p->to.type = D_REG; p->to.reg = REGSP; - if(thumb){ - p->link = fnret(nil, REGLINK, foreign, p); - break; - } + q = prg(); -// if(foreign) print("ABXRET 2 %s\n", curtext->from.sym->name); - q->as = foreign ? ABXRET : AB; + q->as = AB; q->scond = p->scond; q->line = p->line; q->to.type = D_OREG; @@ -360,100 +240,16 @@ noops(void) break; #endif } - if(thumb){ - if(curtext->mark & LEAF){ - if(autosize){ - p->as = AADD; - p->from.type = D_CONST; - p->from.offset = autosize; - p->to.type = D_REG; - p->to.reg = REGSP; - q = nil; - } - else - q = p; - q = fnret(q, REGLINK, foreign, p); - if(q != p) - p->link = q; - } - else{ - p->as = AMOVW; - p->from.type = D_OREG; - p->from.name = D_NONE; - p->from.reg = REGSP; - p->from.offset = 0; - p->to.type = D_REG; - p->to.reg = REGTMPT-1; - if(autosize){ - q = prg(); - q->as = AADD; - q->from.type = D_CONST; - q->from.offset = autosize; - q->to.type = D_REG; - q->to.reg = REGSP; - q->link = p->link; - p->link = q; - } - else - q = p; - q1 = fnret(nil, REGTMPT-1, foreign, p); - q1->link = q->link; - q->link = q1; - } - break; - } - if(foreign) { -// if(foreign) print("ABXRET 3 %s\n", curtext->from.sym->name); -#define R 1 - p->as = AMOVW; - p->from.type = D_OREG; - p->from.name = D_NONE; - p->from.reg = REGSP; - p->from.offset = 0; - p->to.type = D_REG; - p->to.reg = R; - q = prg(); - q->as = AADD; - q->scond = p->scond; - q->line = p->line; - q->from.type = D_CONST; - q->from.offset = autosize; - q->to.type = D_REG; - q->to.reg = REGSP; - q->link = p->link; - p->link = q; - q1 = prg(); - q1->as = ABXRET; - q1->scond = p->scond; - q1->line = p->line; - q1->to.type = D_OREG; - q1->to.offset = 0; - q1->to.reg = R; - q1->link = q->link; - q->link = q1; -#undef R - } - else { - p->as = AMOVW; - p->scond |= C_PBIT; - p->from.type = D_OREG; - p->from.offset = autosize; - p->from.reg = REGSP; - p->to.type = D_REG; - p->to.reg = REGPC; - } + p->as = AMOVW; + p->scond |= C_PBIT; + p->from.type = D_OREG; + p->from.offset = autosize; + p->from.reg = REGSP; + p->to.type = D_REG; + p->to.reg = REGPC; break; become: - if(foreign){ - diag("foreign become - help"); - break; - } - if(thumb){ - diag("thumb become - help"); - break; - } - print("arm become\n"); if(curtext->mark & LEAF) { if(!autosize) { @@ -493,29 +289,7 @@ noops(void) q->cond = p->cond; q->link = p->link; p->link = q; - if(thumb){ - q1 = prg(); - q1->line = p->line; - q1->as = AADD; - q1->from.type = D_CONST; - q1->from.offset = autosize; - q1->to.type = D_REG; - q1->to.reg = REGSP; - p->as = AMOVW; - p->line = p->line; - p->from.type = D_OREG; - p->from.name = D_NONE; - p->from.reg = REGSP; - p->from.offset = 0; - p->to.type = D_REG; - p->to.reg = REGTMPT-1; - q1->link = q; - p->link = q1; - q2 = movrr(nil, REGTMPT-1, REGLINK, p); - q2->link = q; - q1->link = q2; - break; - } + p->as = AMOVW; p->scond |= C_PBIT; p->from = zprg.from; @@ -528,6 +302,30 @@ noops(void) break; + /* + * 5c code generation for unsigned -> double made the + * unfortunate assumption that single and double floating + * point registers are aliased - true for emulated 7500 + * but not for vfp. Now corrected, but this test is + * insurance against old 5c compiled code in libraries. + */ + case AMOVWD: + if((q = p->link) != P && q->as == ACMP) + if((q = q->link) != P && q->as == AMOVF) + if((q1 = q->link) != P && q1->as == AADDF) + if(q1->to.type == D_FREG && q1->to.reg == p->to.reg) { + q1->as = AADDD; + q1 = prg(); + q1->scond = q->scond; + q1->line = q->line; + q1->as = AMOVFD; + q1->from = q->to; + q1->to = q1->from; + q1->link = q->link; + q->link = q1; + } + break; + case ADIV: case ADIVU: case AMOD: @@ -567,7 +365,7 @@ noops(void) if(q1->reg == NREG) p->from.reg = q1->to.reg; p->to.type = D_REG; - p->to.reg = prog_div != UP && prog_div->from.sym->thumb ? REGTMPT : REGTMP; + p->to.reg = REGTMP; p->to.offset = 0; /* CALL appropriate */ @@ -576,14 +374,7 @@ noops(void) p->link = q; p = q; -#ifdef CALLEEBX p->as = ABL; -#else - if(prog_div != UP && prog_div->from.sym->thumb) - p->as = thumb ? ABL : ABX; - else - p->as = thumb ? ABX : ABL; -#endif p->line = q1->line; p->to.type = D_BRANCH; p->cond = p; @@ -615,7 +406,7 @@ noops(void) p->as = AMOVW; p->line = q1->line; p->from.type = D_REG; - p->from.reg = prog_div != UP && prog_div->from.sym->thumb ? REGTMPT : REGTMP; + p->from.reg = REGTMP; p->from.offset = 0; p->to.type = D_REG; p->to.reg = q1->to.reg; @@ -642,145 +433,6 @@ noops(void) q1->reg = NREG; q1->to.type = D_REG; q1->to.reg = REGSP; - - break; - case AMOVW: - if(thumb){ - Adr *a = &p->from; - - if(a->type == D_CONST && ((a->name == D_NONE && a->reg == REGSP) || a->name == D_AUTO || a->name == D_PARAM) && (a->offset & 3)) - diag("SP offset not multiple of 4"); - } - break; - case AMOVB: - case AMOVBU: - case AMOVH: - case AMOVHU: - if(thumb){ - if(p->from.type == D_OREG && (p->from.name == D_AUTO || p->from.name == D_PARAM || (p->from.name == D_CONST && p->from.reg == REGSP))){ - q = prg(); - *q = *p; - if(p->from.name == D_AUTO) - q->from.offset += autosize; - else if(p->from.name == D_PARAM) - q->from.offset += autosize+4; - q->from.name = D_NONE; - q->from.reg = REGTMPT; - p = movrr(p, REGSP, REGTMPT, p); - q->link = p->link; - p->link = q; - } - if(p->to.type == D_OREG && (p->to.name == D_AUTO || p->to.name == D_PARAM || (p->to.name == D_CONST && p->to.reg == REGSP))){ - q = prg(); - *q = *p; - if(p->to.name == D_AUTO) - q->to.offset += autosize; - else if(p->to.name == D_PARAM) - q->to.offset += autosize+4; - q->to.name = D_NONE; - q->to.reg = REGTMPT; - p = movrr(p, REGSP, REGTMPT, p); - q->link = p->link; - p->link = q; - if(q->to.offset < 0 || q->to.offset > 255){ // complicated - p->to.reg = REGTMPT+1; // mov sp, r8 - q1 = prg(); - q1->line = p->line; - q1->as = AMOVW; - q1->from.type = D_CONST; - q1->from.offset = q->to.offset; - q1->to.type = D_REG; - q1->to.reg = REGTMPT; // mov $o, r7 - p->link = q1; - q1->link = q; - q1 = prg(); - q1->line = p->line; - q1->as = AADD; - q1->from.type = D_REG; - q1->from.reg = REGTMPT+1; - q1->to.type = D_REG; - q1->to.reg = REGTMPT; // add r8, r7 - p->link->link = q1; - q1->link = q; - q->to.offset = 0; // mov* r, 0(r7) - /* phew */ - } - } - } - break; - case AMOVM: - if(thumb){ - if(p->from.type == D_OREG){ - if(p->from.offset == 0) - p->from.type = D_REG; - else - diag("non-zero AMOVM offset"); - } - else if(p->to.type == D_OREG){ - if(p->to.offset == 0) - p->to.type = D_REG; - else - diag("non-zero AMOVM offset"); - } - } - break; - case AB: - if(thumb && p->to.type == D_OREG){ - if(p->to.offset == 0){ - p->as = AMOVW; - p->from.type = D_REG; - p->from.reg = p->to.reg; - p->to.type = D_REG; - p->to.reg = REGPC; - } - else{ - p->as = AADD; - p->from.type = D_CONST; - p->from.offset = p->to.offset; - p->reg = p->to.reg; - p->to.type = D_REG; - p->to.reg = REGTMPT-1; - q = prg(); - q->as = AMOVW; - q->line = p->line; - q->from.type = D_REG; - q->from.reg = REGTMPT-1; - q->to.type = D_REG; - q->to.reg = REGPC; - q->link = p->link; - p->link = q; - } - } - if(seenthumb && !thumb && p->to.type == D_OREG && p->to.reg == REGLINK){ - // print("warn %s: b (R%d) assuming a return\n", curtext->from.sym->name, p->to.reg); - p->as = ABXRET; - } - break; - case ABL: - case ABX: - if(thumb && p->to.type == D_OREG){ - if(p->to.offset == 0){ - p->as = o; - p->from.type = D_NONE; - p->to.type = D_REG; - } - else{ - p->as = AADD; - p->from.type = D_CONST; - p->from.offset = p->to.offset; - p->reg = p->to.reg; - p->to.type = D_REG; - p->to.reg = REGTMPT-1; - q = prg(); - q->as = o; - q->line = p->line; - q->from.type = D_NONE; - q->to.type = D_REG; - q->to.reg = REGTMPT-1; - q->link = p->link; - p->link = q; - } - } break; } } @@ -870,21 +522,6 @@ initdiv(void) } } -static void -setdiv(int as) -{ - Prog *p = nil; - - switch(as){ - case ADIV: p = prog_div; break; - case ADIVU: p = prog_divu; break; - case AMOD: p = prog_mod; break; - case AMODU: p = prog_modu; break; - } - if(p != UP && thumb != p->from.sym->thumb) - p->from.sym->foreign = 1; -} - void nocache(Prog *p) { diff --git a/utils/5l/obj.c b/utils/5l/obj.c index 35c5f558..202f8eec 100644 --- a/utils/5l/obj.c +++ b/utils/5l/obj.c @@ -11,14 +11,28 @@ char symname[] = SYMDEF; char thechar = '5'; char *thestring = "arm"; +char** libdir; +int nlibdir = 0; +static int maxlibdir = 0; + /* + * -H0 no header * -H1 -T0x10005000 -R4 is aif for risc os * -H2 -T4128 -R4096 is plan9 format * -H3 -T0xF0000020 -R4 is NetBSD format * -H4 is IXP1200 (raw) * -H5 -T0xC0008010 -R1024 is ipaq + * -H6 -R4096 no header with segments padded to pages + * -H7 is elf */ +void +usage(void) +{ + diag("usage: %s [-options] objects", argv0); + errorexit(); +} + static int isobjfile(char *f) { @@ -46,9 +60,9 @@ main(int argc, char *argv[]) { int c; char *a; + char name[LIBNAMELEN]; Binit(&bso, 1, OWRITE); - srand(time(0)); cout = -1; listinit(); outfile = 0; @@ -56,6 +70,7 @@ main(int argc, char *argv[]) curtext = P; HEADTYPE = -1; INITTEXT = -1; + INITTEXTP = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; @@ -74,11 +89,19 @@ main(int argc, char *argv[]) if(a) INITENTRY = a; break; + case 'L': + addlibpath(EARGF(usage())); + break; case 'T': a = ARGF(); if(a) INITTEXT = atolwhex(a); break; + case 'P': + a = ARGF(); + if(a) + INITTEXTP = atolwhex(a); + break; case 'D': a = ARGF(); if(a) @@ -102,7 +125,6 @@ main(int argc, char *argv[]) break; case 'u': /* produce dynamically loadable module */ dlm = 1; - debug['l']++; if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) readundefs(ARGF(), SIMPORT); break; @@ -110,12 +132,20 @@ main(int argc, char *argv[]) USED(argc); - if(*argv == 0) { - diag("usage: 5l [-options] objects"); - errorexit(); - } + if(*argv == 0) + usage(); if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; + a = getenv("ccroot"); + if(a != nil && *a != '\0') { + if(!fileexists(a)) { + diag("nonexistent $ccroot: %s", a); + errorexit(); + } + }else + a = ""; + snprint(name, sizeof(name), "%s/%s/lib", a, thestring); + addlibpath(name); if(HEADTYPE == -1) { if(debug['U']) HEADTYPE = 0; @@ -129,6 +159,7 @@ main(int argc, char *argv[]) diag("unknown -H option"); errorexit(); case 0: /* no header */ + case 6: /* no header, padded segments */ HEADR = 0L; if(INITTEXT == -1) INITTEXT = 0; @@ -182,7 +213,18 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 1024; break; + case 7: /* elf executable */ + HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16); + if(INITTEXT == -1) + INITTEXT = 4096+HEADR; + if(INITDAT == -1) + INITDAT = 0; + if(INITRND == -1) + INITRND = 4; + break; } + if (INITTEXTP == -1) + INITTEXTP = INITTEXT; if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", INITDAT, INITRND); @@ -198,7 +240,6 @@ main(int argc, char *argv[]) zprg.from.reg = NREG; zprg.to = zprg.from; buildop(); - thumbbuildop(); // could build on demand histgen = 0; textp = P; datap = P; @@ -208,7 +249,7 @@ main(int argc, char *argv[]) outfile = "5.out"; cout = create(outfile, 1, 0775); if(cout < 0) { - diag("%s: cannot create", outfile); + diag("cannot create %s: %r", outfile); errorexit(); } nuxiinit(); @@ -225,7 +266,7 @@ main(int argc, char *argv[]) INITENTRY = "_mainp"; if(!debug['l']) lookup(INITENTRY, 0)->type = SXREF; - } else + } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9')) lookup(INITENTRY, 0)->type = SXREF; while(*argv) @@ -259,11 +300,7 @@ main(int argc, char *argv[]) doprof1(); else doprof2(); - if(debug['u']) - reachable(); dodata(); - if(seenthumb && debug['f']) - fnptrs(); follow(); if(firstp == P) goto out; @@ -273,10 +310,6 @@ main(int argc, char *argv[]) undef(); out: - if(debug['c']){ - thumbcount(); - print("ARM size = %d\n", armsize); - } if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); Bprint(&bso, "%ld memory used\n", thunk); @@ -288,6 +321,42 @@ out: } void +addlibpath(char *arg) +{ + char **p; + + if(nlibdir >= maxlibdir) { + if(maxlibdir == 0) + maxlibdir = 8; + else + maxlibdir *= 2; + p = malloc(maxlibdir*sizeof(*p)); + if(p == nil) { + diag("out of memory"); + errorexit(); + } + memmove(p, libdir, nlibdir*sizeof(*p)); + free(libdir); + libdir = p; + } + libdir[nlibdir++] = strdup(arg); +} + +char* +findlib(char *file) +{ + int i; + char name[LIBNAMELEN]; + + for(i = 0; i < nlibdir; i++) { + snprint(name, sizeof(name), "%s/%s", libdir[i], file); + if(fileexists(name)) + return libdir[i]; + } + return nil; +} + +void loadlib(void) { int i; @@ -298,7 +367,7 @@ loop: xrefresolv = 0; for(i=0; i<libraryp; i++) { if(debug['v']) - Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]); + Bprint(&bso, "%5.2f autolib: %s\n", cputime(), library[i]); objfile(library[i]); } if(xrefresolv) @@ -312,7 +381,6 @@ void errorexit(void) { - Bflush(&bso); if(nerrors) { if(cout >= 0) remove(outfile); @@ -328,25 +396,26 @@ objfile(char *file) int f, work; Sym *s; char magbuf[SARMAG]; - char name[100], pname[150]; + char name[LIBNAMELEN], pname[LIBNAMELEN]; struct ar_hdr arhdr; char *e, *start, *stop; - if(file[0] == '-' && file[1] == 'l') { - if(debug['9']) - sprint(name, "/%s/lib/lib", thestring); - else - sprint(name, "/usr/%clib/lib", thechar); - strcat(name, file+2); - strcat(name, ".a"); - file = name; - } if(debug['v']) Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); Bflush(&bso); + if(file[0] == '-' && file[1] == 'l') { + snprint(pname, sizeof(pname), "lib%s.a", file+2); + e = findlib(pname); + if(e == nil) { + diag("cannot find library: %s", file); + errorexit(); + } + snprint(name, sizeof(name), "%s/%s", e, pname); + file = name; + } f = open(file, 0); if(f < 0) { - diag("cannot open file: %s", file); + diag("cannot open %s: %r", file); errorexit(); } l = read(f, magbuf, SARMAG); @@ -407,7 +476,8 @@ objfile(char *file) l |= (e[3] & 0xff) << 16; l |= (e[4] & 0xff) << 24; seek(f, l, 0); - l = read(f, &arhdr, SAR_HDR); + /* need readn to read the dumps (at least) */ + l = readn(f, &arhdr, SAR_HDR); if(l != SAR_HDR) goto bad; if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) @@ -434,7 +504,7 @@ int zaddr(uchar *p, Adr *a, Sym *h[]) { int i, c; - long l; + int l; Sym *s; Auto *u; @@ -456,17 +526,6 @@ zaddr(uchar *p, Adr *a, Sym *h[]) return 0; /* force real diagnostic */ } - if(a->type == D_CONST || a->type == D_OCONST) { - if(a->name == D_EXTERN || a->name == D_STATIC) { - s = a->sym; - if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF)) { - if(0 && !s->fnptr && s->name[0] != '.') - print("%s used as function pointer\n", s->name); - s->fnptr = 1; // over the top cos of SXREF - } - } - } - switch(a->type) { default: print("unknown type %d\n", a->type); @@ -553,25 +612,24 @@ zaddr(uchar *p, Adr *a, Sym *h[]) void addlib(char *obj) { - char name[1024], comp[256], *p; - int i; + char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name; + int i, search; if(histfrogp <= 0) return; + name = fn1; + search = 0; if(histfrog[0]->name[1] == '/') { sprint(name, ""); i = 1; - } else - if(histfrog[0]->name[1] == '.') { + } else if(histfrog[0]->name[1] == '.') { sprint(name, "."); i = 0; } else { - if(debug['9']) - sprint(name, "/%s/lib", thestring); - else - sprint(name, "/usr/%clib", thechar); + sprint(name, ""); i = 0; + search = 1; } for(; i<histfrogp; i++) { @@ -594,13 +652,25 @@ addlib(char *obj) memmove(p+strlen(thestring), p+2, strlen(p+2)+1); memmove(p, thestring, strlen(thestring)); } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { + if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) { diag("library component too long"); return; } - strcat(name, "/"); - strcat(name, comp); + if(i > 0 || !search) + strcat(fn1, "/"); + strcat(fn1, comp); + } + + cleanname(name); + + if(search){ + p = findlib(name); + if(p != nil){ + snprint(fn2, sizeof(fn2), "%s/%s", p, name); + name = fn2; + } } + for(i=0; i<libraryp; i++) if(strcmp(name, library[i]) == 0) return; @@ -719,8 +789,6 @@ readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) return stop + n; } -static void puntfp(Prog *); - void ldobj(int f, long c, char *pn) { @@ -955,9 +1023,6 @@ loop: break; case ATEXT: - setarch(p); - setthumb(p); - p->align = 4; if(curtext != P) { histtoauto(); curtext->to.autom = curauto; @@ -982,7 +1047,6 @@ loop: } s->type = STEXT; s->value = pc; - s->thumb = thumb; lastp->link = p; lastp = p; p->pc = pc; @@ -1014,31 +1078,7 @@ loop: } goto casedef; - case AMOVWD: - case AMOVWF: - case AMOVDW: - case AMOVFW: - case AMOVFD: - case AMOVDF: - // case AMOVF: - // case AMOVD: - case ACMPF: - case ACMPD: - case AADDF: - case AADDD: - case ASUBF: - case ASUBD: - case AMULF: - case AMULD: - case ADIVF: - case ADIVD: - if(thumb) - puntfp(p); - goto casedef; - case AMOVF: - if(thumb) - puntfp(p); if(skip) goto casedef; @@ -1068,8 +1108,6 @@ loop: goto casedef; case AMOVD: - if(thumb) - puntfp(p); if(skip) goto casedef; @@ -1130,8 +1168,7 @@ lookup(char *symb, int v) for(p=symb; c = *p; p++) h = h+h+h + c; l = (p - symb) + 1; - if(h < 0) - h = ~h; + h &= 0xffffff; h %= NHASH; for(s = hash[h]; s != S; s = s->link) if(s->version == v) @@ -1152,8 +1189,6 @@ lookup(char *symb, int v) s->version = v; s->value = 0; s->sig = 0; - s->used = s->thumb = s->foreign = s->fnptr = 0; - s->use = nil; hash[h] = s; return s; } @@ -1208,7 +1243,6 @@ doprof1(void) s = lookup("__mcount", 0); n = 1; for(p = firstp->link; p != P; p = p->link) { - setarch(p); if(p->as == ATEXT) { q = prg(); q->line = p->line; @@ -1235,7 +1269,7 @@ doprof1(void) p->from.sym = s; p->from.offset = n*4 + 4; p->to.type = D_REG; - p->to.reg = thumb ? REGTMPT : REGTMP; + p->to.reg = REGTMP; q = prg(); q->line = p->line; @@ -1247,7 +1281,7 @@ doprof1(void) p->from.type = D_CONST; p->from.offset = 1; p->to.type = D_REG; - p->to.reg = thumb ? REGTMPT : REGTMP; + p->to.reg = REGTMP; q = prg(); q->line = p->line; @@ -1257,7 +1291,7 @@ doprof1(void) p = q; p->as = AMOVW; p->from.type = D_REG; - p->from.reg = thumb ? REGTMPT : REGTMP; + p->from.reg = REGTMP; p->to.type = D_OREG; p->to.name = D_EXTERN; p->to.sym = s; @@ -1284,25 +1318,36 @@ doprof1(void) s->value = n*4; } +static int brcond[] = {ABEQ, ABNE, ABCS, ABCC, ABMI, ABPL, ABVS, ABVC, ABHI, ABLS, ABGE, ABLT, ABGT, ABLE}; + void doprof2(void) { Sym *s2, *s4; - Prog *p, *q, *ps2, *ps4; + Prog *p, *q, *q2, *ps2, *ps4; if(debug['v']) Bprint(&bso, "%5.2f profile 2\n", cputime()); Bflush(&bso); - s2 = lookup("_profin", 0); - s4 = lookup("_profout", 0); + + if(debug['e']){ + s2 = lookup("_tracein", 0); + s4 = lookup("_traceout", 0); + }else{ + s2 = lookup("_profin", 0); + s4 = lookup("_profout", 0); + } if(s2->type != STEXT || s4->type != STEXT) { - diag("_profin/_profout not defined"); + if(debug['e']) + diag("_tracein/_traceout not defined %d %d", s2->type, s4->type); + else + diag("_profin/_profout not defined"); return; } + ps2 = P; ps4 = P; for(p = firstp; p != P; p = p->link) { - setarch(p); if(p->as == ATEXT) { if(p->from.sym == s2) { ps2 = p; @@ -1315,7 +1360,6 @@ doprof2(void) } } for(p = firstp; p != P; p = p->link) { - setarch(p); if(p->as == ATEXT) { if(p->reg & NOPROF) { for(;;) { @@ -1330,13 +1374,26 @@ doprof2(void) } /* - * BL profin, R2 + * BL profin */ q = prg(); q->line = p->line; q->pc = p->pc; q->link = p->link; - p->link = q; + if(debug['e']){ /* embedded tracing */ + q2 = prg(); + p->link = q2; + q2->link = q; + + q2->line = p->line; + q2->pc = p->pc; + + q2->as = AB; + q2->to.type = D_BRANCH; + q2->to.sym = p->to.sym; + q2->cond = q->link; + }else + p->link = q; p = q; p->as = ABL; p->to.type = D_BRANCH; @@ -1347,27 +1404,64 @@ doprof2(void) } if(p->as == ARET) { /* + * RET (default) + */ + if(debug['e']){ /* embedded tracing */ + q = prg(); + q->line = p->line; + q->pc = p->pc; + q->link = p->link; + p->link = q; + p = q; + } + + /* * RET */ q = prg(); q->as = ARET; q->from = p->from; q->to = p->to; + q->cond = p->cond; q->link = p->link; + q->reg = p->reg; p->link = q; - /* - * BL profout - */ - p->as = ABL; - p->from = zprg.from; - p->to = zprg.to; - p->to.type = D_BRANCH; - p->cond = ps4; - p->to.sym = s4; - - p = q; - + if(p->scond != 14) { + q = prg(); + q->as = ABL; + q->from = zprg.from; + q->to = zprg.to; + q->to.type = D_BRANCH; + q->cond = ps4; + q->to.sym = s4; + q->link = p->link; + p->link = q; + + p->as = brcond[p->scond^1]; /* complement */ + p->scond = 14; + p->from = zprg.from; + p->to = zprg.to; + p->to.type = D_BRANCH; + p->cond = q->link->link; /* successor of RET */ + p->to.offset = q->link->link->pc; + + p = q->link->link; + } else { + + /* + * BL profout + */ + p->as = ABL; + p->from = zprg.from; + p->to = zprg.to; + p->to.type = D_BRANCH; + p->cond = ps4; + p->to.sym = s4; + p->scond = 14; + + p = q; + } continue; } } @@ -1387,7 +1481,7 @@ nuxiinit(void) inuxi1[i] = c; inuxi4[i] = c; fnuxi4[i] = c; - if(!debug['d']){ + if(debug['d'] == 0){ fnuxi8[i] = c; fnuxi8[i+4] = c+4; } @@ -1481,17 +1575,6 @@ ieeedtod(Ieee *ieeep) return ldexp(fr, exp); } -static void -puntfp(Prog *p) -{ - USED(p); - /* floating point - punt for now */ - curtext->reg = NREG; /* ARM */ - curtext->from.sym->thumb = 0; - thumb = 0; - // print("%s: generating ARM code (contains floating point ops %d)\n", curtext->from.sym->name, p->line); -} - void undefsym(Sym *s) { @@ -1544,7 +1627,7 @@ readundefs(char *f, int t) diag("%s: bad format", f); errorexit(); } - for(i = 0; i < n; i++){ + for(i = 0; i < n; i++) { s = lookup(fields[i], 0); s->type = SXREF; s->subtype = t; diff --git a/utils/5l/optab.c b/utils/5l/optab.c index 65ad3447..e9a566fd 100644 --- a/utils/5l/optab.c +++ b/utils/5l/optab.c @@ -29,13 +29,10 @@ Optab optab[] = { AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, LPOOL }, { ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0 }, - { ABX, C_NONE, C_NONE, C_SBRA, 74, 20, 0 }, { ABEQ, C_NONE, C_NONE, C_SBRA, 5, 4, 0 }, { AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL }, { ABL, C_NONE, C_NONE, C_ROREG, 7, 8, 0 }, - { ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0 }, - { ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0 }, { ASLL, C_RCON, C_REG, C_REG, 8, 4, 0 }, { ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0 }, @@ -47,7 +44,6 @@ Optab optab[] = { ASWI, C_NONE, C_NONE, C_LOREG, 10, 4, 0 }, { AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0 }, - { AWORD, C_NONE, C_NONE, C_GCON, 11, 4, 0 }, { AWORD, C_NONE, C_NONE, C_LEXT, 11, 4, 0 }, { AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0 }, @@ -215,6 +211,14 @@ Optab optab[] = { ACASE, C_REG, C_NONE, C_NONE, 62, 4, 0 }, { ABCASE, C_NONE, C_NONE, C_SBRA, 63, 4, 0 }, + { AADDF, C_FREG, C_NONE, C_FREG, 74, 4, 0, VFP }, + { AADDF, C_FREG, C_REG, C_FREG, 74, 4, 0, VFP }, + { AMOVF, C_FREG, C_NONE, C_FREG, 74, 4, 0, VFP }, + { ACMPF, C_FREG, C_REG, C_NONE, 75, 8, 0, VFP }, + { ACMPF, C_FCON, C_REG, C_NONE, 75, 8, 0, VFP }, + { AMOVFW, C_FREG, C_NONE, C_REG, 76, 8, 0, VFP }, + { AMOVFW, C_REG, C_NONE, C_FREG, 76, 8, 0, VFP }, + { AMOVH, C_REG, C_NONE, C_HEXT, 70, 4, REGSB, V4 }, { AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, V4 }, { AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, V4 }, diff --git a/utils/5l/pass.c b/utils/5l/pass.c index e4322df5..8ce7b6d0 100644 --- a/utils/5l/pass.c +++ b/utils/5l/pass.c @@ -24,11 +24,6 @@ dodata(void) if(v > s->value) diag("initialize bounds (%ld): %s\n%P", s->value, s->name, p); - if((s->type == SBSS || s->type == SDATA) && (p->to.type == D_CONST || p->to.type == D_OCONST) && (p->to.name == D_EXTERN || p->to.name == D_STATIC)){ - s = p->to.sym; - if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF)) - s->fnptr = 1; - } } if(debug['t']) { @@ -187,7 +182,6 @@ xfol(Prog *p) loop: if(p == P) return; - setarch(p); a = p->as; if(a == ATEXT) curtext = p; @@ -260,7 +254,7 @@ loop: return; } if(p->cond != P) - if(a != ABL && a != ABX && p->link != P) { + if(a != ABL && p->link != P) { q = brchain(p->link); if(a != ATEXT && a != ABCASE) if(q != P && (q->mark&FOLL)) { @@ -288,7 +282,7 @@ patch(void) { long c, vexit; Prog *p, *q; - Sym *s, *s1; + Sym *s; int a; if(debug['v']) @@ -298,17 +292,10 @@ patch(void) s = lookup("exit", 0); vexit = s->value; for(p = firstp; p != P; p = p->link) { - setarch(p); a = p->as; if(a == ATEXT) curtext = p; - if(seenthumb && a == ABL){ - // if((s = p->to.sym) != S && (s1 = curtext->from.sym) != S) - // print("%s calls %s\n", s1->name, s->name); - if((s = p->to.sym) != S && (s1 = curtext->from.sym) != S && s->thumb != s1->thumb) - s->foreign = 1; - } - if((a == ABL || a == ABX || a == AB || a == ARET) && + if((a == ABL || a == AB || a == ARET) && p->to.type != D_BRANCH && p->to.sym != S) { s = p->to.sym; switch(s->type) { @@ -351,21 +338,8 @@ patch(void) } for(p = firstp; p != P; p = p->link) { - setarch(p); - a = p->as; if(p->as == ATEXT) curtext = p; - if(seenthumb && a == ABL) { -#ifdef CALLEEBX - if(0) - {} -#else - if((s = p->to.sym) != S && (s->foreign || s->fnptr)) - p->as = ABX; -#endif - else if(p->to.type == D_OREG) - p->as = ABX; - } if(p->cond != P && p->cond != UP) { p->cond = brloop(p->cond); if(p->cond != P) @@ -483,327 +457,6 @@ rnd(long v, long r) return v; } -#define Reachable(n) if((s = lookup(n, 0)) != nil) s->used++ - -static void -rused(Adr *a) -{ - Sym *s = a->sym; - - if(s == S) - return; - if(a->type == D_OREG || a->type == D_OCONST || a->type == D_CONST){ - if(a->name == D_EXTERN || a->name == D_STATIC){ - if(s->used == 0) - s->used = 1; - } - } - else if(a->type == D_BRANCH){ - if(s->used == 0) - s->used = 1; - } -} - -void -reachable() -{ - Prog *p, *prev, *prevt, *nextt, *q; - Sym *s, *s0; - int i, todo; - char *a; - - Reachable("_div"); - Reachable("_divu"); - Reachable("_mod"); - Reachable("_modu"); - a = INITENTRY; - if(*a >= '0' && *a <= '9') - return; - s = lookup(a, 0); - if(s == nil) - return; - if(s->type == 0){ - s->used = 1; // to stop asm complaining - for(p = firstp; p != P && p->as != ATEXT; p = p->link) - ; - if(p == nil) - return; - s = p->from.sym; - } - s->used = 1; - do{ - todo = 0; - for(p = firstp; p != P; p = p->link){ - if(p->as == ATEXT && (s0 = p->from.sym)->used == 1){ - todo = 1; - for(q = p->link; q != P && q->as != ATEXT; q = q->link){ - rused(&q->from); - rused(&q->to); - } - s0->used = 2; - } - } - for(p = datap; p != P; p = p->link){ - if((s0 = p->from.sym)->used == 1){ - todo = 1; - for(q = p; q != P; q = q->link){ // data can be scattered - if(q->from.sym == s0) - rused(&q->to); - } - s0->used = 2; - } - } - }while(todo); - prev = nil; - prevt = nextt = nil; - for(p = firstp; p != P; ){ - if(p->as == ATEXT){ - prevt = nextt; - nextt = p; - } - if(p->as == ATEXT && (s0 = p->from.sym)->used == 0){ - s0->type = SREMOVED; - for(q = p->link; q != P && q->as != ATEXT; q = q->link) - ; - if(q != p->cond) - diag("bad ptr in reachable()"); - if(prev == nil) - firstp = q; - else - prev->link = q; - if(q == nil) - lastp = prev; - if(prevt == nil) - textp = q; - else - prevt->cond = q; - if(q == nil) - etextp = prevt; - nextt = prevt; - if(debug['V']) - print("%s unused\n", s0->name); - p = q; - } - else{ - prev = p; - p = p->link; - } - } - prevt = nil; - for(p = datap; p != nil; ){ - if((s0 = p->from.sym)->used == 0){ - s0->type = SREMOVED; - prev = prevt; - for(q = p; q != nil; q = q->link){ - if(q->from.sym == s0){ - if(prev == nil) - datap = q->link; - else - prev->link = q->link; - } - else - prev = q; - } - if(debug['V']) - print("%s unused (data)\n", s0->name); - p = prevt->link; - } - else{ - prevt = p; - p = p->link; - } - } - for(i=0; i<NHASH; i++){ - for(s = hash[i]; s != S; s = s->link){ - if(s->used == 0) - s->type = SREMOVED; - } - } -} - -static void -fused(Adr *a, Prog *p, Prog *ct) -{ - Sym *s = a->sym; - Use *u; - - if(s == S) - return; - if(a->type == D_OREG || a->type == D_OCONST || a->type == D_CONST){ - if(a->name == D_EXTERN || a->name == D_STATIC){ - u = malloc(sizeof(Use)); - u->p = p; - u->ct = ct; - u->link = s->use; - s->use = u; - } - } - else if(a->type == D_BRANCH){ - u = malloc(sizeof(Use)); - u->p = p; - u->ct = ct; - u->link = s->use; - s->use = u; - } -} - -static int -ckfpuse(Prog *p, Prog *ct, Sym *fp, Sym *r) -{ - int reg; - - USED(fp); - USED(ct); - if(p->from.sym == r && p->as == AMOVW && (p->from.type == D_CONST || p->from.type == D_OREG) && p->reg == NREG && p->to.type == D_REG){ - reg = p->to.reg; - for(p = p->link; p != P && p->as != ATEXT; p = p->link){ - if((p->as == ABL || p->as == ABX) && p->to.type == D_OREG && p->to.reg == reg) - return 1; - if(!debug['F'] && (isbranch(p) || p->as == ARET)){ - // print("%s: branch %P in %s\n", fp->name, p, ct->from.sym->name); - return 0; - } - if((p->from.type == D_REG || p->from.type == D_OREG) && p->from.reg == reg){ - if(!debug['F'] && p->to.type != D_REG){ - // print("%s: store %P in %s\n", fp->name, p, ct->from.sym->name); - return 0; - } - reg = p->to.reg; - } - } - } - // print("%s: no MOVW O(R), R\n", fp->name); - return debug['F']; -} - -static void -setfpuse(Prog *p, Sym *fp, Sym *r) -{ - int reg; - - if(p->from.sym == r && p->as == AMOVW && (p->from.type == D_CONST || p->from.type == D_OREG) && p->reg == NREG && p->to.type == D_REG){ - reg = p->to.reg; - for(p = p->link; p != P && p->as != ATEXT; p = p->link){ - if((p->as == ABL || p->as == ABX) && p->to.type == D_OREG && p->to.reg == reg){ - fp->fnptr = 0; - p->as = ABL; // safe to do so -// print("simplified %s call\n", fp->name); - break; - } - if(!debug['F'] && (isbranch(p) || p->as == ARET)) - diag("bad setfpuse call"); - if((p->from.type == D_REG || p->from.type == D_OREG) && p->from.reg == reg){ - if(!debug['F'] && p->to.type != D_REG) - diag("bad setfpuse call"); - reg = p->to.reg; - } - } - } -} - -static int -cksymuse(Sym *s, int t) -{ - Prog *p; - - for(p = datap; p != P; p = p->link){ - if(p->from.sym == s && p->to.sym != nil && strcmp(p->to.sym->name, ".string") != 0 && p->to.sym->thumb != t){ - // print("%s %s %d %d ", p->from.sym->name, p->to.sym->name, p->to.sym->thumb, t); - return 0; - } - } - return 1; -} - -/* check the use of s at the given point */ -static int -ckuse(Sym *s, Sym *s0, Use *u) -{ - Sym *s1; - - s1 = u->p->from.sym; -// print("ckuse %s %s %s\n", s->name, s0->name, s1 ? s1->name : "nil"); - if(u->ct == nil){ /* in data area */ - if(s0 == s && !cksymuse(s1, s0->thumb)){ - // print("%s: cksymuse fails\n", s0->name); - return 0; - } - for(u = s1->use; u != U; u = u->link) - if(!ckuse(s1, s0, u)) - return 0; - } - else{ /* in text area */ - if(u->ct->from.sym->thumb != s0->thumb){ - // print("%s(%d): foreign call %s(%d)\n", s0->name, s0->thumb, u->ct->from.sym->name, u->ct->from.sym->thumb); - return 0; - } - return ckfpuse(u->p, u->ct, s0, s); - } - return 1; -} - -static void -setuse(Sym *s, Sym *s0, Use *u) -{ - Sym *s1; - - s1 = u->p->from.sym; - if(u->ct == nil){ /* in data area */ - for(u = s1->use; u != U; u = u->link) - setuse(s1, s0, u); - } - else{ /* in text area */ - setfpuse(u->p, s0, s); - } -} - -/* detect BX O(R) which can be done as BL O(R) */ -void -fnptrs() -{ - int i; - Sym *s; - Prog *p; - Use *u; - - for(i=0; i<NHASH; i++){ - for(s = hash[i]; s != S; s = s->link){ - if(s->fnptr && (s->type == STEXT || s->type == SLEAF || s->type == SCONST)){ - // print("%s : fnptr %d %d\n", s->name, s->thumb, s->foreign); - } - } - } - /* record use of syms */ - for(p = firstp; p != P; p = p->link){ - if(p->as == ATEXT) - curtext = p; - else{ - fused(&p->from, p, curtext); - fused(&p->to, p, curtext); - } - } - for(p = datap; p != P; p = p->link) - fused(&p->to, p, nil); - - /* now look for fn ptrs */ - for(i=0; i<NHASH; i++){ - for(s = hash[i]; s != S; s = s->link){ - if(s->fnptr && (s->type == STEXT || s->type == SLEAF || s->type == SCONST)){ - for(u = s->use; u != U; u = u->link){ - if(!ckuse(s, s, u)) - break; - } - if(u == U){ // can simplify - for(u = s->use; u != U; u = u->link) - setuse(s, s, u); - } - } - } - } - - /* now free Use structures */ -} - void import(void) { diff --git a/utils/5l/span.c b/utils/5l/span.c index 0b69a96f..d086f592 100644 --- a/utils/5l/span.c +++ b/utils/5l/span.c @@ -3,140 +3,19 @@ static struct { ulong start; ulong size; - ulong extra; } pool; -int checkpool(Prog*, int); -int flushpool(Prog*, int, int); - -int -isbranch(Prog *p) -{ - int as = p->as; - return (as >= ABEQ && as <= ABLE) || as == AB || as == ABL || as == ABX; -} - -static int -ispad(Prog *p) -{ - if(p->as != AMOVW) - return 0; - if(p->from.type != D_REG || p->from.reg != REGSB) - return 0; - if(p->to.type != D_REG || p->to.reg != REGSB) - return 0; - return 1; -} - -int -fninc(Sym *s) -{ - if(thumb){ - if(s->thumb){ - if(s->foreign) - return 8; - else - return 0; - } - else{ - if(s->foreign) - return 0; - else - diag("T A !foreign in fninc"); - } - } - else{ - if(s->thumb){ - if(s->foreign) - return 0; - else - diag("A T !foreign in fninc"); - } - else{ - if(s->foreign) - return 4; - else - return 0; - } - } - return 0; -} - -int -fnpinc(Sym *s) -{ - if(!s->fnptr){ // a simplified case BX O(R) -> BL O(R) - if(!debug['f']) - diag("fnptr == 0 in fnpinc"); - if(s->foreign) - diag("bad usage in fnpinc %s %d %d %d", s->name, s->used, s->foreign, s->thumb); - return 0; - } - /* 0, 1, 2, 3 squared */ - if(s->thumb) - return s->foreign ? 9 : 1; - else - return s->foreign ? 4 : 0; -} - -static Prog * -pad(Prog *p, int pc) -{ - Prog *q; - - q = prg(); - q->as = AMOVW; - q->line = p->line; - q->from.type = D_REG; - q->from.reg = REGSB; - q->to.type = D_REG; - q->to.reg = REGSB; - q->pc = pc; - q->link = p->link; - return q; -} - -static int -scan(Prog *op, Prog *p, int c) -{ - Prog *q; - - for(q = op->link; q != p; q = q->link){ - q->pc = c; - c += oplook(q)->size; - nocache(q); - } - return c; -} - -/* size of a case statement including jump table */ -static long -casesz(Prog *p) -{ - int jt = 0; - long n = 0; - Optab *o; - - for( ; p != P; p = p->link){ - if(p->as == ABCASE) - jt = 1; - else if(jt) - break; - o = oplook(p); - n += o->size; - } - return n; -} +void checkpool(Prog*); +void flushpool(Prog*, int); void span(void) { - Prog *p, *op; + Prog *p; Sym *setext, *s; Optab *o; int m, bflag, i; long c, otxt, v; - int lastthumb = -1; if(debug['v']) Bprint(&bso, "%5.2f span\n", cputime()); @@ -144,27 +23,13 @@ span(void) bflag = 0; c = INITTEXT; - op = nil; otxt = c; - for(p = firstp; p != P; op = p, p = p->link) { - setarch(p); + for(p = firstp; p != P; p = p->link) { p->pc = c; o = oplook(p); m = o->size; - // must check literal pool here in case p generates many instructions - if(blitrl){ - if(thumb && isbranch(p)) - pool.extra += brextra(p); - if(checkpool(op, p->as == ACASE ? casesz(p) : m)) - c = p->pc = scan(op, p, c); - } if(m == 0) { if(p->as == ATEXT) { - if(blitrl && lastthumb != -1 && lastthumb != thumb){ // flush literal pool - if(flushpool(op, 0, 1)) - c = p->pc = scan(op, p, c); - } - lastthumb = thumb; curtext = p; autosize = p->to.offset + 4; if(p->from.sym != S) @@ -173,8 +38,6 @@ span(void) if(c-otxt >= 1L<<17) bflag = 1; otxt = c; - if(thumb && blitrl) - pool.extra += brextra(p); continue; } diag("zero-width instruction\n%P", p); @@ -189,17 +52,14 @@ span(void) break; case LPOOL: if ((p->scond&C_SCOND) == 14) - flushpool(p, 0, 0); + flushpool(p, 0); break; } if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14) - flushpool(p, 0, 0); + flushpool(p, 0); c += m; - if(blitrl && p->link == P){ - if(thumb && isbranch(p)) - pool.extra += brextra(p); - checkpool(p, 0); - } + if(blitrl) + checkpool(p); } /* @@ -214,10 +74,7 @@ span(void) bflag = 0; c = INITTEXT; for(p = firstp; p != P; p = p->link) { - setarch(p); p->pc = c; - if(thumb && isbranch(p)) - nocache(p); o = oplook(p); /* very larg branches if(o->type == 6 && p->cond) { @@ -258,93 +115,6 @@ span(void) } } - if(seenthumb){ // branch resolution - int passes = 0; - int lastc = 0; - int again; - Prog *oop; - - loop: - passes++; - if(passes > 150){ - diag("span looping !"); - errorexit(); - } - c = INITTEXT; - oop = op = nil; - again = 0; - for(p = firstp; p != P; oop = op, op = p, p = p->link){ - setarch(p); - if(p->pc != c) - again = 1; - p->pc = c; - if(thumb && isbranch(p)) - nocache(p); - o = oplook(p); - m = o->size; - if(passes == 1 && thumb && isbranch(p)){ // start conservative so unneeded alignment is not added - if(p->as == ABL) - m = 4; - else - m = 2; - p->align = 0; - } - if(p->align){ - if((p->align == 4 && (c&3)) || (p->align == 2 && !(c&3))){ - if(ispad(op)){ - oop->link = p; - op = oop; - c -= 2; - p->pc = c; - } - else{ - op->link = pad(op, c); - op = op->link; - c += 2; - p->pc = c; - } - again = 1; - } - } - if(m == 0) { - if(p->as == ATEXT) { - curtext = p; - autosize = p->to.offset + 4; - if(p->from.sym != S) - p->from.sym->value = c; - continue; - } - } - c += m; - } - if(c != lastc || again){ - lastc = c; - goto loop; - } - } - - if(0 && seenthumb){ // rm redundant padding - obsolete - int d; - - op = nil; - d = 0; - for(p = firstp; p != P; op = p, p = p->link){ - p->pc -= d; - if(p->as == ATEXT){ - if(p->from.sym != S) - p->from.sym->value -= d; -// if(p->from.sym != S) print("%s %ux %d %d %d\n", p->from.sym->name ? p->from.sym->name : "?", p->from.sym->value, p->from.sym->thumb, p->from.sym->foreign, p->from.sym->fnptr); - } - if(ispad(p) && p->link != P && ispad(p->link)){ - op->link = p->link->link; - d += 4; - p = op; - } - } - // print("%d bytes removed (padding)\n", d); - c -= d; - } - if(debug['t']) { /* * add strings to text segment @@ -361,7 +131,7 @@ span(void) c += v; } } - + c = rnd(c, 8); setext = lookup("etext", 0); @@ -382,31 +152,24 @@ span(void) * drop the pool now, and branch round it. * this happens only in extended basic blocks that exceed 4k. */ -int -checkpool(Prog *p, int sz) +void +checkpool(Prog *p) { - if(thumb){ - if(pool.size >= 0x3fc || (p->pc+sz+pool.extra+2+2)+(pool.size-4)-pool.start-4 >= 0x3fc) - return flushpool(p, 1, 0); - else if(p->link == P) - return flushpool(p, 2, 0); - return 0; - } - if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0) - return flushpool(p, 1, 0); + if(pool.size >= 0xffc || immaddr((p->pc+4)+4+pool.size - pool.start+8) == 0) + flushpool(p, 1); else if(p->link == P) - return flushpool(p, 2, 0); - return 0; + flushpool(p, 2); } -int -flushpool(Prog *p, int skip, int force) +void +flushpool(Prog *p, int skip) { Prog *q; if(blitrl) { if(skip){ - if(0 && skip==1)print("note: flush literal pool at %lux: len=%lud ref=%lux\n", p->pc+4, pool.size, pool.start); + if(debug['v'] && skip == 1) + print("note: flush literal pool at %lux: len=%lud ref=%lux\n", p->pc+4, pool.size, pool.start); q = prg(); q->as = AB; q->to.type = D_BRANCH; @@ -414,18 +177,15 @@ flushpool(Prog *p, int skip, int force) q->link = blitrl; blitrl = q; } - else if(!force && (p->pc+pool.size-pool.start < (thumb ? 0x3fc+4-pool.extra : 2048))) - return 0; + else if(p->pc+pool.size-pool.start < 2048) + return; elitrl->link = p->link; p->link = blitrl; blitrl = 0; /* BUG: should refer back to values until out-of-range */ elitrl = 0; pool.size = 0; pool.start = 0; - pool.extra = 0; - return 1; } - return 0; } void @@ -434,10 +194,7 @@ addpool(Prog *p, Adr *a) Prog *q, t; int c; - if(thumb) - c = thumbaclass(a, p); - else - c = aclass(a); + c = aclass(a); t = zprg; t.as = AWORD; @@ -447,18 +204,15 @@ addpool(Prog *p, Adr *a) t.to = *a; break; - case C_SROREG: + case C_SROREG: case C_LOREG: case C_ROREG: case C_FOREG: case C_SOREG: - case C_HOREG: - case C_GOREG: case C_FAUTO: case C_SAUTO: case C_LAUTO: case C_LACON: - case C_GACON: t.to.type = D_CONST; t.to.offset = instoffset; break; @@ -477,7 +231,6 @@ addpool(Prog *p, Adr *a) if(blitrl == P) { blitrl = q; pool.start = p->pc; - q->align = 4; } else elitrl->link = q; elitrl = q; @@ -678,16 +431,8 @@ aclass(Adr *a) s->type = SDATA; } instoffset = s->value + a->offset + INITDAT; - if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) { + if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) instoffset = s->value + a->offset; -#ifdef CALLEEBX - instoffset += fnpinc(s); -#else - if(s->thumb) - instoffset++; // T bit -#endif - return C_LCON; - } return C_LCON; } return C_GOK; @@ -730,12 +475,6 @@ aclass(Adr *a) case SCONST: case SLEAF: instoffset = s->value + a->offset; -#ifdef CALLEEBX - instoffset += fnpinc(s); -#else - if(s->thumb) - instoffset++; // T bit -#endif return C_LCON; } if(!dlm) { @@ -773,35 +512,19 @@ oplook(Prog *p) int a1, a2, a3, r; char *c1, *c3; Optab *o, *e; - Optab *otab; - Oprang *orange; - if(thumb){ - otab = thumboptab; - orange = thumboprange; - } - else{ - otab = optab; - orange = oprange; - } a1 = p->optab; if(a1) - return otab+(a1-1); + return optab+(a1-1); a1 = p->from.class; if(a1 == 0) { - if(thumb) - a1 = thumbaclass(&p->from, p) + 1; - else - a1 = aclass(&p->from) + 1; + a1 = aclass(&p->from) + 1; p->from.class = a1; } a1--; a3 = p->to.class; if(a3 == 0) { - if(thumb) - a3 = thumbaclass(&p->to, p) + 1; - else - a3 = aclass(&p->to) + 1; + a3 = aclass(&p->to) + 1; p->to.class = a3; } a3--; @@ -809,35 +532,35 @@ oplook(Prog *p) if(p->reg != NREG) a2 = C_REG; r = p->as; - o = orange[r].start; + o = oprange[r].start; if(o == 0) { a1 = opcross[repop[r]][a1][a2][a3]; if(a1) { p->optab = a1+1; - return otab+a1; + return optab+a1; } - o = orange[r].stop; /* just generate an error */ + o = oprange[r].stop; /* just generate an error */ } if(0) { print("oplook %A %d %d %d\n", (int)p->as, a1, a2, a3); print(" %d %d\n", p->from.type, p->to.type); } - e = orange[r].stop; + e = oprange[r].stop; c1 = xcmp[a1]; c3 = xcmp[a3]; for(; o<e; o++) if(o->a2 == a2) if(c1[o->a1]) if(c3[o->a3]) { - p->optab = (o-otab)+1; + p->optab = (o-optab)+1; return o; } diag("illegal combination %A %d %d %d", p->as, a1, a2, a3); prasm(p); if(o == 0) - o = otab; + o = optab; return o; } @@ -898,19 +621,12 @@ cmp(int a, int b) if(b == C_SBRA) return 1; break; - case C_GBRA: - if(b == C_SBRA || b == C_LBRA) - return 1; - - case C_HREG: - return cmp(C_SP, b) || cmp(C_PC, b); - } return 0; } int -ocmp(const void *a1, const void *a2) +ocmp(void *a1, void *a2) { Optab *p1, *p2; int n; @@ -923,6 +639,9 @@ ocmp(const void *a1, const void *a2) n = (p2->flag&V4) - (p1->flag&V4); /* architecture version */ if(n) return n; + n = (p2->flag&VFP) - (p1->flag&VFP); /* floating point arch */ + if(n) + return n; n = p1->a1 - p2->a1; if(n) return n; @@ -941,14 +660,18 @@ buildop(void) int i, n, r; armv4 = !debug['h']; + vfp = debug['f']; for(i=0; i<C_GOK; i++) for(n=0; n<C_GOK; n++) xcmp[i][n] = cmp(n, i); - for(n=0; optab[n].as != AXXX; n++) + for(n=0; optab[n].as != AXXX; n++) { + if((optab[n].flag & VFP) && !vfp) + optab[n].as = AXXX; if((optab[n].flag & V4) && !armv4) { optab[n].as = AXXX; break; } + } qsort(optab, n, sizeof(optab[0]), ocmp); for(i=0; i<n; i++) { r = optab[i].as; @@ -963,6 +686,8 @@ buildop(void) default: diag("unknown op in build: %A", r); errorexit(); + case AXXX: + break; case AADD: oprange[AAND] = oprange[r]; oprange[AEOR] = oprange[r]; diff --git a/utils/6a/README b/utils/6a/README deleted file mode 100644 index 602f5378..00000000 --- a/utils/6a/README +++ /dev/null @@ -1 +0,0 @@ -this is an intermediate version not yet ready for use diff --git a/utils/6a/lex.c b/utils/6a/lex.c index bd836040..3d901415 100644 --- a/utils/6a/lex.c +++ b/utils/6a/lex.c @@ -1011,7 +1011,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } } diff --git a/utils/6c/README b/utils/6c/README deleted file mode 100644 index 602f5378..00000000 --- a/utils/6c/README +++ /dev/null @@ -1 +0,0 @@ -this is an intermediate version not yet ready for use diff --git a/utils/6c/cgen.c b/utils/6c/cgen.c index 74b6389f..6b1e9418 100644 --- a/utils/6c/cgen.c +++ b/utils/6c/cgen.c @@ -439,9 +439,10 @@ cgen(Node *n, Node *nn) if(o == OLDIV || o == OLMOD) zeroregm(&nod1); if(r->addable < INDEXED || r->op == OCONST) { - regsalloc(&nod3, r); + regalloc(&nod3, r, Z); cgen(r, &nod3); gopcode(o, n->type, &nod3, Z); + regfree(&nod3); } else gopcode(o, n->type, r, Z); } else { @@ -573,7 +574,7 @@ cgen(Node *n, Node *nn) reglcgen(&nod, l, Z); else nod = *l; - if(o != OASMUL && o != OASADD) { + if(o != OASMUL && o != OASADD || !typefd[l->type->etype]) { regalloc(&nod2, r, Z); gmove(&nod, &nod2); gopcode(o, r->type, &nod1, &nod2); @@ -1595,7 +1596,7 @@ copy: regsalloc(&nod2, nn); nn->type = t; - gins(AMOVL, &nod1, &nod2); + gins(AMOVQ, &nod1, &nod2); regfree(&nod1); nod2.type = typ(TIND, t); @@ -1696,7 +1697,7 @@ copy: c = 0; if(n->complex > nn->complex) { t = n->type; - n->type = types[TLONG]; + n->type = types[TIND]; nodreg(&nod1, n, D_SI); if(reg[D_SI]) { gins(APUSHQ, &nod1, Z); @@ -1707,7 +1708,7 @@ copy: n->type = t; t = nn->type; - nn->type = types[TLONG]; + nn->type = types[TIND]; nodreg(&nod2, nn, D_DI); if(reg[D_DI]) { warn(Z, "DI botch"); @@ -1719,7 +1720,7 @@ warn(Z, "DI botch"); nn->type = t; } else { t = nn->type; - nn->type = types[TLONG]; + nn->type = types[TIND]; nodreg(&nod2, nn, D_DI); if(reg[D_DI]) { warn(Z, "DI botch"); @@ -1731,7 +1732,7 @@ warn(Z, "DI botch"); nn->type = t; t = n->type; - n->type = types[TLONG]; + n->type = types[TIND]; nodreg(&nod1, n, D_SI); if(reg[D_SI]) { gins(APUSHQ, &nod1, Z); diff --git a/utils/6c/gc.h b/utils/6c/gc.h index 57d3a999..22ae99bc 100644 --- a/utils/6c/gc.h +++ b/utils/6c/gc.h @@ -270,7 +270,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void casf(void); @@ -278,7 +278,6 @@ void bitload(Node*, Node*, Node*, Node*, Node*); void bitstore(Node*, Node*, Node*, Node*, Node*); long outstring(char*, long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); @@ -299,7 +298,7 @@ int Bconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); Bits mkvar(Reg*, Adr*); diff --git a/utils/6c/mkfile b/utils/6c/mkfile index 4f1803e6..e8aab371 100644 --- a/utils/6c/mkfile +++ b/utils/6c/mkfile @@ -1,6 +1,5 @@ <../../mkconfig -TARG=6ca TARG=6c OFILES=\ diff --git a/utils/6c/reg.c b/utils/6c/reg.c index 32b9abf5..e04cb5fb 100644 --- a/utils/6c/reg.c +++ b/utils/6c/reg.c @@ -16,7 +16,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; @@ -50,6 +50,8 @@ regopt(Prog *p) lastr = R; nvar = 0; regbits = RtoB(D_SP) | RtoB(D_AX) | RtoB(D_X0); + if(REGEXT) + regbits |= RtoB(REGEXT) | RtoB(REGEXT-1); for(z=0; z<BITS; z++) { externs.b[z] = 0; params.b[z] = 0; diff --git a/utils/6c/swt.c b/utils/6c/swt.c index b201c9ca..c0b4d844 100644 --- a/utils/6c/swt.c +++ b/utils/6c/swt.c @@ -9,7 +9,7 @@ swit1(C1 *q, int nc, long def, Node *n) if(nc < 5) { for(i=0; i<nc; i++) { - if(debug['W']) + if(debug['K']) print("case = %.8llux\n", q->val); gcmp(OEQ, n, q->val); patch(p, q->label); @@ -21,7 +21,7 @@ swit1(C1 *q, int nc, long def, Node *n) } i = nc / 2; r = q+i; - if(debug['W']) + if(debug['K']) print("case > %.8llux\n", r->val); gcmp(OGT, n, r->val); sp = p; @@ -30,7 +30,7 @@ swit1(C1 *q, int nc, long def, Node *n) patch(p, r->label); swit1(q, i, def, n); - if(debug['W']) + if(debug['K']) print("case < %.8llux\n", r->val); patch(sp, pc); swit1(r+1, nc-i-1, def, n); @@ -128,23 +128,6 @@ outstring(char *s, long n) } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0L)); - p->from.offset += o+e; - p->from.scale = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { if(0 && a->op == OCONST && typev[a->type->etype]) { @@ -523,8 +506,8 @@ align(long i, Type *t, int op) long maxround(long max, long v) { - v += SZ_VLONG-1; + v = round(v, SZ_VLONG); if(v > max) - max = round(v, SZ_VLONG); + return v; return max; } diff --git a/utils/6c/txt.c b/utils/6c/txt.c index 9d9c86b1..e3b9a9ee 100644 --- a/utils/6c/txt.c +++ b/utils/6c/txt.c @@ -1,5 +1,7 @@ #include "gc.h" +static int resvreg[nelem(reg)]; + void ginit(void) { @@ -23,6 +25,7 @@ ginit(void) tfield = types[TINT]; typeword = typechlvp; + typeswitch = typechlv; typecmplx = typesu; /* TO DO */ @@ -93,6 +96,7 @@ ginit(void) if(0) com64init(); + memset(reg, 0, sizeof(reg)); for(i=0; i<nelem(reg); i++) { reg[i] = 1; if(i >= D_AX && i <= D_R15 && i != D_SP) @@ -100,6 +104,10 @@ ginit(void) if(i >= D_X0 && i <= D_X7) reg[i] = 0; } + /* keep two external registers */ + reg[REGEXT] = 1; + reg[REGEXT-1] = 1; + memmove(resvreg, reg, sizeof(resvreg)); } void @@ -110,10 +118,10 @@ gclean(void) reg[D_SP]--; for(i=D_AX; i<=D_R15; i++) - if(reg[i]) + if(reg[i] && !resvreg[i]) diag(Z, "reg %R left allocated", i); for(i=D_X0; i<=D_X7; i++) - if(reg[i]) + if(reg[i] && !resvreg[i]) diag(Z, "reg %R left allocated", i); while(mnstring) outstring("", 1L); @@ -178,7 +186,7 @@ nareg(void) n = 0; for(i=D_AX; i<=D_R15; i++) - if(reg[i] == 0) + if(reg[i] == 0 && !resvreg[i]) n++; return n; } @@ -336,7 +344,7 @@ regalloc(Node *n, Node *tn, Node *o) goto out; } for(i=D_AX; i<=D_R15; i++) - if(reg[i] == 0) + if(reg[i] == 0 && !resvreg[i]) goto out; diag(tn, "out of fixed registers"); goto err; @@ -349,7 +357,7 @@ regalloc(Node *n, Node *tn, Node *o) goto out; } for(i=D_X0; i<=D_X7; i++) - if(reg[i] == 0) + if(reg[i] == 0 && !resvreg[i]) goto out; diag(tn, "out of float registers"); goto out; diff --git a/utils/6l/Nt.c b/utils/6l/Nt.c deleted file mode 100644 index 73c6f795..00000000 --- a/utils/6l/Nt.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <windows.h> -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/6l/Plan9.c b/utils/6l/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/6l/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/6l/Posix.c b/utils/6l/Posix.c deleted file mode 100644 index 7c3a661f..00000000 --- a/utils/6l/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fials if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} diff --git a/utils/6l/README b/utils/6l/README deleted file mode 100644 index 602f5378..00000000 --- a/utils/6l/README +++ /dev/null @@ -1 +0,0 @@ -this is an intermediate version not yet ready for use diff --git a/utils/6l/asm.c b/utils/6l/asm.c index c4d46633..a4afaa2a 100644 --- a/utils/6l/asm.c +++ b/utils/6l/asm.c @@ -2,7 +2,7 @@ #define Dbufslop 100 -#define PADDR(a) ((ulong)(a) & ~0x80000000) +#define PADDR(a) ((a) & ~0xfffffffff0000000ull) vlong entryvalue(void) @@ -28,15 +28,15 @@ entryvalue(void) return s->value; } -void -wputl(ushort w) +/* these need to take long arguments to be compatible with elf.c */void +wputl(long w) { cput(w); cput(w>>8); } void -wput(ushort w) +wput(long w) { cput(w>>8); cput(w); @@ -68,6 +68,13 @@ lputl(long l) } void +llputl(vlong v) +{ + lputl(v); + lputl(v>>32); +} + +void strnput(char *s, int n) { for(; *s && n > 0; s++){ @@ -133,6 +140,7 @@ asmb(void) diag("unknown header type %ld", HEADTYPE); case 2: case 5: + case 6: seek(cout, HEADR+textsize, 0); break; } @@ -166,6 +174,7 @@ asmb(void) default: case 2: case 5: + case 6: seek(cout, HEADR+textsize+datsize, 0); break; } @@ -210,65 +219,11 @@ asmb(void) lput(lcsize); /* line offsets */ llput(vl); /* va of entry */ break; - case 3: /* plan9 */ - magic = 4*26*26+7; - if(dlm) - magic |= 0x80000000; - lput(magic); /* magic */ - lput(textsize); /* sizes */ - lput(datsize); - lput(bsssize); - lput(symsize); /* nsyms */ - lput(entryvalue()); /* va of entry */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ - break; case 5: - strnput("\177ELF", 4); /* e_ident */ - cput(1); /* class = 32 bit */ - cput(1); /* data = LSB */ - cput(1); /* version = CURRENT */ - strnput("", 9); - wputl(2); /* type = EXEC */ - wputl(62); /* machine = AMD64 */ - lputl(1L); /* version = CURRENT */ - lputl(PADDR(entryvalue())); /* entry vaddr */ - lputl(52L); /* offset to first phdr */ - lputl(0L); /* offset to first shdr */ - lputl(0L); /* processor specific flags */ - wputl(52); /* Ehdr size */ - wputl(32); /* Phdr size */ - wputl(3); /* # of Phdrs */ - wputl(0); /* Shdr size */ - wputl(0); /* # of Shdrs */ - wputl(0); /* Shdr string size */ - - lputl(1L); /* text - type = PT_LOAD */ - lputl(HEADR); /* file offset */ - lputl(INITTEXT); /* vaddr */ - lputl(PADDR(INITTEXT)); /* paddr */ - lputl(textsize); /* file size */ - lputl(textsize); /* memory size */ - lputl(0x05L); /* protections = RX */ - lputl(INITRND); /* alignment */ - - lputl(1L); /* data - type = PT_LOAD */ - lputl(HEADR+textsize); /* file offset */ - lputl(INITDAT); /* vaddr */ - lputl(PADDR(INITDAT)); /* paddr */ - lputl(datsize); /* file size */ - lputl(datsize+bsssize); /* memory size */ - lputl(0x06L); /* protections = RW */ - lputl(INITRND); /* alignment */ - - lputl(0L); /* data - type = PT_NULL */ - lputl(HEADR+textsize+datsize); /* file offset */ - lputl(0L); - lputl(0L); - lputl(symsize); /* symbol table size */ - lputl(lcsize); /* line number size */ - lputl(0x04L); /* protections = R */ - lputl(0x04L); /* alignment */ + elf32(debug['8']? I386: AMD64, ELFDATA2LSB, 0, nil); + break; + case 6: + elf64(AMD64, ELFDATA2LSB, 0, nil); break; } cflush(); diff --git a/utils/6l/l.h b/utils/6l/l.h index 115aa69d..5a1c6b95 100644 --- a/utils/6l/l.h +++ b/utils/6l/l.h @@ -1,6 +1,7 @@ #include <lib9.h> #include <bio.h> #include "../6c/6.out.h" +#include "../8l/elf.h" #ifndef EXTERN #define EXTERN extern @@ -14,6 +15,8 @@ if(--cbc <= 0)\ cflush(); } +#define LIBNAMELEN 300 + typedef struct Adr Adr; typedef struct Prog Prog; typedef struct Sym Sym; @@ -226,7 +229,7 @@ EXTERN union { struct { - char obuf[MAXIO]; /* output buffer */ + uchar obuf[MAXIO]; /* output buffer */ uchar ibuf[MAXIO]; /* input buffer */ } u; char dbuf[1]; @@ -235,22 +238,26 @@ EXTERN union #define cbuf u.obuf #define xbuf u.ibuf +#pragma varargck type "A" int #pragma varargck type "A" uint #pragma varargck type "D" Adr* #pragma varargck type "P" Prog* #pragma varargck type "R" int #pragma varargck type "S" char* +#pragma varargck argpos diag 1 + EXTERN long HEADR; EXTERN long HEADTYPE; EXTERN vlong INITDAT; EXTERN long INITRND; EXTERN vlong INITTEXT; +EXTERN vlong INITTEXTP; EXTERN char* INITENTRY; /* entry point */ EXTERN Biobuf bso; EXTERN long bsssize; EXTERN int cbc; -EXTERN char* cbp; +EXTERN uchar* cbp; EXTERN char* pcstr; EXTERN int cout; EXTERN Auto* curauto; @@ -323,6 +330,7 @@ int Pconv(Fmt*); int Rconv(Fmt*); int Sconv(Fmt*); void addhist(long, int); +void addlibpath(char*); Prog* appendp(Prog*); void asmb(void); void asmdyn(void); @@ -349,8 +357,10 @@ void dynreloc(Sym*, ulong, int); vlong entryvalue(void); void errorexit(void); void export(void); +int fileexists(char*); int find1(long, int); int find2(long, int); +char* findlib(char*); void follow(void); void gethunk(void); void histtoauto(void); @@ -361,6 +371,8 @@ void ldobj(int, long, char*); void loadlib(void); void listinit(void); Sym* lookup(char*, int); +void llput(vlong v); +void llputl(vlong v); void lput(long); void lputl(long); void main(int, char*[]); @@ -376,17 +388,13 @@ int relinv(int); long reuse(Prog*, Sym*); vlong rnd(vlong, vlong); void span(void); +void strnput(char*, int); void undef(void); void undefsym(Sym*); vlong vaddr(Adr*); -void wput(ushort); +void wput(long); +void wputl(long); void xdefine(char*, int, vlong); void xfol(Prog*); int zaddr(uchar*, Adr*, Sym*[]); void zerosig(char*); - -#pragma varargck type "D" Adr* -#pragma varargck type "P" Prog* -#pragma varargck type "R" int -#pragma varargck type "A" int -#pragma varargck argpos diag 1 diff --git a/utils/6l/mkfile b/utils/6l/mkfile index 19a65c8b..e0bb5f7c 100644 --- a/utils/6l/mkfile +++ b/utils/6l/mkfile @@ -11,6 +11,7 @@ OFILES=\ list.$O\ enam.$O\ $TARGMODEL.$O\ + elf.$O\ HFILES=\ l.h\ @@ -23,7 +24,12 @@ BIN=$ROOT/$OBJDIR/bin <$ROOT/mkfiles/mkone-$SHELLTYPE -CFLAGS= $CFLAGS -I../include +CFLAGS= $CFLAGS -I../include -I. enam.$O: ../6c/enam.c $CC $CFLAGS ../6c/enam.c +elf.$O: ../ld/elf.c + $CC $CFLAGS ../ld/elf.c + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/6l/obj.c b/utils/6l/obj.c index 9f57d612..ed52ec2b 100644 --- a/utils/6l/obj.c +++ b/utils/6l/obj.c @@ -12,14 +12,25 @@ char thechar = '6'; char *thestring = "amd64"; char *paramspace = "FP"; +char** libdir; +int nlibdir = 0; +static int maxlibdir = 0; + /* - * -H2 -T4136 -R4096 is plan9 64-bit format - * -H3 -T4128 -R4096 is plan9 32-bit format + * -H2 -T0x200028 -R0x200000 is plan9 format (was -T4136 -R4096) * -H5 -T0x80110000 -R4096 is ELF32 + * -H6 -T0x2000e8 -R0x200000 is ELF64 * - * options used: 189BLQSWabcjlnpsvz + * options used: 189BLPQSVWabcjlnpsvz */ +void +usage(void) +{ + diag("usage: %s [-options] objects", argv0); + errorexit(); +} + static int isobjfile(char *f) { @@ -47,6 +58,7 @@ main(int argc, char *argv[]) { int i, c; char *a; + char name[LIBNAMELEN]; Binit(&bso, 1, OWRITE); cout = -1; @@ -56,6 +68,7 @@ main(int argc, char *argv[]) outfile = "6.out"; HEADTYPE = -1; INITTEXT = -1; + INITTEXTP = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; @@ -78,11 +91,19 @@ main(int argc, char *argv[]) if(a) HEADTYPE = atolwhex(a); break; + case 'L': + addlibpath(EARGF(usage())); + break; case 'T': a = ARGF(); if(a) INITTEXT = atolwhex(a); break; + case 'P': + a = ARGF(); + if(a) + INITTEXTP = atolwhex(a); + break; case 'D': a = ARGF(); if(a) @@ -106,12 +127,20 @@ main(int argc, char *argv[]) break; } ARGEND USED(argc); - if(*argv == 0) { - diag("usage: 6l [-options] objects"); - errorexit(); - } + if(*argv == 0) + usage(); if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; + a = getenv("ccroot"); + if(a != nil && *a != '\0') { + if(!fileexists(a)) { + diag("nonexistent $ccroot: %s", a); + errorexit(); + } + }else + a = ""; + snprint(name, sizeof(name), "%s/%s/lib", a, thestring); + addlibpath(name); if(HEADTYPE == -1) { if(debug['B']) HEADTYPE = 2; @@ -125,31 +154,33 @@ main(int argc, char *argv[]) case 2: /* plan 9 */ HEADR = 32L+8L; if(INITTEXT == -1) - INITTEXT = 4096+HEADR; + INITTEXT = 0x200000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) - INITRND = 4096; + INITRND = 0x200000; break; - case 3: /* plan 9 */ - HEADR = 32L; + case 5: /* elf32 executable */ + HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16); if(INITTEXT == -1) - INITTEXT = 4096+32; + INITTEXT = 0xf0110000L; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; - case 5: /* elf32 executable */ - HEADR = rnd(52L+3*32L, 16); + case 6: /* ELF64 executable */ + HEADR = rnd(Ehdr64sz+3*Phdr64sz, 16); if(INITTEXT == -1) - INITTEXT = 0x80110000L; + INITTEXT = 0x200000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) - INITRND = 4096; + INITRND = 0x200000; break; } + if (INITTEXTP == -1) + INITTEXTP = INITTEXT; if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%llux is ignored because of -R0x%lux\n", INITDAT, INITRND); @@ -283,7 +314,7 @@ main(int argc, char *argv[]) dtype = 4; cout = create(outfile, 1, 0775); if(cout < 0) { - diag("cannot create %s", outfile); + diag("cannot create %s: %r", outfile); errorexit(); } version = 0; @@ -351,6 +382,42 @@ main(int argc, char *argv[]) } void +addlibpath(char *arg) +{ + char **p; + + if(nlibdir >= maxlibdir) { + if(maxlibdir == 0) + maxlibdir = 8; + else + maxlibdir *= 2; + p = malloc(maxlibdir*sizeof(*p)); + if(p == nil) { + diag("out of memory"); + errorexit(); + } + memmove(p, libdir, nlibdir*sizeof(*p)); + free(libdir); + libdir = p; + } + libdir[nlibdir++] = strdup(arg); +} + +char* +findlib(char *file) +{ + int i; + char name[LIBNAMELEN]; + + for(i = 0; i < nlibdir; i++) { + snprint(name, sizeof(name), "%s/%s", libdir[i], file); + if(fileexists(name)) + return libdir[i]; + } + return nil; +} + +void loadlib(void) { int i; @@ -390,25 +457,26 @@ objfile(char *file) int f, work; Sym *s; char magbuf[SARMAG]; - char name[100], pname[150]; + char name[LIBNAMELEN], pname[LIBNAMELEN]; struct ar_hdr arhdr; char *e, *start, *stop; - if(file[0] == '-' && file[1] == 'l') { - if(debug['9']) - sprint(name, "/%s/lib/lib", thestring); - else - sprint(name, "/usr/%clib/lib", thechar); - strcat(name, file+2); - strcat(name, ".a"); - file = name; - } if(debug['v']) Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); Bflush(&bso); + if(file[0] == '-' && file[1] == 'l') { + snprint(pname, sizeof(pname), "lib%s.a", file+2); + e = findlib(pname); + if(e == nil) { + diag("cannot find library: %s", file); + errorexit(); + } + snprint(name, sizeof(name), "%s/%s", e, pname); + file = name; + } f = open(file, 0); if(f < 0) { - diag("cannot open file: %s", file); + diag("cannot open %s: %r", file); errorexit(); } l = read(f, magbuf, SARMAG); @@ -467,7 +535,8 @@ objfile(char *file) l |= (e[3] & 0xff) << 16; l |= (e[4] & 0xff) << 24; seek(f, l, 0); - l = read(f, &arhdr, SAR_HDR); + /* need readn to read the dumps (at least) */ + l = readn(f, &arhdr, SAR_HDR); if(l != SAR_HDR) goto bad; if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) @@ -494,7 +563,7 @@ int zaddr(uchar *p, Adr *a, Sym *h[]) { int c, t, i; - long l; + int l; Sym *s; Auto *u; @@ -579,25 +648,24 @@ zaddr(uchar *p, Adr *a, Sym *h[]) void addlib(char *obj) { - char name[1024], comp[256], *p; - int i; + char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name; + int i, search; if(histfrogp <= 0) return; + name = fn1; + search = 0; if(histfrog[0]->name[1] == '/') { sprint(name, ""); i = 1; - } else - if(histfrog[0]->name[1] == '.') { + } else if(histfrog[0]->name[1] == '.') { sprint(name, "."); i = 0; } else { - if(debug['9']) - sprint(name, "/%s/lib", thestring); - else - sprint(name, "/usr/%clib", thechar); + sprint(name, ""); i = 0; + search = 1; } for(; i<histfrogp; i++) { @@ -620,13 +688,25 @@ addlib(char *obj) memmove(p+strlen(thestring), p+2, strlen(p+2)+1); memmove(p, thestring, strlen(thestring)); } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { + if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) { diag("library component too long"); return; } - strcat(name, "/"); - strcat(name, comp); + if(i > 0 || !search) + strcat(fn1, "/"); + strcat(fn1, comp); + } + + cleanname(name); + + if(search){ + p = findlib(name); + if(p != nil){ + snprint(fn2, sizeof(fn2), "%s/%s", p, name); + name = fn2; + } } + for(i=0; i<libraryp; i++) if(strcmp(name, library[i]) == 0) return; @@ -1138,8 +1218,7 @@ lookup(char *symb, int v) for(p=symb; c = *p; p++) h = h+h+h + c; l = (p - symb) + 1; - if(h < 0) - h = ~h; + h &= 0xffffff; h %= NHASH; for(s = hash[h]; s != S; s = s->link) if(s->version == v) @@ -1288,16 +1367,24 @@ void doprof2(void) { Sym *s2, *s4; - Prog *p, *q, *ps2, *ps4; + Prog *p, *q, *q2, *ps2, *ps4; if(debug['v']) Bprint(&bso, "%5.2f profile 2\n", cputime()); Bflush(&bso); - s2 = lookup("_profin", 0); - s4 = lookup("_profout", 0); + if(debug['e']){ + s2 = lookup("_tracein", 0); + s4 = lookup("_traceout", 0); + }else{ + s2 = lookup("_profin", 0); + s4 = lookup("_profout", 0); + } if(s2->type != STEXT || s4->type != STEXT) { - diag("_profin/_profout not defined"); + if(debug['e']) + diag("_tracein/_traceout not defined %d %d", s2->type, s4->type); + else + diag("_profin/_profout not defined"); return; } @@ -1338,7 +1425,20 @@ doprof2(void) q->line = p->line; q->pc = p->pc; q->link = p->link; - p->link = q; + if(debug['e']){ /* embedded tracing */ + q2 = prg(); + p->link = q2; + q2->link = q; + + q2->line = p->line; + q2->pc = p->pc; + + q2->as = AJMP; + q2->to.type = D_BRANCH; + q2->to.sym = p->to.sym; + q2->pcond = q->link; + }else + p->link = q; p = q; p->as = ACALL; p->to.type = D_BRANCH; @@ -1349,6 +1449,17 @@ doprof2(void) } if(p->as == ARET) { /* + * RET (default) + */ + if(debug['e']){ /* embedded tracing */ + q = prg(); + q->line = p->line; + q->pc = p->pc; + q->link = p->link; + p->link = q; + p = q; + } + /* * RET */ q = prg(); diff --git a/utils/6l/optab.c b/utils/6l/optab.c index db22ca67..133bb1d2 100644 --- a/utils/6l/optab.c +++ b/utils/6l/optab.c @@ -15,8 +15,10 @@ uchar ynop[] = Ynone, Ynone, Zpseudo,1, Ynone, Yml, Zpseudo,1, Ynone, Yrf, Zpseudo,1, + Ynone, Yxr, Zpseudo,1, Yml, Ynone, Zpseudo,1, Yrf, Ynone, Zpseudo,1, + Yxr, Ynone, Zpseudo,1, 0 }; uchar yxorb[] = @@ -753,7 +755,7 @@ Optab optab[] = { AMOVBWSX, ymb_rl, Pq, 0xbe }, { AMOVBWZX, ymb_rl, Pq, 0xb6 }, { AMOVO, yxmov, Pe, 0x6f,0x7f }, - { AMOVOU, yxmov, Pf2, 0x6f,0x7f }, + { AMOVOU, yxmov, Pf3, 0x6f,0x7f }, { AMOVHLPS, yxr, Pm, 0x12 }, { AMOVHPD, yxmov, Pe, 0x16,0x17 }, { AMOVHPS, yxmov, Pm, 0x16,0x17 }, @@ -762,7 +764,7 @@ Optab optab[] = { AMOVLPD, yxmov, Pe, 0x12,0x13 }, { AMOVLPS, yxmov, Pm, 0x12,0x13 }, { AMOVLQSX, yml_rl, Pw, 0x63 }, - { AMOVLQZX, yml_rl, Px, 0x63 }, + { AMOVLQZX, yml_rl, Px, 0x8b }, { AMOVMSKPD, yxrrl, Pq, 0x50 }, { AMOVMSKPS, yxrrl, Pm, 0x50 }, { AMOVNTO, yxr_ml, Pe, 0xe7 }, @@ -877,9 +879,9 @@ Optab optab[] = { APOPQ, ypopl, Py, 0x58,0x8f,(00) }, { APOPW, ypopl, Pe, 0x58,0x8f,(00) }, { APOR, ymm, Py, 0xeb,Pe,0xeb }, - { APSADBW, yxm, Pw, Pe,0xf6 }, + { APSADBW, yxm, Pq, 0xf6 }, { APSHUFHW, yxshuf, Pf3, 0x70 }, - { APSHUFL, yxm, Pw, Pe,0x70 }, + { APSHUFL, yxshuf, Pq, 0x70 }, { APSHUFLW, yxshuf, Pf2, 0x70 }, { APSHUFW, ymshuf, Pm, 0x70 }, { APSLLO, ypsdq, Pq, 0x73,(07) }, diff --git a/utils/6l/span.c b/utils/6l/span.c index 1ce533d0..e49d873f 100644 --- a/utils/6l/span.c +++ b/utils/6l/span.c @@ -127,9 +127,17 @@ putsymb(char *s, int t, vlong v, int ver) if(t == 'f') s++; l = 4; - if(!debug['8']){ + switch(HEADTYPE){ + default: + break; + case 5: + if(debug['8']) + break; + case 2: + case 6: lput(v>>32); l = 8; + break; } lput(v); if(ver) @@ -245,12 +253,12 @@ asmlc(void) if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { if(p->as == ATEXT) curtext = p; - if(debug['L']) + if(debug['V']) Bprint(&bso, "%6llux %P\n", p->pc, p); continue; } - if(debug['L']) + if(debug['V']) Bprint(&bso, "\t\t%6ld", lcsize); v = (p->pc - oldpc) / MINLC; while(v) { @@ -258,7 +266,7 @@ asmlc(void) if(v < 127) s = v; cput(s+128); /* 129-255 +pc */ - if(debug['L']) + if(debug['V']) Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); v -= s; lcsize++; @@ -272,7 +280,7 @@ asmlc(void) cput(s>>16); cput(s>>8); cput(s); - if(debug['L']) { + if(debug['V']) { if(s > 0) Bprint(&bso, " lc+%ld(%d,%ld)\n", s, 0, s); @@ -287,14 +295,14 @@ asmlc(void) } if(s > 0) { cput(0+s); /* 1-64 +lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); Bprint(&bso, "%6llux %P\n", p->pc, p); } } else { cput(64-s); /* 65-128 -lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); Bprint(&bso, "%6llux %P\n", p->pc, p); @@ -307,7 +315,7 @@ asmlc(void) cput(s); lcsize++; } - if(debug['v'] || debug['L']) + if(debug['v'] || debug['V']) Bprint(&bso, "lcsize = %ld\n", lcsize); Bflush(&bso); } @@ -1385,7 +1393,7 @@ found: q = p->pcond; if(q) { v = q->pc - p->pc - 2; - if(v < -128 && v > 127) + if(v < -128 || v > 127) diag("loop too far: %P", p); *andptr++ = op; *andptr++ = v; @@ -1574,7 +1582,7 @@ asmins(Prog *p) /* * as befits the whole approach of the architecture, * the rex prefix must appear before the first opcode byte - * (and thus after any 66/67/f2/f3 prefix bytes, but + * (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but * before the 0f opcode escape!), or it might be ignored. * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'. */ @@ -1583,7 +1591,7 @@ asmins(Prog *p) n = andptr - and; for(np = 0; np < n; np++) { c = and[np]; - if(c != 0x66 && c != 0xf2 && c != 0xf3 && c != 0x67) + if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26) break; } memmove(and+np+1, and+np, n-np); diff --git a/utils/8a/a.h b/utils/8a/a.h index 82afc593..46de8b7a 100644 --- a/utils/8a/a.h +++ b/utils/8a/a.h @@ -2,7 +2,6 @@ #include <bio.h> #include "../8c/8.out.h" - #ifndef EXTERN #define EXTERN extern #endif @@ -72,6 +71,7 @@ struct Gen double dval; char sval[8]; long offset; + long offset2; Sym* sym; short type; short index; @@ -174,7 +174,7 @@ void setinclude(char*); int assemble(char*); /* - * Posix.c/Inferno.c/Nt.c + * system-dependent stuff from ../cc/compat.c */ enum /* keep in synch with ../cc/cc.h */ { diff --git a/utils/8a/a.y b/utils/8a/a.y index 631344d3..7c9487f6 100644 --- a/utils/8a/a.y +++ b/utils/8a/a.y @@ -4,6 +4,10 @@ %union { Sym *sym; long lval; + struct { + long v1; + long v2; + } con2; double dval; char sval[8]; Gen gen; @@ -16,16 +20,17 @@ %left '+' '-' %left '*' '/' '%' %token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 -%token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI +%token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG %token <lval> LCONST LFP LPC LSB %token <lval> LBREG LLREG LSREG LFREG %token <dval> LFCONST %token <sval> LSCONST LSP %token <sym> LNAME LLAB LVAR %type <lval> con expr pointer offset -%type <gen> mem imm reg nam rel rem rim rom omem nmem +%type <con2> con2 +%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem %type <gen2> nonnon nonrel nonrem rimnon rimrem remrim -%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 +%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 %% prog: | prog line @@ -73,6 +78,7 @@ inst: | LTYPES spec5 { outcode($1, &$2); } | LTYPEM spec6 { outcode($1, &$2); } | LTYPEI spec7 { outcode($1, &$2); } +| LTYPEG spec8 { outcode($1, &$2); } nonnon: { @@ -219,6 +225,19 @@ spec7: $$.to = $3; } +spec8: /* GLOBL */ + mem ',' imm + { + $$.from = $1; + $$.to = $3; + } +| mem ',' con ',' imm + { + $$.from = $1; + $$.from.scale = $3; + $$.to = $5; + } + rem: reg | mem @@ -336,6 +355,37 @@ imm: $$.dval = -$3; } +imm2: + '$' con2 + { + $$ = nullgen; + $$.type = D_CONST2; + $$.offset = $2.v1; + $$.offset2 = $2.v2; + } + +con2: + LCONST + { + $$.v1 = $1; + $$.v2 = 0; + } +| '-' LCONST + { + $$.v1 = -$2; + $$.v2 = 0; + } +| LCONST '-' LCONST + { + $$.v1 = $1; + $$.v2 = $3; + } +| '-' LCONST '-' LCONST + { + $$.v1 = -$2; + $$.v2 = $4; + } + mem: omem | nmem diff --git a/utils/8a/l.s b/utils/8a/l.s index 09980d48..4bb92ef5 100644 --- a/utils/8a/l.s +++ b/utils/8a/l.s @@ -221,7 +221,7 @@ TEXT mode32bit(SB),$0 * 16 meg of physical memory */ LEAL tpt-KZERO(SB),AX /* get phys addr of temporary page table */ - ADDL $(BY2PG-1),AX /* must be page alligned */ + ADDL $(BY2PG-1),AX /* must be page aligned */ ANDL $(~(BY2PG-1)),AX /* ... */ MOVL $(4*1024),CX /* pte's per page */ MOVL $((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX diff --git a/utils/8a/lex.c b/utils/8a/lex.c index 0ec4dc17..3c7d0859 100644 --- a/utils/8a/lex.c +++ b/utils/8a/lex.c @@ -1,7 +1,7 @@ +#include <ctype.h> #define EXTERN #include "a.h" #include "y.tab.h" -#include <ctype.h> void main(int argc, char *argv[]) @@ -274,6 +274,9 @@ struct "CMPSB", LTYPE0, ACMPSB, "CMPSL", LTYPE0, ACMPSL, "CMPSW", LTYPE0, ACMPSW, + "CMPXCHGB", LTYPE3, ACMPXCHGB, + "CMPXCHGL", LTYPE3, ACMPXCHGL, + "CMPXCHGW", LTYPE3, ACMPXCHGW, "DAA", LTYPE0, ADAA, "DAS", LTYPE0, ADAS, "DATA", LTYPED, ADATA, @@ -285,14 +288,14 @@ struct "DIVW", LTYPE2, ADIVW, "END", LTYPE0, AEND, "ENTER", LTYPE2, AENTER, - "GLOBL", LTYPET, AGLOBL, + "GLOBL", LTYPEG, AGLOBL, "HLT", LTYPE0, AHLT, "IDIVB", LTYPE2, AIDIVB, "IDIVL", LTYPE2, AIDIVL, "IDIVW", LTYPE2, AIDIVW, - "IMULB", LTYPE2, AIMULB, - "IMULL", LTYPE2, AIMULL, - "IMULW", LTYPE2, AIMULW, + "IMULB", LTYPEI, AIMULB, + "IMULL", LTYPEI, AIMULL, + "IMULW", LTYPEI, AIMULW, "INB", LTYPE0, AINB, "INL", LTYPE0, AINL, "INW", LTYPE0, AINW, @@ -493,6 +496,39 @@ struct "XORL", LTYPE3, AXORL, "XORW", LTYPE3, AXORW, + "CMOVLCC", LTYPE3, ACMOVLCC, + "CMOVLCS", LTYPE3, ACMOVLCS, + "CMOVLEQ", LTYPE3, ACMOVLEQ, + "CMOVLGE", LTYPE3, ACMOVLGE, + "CMOVLGT", LTYPE3, ACMOVLGT, + "CMOVLHI", LTYPE3, ACMOVLHI, + "CMOVLLE", LTYPE3, ACMOVLLE, + "CMOVLLS", LTYPE3, ACMOVLLS, + "CMOVLLT", LTYPE3, ACMOVLLT, + "CMOVLMI", LTYPE3, ACMOVLMI, + "CMOVLNE", LTYPE3, ACMOVLNE, + "CMOVLOC", LTYPE3, ACMOVLOC, + "CMOVLOS", LTYPE3, ACMOVLOS, + "CMOVLPC", LTYPE3, ACMOVLPC, + "CMOVLPL", LTYPE3, ACMOVLPL, + "CMOVLPS", LTYPE3, ACMOVLPS, + "CMOVWCC", LTYPE3, ACMOVWCC, + "CMOVWCS", LTYPE3, ACMOVWCS, + "CMOVWEQ", LTYPE3, ACMOVWEQ, + "CMOVWGE", LTYPE3, ACMOVWGE, + "CMOVWGT", LTYPE3, ACMOVWGT, + "CMOVWHI", LTYPE3, ACMOVWHI, + "CMOVWLE", LTYPE3, ACMOVWLE, + "CMOVWLS", LTYPE3, ACMOVWLS, + "CMOVWLT", LTYPE3, ACMOVWLT, + "CMOVWMI", LTYPE3, ACMOVWMI, + "CMOVWNE", LTYPE3, ACMOVWNE, + "CMOVWOC", LTYPE3, ACMOVWOC, + "CMOVWOS", LTYPE3, ACMOVWOS, + "CMOVWPC", LTYPE3, ACMOVWPC, + "CMOVWPL", LTYPE3, ACMOVWPL, + "CMOVWPS", LTYPE3, ACMOVWPS, + "FMOVB", LTYPE3, AFMOVB, "FMOVBP", LTYPE3, AFMOVBP, "FMOVD", LTYPE3, AFMOVD, @@ -507,6 +543,14 @@ struct "FMOVWP", LTYPE3, AFMOVWP, "FMOVX", LTYPE3, AFMOVX, "FMOVXP", LTYPE3, AFMOVXP, + "FCMOVCC", LTYPE3, AFCMOVCC, + "FCMOVCS", LTYPE3, AFCMOVCS, + "FCMOVEQ", LTYPE3, AFCMOVEQ, + "FCMOVHI", LTYPE3, AFCMOVHI, + "FCMOVLS", LTYPE3, AFCMOVLS, + "FCMOVNE", LTYPE3, AFCMOVNE, + "FCMOVNU", LTYPE3, AFCMOVNU, + "FCMOVUN", LTYPE3, AFCMOVUN, "FCOMB", LTYPE3, AFCOMB, "FCOMBP", LTYPE3, AFCOMBP, "FCOMD", LTYPE3, AFCOMD, @@ -514,11 +558,15 @@ struct "FCOMDPP", LTYPE3, AFCOMDPP, "FCOMF", LTYPE3, AFCOMF, "FCOMFP", LTYPE3, AFCOMFP, + "FCOMI", LTYPE3, AFCOMI, + "FCOMIP", LTYPE3, AFCOMIP, "FCOML", LTYPE3, AFCOML, "FCOMLP", LTYPE3, AFCOMLP, "FCOMW", LTYPE3, AFCOMW, "FCOMWP", LTYPE3, AFCOMWP, "FUCOM", LTYPE3, AFUCOM, + "FUCOMI", LTYPE3, AFUCOMI, + "FUCOMIP", LTYPE3, AFUCOMIP, "FUCOMP", LTYPE3, AFUCOMP, "FUCOMPP", LTYPE3, AFUCOMPP, "FADDW", LTYPE3, AFADDW, @@ -629,7 +677,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } } @@ -704,6 +752,9 @@ zaddr(Gen *a, int s) case D_FCONST: t |= T_FCONST; break; + case D_CONST2: + t |= T_OFFSET|T_OFFSET2; + break; case D_SCONST: t |= T_SCONST; break; @@ -723,6 +774,13 @@ zaddr(Gen *a, int s) Bputc(&obuf, l>>16); Bputc(&obuf, l>>24); } + if(t & T_OFFSET2) { + l = a->offset2; + Bputc(&obuf, l); + Bputc(&obuf, l>>8); + Bputc(&obuf, l>>16); + Bputc(&obuf, l>>24); + } if(t & T_SYM) /* implies sym */ Bputc(&obuf, s); if(t & T_FCONST) { diff --git a/utils/8c/8.out.h b/utils/8c/8.out.h index c38ab83f..a87341a2 100644 --- a/utils/8c/8.out.h +++ b/utils/8c/8.out.h @@ -2,6 +2,7 @@ #define NSNAME 8 #define NOPROF (1<<0) #define DUPOK (1<<1) +#define NOSPLIT (1<<2) enum as { @@ -353,6 +354,58 @@ enum as ASIGNAME, + AFCOMI, + AFCOMIP, + AFUCOMI, + AFUCOMIP, + ACMPXCHGB, + ACMPXCHGL, + ACMPXCHGW, + + /* conditional move */ + ACMOVLCC, + ACMOVLCS, + ACMOVLEQ, + ACMOVLGE, + ACMOVLGT, + ACMOVLHI, + ACMOVLLE, + ACMOVLLS, + ACMOVLLT, + ACMOVLMI, + ACMOVLNE, + ACMOVLOC, + ACMOVLOS, + ACMOVLPC, + ACMOVLPL, + ACMOVLPS, + ACMOVWCC, + ACMOVWCS, + ACMOVWEQ, + ACMOVWGE, + ACMOVWGT, + ACMOVWHI, + ACMOVWLE, + ACMOVWLS, + ACMOVWLT, + ACMOVWMI, + ACMOVWNE, + ACMOVWOC, + ACMOVWOS, + ACMOVWPC, + ACMOVWPL, + ACMOVWPS, + + AFCMOVCC, + AFCMOVCS, + AFCMOVEQ, + AFCMOVHI, + AFCMOVLS, + AFCMOVNE, + AFCMOVNU, + AFCMOVUN, + + /* add new operations here. nowhere else. here. */ ALAST }; @@ -378,6 +431,7 @@ enum D_DI, D_F0 = 16, + D_F7 = D_F0 + 7, D_CS = 24, D_SS, @@ -413,12 +467,18 @@ enum D_INDIR, /* additive */ + D_CONST2 = D_INDIR+D_INDIR, + + D_SIZE, /* 8l internal */ + T_TYPE = 1<<0, T_INDEX = 1<<1, T_OFFSET = 1<<2, T_FCONST = 1<<3, T_SYM = 1<<4, T_SCONST = 1<<5, + T_OFFSET2 = 1<<6, + T_GOTYPE = 1<<7, REGARG = -1, REGRET = D_AX, diff --git a/utils/8c/cgen.c b/utils/8c/cgen.c index c8511e2c..fac3b5d8 100644 --- a/utils/8c/cgen.c +++ b/utils/8c/cgen.c @@ -25,6 +25,12 @@ cgen(Node *n, Node *nn) l = n->left; r = n->right; o = n->op; +// Go's version does the following, but it's the wrong place: doesn't allow assignment +// if(o == OEXREG || nn != Z && nn->op == OEXREG) { +// gmove(n, nn); +// return; +// } + if(n->addable >= INDEXED) { if(nn == Z) { switch(o) { @@ -244,7 +250,7 @@ cgen(Node *n, Node *nn) if(n->op == OADD && l->op == OASHL && l->right->op == OCONST && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) { c = l->right->vconst; - if(c > 0 && c <= 3) { + if(c > 0 && c <= 3 && nareg(1) >= 4) { if(l->left->complex >= r->complex) { regalloc(&nod, l->left, nn); cgen(l->left, &nod); @@ -309,7 +315,7 @@ cgen(Node *n, Node *nn) if(typefd[n->type->etype]) goto fop; if(r->op == OCONST) { - SET(v); + v = 0; switch(o) { case ODIV: case OMOD: @@ -361,20 +367,27 @@ cgen(Node *n, Node *nn) t = l; l = r; r = t; + goto imula; } - /* should favour AX */ - regalloc(&nod, l, nn); - cgen(l, &nod); - if(r->addable < INDEXED) { + else if(r->addable >= INDEXED) { + imula: +/* should favour AX */ + regalloc(&nod, l, nn); + cgen(l, &nod); + gopcode(OMUL, n->type, r, &nod); + } + else { +/* should favour AX */ + regalloc(&nod, l, nn); + cgen(l, &nod); regalloc(&nod1, r, Z); cgen(r, &nod1); gopcode(OMUL, n->type, &nod1, &nod); regfree(&nod1); - }else - gopcode(OMUL, n->type, r, &nod); /* addressible */ + } gmove(&nod, nn); regfree(&nod); - break; + goto done; } /* @@ -427,21 +440,33 @@ cgen(Node *n, Node *nn) } reg[D_AX]++; - if(r->op == OCONST && (o == ODIV || o == OLDIV)) { - reg[D_DX]++; - if(l->addable < INDEXED) { - regalloc(&nod2, l, Z); - cgen(l, &nod2); - l = &nod2; - } - if(o == ODIV) + if(r->op == OCONST) { + switch(o) { + case ODIV: + reg[D_DX]++; + if(l->addable < INDEXED) { + regalloc(&nod2, l, Z); + cgen(l, &nod2); + l = &nod2; + } sdivgen(l, r, &nod, &nod1); - else + gmove(&nod1, nn); + if(l == &nod2) + regfree(l); + goto freeaxdx; + case OLDIV: + reg[D_DX]++; + if(l->addable < INDEXED) { + regalloc(&nod2, l, Z); + cgen(l, &nod2); + l = &nod2; + } udivgen(l, r, &nod, &nod1); - gmove(&nod1, nn); - if(l == &nod2) - regfree(l); - goto freeaxdx; + gmove(&nod1, nn); + if(l == &nod2) + regfree(l); + goto freeaxdx; + } } if(l->complex >= r->complex) { @@ -572,7 +597,7 @@ cgen(Node *n, Node *nn) if(typefd[n->type->etype]||typefd[r->type->etype]) goto asfop; if(r->op == OCONST) { - SET(v); + v = 0; switch(o) { case OASDIV: case OASMOD: @@ -631,7 +656,7 @@ cgen(Node *n, Node *nn) } if(o == OASMUL) { - /* should favour AX */ +/* should favour AX */ regalloc(&nod, l, nn); if(r->complex >= FNX) { regalloc(&nod1, r, Z); @@ -661,7 +686,7 @@ cgen(Node *n, Node *nn) regfree(&nod); if(hardleft) regfree(&nod2); - break; + goto done; } /* @@ -868,6 +893,7 @@ cgen(Node *n, Node *nn) break; case OFUNC: + l = uncomma(l); if(l->complex >= FNX) { if(l->op != OIND) diag(n, "bad function call"); @@ -1617,7 +1643,6 @@ copy: case OASMUL: case OASLMUL: - case OASASHL: case OASASHR: case OASLSHR: @@ -1806,6 +1831,12 @@ copy: gins(ACLD, Z, Z); gins(AREP, Z, Z); gins(AMOVSL, Z, Z); + if(w & (SZ_LONG-1)) { + /* odd length of packed structure */ + gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3); + gins(AREP, Z, Z); + gins(AMOVSB, Z, Z); + } if(c & 4) { gins(APOPL, Z, &nod3); reg[D_CX]--; diff --git a/utils/8c/cgen64.c b/utils/8c/cgen64.c index dd82adfa..6c4be5aa 100644 --- a/utils/8c/cgen64.c +++ b/utils/8c/cgen64.c @@ -188,70 +188,6 @@ storepair(Node *n, Node *nn, int f) freepair(n); } -/* generate a cast t from n to tt */ -static void -cast(Node *n, Type *t, Node *nn) -{ - Node *r; - - r = new(OCAST, n, Z); - r->type = t; - sugen(r, nn, 8); -} - -static void -swapregs(Node *a, Node *b) -{ - int t; - - t = a->reg; - a->reg = b->reg; - b->reg = t; -} - -static void -swappairs(Node *a, Node *b) -{ - swapregs(a->left, b->left); - swapregs(a->right, b->right); -} - -static int -saveme(Node *n) -{ - int r; - - r = n->reg; - return r >= D_AX && r <= D_DI; -} - -static void -saveit(Node *n, Node *t, Node *r) -{ - Node nod; - - if(saveme(n)) { - t->reg = n->reg; - gins(AMOVL, t, r); - r->xoffset += SZ_LONG; - if(n->reg == D_AX) { - regalloc(&nod, n, Z); - regfree(n); - n->reg = nod.reg; - } - } -} - -static void -restoreit(Node *n, Node *t, Node *r) -{ - if(saveme(n)) { - t->reg = n->reg; - gins(AMOVL, r, t); - r->xoffset += SZ_LONG; - } -} - enum { /* 4 only, see WW */ @@ -319,26 +255,6 @@ vfunc(Node *n, Node *nn) return t; } -static int -forcereg(Node *d, int r, int o, Node *t) -{ - int a; - - if(d->reg != D_NONE) - diag(Z, "force alloc"); - d->reg = r; - a = 0; - if(reg[r]) { - reg[o]++; - regalloc(t, d, Z); - a = 1; - gins(AMOVL, d, t); - reg[o]--; - } - reg[r]++; - return a; -} - /* try to steal a reg */ static int getreg(Node **np, Node *t, int r) diff --git a/utils/8c/enam.c b/utils/8c/enam.c index 3e293a28..cc6d0bf1 100644 --- a/utils/8c/enam.c +++ b/utils/8c/enam.c @@ -333,5 +333,52 @@ char* anames[] = "DYNT", "INIT", "SIGNAME", + "FCOMI", + "FCOMIP", + "FUCOMI", + "FUCOMIP", + "CMPXCHGB", + "CMPXCHGL", + "CMPXCHGW", + "CMOVLCC", + "CMOVLCS", + "CMOVLEQ", + "CMOVLGE", + "CMOVLGT", + "CMOVLHI", + "CMOVLLE", + "CMOVLLS", + "CMOVLLT", + "CMOVLMI", + "CMOVLNE", + "CMOVLOC", + "CMOVLOS", + "CMOVLPC", + "CMOVLPL", + "CMOVLPS", + "CMOVWCC", + "CMOVWCS", + "CMOVWEQ", + "CMOVWGE", + "CMOVWGT", + "CMOVWHI", + "CMOVWLE", + "CMOVWLS", + "CMOVWLT", + "CMOVWMI", + "CMOVWNE", + "CMOVWOC", + "CMOVWOS", + "CMOVWPC", + "CMOVWPL", + "CMOVWPS", + "FCMOVCC", + "FCMOVCS", + "FCMOVEQ", + "FCMOVHI", + "FCMOVLS", + "FCMOVNE", + "FCMOVNU", + "FCMOVUN", "LAST", }; diff --git a/utils/8c/gc.h b/utils/8c/gc.h index b7257962..f635ed76 100644 --- a/utils/8c/gc.h +++ b/utils/8c/gc.h @@ -61,7 +61,7 @@ struct Prog struct Case { Case* link; - long val; + vlong val; long label; char def; char isv; @@ -70,7 +70,7 @@ struct Case struct C1 { - long val; + vlong val; long label; }; @@ -240,6 +240,7 @@ void nextpc(void); void gargs(Node*, Node*, Node*); void garg1(Node*, Node*, Node*, int, Node**); Node* nodconst(long); +int nareg(int); Node* nodfconst(double); int nodreg(Node*, Node*, int); int isreg(Node*, int); @@ -266,7 +267,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void casf(void); @@ -274,7 +275,6 @@ void bitload(Node*, Node*, Node*, Node*, Node*); void bitstore(Node*, Node*, Node*, Node*, Node*); long outstring(char*, long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); @@ -295,10 +295,10 @@ int Bconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); -Bits mkvar(Reg*, Adr*); +Bits mkvar(Reg*, Adr*, int); void prop(Reg*, Bits, Bits); void loopit(Reg*, long); void synch(Reg*, Bits); @@ -336,11 +336,6 @@ int BtoF(long); #define D_LO D_NONE /* - * bound - */ -void comtarg(void); - -/* * com64 */ int cond(int); diff --git a/utils/8c/list.c b/utils/8c/list.c index 84466942..4251a387 100644 --- a/utils/8c/list.c +++ b/utils/8c/list.c @@ -27,7 +27,7 @@ Bconv(Fmt *fp) if(str[0]) strcat(str, " "); if(var[i].sym == S) { - sprint(ss, "$%ld", var[i].offset); + snprint(ss, sizeof(ss), "$%ld", var[i].offset); s = ss; } else s = var[i].sym->name; @@ -47,13 +47,13 @@ Pconv(Fmt *fp) p = va_arg(fp->args, Prog*); if(p->as == ADATA) - sprint(str, " %A %D/%d,%D", + snprint(str, sizeof(str), " %A %D/%d,%D", p->as, &p->from, p->from.scale, &p->to); else if(p->as == ATEXT) - sprint(str, " %A %D,%d,%D", + snprint(str, sizeof(str), " %A %D,%d,%D", p->as, &p->from, p->from.scale, &p->to); else - sprint(str, " %A %D,%D", + snprint(str, sizeof(str), " %A %D,%D", p->as, &p->from, &p->to); return fmtstrcpy(fp, str); } @@ -70,7 +70,7 @@ Aconv(Fmt *fp) int Dconv(Fmt *fp) { - char str[STRINGSZ], s[STRINGSZ]; + char str[40], s[20]; Adr *a; int i; @@ -78,18 +78,18 @@ Dconv(Fmt *fp) i = a->type; if(i >= D_INDIR) { if(a->offset) - sprint(str, "%ld(%R)", a->offset, i-D_INDIR); + snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR); else - sprint(str, "(%R)", i-D_INDIR); + snprint(str, sizeof(str), "(%R)", i-D_INDIR); goto brk; } switch(i) { default: if(a->offset) - sprint(str, "$%ld,%R", a->offset, i); + snprint(str, sizeof(str), "$%ld,%R", a->offset, i); else - sprint(str, "%R", i); + snprint(str, sizeof(str), "%R", i); break; case D_NONE: @@ -97,53 +97,54 @@ Dconv(Fmt *fp) break; case D_BRANCH: - sprint(str, "%ld(PC)", a->offset-pc); + snprint(str, sizeof(str), "%ld(PC)", a->offset-pc); break; case D_EXTERN: - sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset); break; case D_STATIC: - sprint(str, "%s<>+%ld(SB)", a->sym->name, + snprint(str, sizeof(str), "%s<>+%ld(SB)", a->sym->name, a->offset); break; case D_AUTO: - sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset); break; case D_PARAM: if(a->sym) - sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset); else - sprint(str, "%ld(FP)", a->offset); + snprint(str, sizeof(str), "%ld(FP)", a->offset); break; case D_CONST: - sprint(str, "$%ld", a->offset); + snprint(str, sizeof(str), "$%ld", a->offset); break; case D_FCONST: - sprint(str, "$(%.17e)", a->dval); + snprint(str, sizeof(str), "$(%.17e)", a->dval); break; case D_SCONST: - sprint(str, "$\"%S\"", a->sval); + snprint(str, sizeof(str), "$\"%S\"", a->sval); break; case D_ADDR: a->type = a->index; a->index = D_NONE; - sprint(str, "$%D", a); + snprint(str, sizeof(str), "$%D", a); a->index = a->type; a->type = D_ADDR; goto conv; } brk: if(a->index != D_NONE) { - sprint(s, "(%R*%d)", (int)a->index, (int)a->scale); - strcat(str, s); + fmtstrcpy(fp, str); + snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale); + return fmtstrcpy(fp, s); } conv: return fmtstrcpy(fp, str); @@ -224,14 +225,14 @@ char* regstr[] = int Rconv(Fmt *fp) { - char str[STRINGSZ]; + char str[20]; int r; r = va_arg(fp->args, int); if(r >= D_AL && r <= D_NONE) - sprint(str, "%s", regstr[r-D_AL]); + snprint(str, sizeof(str), "%s", regstr[r-D_AL]); else - sprint(str, "gok(%d)", r); + snprint(str, sizeof(str), "gok(%d)", r); return fmtstrcpy(fp, str); } @@ -240,7 +241,7 @@ int Sconv(Fmt *fp) { int i, c; - char str[STRINGSZ], *p, *a; + char str[30], *p, *a; a = va_arg(fp->args, char*); p = str; diff --git a/utils/8c/machcap.c b/utils/8c/machcap.c index 3a8831a7..1734e9c3 100644 --- a/utils/8c/machcap.c +++ b/utils/8c/machcap.c @@ -3,6 +3,7 @@ int machcap(Node *n) { +// return 0; if(n == Z) return 1; /* test */ @@ -15,6 +16,8 @@ machcap(Node *n) if(typechl[n->type->etype]) return 1; if(typev[n->type->etype]) { +// if(typev[n->type->etype] && n->right->op == OCONST) { +// if(hi64v(n->right) == 0) return 1; } break; @@ -50,6 +53,7 @@ machcap(Node *n) case OANDAND: case OOROR: case ONOT: + case ODOT: return 1; case OASADD: @@ -80,6 +84,7 @@ machcap(Node *n) case OHS: case OLO: case OLS: +//print("%O\n", n->op); return 1; } return 0; diff --git a/utils/8c/peep.c b/utils/8c/peep.c index 3d98b771..5f61925d 100644 --- a/utils/8c/peep.c +++ b/utils/8c/peep.c @@ -275,6 +275,9 @@ subprop(Reg *r0) case ACWD: case ACDQ: + case ASTOSB: + case ASTOSL: + case AMOVSB: case AMOVSL: case AFSTSW: return 0; @@ -645,11 +648,18 @@ copyu(Prog *p, Adr *v, Adr *s) return 2; goto caseread; + case AMOVSB: case AMOVSL: if(v->type == D_DI || v->type == D_SI) return 2; goto caseread; + case ASTOSB: + case ASTOSL: + if(v->type == D_AX || v->type == D_DI) + return 2; + goto caseread; + case AFSTSW: if(v->type == D_AX) return 2; diff --git a/utils/8c/reg.c b/utils/8c/reg.c index fe84f573..9677cd24 100644 --- a/utils/8c/reg.c +++ b/utils/8c/reg.c @@ -16,7 +16,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; @@ -119,7 +119,7 @@ regopt(Prog *p) r1->s1 = R; } - bit = mkvar(r, &p->from); + bit = mkvar(r, &p->from, p->as==AMOVL); if(bany(&bit)) switch(p->as) { /* @@ -139,7 +139,7 @@ regopt(Prog *p) break; } - bit = mkvar(r, &p->to); + bit = mkvar(r, &p->to, 0); if(bany(&bit)) switch(p->as) { default: @@ -639,7 +639,7 @@ doregbits(int r) } Bits -mkvar(Reg *r, Adr *a) +mkvar(Reg *r, Adr *a, int isro) { Var *v; int i, t, n, et, z; @@ -653,13 +653,21 @@ mkvar(Reg *r, Adr *a) t = a->type; r->regu |= doregbits(t); r->regu |= doregbits(a->index); + et = a->etype; switch(t) { default: goto none; + case D_INDIR+D_GS: + if(!isro || 1) + goto none; + n = t; + {static Sym er; a->sym = &er;} + a->sym->name = "$extreg"; + break; case D_ADDR: a->type = a->index; - bit = mkvar(r, a); + bit = mkvar(r, a, 0); for(z=0; z<BITS; z++) addrs.b[z] |= bit.b[z]; a->type = t; @@ -676,7 +684,6 @@ mkvar(Reg *r, Adr *a) goto none; if(s->name[0] == '.') goto none; - et = a->etype; o = a->offset; v = var; for(i=0; i<nvar; i++) { @@ -1010,7 +1017,7 @@ paint1(Reg *r, int bn) if(r->use1.b[z] & bb) { change += CREF * r->loop; - if(p->as == AFMOVL) + if(p->as == AFMOVL || p->as == AFMOVW) if(BtoR(bb) != D_F0) change = -CINF; if(debug['R'] && debug['v']) @@ -1020,7 +1027,7 @@ paint1(Reg *r, int bn) if((r->use2.b[z]|r->set.b[z]) & bb) { change += CREF * r->loop; - if(p->as == AFMOVL) + if(p->as == AFMOVL || p->as == AFMOVW) if(BtoR(bb) != D_F0) change = -CINF; if(debug['R'] && debug['v']) @@ -1030,7 +1037,7 @@ paint1(Reg *r, int bn) if(STORE(r) & r->regdiff.b[z] & bb) { change -= CLOAD * r->loop; - if(p->as == AFMOVL) + if(p->as == AFMOVL || p->as == AFMOVW) if(BtoR(bb) != D_F0) change = -CINF; if(debug['R'] && debug['v']) diff --git a/utils/8c/sgen.c b/utils/8c/sgen.c index df12f903..9ba278c8 100644 --- a/utils/8c/sgen.c +++ b/utils/8c/sgen.c @@ -88,6 +88,10 @@ xcom(Node *n) n->addable = 11; break; + case OEXREG: + n->addable = 12; + break; + case OREGISTER: n->addable = 12; break; diff --git a/utils/8c/swt.c b/utils/8c/swt.c index 46fd71eb..aad14717 100644 --- a/utils/8c/swt.c +++ b/utils/8c/swt.c @@ -9,8 +9,8 @@ swit1(C1 *q, int nc, long def, Node *n) if(nc < 5) { for(i=0; i<nc; i++) { - if(debug['W']) - print("case = %.8lux\n", q->val); + if(debug['K']) + print("case = %.8llux\n", q->val); gopcode(OEQ, n->type, n, nodconst(q->val)); patch(p, q->label); q++; @@ -21,8 +21,8 @@ swit1(C1 *q, int nc, long def, Node *n) } i = nc / 2; r = q+i; - if(debug['W']) - print("case > %.8lux\n", r->val); + if(debug['K']) + print("case > %.8llux\n", r->val); gopcode(OGT, n->type, n, nodconst(r->val)); sp = p; gbranch(OGOTO); @@ -30,8 +30,8 @@ swit1(C1 *q, int nc, long def, Node *n) patch(p, r->label); swit1(q, i, def, n); - if(debug['W']) - print("case < %.8lux\n", r->val); + if(debug['K']) + print("case < %.8llux\n", r->val); patch(sp, pc); swit1(r+1, nc-i-1, def, n); } @@ -128,23 +128,6 @@ outstring(char *s, long n) } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0L)); - p->from.offset += o+e; - p->from.scale = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { if(a->op == OCONST && typev[a->type->etype]) { @@ -512,8 +495,8 @@ align(long i, Type *t, int op) long maxround(long max, long v) { - v += SZ_LONG-1; + v = round(v, SZ_LONG); if(v > max) - max = round(v, SZ_LONG); + return v; return max; } diff --git a/utils/8c/txt.c b/utils/8c/txt.c index 44413d81..5415cef2 100644 --- a/utils/8c/txt.c +++ b/utils/8c/txt.c @@ -22,6 +22,8 @@ ginit(void) lastp = P; tfield = types[TLONG]; + typeswitch = typechlv; + zprog.link = P; zprog.as = AGOK; zprog.from.type = D_NONE; @@ -158,7 +160,8 @@ gargs(Node *n, Node *tn1, Node *tn2) cursafe = regs; } -int nareg(void) +int +nareg(int notbp) { int i, n; @@ -166,6 +169,8 @@ int nareg(void) for(i=D_AX; i<=D_DI; i++) if(reg[i] == 0) n++; + if(notbp && reg[D_BP] == 0) + n--; return n; } @@ -311,9 +316,29 @@ abort(); case TFLOAT: case TDOUBLE: - case TVLONG: i = D_F0; goto out; + + case TVLONG: + case TUVLONG: + n->op = OREGPAIR; + n->complex = 0; /* already in registers */ + n->addable = 11; + n->type = tn->type; + n->lineno = nearln; + n->left = alloc(sizeof(Node)); + n->right = alloc(sizeof(Node)); + if(o != Z && o->op == OREGPAIR) { + regalloc(n->left, ®node, o->left); + regalloc(n->right, ®node, o->right); + } else { + regalloc(n->left, ®node, Z); + regalloc(n->right, ®node, Z); + } + n->right->type = types[TULONG]; + if(tn->type->etype == TUVLONG) + n->left->type = types[TULONG]; + return; } diag(tn, "unknown type in regalloc: %T", tn->type); err: @@ -340,6 +365,12 @@ regfree(Node *n) { int i; + if(n->op == OREGPAIR) { + regfree(n->left); + regfree(n->right); + return; + } + i = 0; if(n->op != OREGISTER && n->op != OINDREG) goto err; @@ -431,6 +462,11 @@ naddr(Node *n, Adr *a) a->sym = S; break; + case OEXREG: + a->type = D_INDIR + D_GS; + a->offset = n->reg - 1; + a->etype = n->etype; + break; case OIND: naddr(n->left, a); @@ -610,9 +646,6 @@ gmove(Node *f, Node *t) case TDOUBLE: gins(AFMOVD, f, t); return; - case TVLONG: - gins(AFMOVV, f, t); - return; } /* @@ -651,9 +684,6 @@ gmove(Node *f, Node *t) case TDOUBLE: gins(AFMOVDP, f, t); return; - case TVLONG: - gins(AFMOVVP, f, t); - return; } /* @@ -838,7 +868,7 @@ gmove(Node *f, Node *t) gmove(f, &fregnode0); gins(AFADDD, nodfconst(-2147483648.), &fregnode0); gins(AFMOVLP, f, &nod); - gins(ASUBL, nodconst(-2147483648), &nod); + gins(ASUBL, nodconst(-2147483648u), &nod); gmove(&nod, t); return; @@ -981,7 +1011,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev) if(et == TFLOAT) a = AFADDF; else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFADDD; if(pop) a = AFADDDP; @@ -995,7 +1025,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev) if(rev) a = AFSUBRF; } else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFSUBD; if(pop) a = AFSUBDP; @@ -1012,7 +1042,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev) if(et == TFLOAT) a = AFMULF; else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFMULD; if(pop) a = AFMULDP; @@ -1028,7 +1058,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev) if(rev) a = AFDIVRF; } else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFDIVD; if(pop) a = AFDIVDP; @@ -1055,7 +1085,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev) a = AGOK; } } else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFCOMF; if(pop) { a = AFCOMDP; @@ -1356,7 +1386,15 @@ long exreg(Type *t) { - USED(t); + int o; + + if(typechlp[t->etype]){ + if(exregoffset >= 32) + return 0; + o = exregoffset; + exregoffset += 4; + return o+1; /* +1 to avoid 0 == failure; naddr case OEXREG will -1. */ + } return 0; } diff --git a/utils/8l/Nt.c b/utils/8l/Nt.c deleted file mode 100644 index 73c6f795..00000000 --- a/utils/8l/Nt.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <windows.h> -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/8l/Plan9.c b/utils/8l/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/8l/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/8l/asm.c b/utils/8l/asm.c index a1bb36ba..6d09ae7c 100644 --- a/utils/8l/asm.c +++ b/utils/8l/asm.c @@ -2,8 +2,6 @@ #define Dbufslop 100 -#define PADDR(a) ((ulong)(a) & ~0xF0000000) - long entryvalue(void) { @@ -28,15 +26,16 @@ entryvalue(void) return s->value; } +/* these need to take long arguments to be compatible with elf.c */ void -wputl(ushort w) +wputl(long w) { cput(w); cput(w>>8); } void -wput(ushort w) +wput(long w) { cput(w>>8); cput(w); @@ -61,6 +60,20 @@ lputl(long l) } void +llput(vlong v) +{ + lput(v>>32); + lput(v); +} + +void +llputl(vlong v) +{ + lputl(v); + lputl(v>>32); +} + +void strnput(char *s, int n) { for(; *s && n > 0; s++){ @@ -335,51 +348,7 @@ asmb(void) wputl(0x0000); /* overlay number */ break; case 5: - strnput("\177ELF", 4); /* e_ident */ - cput(1); /* class = 32 bit */ - cput(1); /* data = LSB */ - cput(1); /* version = CURRENT */ - strnput("", 9); - wputl(2); /* type = EXEC */ - wputl(3); /* machine = 386 */ - lputl(1L); /* version = CURRENT */ - lputl(PADDR(entryvalue())); /* entry vaddr */ - lputl(52L); /* offset to first phdr */ - lputl(0L); /* offset to first shdr */ - lputl(0L); /* flags = 386 */ - wputl(52); /* Ehdr size */ - wputl(32); /* Phdr size */ - wputl(3); /* # of Phdrs */ - wputl(0); /* Shdr size */ - wputl(0); /* # of Shdrs */ - wputl(0); /* Shdr string size */ - - lputl(1L); /* text - type = PT_LOAD */ - lputl(HEADR); /* file offset */ - lputl(INITTEXT); /* vaddr */ - lputl(PADDR(INITTEXT)); /* paddr */ - lputl(textsize); /* file size */ - lputl(textsize); /* memory size */ - lputl(0x05L); /* protections = RX */ - lputl(INITRND); /* alignment */ - - lputl(1L); /* data - type = PT_LOAD */ - lputl(HEADR+textsize); /* file offset */ - lputl(INITDAT); /* vaddr */ - lputl(PADDR(INITDAT)); /* paddr */ - lputl(datsize); /* file size */ - lputl(datsize+bsssize); /* memory size */ - lputl(0x06L); /* protections = RW */ - lputl(INITRND); /* alignment */ - - lputl(0L); /* data - type = PT_NULL */ - lputl(HEADR+textsize+datsize); /* file offset */ - lputl(0L); - lputl(0L); - lputl(symsize); /* symbol table size */ - lputl(lcsize); /* line number size */ - lputl(0x04L); /* protections = R */ - lputl(0x04L); /* alignment */ + elf32(I386, ELFDATA2LSB, 0, nil); break; } cflush(); diff --git a/utils/8l/l.h b/utils/8l/l.h index e3be6b17..c03f7adf 100644 --- a/utils/8l/l.h +++ b/utils/8l/l.h @@ -1,6 +1,7 @@ #include <lib9.h> #include <bio.h> #include "../8c/8.out.h" +#include "../8l/elf.h" #ifndef EXTERN #define EXTERN extern @@ -15,6 +16,8 @@ if(--cbc <= 0)\ cflush(); } +#define LIBNAMELEN 300 + typedef struct Adr Adr; typedef struct Prog Prog; typedef struct Sym Sym; @@ -36,7 +39,7 @@ struct Adr Sym* u1sym; } u1; short type; - char index; + uchar index; char scale; }; @@ -57,11 +60,12 @@ struct Prog Prog* pcond; /* work on this */ long pc; long line; - uchar mark; /* work on these */ - uchar back; - short as; char width; /* fake for DATA */ + char ft; /* oclass cache */ + char tt; + uchar mark; /* work on these */ + uchar back; }; struct Auto { @@ -188,7 +192,7 @@ EXTERN union { struct { - char obuf[MAXIO]; /* output buffer */ + uchar obuf[MAXIO]; /* output buffer */ uchar ibuf[MAXIO]; /* input buffer */ } u; char dbuf[1]; @@ -197,23 +201,28 @@ EXTERN union #define cbuf u.obuf #define xbuf u.ibuf +#pragma varargck type "A" int #pragma varargck type "A" uint #pragma varargck type "D" Adr* #pragma varargck type "P" Prog* #pragma varargck type "R" int +#pragma varargck type "R" uint #pragma varargck type "S" char* +#pragma varargck argpos diag 1 + EXTERN long HEADR; EXTERN long HEADTYPE; EXTERN long INITDAT; EXTERN long INITRND; EXTERN long INITTEXT; +EXTERN long INITTEXTP; EXTERN char* INITENTRY; /* entry point */ EXTERN Biobuf bso; EXTERN long bsssize; EXTERN long casepc; EXTERN int cbc; -EXTERN char* cbp; +EXTERN uchar* cbp; EXTERN char* pcstr; EXTERN int cout; EXTERN Auto* curauto; @@ -281,6 +290,7 @@ int Pconv(Fmt*); int Rconv(Fmt*); int Sconv(Fmt*); void addhist(long, int); +void addlibpath(char*); Prog* appendp(Prog*); void asmb(void); void asmdyn(void); @@ -306,8 +316,10 @@ void dynreloc(Sym*, ulong, int); long entryvalue(void); void errorexit(void); void export(void); +int fileexists(char*); int find1(long, int); int find2(long, int); +char* findlib(char*); void follow(void); void gethunk(void); void histtoauto(void); @@ -320,6 +332,8 @@ void listinit(void); Sym* lookup(char*, int); void lput(long); void lputl(long); +void llput(vlong v); +void llputl(vlong v); void main(int, char*[]); void mkfwd(void); void* mysbrk(ulong); @@ -333,10 +347,12 @@ int relinv(int); long reuse(Prog*, Sym*); long rnd(long, long); void span(void); +void strnput(char*, int); void undef(void); void undefsym(Sym*); long vaddr(Adr*); -void wput(ushort); +void wput(long); +void wputl(long); void xdefine(char*, int, long); void xfol(Prog*); int zaddr(uchar*, Adr*, Sym*[]); @@ -346,4 +362,3 @@ void zerosig(char*); #pragma varargck type "P" Prog* #pragma varargck type "R" int #pragma varargck type "A" int -#pragma varargck argpos diag 1 diff --git a/utils/8l/list.c b/utils/8l/list.c index f52477d5..f452b758 100644 --- a/utils/8l/list.c +++ b/utils/8l/list.c @@ -24,18 +24,18 @@ Pconv(Fmt *fp) switch(p->as) { case ATEXT: if(p->from.scale) { - sprint(str, "(%ld) %A %D,%d,%D", + snprint(str, sizeof(str), "(%ld) %A %D,%d,%D", p->line, p->as, &p->from, p->from.scale, &p->to); break; } default: - sprint(str, "(%ld) %A %D,%D", + snprint(str, sizeof(str), "(%ld) %A %D,%D", p->line, p->as, &p->from, &p->to); break; case ADATA: case AINIT: case ADYNT: - sprint(str, "(%ld) %A %D/%d,%D", + snprint(str, sizeof(str), "(%ld) %A %D/%d,%D", p->line, p->as, &p->from, p->from.scale, &p->to); break; } @@ -55,7 +55,7 @@ Aconv(Fmt *fp) int Dconv(Fmt *fp) { - char str[40], s[20]; + char str[STRINGSZ+40], s[20]; Adr *a; int i; @@ -63,15 +63,15 @@ Dconv(Fmt *fp) i = a->type; if(i >= D_INDIR) { if(a->offset) - sprint(str, "%ld(%R)", a->offset, i-D_INDIR); + snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR); else - sprint(str, "(%R)", i-D_INDIR); + snprint(str, sizeof(str), "(%R)", i-D_INDIR); goto brk; } switch(i) { default: - sprint(str, "%R", i); + snprint(str, sizeof(str), "%R", i); break; case D_NONE: @@ -81,57 +81,57 @@ Dconv(Fmt *fp) case D_BRANCH: if(bigP != P && bigP->pcond != P) if(a->sym != S) - sprint(str, "%lux+%s", bigP->pcond->pc, + snprint(str, sizeof(str), "%lux+%s", bigP->pcond->pc, a->sym->name); else - sprint(str, "%lux", bigP->pcond->pc); + snprint(str, sizeof(str), "%lux", bigP->pcond->pc); else - sprint(str, "%ld(PC)", a->offset); + snprint(str, sizeof(str), "%ld(PC)", a->offset); break; case D_EXTERN: - sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset); break; case D_STATIC: - sprint(str, "%s<%d>+%ld(SB)", a->sym->name, + snprint(str, sizeof(str), "%s<%d>+%ld(SB)", a->sym->name, a->sym->version, a->offset); break; case D_AUTO: - sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset); break; case D_PARAM: if(a->sym) - sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset); else - sprint(str, "%ld(FP)", a->offset); + snprint(str, sizeof(str), "%ld(FP)", a->offset); break; case D_CONST: - sprint(str, "$%ld", a->offset); + snprint(str, sizeof(str), "$%ld", a->offset); break; case D_FCONST: - sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); + snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); break; case D_SCONST: - sprint(str, "$\"%S\"", a->scon); + snprint(str, sizeof(str), "$\"%S\"", a->scon); break; case D_ADDR: a->type = a->index; a->index = D_NONE; - sprint(str, "$%D", a); + snprint(str, sizeof(str), "$%D", a); a->index = a->type; a->type = D_ADDR; goto conv; } brk: if(a->index != D_NONE) { - sprint(s, "(%R*%d)", a->index, a->scale); + snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale); strcat(str, s); } conv: @@ -218,9 +218,9 @@ Rconv(Fmt *fp) r = va_arg(fp->args, int); if(r >= D_AL && r <= D_NONE) - sprint(str, "%s", regstr[r-D_AL]); + snprint(str, sizeof(str), "%s", regstr[r-D_AL]); else - sprint(str, "gok(%d)", r); + snprint(str, sizeof(str), "gok(%d)", r); return fmtstrcpy(fp, str); } diff --git a/utils/8l/mkfile b/utils/8l/mkfile index aa383d07..8fbf064c 100644 --- a/utils/8l/mkfile +++ b/utils/8l/mkfile @@ -11,6 +11,7 @@ OFILES=\ list.$O\ enam.$O\ $TARGMODEL.$O\ + elf.$O\ HFILES=\ l.h\ @@ -23,7 +24,12 @@ BIN=$ROOT/$OBJDIR/bin <$ROOT/mkfiles/mkone-$SHELLTYPE -CFLAGS= $CFLAGS -I../include +CFLAGS= $CFLAGS -I../include -I. enam.$O: ../8c/enam.c $CC $CFLAGS ../8c/enam.c +elf.$O: ../ld/elf.c + $CC $CFLAGS ../ld/elf.c + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/8l/obj.c b/utils/8l/obj.c index a2cd7c9a..d8a4bed1 100644 --- a/utils/8l/obj.c +++ b/utils/8l/obj.c @@ -11,6 +11,10 @@ char symname[] = SYMDEF; char thechar = '8'; char *thestring = "386"; +char** libdir; +int nlibdir = 0; +static int maxlibdir = 0; + /* * -H0 -T0x40004C -D0x10000000 is garbage unix * -H1 -T0xd0 -R4 is unix coff @@ -20,6 +24,13 @@ char *thestring = "386"; * -H5 -T0x80100020 -R4096 is ELF */ +void +usage(void) +{ + diag("usage: %s [-options] objects", argv0); + errorexit(); +} + static int isobjfile(char *f) { @@ -47,6 +58,7 @@ main(int argc, char *argv[]) { int i, c; char *a; + char name[LIBNAMELEN]; Binit(&bso, 1, OWRITE); cout = -1; @@ -56,6 +68,7 @@ main(int argc, char *argv[]) outfile = "8.out"; HEADTYPE = -1; INITTEXT = -1; + INITTEXTP = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; @@ -78,11 +91,19 @@ main(int argc, char *argv[]) if(a) HEADTYPE = atolwhex(a); break; + case 'L': + addlibpath(EARGF(usage())); + break; case 'T': a = ARGF(); if(a) INITTEXT = atolwhex(a); break; + case 'P': + a = ARGF(); + if(a) + INITTEXTP = atolwhex(a); + break; case 'D': a = ARGF(); if(a) @@ -111,12 +132,20 @@ main(int argc, char *argv[]) break; } ARGEND USED(argc); - if(*argv == 0) { - diag("usage: 8l [-options] objects"); - errorexit(); - } + if(*argv == 0) + usage(); if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; + a = getenv("ccroot"); + if(a != nil && *a != '\0') { + if(!fileexists(a)) { + diag("nonexistent $ccroot: %s", a); + errorexit(); + } + }else + a = ""; + snprint(name, sizeof(name), "%s/%s/lib", a, thestring); + addlibpath(name); if(HEADTYPE == -1) { if(debug['U']) HEADTYPE = 1; @@ -179,7 +208,7 @@ main(int argc, char *argv[]) Bprint(&bso, "HEADR = 0x%ld\n", HEADR); break; case 5: /* elf executable */ - HEADR = rnd(52L+3*32L, 16); + HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16); if(INITTEXT == -1) INITTEXT = 0x80100020L; if(INITDAT == -1) @@ -188,6 +217,8 @@ main(int argc, char *argv[]) INITRND = 4096; break; } + if (INITTEXTP == -1) + INITTEXTP = INITTEXT; if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", INITDAT, INITRND); @@ -269,7 +300,7 @@ main(int argc, char *argv[]) dtype = 4; cout = create(outfile, 1, 0775); if(cout < 0) { - diag("cannot create %s", outfile); + diag("cannot create %s: %r", outfile); errorexit(); } version = 0; @@ -284,7 +315,7 @@ main(int argc, char *argv[]) INITENTRY = "_mainp"; if(!debug['l']) lookup(INITENTRY, 0)->type = SXREF; - } else + } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9')) lookup(INITENTRY, 0)->type = SXREF; while(*argv) @@ -335,6 +366,42 @@ main(int argc, char *argv[]) } void +addlibpath(char *arg) +{ + char **p; + + if(nlibdir >= maxlibdir) { + if(maxlibdir == 0) + maxlibdir = 8; + else + maxlibdir *= 2; + p = malloc(maxlibdir*sizeof(*p)); + if(p == nil) { + diag("out of memory"); + errorexit(); + } + memmove(p, libdir, nlibdir*sizeof(*p)); + free(libdir); + libdir = p; + } + libdir[nlibdir++] = strdup(arg); +} + +char* +findlib(char *file) +{ + int i; + char name[LIBNAMELEN]; + + for(i = 0; i < nlibdir; i++) { + snprint(name, sizeof(name), "%s/%s", libdir[i], file); + if(fileexists(name)) + return libdir[i]; + } + return nil; +} + +void loadlib(void) { int i; @@ -374,25 +441,26 @@ objfile(char *file) int f, work; Sym *s; char magbuf[SARMAG]; - char name[100], pname[150]; + char name[LIBNAMELEN], pname[LIBNAMELEN]; struct ar_hdr arhdr; char *e, *start, *stop; - if(file[0] == '-' && file[1] == 'l') { - if(debug['9']) - sprint(name, "/%s/lib/lib", thestring); - else - sprint(name, "/usr/%clib/lib", thechar); - strcat(name, file+2); - strcat(name, ".a"); - file = name; - } if(debug['v']) Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); Bflush(&bso); + if(file[0] == '-' && file[1] == 'l') { + snprint(pname, sizeof(pname), "lib%s.a", file+2); + e = findlib(pname); + if(e == nil) { + diag("cannot find library: %s", file); + errorexit(); + } + snprint(name, sizeof(name), "%s/%s", e, pname); + file = name; + } f = open(file, 0); if(f < 0) { - diag("cannot open file: %s", file); + diag("cannot open %s: %r", file); errorexit(); } l = read(f, magbuf, SARMAG); @@ -451,7 +519,8 @@ objfile(char *file) l |= (e[3] & 0xff) << 16; l |= (e[4] & 0xff) << 24; seek(f, l, 0); - l = read(f, &arhdr, SAR_HDR); + /* need readn to read the dumps (at least) */ + l = readn(f, &arhdr, SAR_HDR); if(l != SAR_HDR) goto bad; if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) @@ -478,7 +547,7 @@ int zaddr(uchar *p, Adr *a, Sym *h[]) { int c, t, i; - long l; + int l; Sym *s; Auto *u; @@ -554,25 +623,24 @@ zaddr(uchar *p, Adr *a, Sym *h[]) void addlib(char *obj) { - char name[1024], comp[256], *p; - int i; + char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name; + int i, search; if(histfrogp <= 0) return; + name = fn1; + search = 0; if(histfrog[0]->name[1] == '/') { sprint(name, ""); i = 1; - } else - if(histfrog[0]->name[1] == '.') { + } else if(histfrog[0]->name[1] == '.') { sprint(name, "."); i = 0; } else { - if(debug['9']) - sprint(name, "/%s/lib", thestring); - else - sprint(name, "/usr/%clib", thechar); + sprint(name, ""); i = 0; + search = 1; } for(; i<histfrogp; i++) { @@ -595,13 +663,25 @@ addlib(char *obj) memmove(p+strlen(thestring), p+2, strlen(p+2)+1); memmove(p, thestring, strlen(thestring)); } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { + if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) { diag("library component too long"); return; } - strcat(name, "/"); - strcat(name, comp); + if(i > 0 || !search) + strcat(fn1, "/"); + strcat(fn1, comp); + } + + cleanname(name); + + if(search){ + p = findlib(name); + if(p != nil){ + snprint(fn2, sizeof(fn2), "%s/%s", p, name); + name = fn2; + } } + for(i=0; i<libraryp; i++) if(strcmp(name, library[i]) == 0) return; @@ -1087,8 +1167,7 @@ lookup(char *symb, int v) for(p=symb; c = *p; p++) h = h+h+h + c; l = (p - symb) + 1; - if(h < 0) - h = ~h; + h &= 0xffffff; h %= NHASH; for(s = hash[h]; s != S; s = s->link) if(s->version == v) @@ -1236,16 +1315,24 @@ void doprof2(void) { Sym *s2, *s4; - Prog *p, *q, *ps2, *ps4; + Prog *p, *q, *q2, *ps2, *ps4; if(debug['v']) Bprint(&bso, "%5.2f profile 2\n", cputime()); Bflush(&bso); - s2 = lookup("_profin", 0); - s4 = lookup("_profout", 0); + if(debug['e']){ + s2 = lookup("_tracein", 0); + s4 = lookup("_traceout", 0); + }else{ + s2 = lookup("_profin", 0); + s4 = lookup("_profout", 0); + } if(s2->type != STEXT || s4->type != STEXT) { - diag("_profin/_profout not defined"); + if(debug['e']) + diag("_tracein/_traceout not defined %d %d", s2->type, s4->type); + else + diag("_profin/_profout not defined"); return; } @@ -1286,7 +1373,20 @@ doprof2(void) q->line = p->line; q->pc = p->pc; q->link = p->link; - p->link = q; + if(debug['e']){ /* embedded tracing */ + q2 = prg(); + p->link = q2; + q2->link = q; + + q2->line = p->line; + q2->pc = p->pc; + + q2->as = AJMP; + q2->to.type = D_BRANCH; + q2->to.sym = p->to.sym; + q2->pcond = q->link; + }else + p->link = q; p = q; p->as = ACALL; p->to.type = D_BRANCH; @@ -1297,6 +1397,17 @@ doprof2(void) } if(p->as == ARET) { /* + * RET (default) + */ + if(debug['e']){ /* embedded tracing */ + q = prg(); + q->line = p->line; + q->pc = p->pc; + q->link = p->link; + p->link = q; + p = q; + } + /* * RET */ q = prg(); diff --git a/utils/8l/pass.c b/utils/8l/pass.c index 0e0ec346..6de027af 100644 --- a/utils/8l/pass.c +++ b/utils/8l/pass.c @@ -91,8 +91,10 @@ dodata(void) s->value = bsssize + datsize; bsssize += t; } + xdefine("bdata", SDATA, 0L); xdefine("edata", SBSS, datsize); xdefine("end", SBSS, bsssize + datsize); + /* etext is defined in span.c */ } Prog* @@ -308,7 +310,8 @@ patch(void) Bprint(&bso, "%s calls %s\n", TNAME, s->name); switch(s->type) { default: - diag("undefined: %s in %s", s->name, TNAME); + /* diag prints TNAME first */ + diag("undefined: %s", s->name); s->type = STEXT; s->value = vexit; break; /* or fall through to set offset? */ diff --git a/utils/8l/span.c b/utils/8l/span.c index 67ec929b..729ae8df 100644 --- a/utils/8l/span.c +++ b/utils/8l/span.c @@ -236,12 +236,12 @@ asmlc(void) if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { if(p->as == ATEXT) curtext = p; - if(debug['L']) + if(debug['V']) Bprint(&bso, "%6lux %P\n", p->pc, p); continue; } - if(debug['L']) + if(debug['V']) Bprint(&bso, "\t\t%6ld", lcsize); v = (p->pc - oldpc) / MINLC; while(v) { @@ -249,7 +249,7 @@ asmlc(void) if(v < 127) s = v; cput(s+128); /* 129-255 +pc */ - if(debug['L']) + if(debug['V']) Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); v -= s; lcsize++; @@ -263,7 +263,7 @@ asmlc(void) cput(s>>16); cput(s>>8); cput(s); - if(debug['L']) { + if(debug['V']) { if(s > 0) Bprint(&bso, " lc+%ld(%d,%ld)\n", s, 0, s); @@ -278,14 +278,14 @@ asmlc(void) } if(s > 0) { cput(0+s); /* 1-64 +lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); Bprint(&bso, "%6lux %P\n", p->pc, p); } } else { cput(64-s); /* 65-128 -lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); Bprint(&bso, "%6lux %P\n", p->pc, p); @@ -298,12 +298,30 @@ asmlc(void) cput(s); lcsize++; } - if(debug['v'] || debug['L']) + if(debug['v'] || debug['V']) Bprint(&bso, "lcsize = %ld\n", lcsize); Bflush(&bso); } int +prefixof(Adr *a) +{ + switch(a->type) { + case D_INDIR+D_CS: + return 0x2e; + case D_INDIR+D_DS: + return 0x3e; + case D_INDIR+D_ES: + return 0x26; + case D_INDIR+D_FS: + return 0x64; + case D_INDIR+D_GS: + return 0x65; + } + return 0; +} + +int oclass(Adr *a) { long v; @@ -608,7 +626,7 @@ asmand(Adr *a, int r) } if(t >= D_INDIR) { t -= D_INDIR; - if(t == D_NONE) { + if(t == D_NONE || D_CS <= t && t <= D_GS) { *andptr++ = (0 << 6) | (5 << 0) | (r << 3); put4(v); return; @@ -769,6 +787,7 @@ uchar ymovtab[] = ASHRL, Ycol, Yml, 6, 0xac,0xad,0,0, /* extra imul */ + AIMULW, Yml, Yrl, 7, Pq,0xaf,0,0, AIMULL, Yml, Yrl, 7, Pm,0xaf,0,0, 0 }; @@ -823,7 +842,14 @@ doasm(Prog *p) Prog *q, pp; uchar *t; int z, op, ft, tt; - long v; + long v, pre; + + pre = prefixof(&p->from); + if(pre) + *andptr++ = pre; + pre = prefixof(&p->to); + if(pre) + *andptr++ = pre; o = &optab[p->as]; ft = oclass(&p->from) * Ymax; @@ -1063,7 +1089,7 @@ found: q = p->pcond; if(q) { v = q->pc - p->pc - 2; - if(v < -128 && v > 127) + if(v < -128 || v > 127) diag("loop too far: %P", p); *andptr++ = op; *andptr++ = v; diff --git a/utils/acid/expr.c b/utils/acid/expr.c index 4d3dcd94..826edef5 100644 --- a/utils/acid/expr.c +++ b/utils/acid/expr.c @@ -835,11 +835,11 @@ ocand(Node *n, Node *res) { Node l, r; - res->nstore.fmt = l.nstore.fmt; res->op = OCONST; res->type = TINT; res->nstore.u0.sival = 0; expr(n->left, &l); + res->nstore.fmt = l.nstore.fmt; if(bool(&l) == 0) return; expr(n->right, &r); diff --git a/utils/acid/os-Posix.c b/utils/acid/os-Posix.c index 3729db69..6e00553b 100644 --- a/utils/acid/os-Posix.c +++ b/utils/acid/os-Posix.c @@ -9,6 +9,7 @@ #define Extern extern #include "acid.h" #include <signal.h> +#include <sys/wait.h> static void setraw(int fd, int baud) diff --git a/utils/acid/print.c b/utils/acid/print.c index 3a101b80..9ccb992b 100644 --- a/utils/acid/print.c +++ b/utils/acid/print.c @@ -41,7 +41,7 @@ char *typenames[] = }; int -cmp(const void *a, const void *b) +cmp(void *a, void *b) { return strcmp(*(char**)a, *(char**)b); } diff --git a/utils/awk/run.c b/utils/awk/run.c index 7c2740d2..e66365bf 100644 --- a/utils/awk/run.c +++ b/utils/awk/run.c @@ -1653,7 +1653,7 @@ char *filename(FILE *fp) for (i = 0; i < FOPEN_MAX; i++) if (fp == files[i].fp) return files[i].fname; - return "???"; + return "?"; } Cell *closefile(Node **a, int n) diff --git a/utils/c2l/Posix.c b/utils/c2l/Posix.c index e572e5da..aba318fd 100644 --- a/utils/c2l/Posix.c +++ b/utils/c2l/Posix.c @@ -1,4 +1,5 @@ #include "cc.h" +#include <sys/wait.h> void* mysbrk(ulong size) diff --git a/utils/c2l/c2l.c b/utils/c2l/c2l.c index 83409dbb..42897ce3 100644 --- a/utils/c2l/c2l.c +++ b/utils/c2l/c2l.c @@ -1263,7 +1263,7 @@ static int hasbrk(Node*); static int isgen(char*); static int simple(Node*); static void pfmt(char*); -static void lpfmt(ushort*); +static void lpfmt(Rune*); static int lline(Node*); static void args(Node*); static void addmodn(Sym*); @@ -2095,6 +2095,7 @@ etseq(Syml *syml) pio = io = ARITH|GEOM; e = 0; dd = 0; + d = 0; for(sl = syml; sl != nil; sl = sl->nxt){ s = sl->sym; if(isreal(s->tenum) || s->tenum->etype == TIND) @@ -2782,7 +2783,7 @@ stob(Node *n) { int m; char *s = nil, buf[UTFmax]; - ushort *u = nil; + Rune *u = nil; while(n->op == ONAME) n = n->sym->nconst; @@ -4689,9 +4690,9 @@ pfmt(char *s) } static void -lpfmt(ushort *s) +lpfmt(Rune *s) { - ushort*t = s; + Rune*t = s; while(*s != '\0'){ if(*s == '%'){ diff --git a/utils/c2l/cc.h b/utils/c2l/cc.h index 2d16efb7..5f9ae578 100644 --- a/utils/c2l/cc.h +++ b/utils/c2l/cc.h @@ -16,6 +16,8 @@ typedef struct Term Term; typedef struct Init Init; typedef struct Bits Bits; +typedef Rune TRune; + #define NHUNK 50000L #define BUFSIZ 8192 #define NSYMB 500 @@ -26,7 +28,7 @@ typedef struct Bits Bits; #define NTERM 10 #define MAXALIGN 7 -#define SIGN(n) ((vlong)1<<(n-1)) +#define SIGN(n) ((uvlong)1<<(n-1)) #define MASK(n) (SIGN(n)|(SIGN(n)-1)) #define BITS 5 @@ -54,7 +56,7 @@ struct Node double fconst; /* fp constant */ vlong vconst; /* non fp const */ char* cstring; /* character string */ - ushort* rstring; /* rune string */ + Rune* rstring; /* rune string */ Sym* sym; Type* type; @@ -665,8 +667,8 @@ void constas(Node*, Type*, Type*); void acom(Node*); void acom1(vlong, Node*); void acom2(Node*, Type*); -int acomcmp1(const void*, const void*); -int acomcmp2(const void*, const void*); +int acomcmp1(void*, void*); +int acomcmp2(void*, void*); int addo(Node*); void evconst(Node*); @@ -744,7 +746,7 @@ void gclean(void); void gextern(Sym*, Node*, long, long); void ginit(void); long outstring(char*, long); -long outlstring(ushort*, long); +long outlstring(Rune*, long); void sextern(Sym*, Node*, long, long); void xcom(Node*); long exreg(Type*); @@ -779,7 +781,7 @@ vlong convvtox(vlong, int); void prline(char*); void prstr(char *); -void prlstr(ushort *); +void prlstr(Rune *); void prkeywd(char *); void prid(char *); void prsym(Sym*, int); diff --git a/utils/c2l/cc.y b/utils/c2l/cc.y index 22dc6c0c..c66fdb4b 100644 --- a/utils/c2l/cc.y +++ b/utils/c2l/cc.y @@ -887,8 +887,8 @@ slstring: { $$ = new(OLSTRING, Z, Z); $$->type = typ(TARRAY, types[TUSHORT]); - $$->type->width = $1.l + sizeof(ushort); - $$->rstring = (ushort*)$1.s; + $$->type->width = $1.l + sizeof(TRune); + $$->rstring = (TRune*)$1.s; $$->sym = symstring; } @@ -902,19 +902,19 @@ lstring: char *s; int n1, n2; - n1 = $1->type->width - sizeof(ushort); - n2 = $2->type->width - sizeof(ushort); + n1 = $1->type->width - sizeof(TRune); + n2 = $2->type->width - sizeof(TRune); s = alloc(n1+n2+MAXALIGN); memcpy(s, $1->rstring, n1); memcpy(s+n1, $2->rstring, n2); - *(ushort*)(s+n1+n2) = 0; + *(TRune*)(s+n1+n2) = 0; $1->left = new(OCAT, ncopy($1), $2); $$ = $1; $$->type->width += n2; - $$->rstring = (ushort*)s; + $$->rstring = (TRune*)s; } zelist: diff --git a/utils/c2l/lex.c b/utils/c2l/lex.c index 574ecfc6..3525fbe3 100644 --- a/utils/c2l/lex.c +++ b/utils/c2l/lex.c @@ -266,7 +266,7 @@ void newio(void) { Io *i; - static pushdepth = 0; + static int pushdepth = 0; i = iofree; if(i == I) { @@ -1206,7 +1206,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } fmtinstall('f', gfltconv); diff --git a/utils/c2l/out.c b/utils/c2l/out.c index ab81a995..f4e0e560 100644 --- a/utils/c2l/out.c +++ b/utils/c2l/out.c @@ -603,7 +603,7 @@ prstr(char *s) } void -prlstr(ushort *s) +prlstr(Rune *s) { lprint("\""); while(*s != 0) diff --git a/utils/cc/acid.c b/utils/cc/acid.c index 3d898883..d42b47b4 100644 --- a/utils/cc/acid.c +++ b/utils/cc/acid.c @@ -2,7 +2,7 @@ static char *kwd[] = { - "$adt", "$aggr", "$append", "$complex", "$defn", + "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn", "$delete", "$do", "$else", "$eval", "$head", "$if", "$local", "$loop", "$return", "$tail", "$then", "$union", "$whatis", "$while", @@ -90,6 +90,8 @@ acidinit(void) if(types[TINT]->width != types[TSHORT]->width) warn(Z, "acidmember int not long or short"); } + if(types[TIND]->width == types[TUVLONG]->width) + acidchar[TIND] = 'Y'; } diff --git a/utils/cc/cc.h b/utils/cc/cc.h index 2813d25f..23b1c24b 100644 --- a/utils/cc/cc.h +++ b/utils/cc/cc.h @@ -17,17 +17,19 @@ typedef struct Term Term; typedef struct Init Init; typedef struct Bits Bits; +typedef Rune TRune; /* target system type */ + #define NHUNK 50000L #define BUFSIZ 8192 -#define NSYMB 500 +#define NSYMB 1500 #define NHASH 1024 #define STRINGSZ 200 #define HISTSZ 20 -#define YYMAXDEPTH 500 +#define YYMAXDEPTH 1500 #define NTERM 10 #define MAXALIGN 7 -#define SIGN(n) ((vlong)1<<(n-1)) +#define SIGN(n) ((uvlong)1<<(n-1)) #define MASK(n) (SIGN(n)|(SIGN(n)-1)) #define BITS 5 @@ -48,7 +50,7 @@ struct Node double fconst; /* fp constant */ vlong vconst; /* non fp const */ char* cstring; /* character string */ - ushort* rstring; /* rune string */ + TRune* rstring; /* rune string */ Sym* sym; Type* type; @@ -292,6 +294,7 @@ enum OINDEX, OFAS, OREGPAIR, + OEXREG, OEND }; @@ -333,6 +336,9 @@ enum TFILE, TOLD, NALLTYPES, + + /* adapt size of Rune to target system's size */ + TRUNE = sizeof(TRune)==4? TUINT: TUSHORT, }; enum { @@ -475,6 +481,7 @@ EXTERN int packflg; EXTERN int fproundflg; EXTERN int profileflg; EXTERN int ncontin; +EXTERN int newvlongcode; EXTERN int canreach; EXTERN int warnreach; EXTERN Bits zbits; @@ -504,6 +511,7 @@ extern char typechlv[]; extern char typechlvp[]; extern char typechlp[]; extern char typechlpfd[]; +EXTERN char* typeswitch; EXTERN char* typeword; EXTERN char* typecmplx; @@ -617,7 +625,7 @@ int rsametype(Type*, Type*, int, int); int sametype(Type*, Type*); ulong sign(Sym*); ulong signature(Type*); -void suallign(Type*); +void sualign(Type*); void tmerge(Type*, Sym*); void walkparam(Node*, int); void xdecl(int, Type*, Sym*); @@ -635,6 +643,8 @@ int tcomo(Node*, int); int tcomx(Node*); int tlvalue(Node*); void constas(Node*, Type*, Type*); +Node* uncomma(Node*); +Node* uncomargs(Node*); /* * con.c @@ -642,8 +652,8 @@ void constas(Node*, Type*, Type*); void acom(Node*); void acom1(vlong, Node*); void acom2(Node*, Type*); -int acomcmp1(const void*, const void*); -int acomcmp2(const void*, const void*); +int acomcmp1(void*, void*); +int acomcmp2(void*, void*); int addo(Node*); void evconst(Node*); @@ -657,6 +667,7 @@ void dclfunct(Type*, Sym*); * sub.c */ void arith(Node*, int); +int castucom(Node*); int deadheads(Node*); Type* dotsearch(Sym*, Type*, Node*, long*); long dotoffset(Type*, Type*, Node*); @@ -738,8 +749,7 @@ void gclean(void); void gextern(Sym*, Node*, long, long); void ginit(void); long outstring(char*, long); -long outlstring(ushort*, long); -void sextern(Sym*, Node*, long, long); +long outlstring(TRune*, long); void xcom(Node*); long exreg(Type*); long align(long, Type*, int); diff --git a/utils/cc/cc.y b/utils/cc/cc.y index 3057547b..8c9d09b1 100644 --- a/utils/cc/cc.y +++ b/utils/cc/cc.y @@ -8,12 +8,14 @@ struct { Type* t; - char c; + uchar c; } tycl; struct { Type* t1; Type* t2; + Type* t3; + uchar c; } tyty; struct { @@ -853,9 +855,9 @@ lstring: LLSTRING { $$ = new(OLSTRING, Z, Z); - $$->type = typ(TARRAY, types[TUSHORT]); - $$->type->width = $1.l + sizeof(ushort); - $$->rstring = (ushort*)$1.s; + $$->type = typ(TARRAY, types[TRUNE]); + $$->type->width = $1.l + sizeof(TRune); + $$->rstring = (TRune*)$1.s; $$->sym = symstring; $$->etype = TARRAY; $$->class = CSTATIC; @@ -865,16 +867,16 @@ lstring: char *s; int n; - n = $1->type->width - sizeof(ushort); + n = $1->type->width - sizeof(TRune); s = alloc(n+$2.l+MAXALIGN); memcpy(s, $1->rstring, n); memcpy(s+n, $2.s, $2.l); - *(ushort*)(s+n+$2.l) = 0; + *(TRune*)(s+n+$2.l) = 0; $$ = $1; $$->type->width += $2.l; - $$->rstring = (ushort*)s; + $$->rstring = (TRune*)s; } zelist: @@ -895,16 +897,22 @@ sbody: { $<tyty>$.t1 = strf; $<tyty>$.t2 = strl; + $<tyty>$.t3 = lasttype; + $<tyty>$.c = lastclass; strf = T; strl = T; lastbit = 0; firstbit = 1; + lastclass = CXXX; + lasttype = T; } edecl '}' { $$ = strf; strf = $<tyty>2.t1; strl = $<tyty>2.t2; + lasttype = $<tyty>2.t3; + lastclass = $<tyty>2.c; } zctlist: @@ -995,7 +1003,7 @@ complex: if($$->link != T) diag(Z, "redeclare tag: %s", $2->name); $$->link = $4; - suallign($$); + sualign($$); } | LSTRUCT sbody { @@ -1003,7 +1011,7 @@ complex: sprint(symb, "_%d_", taggen); $$ = dotag(lookup(), TSTRUCT, autobn); $$->link = $2; - suallign($$); + sualign($$); } | LUNION ltag { @@ -1020,7 +1028,7 @@ complex: if($$->link != T) diag(Z, "redeclare tag: %s", $2->name); $$->link = $4; - suallign($$); + sualign($$); } | LUNION sbody { @@ -1028,7 +1036,7 @@ complex: sprint(symb, "_%d_", taggen); $$ = dotag(lookup(), TUNION, autobn); $$->link = $2; - suallign($$); + sualign($$); } | LENUM ltag { diff --git a/utils/cc/com.c b/utils/cc/com.c index 59a7bd06..3a7f29d0 100644 --- a/utils/cc/com.c +++ b/utils/cc/com.c @@ -1,6 +1,15 @@ #include "cc.h" +typedef struct Com Com; +struct Com +{ + int n; + Node *t[500]; +}; + int compar(Node*, int); +static void comma(Node*); +static Node* commas(Com*, Node*); void complex(Node *n) @@ -15,6 +24,8 @@ complex(Node *n) prtree(n, "pre complex"); if(tcom(n)) return; + if(debug['y'] || 1) + comma(n); if(debug['t']) if(n->op != OCONST) prtree(n, "t complex"); @@ -56,6 +67,7 @@ tcomo(Node *n, int f) Node *l, *r; Type *t; int o; + static TRune zer; if(n == Z) { diag(Z, "Z in tcom"); @@ -273,8 +285,11 @@ tcomo(Node *n, int f) goto bad; n->type = l->type; if(n->type->etype == TIND) - if(n->type->link->width < 1) - diag(n, "inc/dec of a void pointer"); + if(n->type->link->width < 1) { + snap(n->type->link); + if(n->type->link->width < 1) + diag(n, "inc/dec of a void pointer"); + } break; case OEQ: @@ -610,6 +625,8 @@ tcomo(Node *n, int f) n->addable = 1; if(n->class == CEXREG) { n->op = OREGISTER; + if(thechar == '8') + n->op = OEXREG; n->reg = n->sym->offset; n->xoffset = 0; break; @@ -617,10 +634,10 @@ tcomo(Node *n, int f) break; case OLSTRING: - if(n->type->link != types[TUSHORT]) { + if(n->type->link != types[TRUNE]) { o = outstring(0, 0); while(o & 3) { - outlstring(L"", sizeof(ushort)); + outlstring(&zer, sizeof(TRune)); o = outlstring(0, 0); } } @@ -882,6 +899,101 @@ tlvalue(Node *n) } /* + * hoist comma operators out of expressions + * (a,b) OP c => (a, b OP c) + * OP(a,b) => (a, OP b) + * a OP (b,c) => (b, a OP c) + */ + +static Node* +comargs(Com *com, Node *n) +{ + if(n != Z && n->op == OLIST){ + n->left = comargs(com, n->left); + n->right = comargs(com, n->right); + } + return commas(com, n); +} + +static Node* +commas(Com *com, Node *n) +{ + Node *t; + + if(n == Z) + return n; + switch(n->op){ + case OREGISTER: + case OINDREG: + case OCONST: + case ONAME: + case OSTRING: + /* leaf */ + return n; + + case OCOMMA: + t = commas(com, n->left); + if(com->n >= nelem(com->t)) + fatal(n, "comma list overflow"); + com->t[com->n++] = t; + return commas(com, n->right); + + case OFUNC: + n->left = commas(com, n->left); + n->right = comargs(com, n->right); + return n; + + case OCOND: + n->left = commas(com, n->left); + comma(n->right->left); + comma(n->right->right); + return n; + + case OANDAND: + case OOROR: + n->left = commas(com, n->left); + comma(n->right); + return n; + + case ORETURN: + comma(n->left); + return n; + } + n->left = commas(com, n->left); + if(n->right != Z) + n->right = commas(com, n->right); + return n; +} + +static void +comma(Node *n) +{ + Com com; + Node *nn; + + com.n = 0; + nn = commas(&com, n); + if(com.n > 0){ +if(debug['y'])print("n=%d\n", com.n); +if(debug['y']) prtree(nn, "res"); + if(nn != n) + *n = *nn; + while(com.n > 0){ +if(debug['y']) prtree(com.t[com.n-1], "tree"); + nn = new1(OXXX, Z, Z); + *nn = *n; + n->op = OCOMMA; + n->type = nn->type; + n->left = com.t[--com.n]; + n->right = nn; + n->lineno = n->left->lineno; + } +if(debug['y']) prtree(n, "final"); + }else if(n != nn) + fatal(n, "odd tree"); +} + +/* * general rewrite * (IND(ADDR x)) ==> x * (ADDR(IND x)) ==> x @@ -928,13 +1040,16 @@ loop: break; case OCAST: + if(castucom(n)) + warn(n, "32-bit unsigned complement zero-extended to 64 bits"); ccom(l); if(l->op == OCONST) { evconst(n); if(n->op == OCONST) break; } - if(nocast(l->type, n->type)) { + if(nocast(l->type, n->type) && + (!typefd[l->type->etype] || typeu[l->type->etype] && typeu[n->type->etype])) { l->type = n->type; *n = *l; } @@ -1342,6 +1457,7 @@ useless: else snprint(cmpbuf, sizeof cmpbuf, "%T %s %s", lt, cmps[relindex(n->op)], xbuf); +if(debug['y']) prtree(n, "strange"); warn(n, "useless or misleading comparison: %s", cmpbuf); return 0; } diff --git a/utils/cc/com64.c b/utils/cc/com64.c index e1f7c8a3..f44a44ff 100644 --- a/utils/cc/com64.c +++ b/utils/cc/com64.c @@ -274,6 +274,8 @@ com64(Node *n) case ORETURN: case OAS: case OIND: + case OLIST: + case OCOMMA: return 1; case OADD: a = nodaddv; diff --git a/utils/cc/dcl.c b/utils/cc/dcl.c index 6a8e7245..c6b762a6 100644 --- a/utils/cc/dcl.c +++ b/utils/cc/dcl.c @@ -232,7 +232,7 @@ nextinit(void) a->cstring++; } if(a->op == OLSTRING) { - b->vconst = convvtox(*a->rstring, TUSHORT); + b->vconst = convvtox(*a->rstring, TRUNE); a->rstring++; } a->type->width -= b->type->width; @@ -519,7 +519,7 @@ newlist(Node *l, Node *r) } void -suallign(Type *t) +sualign(Type *t) { Type *l; long o, w; @@ -540,8 +540,8 @@ suallign(Type *t) } l->offset = o; } else { - if(l->width <= 0) - if(l->down != T) + if(l->width < 0 || + l->width == 0 && l->down != T) if(l->sym) diag(Z, "incomplete structure element: %s", l->sym->name); @@ -581,7 +581,7 @@ suallign(Type *t) return; default: - diag(Z, "unknown type in suallign: %T", t); + diag(Z, "unknown type in sualign: %T", t); break; } } diff --git a/utils/cc/dpchk.c b/utils/cc/dpchk.c index 99a49ee5..011f9c8a 100644 --- a/utils/cc/dpchk.c +++ b/utils/cc/dpchk.c @@ -75,9 +75,9 @@ getflag(char *s) nstar = 0; for(;;) { s += chartorune(&c, s); - fmt += runetochar(fmt, &c); if(c == 0 || c >= nelem(flagbits)) break; + fmt += runetochar(fmt, &c); f = flagbits[c]; switch(f) { case Fnone: diff --git a/utils/cc/lex.c b/utils/cc/lex.c index 8ba5af5a..9aae5c2b 100644 --- a/utils/cc/lex.c +++ b/utils/cc/lex.c @@ -80,7 +80,8 @@ main(int argc, char *argv[]) case 'I': p = ARGF(); - setinclude(p); + if(p) + setinclude(p); break; } ARGEND if(argc < 1 && outfile == 0) { @@ -242,14 +243,10 @@ compile(char *file, char **defs, int ndef) close(fd[1]); av[0] = CPP; i = 1; - if(debug['.']){ - sprint(opt, "-."); - av[i++] = strdup(opt); - } - if(debug['+']) { - sprint(opt, "-+"); - av[i++] = strdup(opt); - } + if(debug['.']) + av[i++] = strdup("-."); + /* 1999 ANSI C requires recognising // comments */ + av[i++] = strdup("-+"); for(c = 0; c < ndef; c++) { sprint(opt, "-D%s", defs[c]); av[i++] = strdup(opt); @@ -469,7 +466,7 @@ l1: yyerror("missing '"); peekc = c1; } - yylval.vval = convvtox(c, TUSHORT); + yylval.vval = convvtox(c, TRUNE); return LUCONST; } if(c == '"') { @@ -543,15 +540,15 @@ l1: c = escchar('"', 1, 0); if(c == EOF) break; - cp = allocn(cp, c1, sizeof(ushort)); - *(ushort*)(cp + c1) = c; - c1 += sizeof(ushort); + cp = allocn(cp, c1, sizeof(TRune)); + *(TRune*)(cp + c1) = c; + c1 += sizeof(TRune); } yylval.sval.l = c1; do { - cp = allocn(cp, c1, sizeof(ushort)); - *(ushort*)(cp + c1) = 0; - c1 += sizeof(ushort); + cp = allocn(cp, c1, sizeof(TRune)); + *(TRune*)(cp + c1) = 0; + c1 += sizeof(TRune); } while(c1 & MAXALIGN); yylval.sval.s = cp; return LLSTRING; @@ -1028,7 +1025,7 @@ getnsc(void) } else c = GETC(); for(;;) { - if(!isspace(c)) + if(c >= Runeself || !isspace(c)) return c; if(c == '\n') { lineno++; @@ -1072,7 +1069,7 @@ loop: */ i = 2; if(longflg) - i = 4; + i = 6; l = 0; for(; i>0; i--) { c = getc(); @@ -1102,7 +1099,7 @@ loop: */ i = 2; if(longflg) - i = 5; + i = 8; l = c - '0'; for(; i>0; i--) { c = getc(); @@ -1238,7 +1235,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } fmtinstall('O', Oconv); diff --git a/utils/cc/lexbody b/utils/cc/lexbody index 6b226ada..d8e3f6eb 100644 --- a/utils/cc/lexbody +++ b/utils/cc/lexbody @@ -417,8 +417,10 @@ l1: if(c1 == '/') { for(;;) { c = GETC(); - if(c == '\n') - goto l1; + if(c == '\n') { + lineno++; + goto l0; + } if(c == EOF) { yyerror("eof in comment"); errorexit(); diff --git a/utils/cc/macbody b/utils/cc/macbody index e26dc427..7c86bac1 100644 --- a/utils/cc/macbody +++ b/utils/cc/macbody @@ -25,7 +25,7 @@ getsym(void) char *cp; c = getnsc(); - if(!isalpha(c) && c != '_') { + if(!isalpha(c) && c != '_' && c < Runeself) { unget(c); return S; } @@ -33,7 +33,7 @@ getsym(void) if(cp <= symb+NSYMB-4) *cp++ = c; c = getc(); - if(isalnum(c) || c == '_') + if(isalnum(c) || c == '_' || c >= Runeself) continue; unget(c); break; diff --git a/utils/cc/pgen.c b/utils/cc/pgen.c index 131ff012..a5f67df2 100644 --- a/utils/cc/pgen.c +++ b/utils/cc/pgen.c @@ -70,8 +70,12 @@ codgen(Node *n, Node *nn) canreach = 1; warnreach = 1; gen(n); - if(canreach && thisfn->link->etype != TVOID) - warn(Z, "no return at end of function: %s", n1->sym->name); + if(canreach && thisfn->link->etype != TVOID){ + if(debug['B']) + warn(Z, "no return at end of function: %s", n1->sym->name); + else + diag(Z, "no return at end of function: %s", n1->sym->name); + } noretval(3); gbranch(ORETURN); @@ -105,10 +109,20 @@ supgen(Node *n) warnreach = owarn; } +Node* +uncomma(Node *n) +{ + while(n != Z && n->op == OCOMMA) { + cgen(n->left, Z); + n = n->right; + } + return n; +} + void gen(Node *n) { - Node *l, nod; + Node *l, nod, rn; Prog *sp, *spc, *spb; Case *cn; long sbc, scc; @@ -129,6 +143,7 @@ loop: case OLABEL: case OCASE: case OLIST: + case OCOMMA: case OBREAK: case OFOR: case OWHILE: @@ -151,6 +166,7 @@ loop: break; case OLIST: + case OCOMMA: gen(n->left); rloop: @@ -163,7 +179,7 @@ loop: complex(n); if(n->type == T) break; - l = n->left; + l = uncomma(n->left); if(l == Z) { noretval(3); gbranch(ORETURN); @@ -181,6 +197,20 @@ loop: gbranch(ORETURN); break; } + if(newvlongcode && !typefd[n->type->etype]){ + regret(&rn, n); + regfree(&rn); + nod = znode; + nod.op = OAS; + nod.left = &rn; + nod.right = l; + nod.type = n->type; + nod.complex = l->complex; + cgen(&nod, Z); + noretval(2); + gbranch(ORETURN); + break; + } regret(&nod, n); cgen(l, &nod); regfree(&nod); @@ -241,16 +271,15 @@ loop: complex(l); if(l->type == T) goto rloop; - if(l->op == OCONST) - if(typeword[l->type->etype] && l->type->etype != TIND) { - casf(); - cases->val = l->vconst; - cases->def = 0; - cases->label = pc; - cases->isv = typev[l->type->etype]; + if(l->op != OCONST || !typeswitch[l->type->etype]) { + diag(n, "case expression must be integer constant"); goto rloop; } - diag(n, "case expression must be integer constant"); + casf(); + cases->val = l->vconst; + cases->def = 0; + cases->label = pc; + cases->isv = typev[l->type->etype]; goto rloop; case OSWITCH: @@ -258,7 +287,7 @@ loop: complex(l); if(l->type == T) break; - if(!typeword[l->type->etype] || l->type->etype == TIND) { + if(!typeswitch[l->type->etype]) { diag(n, "switch expression must be integer"); break; } @@ -531,6 +560,8 @@ usedset(Node *n, int o) int bcomplex(Node *n, Node *c) { + Node *b, nod; + complex(n); if(n->type != T) @@ -542,6 +573,19 @@ bcomplex(Node *n, Node *c) } if(c != Z && n->op == OCONST && deadheads(c)) return 1; + if(newvlongcode && typev[n->type->etype] && machcap(Z)) { + nod = znode; + b = &nod; + b->op = ONE; + b->left = n; + b->right = new(0, Z, Z); + *b->right = *nodconst(0); + b->right->type = n->type; + b->type = types[TLONG]; + xcom(b); + boolgen(b, 1, Z); + return 0; + } bool64(n); boolgen(n, 1, Z); return 0; diff --git a/utils/cc/pickle.c b/utils/cc/pickle.c index ef8df4c0..1946b4e6 100644 --- a/utils/cc/pickle.c +++ b/utils/cc/pickle.c @@ -2,7 +2,7 @@ static char *kwd[] = { - "$adt", "$aggr", "$append", "$complex", "$defn", + "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn", "$delete", "$do", "$else", "$eval", "$head", "$if", "$local", "$loop", "$return", "$tail", "$then", "$union", "$whatis", "$while", diff --git a/utils/cc/pswt.c b/utils/cc/pswt.c index 6ef4f2fb..0471c10d 100644 --- a/utils/cc/pswt.c +++ b/utils/cc/pswt.c @@ -1,7 +1,7 @@ #include "gc.h" int -swcmp(const void *a1, const void *a2) +swcmp(void *a1, void *a2) { C1 *p1, *p2; @@ -16,8 +16,10 @@ void doswit(Node *n) { Case *c; - C1 *q, *iq; - long def, nc, i, isv; + C1 *q, *iq, *iqh, *iql; + long def, nc, i, j, isv, nh; + Prog *hsb; + Node *vr[2]; int dup; def = 0; @@ -33,14 +35,20 @@ doswit(Node *n) isv |= c->isv; nc++; } - if(isv && !typev[n->type->etype]) + if(typev[n->type->etype]) + isv = 1; + else if(isv){ warn(n, "32-bit switch expression with 64-bit case constant"); + isv = 0; + } iq = alloc(nc*sizeof(C1)); q = iq; for(c = cases; c->link != C; c = c->link) { if(c->def) continue; + if(c->isv && !isv) + continue; /* can never match */ q->label = c->label; if(isv) q->val = c->val; @@ -49,7 +57,7 @@ doswit(Node *n) q++; } qsort(iq, nc, sizeof(C1), swcmp); - if(debug['W']) + if(debug['K']) for(i=0; i<nc; i++) print("case %2ld: = %.8llux\n", i, (vlong)iq[i].val); dup = 0; @@ -64,7 +72,51 @@ doswit(Node *n) def = breakpc; nbreak++; } - swit1(iq, nc, def, n); + if(!isv || ewidth[TIND] > ewidth[TLONG] || n->op == OREGISTER) { + swit1(iq, nc, def, n); + return; + } + + /* + * 64-bit case on 32-bit machine: + * switch on high-order words, and + * in each of those, switch on low-order words + */ + if(n->op != OREGPAIR) + fatal(n, "internal: expected register pair"); + if(thechar == '8'){ /* TO DO: need an enquiry function */ + vr[0] = n->left; /* low */ + vr[1] = n->right; /* high */ + }else{ + vr[0] = n->right; + vr[1] = n->left; + } + vr[0]->type = types[TLONG]; + vr[1]->type = types[TLONG]; + gbranch(OGOTO); + hsb = p; + iqh = alloc(nc*sizeof(C1)); + iql = alloc(nc*sizeof(C1)); + nh = 0; + for(i=0; i<nc;){ + iqh[nh].val = iq[i].val >> 32; + q = iql; + /* iq is sorted, so equal top halves are adjacent */ + for(j = i; j < nc; j++){ + if((iq[j].val>>32) != iqh[nh].val) + break; + q->val = (long)iq[j].val; + q->label = iq[j].label; + q++; + } + qsort(iql, q-iql, sizeof(C1), swcmp); + iqh[nh].label = pc; + nh++; + swit1(iql, q-iql, def, vr[0]); + i = j; + } + patch(hsb, pc); + swit1(iqh, nh, def, vr[1]); } void @@ -78,28 +130,29 @@ casf(void) } long -outlstring(ushort *s, long n) +outlstring(TRune *s, long n) { - char buf[2]; - int c; + char buf[sizeof(TRune)]; + uint c; + int i; long r; if(suppress) return nstring; - while(nstring & 1) + while(nstring & (sizeof(TRune)-1)) outstring("", 1); r = nstring; while(n > 0) { c = *s++; if(align(0, types[TCHAR], Aarg1)) { - buf[0] = c>>8; - buf[1] = c; + for(i = 0; i < sizeof(TRune); i++) + buf[i] = c>>(8*(sizeof(TRune) - i - 1)); } else { - buf[0] = c; - buf[1] = c>>8; + for(i = 0; i < sizeof(TRune); i++) + buf[i] = c>>(8*i); } - outstring(buf, 2); - n -= sizeof(ushort); + outstring(buf, sizeof(TRune)); + n -= sizeof(TRune); } return r; } diff --git a/utils/cc/scon.c b/utils/cc/scon.c index f0c2bd13..0a15885c 100644 --- a/utils/cc/scon.c +++ b/utils/cc/scon.c @@ -309,7 +309,7 @@ acom(Node *n) } int -acomcmp1(const void *a1, const void *a2) +acomcmp1(void *a1, void *a2) { vlong c1, c2; Term *t1, *t2; @@ -340,7 +340,7 @@ acomcmp1(const void *a1, const void *a2) } int -acomcmp2(const void *a1, const void *a2) +acomcmp2(void *a1, void *a2) { vlong c1, c2; Term *t1, *t2; diff --git a/utils/cc/sub.c b/utils/cc/sub.c index 46e0cada..441b0c7f 100644 --- a/utils/cc/sub.c +++ b/utils/cc/sub.c @@ -85,7 +85,10 @@ prtree1(Node *n, int d, int f) break; case OLSTRING: - print(" \"%S\"", n->rstring); + if(sizeof(TRune) == sizeof(Rune)) + print(" \"%S\"", (Rune*)n->rstring); + else + print(" \"...\""); i = 0; break; @@ -914,6 +917,10 @@ loop: case ONOT: case OADDR: case OIND: + case OCOM: + case ONEG: + case OPOS: + case OTST: n = n->left; goto loop; @@ -1187,12 +1194,15 @@ warn(Node *n, char *fmt, ...) char buf[STRINGSZ]; va_list arg; - if(debug['w']) { - Bprint(&diagbuf, "warning: "); + if(debug['w'] || debug['W']) { va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); + if(debug['W']) { + diag(n, "%s", buf); + return; + } + Bprint(&diagbuf, "warning: %L %s\n", (n==Z)? nearln: n->lineno, buf); if(n != Z) if(debug['v']) @@ -1485,6 +1495,7 @@ Init onamesinit[] = OINDEX, 0, "INDEX", OFAS, 0, "FAS", OREGPAIR, 0, "REGPAIR", + OEXREG, 0, "EXREG", OEND, 0, "END", -1, 0, 0, }; @@ -1951,6 +1962,7 @@ tinit(void) /* 32-bit defaults */ typeword = typechlp; + typeswitch = typechl; typecmplx = typesuv; } @@ -2022,3 +2034,21 @@ mixedasop(Type *l, Type *r) { return !typefd[l->etype] && typefd[r->etype]; } + + +/* + * (uvlong)~ul creates a ul mask with top bits zero, which is usually wrong + * an explicit cast to ulong after ~ suppresses the diagnostic + */ +int +castucom(Node *r) +{ + Node *rl; + + if(r->op == OCAST && + (rl = r->left)->op == OCOM && + (r->type->etype == TVLONG || r->type->etype == TUVLONG) && + typeu[rl->type->etype] && typechl[rl->type->etype]) + return 1; + return 0; +} diff --git a/utils/include/a.out.h b/utils/include/a.out.h index 59077860..86c7d061 100644 --- a/utils/include/a.out.h +++ b/utils/include/a.out.h @@ -25,14 +25,15 @@ struct Exec #define E_MAGIC _MAGIC(0, 20) /* arm */ #define Q_MAGIC _MAGIC(0, 21) /* powerpc */ #define N_MAGIC _MAGIC(0, 22) /* mips 4000 LE */ -#define L_MAGIC _MAGIC(0, 23) /* dec alpha */ +#define L_MAGIC _MAGIC(0, 23) /* dec alpha (retired) */ #define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */ -#define U_MAGIC _MAGIC(0, 25) /* sparc64 */ +#define U_MAGIC _MAGIC(0, 25) /* sparc64 (retired) */ #define S_MAGIC _MAGIC(HDR_MAGIC, 26) /* amd64 */ #define T_MAGIC _MAGIC(HDR_MAGIC, 27) /* powerpc64 */ +#define R_MAGIC _MAGIC(HDR_MAGIC, 28) /* arm64 */ #define MIN_MAGIC 8 -#define MAX_MAGIC 27 /* <= 90 */ +#define MAX_MAGIC 28 /* <= 90 */ #define DYN_MAGIC 0x80000000 /* dlm */ diff --git a/utils/include/mach.h b/utils/include/mach.h index ea22b7e1..1c8d7a83 100644 --- a/utils/include/mach.h +++ b/utils/include/mach.h @@ -2,7 +2,7 @@ * Architecture-dependent application data */ #include "a.out.h" -#pragma src "/usr/inferno/utils/libmach" +#pragma src "/sys/src/libmach" #pragma lib "libmach.a" /* * Supported architectures: @@ -11,12 +11,11 @@ * i386, * amd64, * sparc, - * sparc64, * mips2 (R4000) * arm * powerpc, * powerpc64 - * alpha + * arm64 */ enum { @@ -31,11 +30,12 @@ enum M29000, /* retired */ MARM, MPOWER, - MALPHA, + MALPHA, /* retired */ NMIPS, - MSPARC64, + MSPARC64, /* retired */ MAMD64, MPOWER64, + MARM64, /* types of executables */ FNONE = 0, /* unidentified */ FMIPS, /* v.out */ @@ -57,14 +57,16 @@ enum FPOWER, /* q.out */ FPOWERB, /* power pc bootable */ FMIPS2LE, /* 0.out */ - FALPHA, /* 7.out */ - FALPHAB, /* DEC Alpha bootable */ + FALPHA, /* retired */ + FALPHAB, /* retired DEC Alpha bootable */ FMIPSLE, /* 3k little endian */ - FSPARC64, /* u.out */ + FSPARC64, /* retired */ FAMD64, /* 6.out */ FAMD64B, /* 6.out bootable */ FPOWER64, /* 9.out */ FPOWER64B, /* 9.out bootable */ + FARM64, /* arm64 */ + FARM64B, /* arm64 bootable */ ANONE = 0, /* dissembler types */ AMIPS, @@ -78,10 +80,11 @@ enum A29000, /* retired */ AARM, APOWER, - AALPHA, - ASPARC64, + AALPHA, /* retired */ + ASPARC64, /* retired */ AAMD64, APOWER64, + AARM64, /* object file types */ Obj68020 = 0, /* .2 */ ObjSparc, /* .k */ @@ -94,11 +97,12 @@ enum ObjArm, /* .5 */ ObjPower, /* .q */ ObjMips2le, /* .0 */ - ObjAlpha, /* .7 */ - ObjSparc64, /* .u */ + ObjAlpha, /* retired */ + ObjSparc64, /* retired */ ObjAmd64, /* .6 */ ObjSpim, /* .0 */ - ObjPower64, /* .9 */ + ObjPower64, /* .9 */ + ObjArm64, /* .4? */ Maxobjtype, CNONE = 0, /* symbol table classes */ @@ -113,11 +117,10 @@ enum typedef struct Map Map; typedef struct Symbol Symbol; typedef struct Reglist Reglist; -typedef struct Mach Mach; -typedef struct Machdata Machdata; - typedef struct segment segment; +typedef struct Mach Mach; +typedef struct Machdata Machdata; typedef int (*Rsegio)(segment*, ulong, long, char*, int); /* @@ -321,6 +324,4 @@ int syminit(int, Fhdr*); int symoff(char*, int, uvlong, int); void textseg(uvlong, Fhdr*); int textsym(Symbol*, int); -void thumbpctab(Biobuf*, Fhdr*); -int thumbpclookup(uvlong); void unusemap(Map*, int); diff --git a/utils/ka/lex.c b/utils/ka/lex.c index 39c8b507..1abf9c4a 100644 --- a/utils/ka/lex.c +++ b/utils/ka/lex.c @@ -483,7 +483,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } } diff --git a/utils/kc/gc.h b/utils/kc/gc.h index 1ff5a633..8f5de33c 100644 --- a/utils/kc/gc.h +++ b/utils/kc/gc.h @@ -255,7 +255,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void swit2(C1*, int, long, Node*, Node*); @@ -287,7 +287,7 @@ int Bconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); Bits mkvar(Adr*, int); diff --git a/utils/kc/list.c b/utils/kc/list.c index 3538c621..58b0611c 100644 --- a/utils/kc/list.c +++ b/utils/kc/list.c @@ -71,7 +71,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a <= AEND) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/kc/reg.c b/utils/kc/reg.c index 309827f7..3d97c34a 100644 --- a/utils/kc/reg.c +++ b/utils/kc/reg.c @@ -16,7 +16,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; diff --git a/utils/kc/swt.c b/utils/kc/swt.c index 05727dd8..14e155c9 100644 --- a/utils/kc/swt.c +++ b/utils/kc/swt.c @@ -235,22 +235,6 @@ loop: goto loop; } -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0)); - p->from.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} void gextern(Sym *s, Node *a, long o, long w) diff --git a/utils/kl/Nt.c b/utils/kl/Nt.c deleted file mode 100644 index 6be99a36..00000000 --- a/utils/kl/Nt.c +++ /dev/null @@ -1,88 +0,0 @@ -#include <windows.h> - -/* - * We can't include l.h, because Windoze wants to use some names - * like FLOAT which we declare. Define what we need here. - */ -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned long ulong; - -extern char *hunk; -extern long nhunk; - -void gethunk(void); - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/kl/Plan9.c b/utils/kl/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/kl/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/kl/Posix.c b/utils/kl/Posix.c deleted file mode 100644 index 7c3a661f..00000000 --- a/utils/kl/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fials if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} diff --git a/utils/kl/l.h b/utils/kl/l.h index c036e14d..7a2f02ae 100644 --- a/utils/kl/l.h +++ b/utils/kl/l.h @@ -305,7 +305,7 @@ void nocache(Prog*); void noops(void); void nuxiinit(void); void objfile(char*); -int ocmp(const void*, const void*); +int ocmp(void*, void*); long opcode(int); Optab* oplook(Prog*); void patch(void); diff --git a/utils/kl/list.c b/utils/kl/list.c index 00fcb7ee..214da7e4 100644 --- a/utils/kl/list.c +++ b/utils/kl/list.c @@ -59,7 +59,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a <= ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/kl/mkfile b/utils/kl/mkfile index cf406d8f..fd44f0d3 100644 --- a/utils/kl/mkfile +++ b/utils/kl/mkfile @@ -1,6 +1,6 @@ <../../mkconfig -CFLAGS=$CFLAGS -I../include +CFLAGS=$CFLAGS -I../include -I. TARG=kl @@ -29,3 +29,6 @@ BIN=$ROOT/$OBJDIR/bin enam.$O: ../kc/enam.c $CC $CFLAGS ../kc/enam.c + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/kl/span.c b/utils/kl/span.c index a788b8d3..28a66dd4 100644 --- a/utils/kl/span.c +++ b/utils/kl/span.c @@ -335,7 +335,7 @@ cmp(int a, int b) } int -ocmp(const void *a1, const void *a2) +ocmp(void *a1, void *a2) { Optab *p1, *p2; int n; diff --git a/utils/ql/Nt.c b/utils/ld/Nt.c index c6748abd..938664c2 100644 --- a/utils/ql/Nt.c +++ b/utils/ld/Nt.c @@ -86,3 +86,15 @@ cputime(void) { return ((double)0); } + +int +fileexists(char *name) +{ + int fd; + + fd = open(f, OREAD); + if(fd < 0) + return 0; + close(fd); + return 1; +} diff --git a/utils/2l/Plan9.c b/utils/ld/Plan9.c index f4cf23f4..ef08b158 100644 --- a/utils/2l/Plan9.c +++ b/utils/ld/Plan9.c @@ -55,3 +55,12 @@ void setmalloctag(void*, ulong) { } + +int +fileexists(char *s) +{ + uchar dirbuf[400]; + + /* it's fine if stat result doesn't fit in dirbuf, since even then the file exists */ + return stat(s, dirbuf, sizeof(dirbuf)) >= 0; +} diff --git a/utils/8l/Posix.c b/utils/ld/Posix.c index 0da0ee0c..a1a2a8c9 100644 --- a/utils/8l/Posix.c +++ b/utils/ld/Posix.c @@ -1,5 +1,6 @@ #include "l.h" #include <sys/types.h> +#include <sys/stat.h> #include <sys/times.h> #undef getwd #include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ @@ -78,3 +79,11 @@ cputime(void) return ret_val; } + +int +fileexists(char *name) +{ + struct stat sb; + + return stat(name, &sb) >= 0; +} diff --git a/utils/ld/elf.c b/utils/ld/elf.c new file mode 100644 index 00000000..2b25c57c --- /dev/null +++ b/utils/ld/elf.c @@ -0,0 +1,266 @@ +/* + * emit 32- or 64-bit elf headers for any architecture. + * this is a component of ?l. + */ +#include "l.h" + +enum { + /* offsets into string table */ + Stitext = 1, + Stidata = 7, + Stistrtab = 13, +}; + +void +elfident(int bo, int class) +{ + strnput("\177ELF", 4); /* e_ident */ + cput(class); + cput(bo); /* byte order */ + cput(1); /* version = CURRENT */ + if(debug['k']){ /* boot/embedded/standalone */ + cput(255); + cput(0); + } + else{ + cput(0); /* osabi = SYSV */ + cput(0); /* abiversion = 3 */ + } + strnput("", 7); +} + +void +elfstrtab(void) +{ + /* string table */ + cput(0); + strnput(".text", 5); /* +1 */ + cput(0); + strnput(".data", 5); /* +7 */ + cput(0); + strnput(".strtab", 7); /* +13 */ + cput(0); + cput(0); +} + +void +elf32phdr(void (*putl)(long), ulong type, ulong off, ulong vaddr, ulong paddr, + ulong filesz, ulong memsz, ulong prots, ulong align) +{ + putl(type); + putl(off); + putl(vaddr); + putl(paddr); + putl(filesz); + putl(memsz); + putl(prots); + putl(align); +} + +void +elf32shdr(void (*putl)(long), ulong name, ulong type, ulong flags, ulong vaddr, + ulong off, ulong sectsz, ulong link, ulong addnl, ulong align, + ulong entsz) +{ + putl(name); + putl(type); + putl(flags); + putl(vaddr); + putl(off); + putl(sectsz); + putl(link); + putl(addnl); + putl(align); + putl(entsz); +} + +static void +elf32sectab(void (*putl)(long)) +{ + seek(cout, HEADR+textsize+datsize+symsize, 0); + elf32shdr(putl, Stitext, Progbits, Salloc|Sexec, INITTEXT, + HEADR, textsize, 0, 0, 0x10000, 0); + elf32shdr(putl, Stidata, Progbits, Salloc|Swrite, INITDAT, + HEADR+textsize, datsize, 0, 0, 0x10000, 0); + elf32shdr(putl, Stistrtab, Strtab, 1 << 5, 0, + HEADR+textsize+datsize+symsize+3*Shdr32sz, 14, 0, 0, 1, 0); + elfstrtab(); +} + +/* if addpsects > 0, putpsects must emit exactly that many psects. */ +void +elf32(int mach, int bo, int addpsects, void (*putpsects)(Putl)) +{ + ulong phydata; + void (*putw)(long), (*putl)(long); + + if(bo == ELFDATA2MSB){ + putw = wput; + putl = lput; + }else if(bo == ELFDATA2LSB){ + putw = wputl; + putl = lputl; + }else{ + print("elf32 byte order is mixed-endian\n"); + errorexit(); + return; + } + + elfident(bo, ELFCLASS32); + putw(EXEC); + putw(mach); + putl(1L); /* version = CURRENT */ + putl(entryvalue()); /* entry vaddr */ + putl(Ehdr32sz); /* offset to first phdr */ + if(debug['S']) + putl(HEADR+textsize+datsize+symsize); /* offset to first shdr */ + else + putl(0); + putl(0L); /* flags */ + putw(Ehdr32sz); + putw(Phdr32sz); + putw(3 + addpsects); /* # of Phdrs */ + putw(Shdr32sz); + if(debug['S']){ + putw(3); /* # of Shdrs */ + putw(2); /* Shdr table index */ + }else{ + putw(0); + putw(0); + } + + /* + * could include ELF headers in text -- 8l doesn't, + * but in theory it aids demand loading. + */ + elf32phdr(putl, PT_LOAD, HEADR, INITTEXT, INITTEXTP, + textsize, textsize, R|X, INITRND); /* text */ + /* + * we need INITDATP, but it has to be computed. + * assume distance between INITTEXT & INITTEXTP is also + * correct for INITDAT and INITDATP. + */ + phydata = INITDAT - (INITTEXT - INITTEXTP); + elf32phdr(putl, PT_LOAD, HEADR+textsize, INITDAT, phydata, + datsize, datsize+bsssize, R|W|X, INITRND); /* data */ + elf32phdr(putl, NOPTYPE, HEADR+textsize+datsize, 0, 0, + symsize, lcsize, R, 4); /* symbol table */ + if (addpsects > 0) + putpsects(putl); + cflush(); + + if(debug['S']) + elf32sectab(putl); +} + +/* + * elf64 + */ + +void +elf64phdr(void (*putl)(long), void (*putll)(vlong), ulong type, uvlong off, + uvlong vaddr, uvlong paddr, uvlong filesz, uvlong memsz, ulong prots, + uvlong align) +{ + putl(type); + putl(prots); + putll(off); + putll(vaddr); + putll(paddr); + putll(filesz); + putll(memsz); + putll(align); +} + +void +elf64shdr(void (*putl)(long), void (*putll)(vlong), ulong name, ulong type, + uvlong flags, uvlong vaddr, uvlong off, uvlong sectsz, ulong link, + ulong addnl, uvlong align, uvlong entsz) +{ + putl(name); + putl(type); + putll(flags); + putll(vaddr); + putll(off); + putll(sectsz); + putl(link); + putl(addnl); + putll(align); + putll(entsz); +} + +static void +elf64sectab(void (*putl)(long), void (*putll)(vlong)) +{ + seek(cout, HEADR+textsize+datsize+symsize, 0); + elf64shdr(putl, putll, Stitext, Progbits, Salloc|Sexec, INITTEXT, + HEADR, textsize, 0, 0, 0x10000, 0); + elf64shdr(putl, putll, Stidata, Progbits, Salloc|Swrite, INITDAT, + HEADR+textsize, datsize, 0, 0, 0x10000, 0); + elf64shdr(putl, putll, Stistrtab, Strtab, 1 << 5, 0, + HEADR+textsize+datsize+symsize+3*Shdr64sz, 14, 0, 0, 1, 0); + elfstrtab(); +} + +/* if addpsects > 0, putpsects must emit exactly that many psects. */ +void +elf64(int mach, int bo, int addpsects, void (*putpsects)(Putl)) +{ + uvlong phydata; + void (*putw)(long), (*putl)(long); + void (*putll)(vlong); + + if(bo == ELFDATA2MSB){ + putw = wput; + putl = lput; + putll = llput; + }else if(bo == ELFDATA2LSB){ + putw = wputl; + putl = lputl; + putll = llputl; + }else{ + print("elf64 byte order is mixed-endian\n"); + errorexit(); + return; + } + + elfident(bo, ELFCLASS64); + putw(EXEC); + putw(mach); + putl(1L); /* version = CURRENT */ + putll(entryvalue()); /* entry vaddr */ + putll(Ehdr64sz); /* offset to first phdr */ + if(debug['S']) + putll(HEADR+textsize+datsize+symsize); /* offset to 1st shdr */ + else + putll(0); + putl(0L); /* flags */ + putw(Ehdr64sz); + putw(Phdr64sz); + putw(3 + addpsects); /* # of Phdrs */ + putw(Shdr64sz); + if(debug['S']){ + putw(3); /* # of Shdrs */ + putw(2); /* Shdr table index */ + }else{ + putw(0); + putw(0); + } + + elf64phdr(putl, putll, PT_LOAD, HEADR, INITTEXT, INITTEXTP, + textsize, textsize, R|X, INITRND); /* text */ + /* + * see 32-bit ELF case for physical data address computation. + */ + phydata = INITDAT - (INITTEXT - INITTEXTP); + elf64phdr(putl, putll, PT_LOAD, HEADR+textsize, INITDAT, phydata, + datsize, datsize+bsssize, R|W, INITRND); /* data */ + elf64phdr(putl, putll, NOPTYPE, HEADR+textsize+datsize, 0, 0, + symsize, lcsize, R, 4); /* symbol table */ + if (addpsects > 0) + putpsects(putl); + cflush(); + + if(debug['S']) + elf64sectab(putl, putll); +} diff --git a/utils/libmach/2.c b/utils/libmach/2.c deleted file mode 100644 index 9d58b00b..00000000 --- a/utils/libmach/2.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 68020 definition - */ -#include <lib9.h> -#include "ureg2.h" -#include <bio.h> -#include "mach.h" - -#define MAXREG 0 -#define MINREG 0 - -#define REGOFF(x) (ulong)(&((struct Ureg *) 0)->x) - -#define VO REGOFF(vo) /* vo, 2 bytes */ -#define SR REGOFF(sr) /* sr, 2 bytes */ -#define R0 REGOFF(r0) -#define PC REGOFF(pc) -#define DBMAGIC REGOFF(magic) -#define SP REGOFF(usp) - -#define REGSIZE (R0+4) -#define FCTL(x) (REGSIZE+(x)*4) -#define FREG(x) (FCTL(3)+(x)*12) -#define FPREGSIZE (11*12) - -/* - * 68020 register set - */ -Reglist m68020reglist[] = { - {"VO", VO, RINT, 'x'}, - {"SR", SR, RINT, 'x'}, - {"MAGIC", DBMAGIC, RINT, 'X'}, - {"PC", PC, RINT, 'X'}, - {"A7", SP, RINT, 'X'}, - {"KSP", REGOFF(sp), RINT, 'X'}, - {"A6", REGOFF(a6), RINT, 'X'}, - {"A5", REGOFF(a5), RINT, 'X'}, - {"A4", REGOFF(a4), RINT, 'X'}, - {"A3", REGOFF(a3), RINT, 'X'}, - {"A2", REGOFF(a2), RINT, 'X'}, - {"A1", REGOFF(a1), RINT, 'X'}, - {"A0", REGOFF(a0), RINT, 'X'}, - {"R7", REGOFF(r7), RINT, 'X'}, - {"R6", REGOFF(r6), RINT, 'X'}, - {"R5", REGOFF(r5), RINT, 'X'}, - {"R4", REGOFF(r4), RINT, 'X'}, - {"R3", REGOFF(r3), RINT, 'X'}, - {"R2", REGOFF(r2), RINT, 'X'}, - {"R1", REGOFF(r1), RINT, 'X'}, - {"R0", REGOFF(r0), RINT, 'X'}, - {"FPCR", FCTL(0), RFLT, 'X'}, - {"FPSR", FCTL(1), RFLT, 'X'}, - {"FPIAR", FCTL(2), RFLT, 'X'}, - {"F0", FREG(0), RFLT, '8'}, - {"F1", FREG(1), RFLT, '8'}, - {"F2", FREG(2), RFLT, '8'}, - {"F3", FREG(3), RFLT, '8'}, - {"F4", FREG(4), RFLT, '8'}, - {"F5", FREG(5), RFLT, '8'}, - {"F6", FREG(6), RFLT, '8'}, - {"F7", FREG(7), RFLT, '8'}, - {0} -}; - -Mach m68020 = -{ - "68020", - M68020, /* machine type */ - m68020reglist, /* register list */ - REGSIZE, /* number of bytes in reg set */ - FPREGSIZE, /* number of bytes in fp reg set */ - "PC", - "A7", - 0, /* link register */ - "a6base", /* static base register name */ - 0, /* value */ - 0x2000, /* page size */ - 0x80000000U, /* kernel base */ - 0x80000000U, /* kernel text mask */ - 0x7FFFFFFFU, /* user stack top */ - 2, /* quantization of pc */ - 4, /* szaddr */ - 4, /* szreg */ - 4, /* szfloat */ - 8, /* szdouble */ -}; diff --git a/utils/libmach/2db.c b/utils/libmach/2db.c deleted file mode 100644 index 284df3c5..00000000 --- a/utils/libmach/2db.c +++ /dev/null @@ -1,2088 +0,0 @@ -#include <lib9.h> -#include <bio.h> -#include <mach.h> - -/* - * 68020-specific debugger interface - */ - -static char *m68020excep(Map*, Rgetter); - -static int m68020foll(Map*, uvlong, Rgetter, uvlong*); -static int m68020inst(Map*, uvlong, char, char*, int); -static int m68020das(Map*, uvlong, char*, int); -static int m68020instlen(Map*, uvlong); - -Machdata m68020mach = -{ - {0x48,0x48,0,0}, /* break point #0 instr. */ - 2, /* size of break point instr. */ - - beswab, /* convert short to local byte order */ - beswal, /* convert long to local byte order */ - beswav, /* convert vlong to local byte order */ - cisctrace, /* C traceback */ - ciscframe, /* frame finder */ - m68020excep, /* print exception */ - 0, /* breakpoint fixup */ - beieeesftos, - beieeedftos, - m68020foll, /* follow-set calculation */ - m68020inst, /* print instruction */ - m68020das, /* dissembler */ - m68020instlen, /* instruction size */ -}; - -/* - * 68020 exception frames - */ - -#define BPTTRAP 4 /* breakpoint gives illegal inst */ - -static char * excep[] = { - 0, /* 0 */ - 0, /* 1 */ - "bus error", /* 2 */ - "address error", /* 3 */ - "illegal instruction", /* 4 */ - "zero divide", /* 5 */ - "CHK", /* 6 */ - "TRAP", /* 7 */ - "privilege violation", /* 8 */ - "Trace", /* 9 */ - "line 1010", /* 10 */ - "line 1011", /* 11 */ - 0, /* 12 */ - "coprocessor protocol violation", /* 13 */ - 0,0,0,0,0,0,0,0,0,0, /* 14-23 */ - "spurious", /* 24 */ - "incon", /* 25 */ - "tac", /* 26 */ - "auto 3", /* 27 */ - "clock", /* 28 */ - "auto 5", /* 29 */ - "parity", /* 30 */ - "mouse", /* 31 */ - "system call", /* 32 */ - "system call 1", /* 33 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 34-47 */ - "FPCP branch", /* 48 */ - "FPCP inexact", /* 49 */ - "FPCP zero div", /* 50 */ - "FPCP underflow", /* 51 */ - "FPCP operand err", /* 52 */ - "FPCP overflow", /* 53 */ - "FPCP signal NAN", /* 54 */ -}; - -static int m68020vec; -static -struct ftype{ - short fmt; - short len; - char *name; -} ftype[] = { /* section 6.5.7 page 6-24 */ - { 0, 4*2, "Short Format" }, - { 1, 4*2, "Throwaway" }, - { 2, 6*2, "Instruction Exception" }, - { 3, 6*2, "MC68040 Floating Point Exception" }, - { 8, 29*2, "MC68010 Bus Fault" }, - { 7, 30*2, "MC68040 Bus Fault" }, - { 9, 10*2, "Coprocessor mid-Instruction" }, - { 10, 16*2, "MC68020 Short Bus Fault" }, - { 11, 46*2, "MC68020 Long Bus Fault" }, - { 0, 0, 0 } -}; - -static int -m68020ufix(Map *map) -{ - struct ftype *ft; - int i, size, vec; - ulong efl[2]; - uchar *ef=(uchar*)efl; - ulong l; - uvlong stktop; - short fvo; - - /* The kernel proc pointer on a 68020 is always - * at #8xxxxxxx; on the 68040 NeXT, the address - * is always #04xxxxxx. the sun3 port at sydney - * uses 0xf8xxxxxx to 0xffxxxxxx. - */ - m68020vec = 0; - - if (get4(map, mach->kbase, (&l)) < 0) - return -1; - if ((l&0xfc000000) == 0x04000000) /* if NeXT */ - size = 30*2; - else - size = 46*2; /* 68020 */ - USED(size); - - stktop = mach->kbase+mach->pgsize; - for(i=3; i<100; i++){ - if (get1(map, stktop-i*4, (uchar*)&l, 4)< 0) - return -1; - - if(machdata->swal(l) == 0xBADC0C0A){ - if (get1(map, stktop-(i-1)*4, (uchar *)&efl[0], 4) < 0) - return -1; - if (get1(map, stktop-(i-2)*4, (uchar *)&efl[1], 4) < 0) - return -1; - fvo = (ef[6]<<8)|ef[7]; - vec = fvo & 0xfff; - vec >>= 2; - if(vec >= 256) - continue; - - for(ft=ftype; ft->name; ft++) { - if(ft->fmt == ((fvo>>12) & 0xF)){ - m68020vec = vec; - return 1; - } - } - break; - } - } - return -1; -} - -static char * -m68020excep(Map *map, Rgetter rget) -{ - uvlong pc; - uchar buf[4]; - - if (m68020ufix(map) < 0) - return "bad exception frame"; - - if(excep[m68020vec] == 0) - return "bad exeception type"; - - if(m68020vec == BPTTRAP) { - pc = (*rget)(map, "PC"); - if (get1(map, pc, buf, machdata->bpsize) > 0) - if(memcmp(buf, machdata->bpinst, machdata->bpsize) == 0) - return "breakpoint"; - } - return excep[m68020vec]; -} - /* 68020 Disassembler and related functions */ -/* -not supported: cpBcc, cpDBcc, cpGEN, cpScc, cpTRAPcc, cpRESTORE, cpSAVE - -opcode: 1 1 1 1 1 1 - 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -%y - register number x x x -%f - trap vector x x x -%e - destination eff addr x x x x x x -%p - conditional predicate x x x x x x -%s - size code x x -%C - cache code x x -%E - source eff addr. x x x x x x -%d - direction bit x -%c - condition code x x x x -%x - register number x x x -%b - shift count x x x -%q - daffy 3-bit quick operand or shift count x x x -%i - immediate operand <varies> -%t - offset(PC) <varies> - -word 1: 1 1 1 1 1 1 - 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -%a - register number x x x -%w - bit field width x x x x x -%L - MMU function code (SFC/DFC/D%a/#[0-3]) x x x x x -%P - conditional predicate x x x x x x -%k - k factor x x x x x x x -%m - register mask x x x x x x x x -%N - control register id x x x x x x x x x x x x -%j - (Dq != Dr) ? Dq:Dr : Dr x x x x x x -%K - dynamic k register x x x -%h - register number x x x -%I - MMU function code mask x x x x -%o - bit field offset x x x x x -%u - register number x x x -%D - float dest reg x x x -%F - (fdr==fsr) ? "F%D" :"F%B,F%D" x x x x x x -%S - float source type x x x -%B - float source register x x x -%Z - ATC level number x x x -%H - MMU register x x x x -%r - register type/number x x x x - -word 2: 1 1 1 1 1 1 - 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -%A - register number x x x -%U - register number x x x -%R - register type,number x x x x - ------------------------------------------------------------------------------ - -%a - register [word 1: 0-2] -%c - condition code [opcode: 8-11] -%d - direction [opcode: 8] -%e - destination effective address [opcode: 0-5] -%f - trap vector [opcode: 0-3] -%h - register [word 1: 5-7] -%i - immediate operand (1, 2, or 4 bytes) -%j - Dq:Dr if Dq != Dr; else Dr => Dr [word 1: 0-2] Dq [word 1: 12-14] -%k - k factor [word 1: 0-6] -%m - register mask [word 1: 0-7] -%o - bit field offset [word 1: 6-10] -%p - conditional predicate [opcode: 0-5] -%q - daffy 3-bit quick operand [opcode: 9-11] -%r - register type, [word 1: 15], register [word 1: 12-14] -%s - size [opcode: 6-7] -%t - offset beyond pc (text address) (2 or 4 bytes) -%u - register [word 1: 6-8] -%w - bit field width [word 1: 0-4] -%x - register [opcode: 9-11] -%y - register [opcode: 0-2] -%A - register [word 2: 0-2] -%B - float source register [word 1: 10-12] -%C - cache identifier [opcode: 6-7] (IC, DC, or BC) -%D - float dest reg [word 1: 7-9] -%E - dest effective address [opcode: 6-11] -%F - float dest reg == float src reg => "F%D"; else "F%B,F%D" -%H - MMU reg [word 1: 10-13] (see above & p 4-53/54) -%I - MMU function code mask [word 1: 5-8] -%K - dynamic k factor register [word 1: 4-6] -%L - MMU function code [word 1: 0-4] (SFC, DFC, D%a, or #[0-3]) -%N - control register [word 1: 0-11] -%P - conditional predicate [word 1: 0-5] -%R - register type, [word 2: 15], register [word 2: 12-14] -%S - float source type code [word 1: 10-12] -%U - register [word 2: 6-8] -%Z - ATC level number [word 1: 10-12] -%1 - Special case: EA as second operand -*/ - /* Operand classes */ -enum { - EAPI = 1, /* extended address: pre decrement only */ - EACA, /* extended address: control alterable */ - EACAD, /* extended address: control alterable or Dreg */ - EACAPI, /* extended address: control alterable or post-incr */ - EACAPD, /* extended address: control alterable or pre-decr */ - EAMA, /* extended address: memory alterable */ - EADA, /* extended address: data alterable */ - EAA, /* extended address: alterable */ - EAC, /* extended address: control addressing */ - EACPI, /* extended address: control addressing or post-incr */ - EACD, /* extended address: control addressing or Dreg */ - EAD, /* extended address: data addressing */ - EAM, /* extended address: memory addressing */ - EAM_B, /* EAM with byte immediate data */ - EADI, /* extended address: data addressing or immediate */ - EADI_L, /* EADI with long immediate data */ - EADI_W, /* EADI with word immediate data */ - EAALL, /* extended address: all modes */ - EAALL_L, /* EAALL with long immediate data */ - EAALL_W, /* EAALL with word immediate data */ - EAALL_B, /* EAALL with byte immediate date */ - /* special codes not directly used for validation */ - EAFLT, /* extended address: EADI for B, W, L, or S; else EAM */ - EADDA, /* destination extended address: EADA */ - BREAC, /* EAC operand for JMP or CALL */ - OP8, /* low 8 bits of op word */ - I8, /* low 8-bits of first extension word */ - I16, /* 16 bits in first extension word */ - I32, /* 32 bits in first and second extension words */ - IV, /* 8, 16 or 32 bit data in first & 2nd extension words */ - C16, /* CAS2 16 bit immediate with bits 9-11 & 3-5 zero */ - BR8, /* 8 bits in op word or 16 or 32 bits in extension words - branch instruction format (p. 2-25) */ - BR16, /* 16-bit branch displacement */ - BR32, /* 32-bit branch displacement */ - STACK, /* return PC on stack - follow set only */ -}; - /* validation bit masks for various EA classes */ -enum { - Dn = 0x0001, /* Data register */ - An = 0x0002, /* Address register */ - Ind = 0x0004, /* Address register indirect */ - Pinc = 0x0008, /* Address register indirect post-increment */ - Pdec = 0x0010, /* Address register indirect pre-decrement */ - Bdisp = 0x0020, /* Base/Displacement in all its forms */ - PCrel = 0x0040, /* PC relative addressing in all its forms */ - Imm = 0x0080, /* Immediate data */ - Abs = 0x0100, /* Absolute */ -}; - /* EA validation table indexed by operand class number */ - -static short validea[] = -{ - 0, /* none */ - Pdec, /* EAPI */ - Abs|Bdisp|Ind, /* EACA */ - Abs|Bdisp|Ind|Dn, /* EACAD */ - Abs|Bdisp|Pinc|Ind, /* EACAPI */ - Abs|Bdisp|Pdec|Ind, /* EACAPD */ - Abs|Bdisp|Pdec|Pinc|Ind, /* EAMA */ - Abs|Bdisp|Pdec|Pinc|Ind|Dn, /* EADA */ - Abs|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAA */ - Abs|PCrel|Bdisp|Ind, /* EAC */ - Abs|PCrel|Bdisp|Pinc|Ind, /* EACPI */ - Abs|PCrel|Bdisp|Ind|Dn, /* EACD */ - Abs|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EAD */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind, /* EAM */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind, /* EAM_B */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EADI */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EADI_L */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EADI_W */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL_L */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL_W */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL_B */ -}; - /* EA types */ -enum -{ - Dreg, /* Dn */ - Areg, /* An */ - AInd, /* (An) */ - APdec, /* -(An) */ - APinc, /* (An)+ */ - ADisp, /* Displacement beyond (An) */ - BXD, /* Base, Index, Displacement */ - PDisp, /* Displacement beyond PC */ - PXD, /* PC, Index, Displacement */ - ABS, /* absolute */ - IMM, /* immediate */ - IREAL, /* single precision real immediate */ - IEXT, /* extended precision real immediate */ - IPACK, /* packed real immediate */ - IDBL, /* double precision real immediate */ -}; - -typedef struct optable Optable; -typedef struct operand Operand; -typedef struct inst Inst; - -struct optable -{ - ushort opcode; - ushort mask0; - ushort op2; - ushort mask1; - char opdata[2]; - char *format; -}; - -struct operand -{ - int eatype; - short ext; - /*union {*/ - long immediate; /* sign-extended integer byte/word/long */ - /*struct {*/ /* index mode displacements */ - long disp; - long outer; - /*};*/ - char floater[24]; /* floating point immediates */ - /*};*/ -}; - -struct inst -{ - int n; /* # bytes in instruction */ - uvlong addr; /* addr of start of instruction */ - ushort raw[4+12]; /* longest instruction: 24 byte packed immediate */ - Operand and[2]; - char *end; /* end of print buffer */ - char *curr; /* current fill point in buffer */ - char *errmsg; -}; - /* class 0: bit field, MOVEP & immediate instructions */ -static Optable t0[] = { -{ 0x003c, 0xffff, 0x0000, 0xff00, {I8}, "ORB %i,CCR" }, -{ 0x007c, 0xffff, 0x0000, 0x0000, {I16}, "ORW %i,SR" }, -{ 0x023c, 0xffff, 0x0000, 0xff00, {I8}, "ANDB %i,CCR" }, -{ 0x027c, 0xffff, 0x0000, 0x0000, {I16}, "ANDW %i,SR" }, -{ 0x0a3c, 0xffff, 0x0000, 0xff00, {I8}, "EORB %i,CCR" }, -{ 0x0a7c, 0xffff, 0x0000, 0x0000, {I16}, "EORW %i,SR" }, -{ 0x0cfc, 0xffff, 0x0000, 0x0000, {C16,C16}, "CAS2W R%a:R%A,R%u:R%U,(%r):(%R)"} , -{ 0x0efc, 0xffff, 0x0000, 0x0000, {C16,C16}, "CAS2L R%a:R%A,R%u:R%U,(%r):(%R)"} , - -{ 0x06c0, 0xfff8, 0x0000, 0x0000, {0}, "RTM R%y" }, -{ 0x06c8, 0xfff8, 0x0000, 0x0000, {0}, "RTM A%y" }, -{ 0x0800, 0xfff8, 0x0000, 0x0000, {I16}, "BTSTL %i,R%y" }, -{ 0x0840, 0xfff8, 0x0000, 0x0000, {I16}, "BCHGL %i,R%y" }, -{ 0x0880, 0xfff8, 0x0000, 0x0000, {I16}, "BCLRL %i,R%y" }, - -{ 0x00c0, 0xffc0, 0x0000, 0x0fff, {EAC}, "CMP2B %e,%r" }, -{ 0x00c0, 0xffc0, 0x0800, 0x0fff, {EAC}, "CHK2B %e,%r" }, -{ 0x02c0, 0xffc0, 0x0000, 0x0fff, {EAC}, "CMP2W %e,%r" }, -{ 0x02c0, 0xffc0, 0x0800, 0x0fff, {EAC}, "CHK2W %e,%r" }, -{ 0x04c0, 0xffc0, 0x0000, 0x0fff, {EAC}, "CMP2L %e,%r" }, -{ 0x04c0, 0xffc0, 0x0800, 0x0fff, {EAC}, "CHK2L %e,%r" }, -{ 0x06c0, 0xffc0, 0x0000, 0x0000, {I16, BREAC}, "CALLM %i,%e" }, -{ 0x0800, 0xffc0, 0x0000, 0x0000, {I16, EAD}, "BTSTB %i,%e" }, -{ 0x0840, 0xffc0, 0x0000, 0x0000, {I16, EADA}, "BCHG %i,%e" }, -{ 0x0880, 0xffc0, 0x0000, 0x0000, {I16, EADA}, "BCLR %i,%e" }, -{ 0x08c0, 0xffc0, 0x0000, 0x0000, {I16, EADA}, "BSET %i,%e" }, -{ 0x0ac0, 0xffc0, 0x0000, 0xfe38, {EAMA}, "CASB R%a,R%u,%e" }, -{ 0x0cc0, 0xffc0, 0x0000, 0xfe38, {EAMA}, "CASW R%a,R%u,%e" }, -{ 0x0ec0, 0xffc0, 0x0000, 0xfe38, {EAMA}, "CASL R%a,R%u,%e" }, - -{ 0x0000, 0xff00, 0x0000, 0x0000, {IV, EADA}, "OR%s %i,%e" }, -{ 0x0200, 0xff00, 0x0000, 0x0000, {IV, EADA}, "AND%s %i,%e" }, -{ 0x0400, 0xff00, 0x0000, 0x0000, {IV, EADA}, "SUB%s %i,%e" }, -{ 0x0600, 0xff00, 0x0000, 0x0000, {IV, EADA}, "ADD%s %i,%e" }, -{ 0x0a00, 0xff00, 0x0000, 0x0000, {IV, EADA}, "EOR%s %i,%e" }, -{ 0x0c00, 0xff00, 0x0000, 0x0000, {IV, EAD}, "CMP%s %i,%e" }, -{ 0x0e00, 0xff00, 0x0000, 0x0800, {EAMA}, "MOVES%s %e,%r" }, -{ 0x0e00, 0xff00, 0x0800, 0x0800, {EAMA}, "MOVES%s %r,%e" }, - -{ 0x0108, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPW (%i,A%y),R%x" }, -{ 0x0148, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPL (%i,A%y),R%x" }, -{ 0x0188, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPW R%x,(%i,A%y)" }, -{ 0x01c8, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPL R%x,(%i,A%y)" }, -{ 0x0100, 0xf1f8, 0x0000, 0x0000, {0}, "BTSTL R%x,R%y" }, -{ 0x0140, 0xf1f8, 0x0000, 0x0000, {0}, "BCHGL R%x,R%y" }, -{ 0x0180, 0xf1f8, 0x0000, 0x0000, {0}, "BCLRL R%x,R%y" }, -{ 0x01c0, 0xf1f8, 0x0000, 0x0000, {0}, "BSET R%x,R%y" }, - -{ 0x0100, 0xf1c0, 0x0000, 0x0000, {EAM_B}, "BTSTB R%x,%e" }, -{ 0x0140, 0xf1c0, 0x0000, 0x0000, {EAMA}, "BCHG R%x,%e" }, -{ 0x0180, 0xf1c0, 0x0000, 0x0000, {EAMA}, "BCLR R%x,%e" }, -{ 0x01c0, 0xf1c0, 0x0000, 0x0000, {EAMA}, "BSET R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 1: move byte */ -static Optable t1[] = { -{ 0x1000, 0xf000, 0x0000, 0x0000, {EAALL_B,EADDA},"MOVB %e,%E" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 2: move long */ -static Optable t2[] = { -{ 0x2040, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "MOVL %e,A%x" }, - -{ 0x2000, 0xf000, 0x0000, 0x0000, {EAALL_L,EADDA},"MOVL %e,%E" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 3: move word */ -static Optable t3[] = { -{ 0x3040, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "MOVW %e,A%x" }, - -{ 0x3000, 0xf000, 0x0000, 0x0000, {EAALL_W,EADDA},"MOVW %e,%E" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 4: miscellaneous */ -static Optable t4[] = { -{ 0x4e75, 0xffff, 0x0000, 0x0000, {STACK}, "RTS" }, -{ 0x4e77, 0xffff, 0x0000, 0x0000, {STACK}, "RTR" }, -{ 0x4afc, 0xffff, 0x0000, 0x0000, {0}, "ILLEGAL" }, -{ 0x4e71, 0xffff, 0x0000, 0x0000, {0}, "NOP" }, -{ 0x4e74, 0xffff, 0x0000, 0x0000, {I16, STACK}, "RTD %i" }, -{ 0x4e76, 0xffff, 0x0000, 0x0000, {0}, "TRAPV" }, -{ 0x4e70, 0xffff, 0x0000, 0x0000, {0}, "RESET" }, -{ 0x4e72, 0xffff, 0x0000, 0x0000, {I16}, "STOP %i" }, -{ 0x4e73, 0xffff, 0x0000, 0x0000, {0}, "RTE" }, -{ 0x4e7a, 0xffff, 0x0000, 0x0000, {I16}, "MOVEL %N,%r" }, -{ 0x4e7b, 0xffff, 0x0000, 0x0000, {I16}, "MOVEL %r,%N" }, - -{ 0x4808, 0xfff8, 0x0000, 0x0000, {I32}, "LINKL A%y,%i" }, -{ 0x4840, 0xfff8, 0x0000, 0x0000, {0}, "SWAPW R%y" }, -{ 0x4848, 0xfff8, 0x0000, 0x0000, {0}, "BKPT #%y" }, -{ 0x4880, 0xfff8, 0x0000, 0x0000, {0}, "EXTW R%y" }, -{ 0x48C0, 0xfff8, 0x0000, 0x0000, {0}, "EXTL R%y" }, -{ 0x49C0, 0xfff8, 0x0000, 0x0000, {0}, "EXTBL R%y" }, -{ 0x4e50, 0xfff8, 0x0000, 0x0000, {I16}, "LINKW A%y,%i" }, -{ 0x4e58, 0xfff8, 0x0000, 0x0000, {0}, "UNLK A%y" }, -{ 0x4e60, 0xfff8, 0x0000, 0x0000, {0}, "MOVEL (A%y),USP" }, -{ 0x4e68, 0xfff8, 0x0000, 0x0000, {0}, "MOVEL USP,(A%y)" }, - -{ 0x4e40, 0xfff0, 0x0000, 0x0000, {0}, "SYS %f" }, - -{ 0x40c0, 0xffc0, 0x0000, 0x0000, {EADA}, "MOVW SR,%e" }, -{ 0x42c0, 0xffc0, 0x0000, 0x0000, {EADA}, "MOVW CCR,%e" }, -{ 0x44c0, 0xffc0, 0x0000, 0x0000, {EADI_W}, "MOVW %e,CCR" }, -{ 0x46c0, 0xffc0, 0x0000, 0x0000, {EADI_W}, "MOVW %e,SR" }, -{ 0x4800, 0xffc0, 0x0000, 0x0000, {EADA}, "NBCDB %e" }, -{ 0x4840, 0xffc0, 0x0000, 0x0000, {EAC}, "PEA %e" }, -{ 0x4880, 0xffc0, 0x0000, 0x0000, {I16, EACAPD},"MOVEMW %i,%e" }, -{ 0x48c0, 0xffc0, 0x0000, 0x0000, {I16, EACAPD},"MOVEML %i,%e" }, -{ 0x4ac0, 0xffc0, 0x0000, 0x0000, {EADA}, "TAS %e" }, -{ 0x4a00, 0xffc0, 0x0000, 0x0000, {EAD}, "TSTB %e" }, -{ 0x4c00, 0xffc0, 0x0000, 0x8ff8, {EADI_L}, "MULUL %e,%r" }, -{ 0x4c00, 0xffc0, 0x0400, 0x8ff8, {EADI_L}, "MULUL %e,R%a:%r" }, -{ 0x4c00, 0xffc0, 0x0800, 0x8ff8, {EADI_L}, "MULSL %e,%r" }, -{ 0x4c00, 0xffc0, 0x0c00, 0x8ff8, {EADI_L}, "MULSL %e,R%a:%r" }, -{ 0x4c40, 0xffc0, 0x0000, 0x8ff8, {EADI_L}, "DIVUL %e,%j" }, -{ 0x4c40, 0xffc0, 0x0400, 0x8ff8, {EADI_L}, "DIVUD %e,%r:R%a" }, -{ 0x4c40, 0xffc0, 0x0800, 0x8ff8, {EADI_L}, "DIVSL %e,%j" }, -{ 0x4c40, 0xffc0, 0x0c00, 0x8ff8, {EADI_L}, "DIVSD %e,%r:R%a" }, -{ 0x4c80, 0xffc0, 0x0000, 0x0000, {I16, EACPI}, "MOVEMW %1,%i" }, -{ 0x4cc0, 0xffc0, 0x0000, 0x0000, {I16, EACPI}, "MOVEML %1,%i" }, -{ 0x4e80, 0xffc0, 0x0000, 0x0000, {BREAC}, "JSR %e" }, -{ 0x4ec0, 0xffc0, 0x0000, 0x0000, {BREAC}, "JMP %e" }, - -{ 0x4000, 0xff00, 0x0000, 0x0000, {EADA}, "NEGX%s %e" }, -{ 0x4200, 0xff00, 0x0000, 0x0000, {EADA}, "CLR%s %e" }, -{ 0x4400, 0xff00, 0x0000, 0x0000, {EADA}, "NEG%s %e" }, -{ 0x4600, 0xff00, 0x0000, 0x0000, {EADA}, "NOT%s %e" }, -{ 0x4a00, 0xff00, 0x0000, 0x0000, {EAALL}, "TST%s %e" }, - -{ 0x4180, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "CHKW %e,R%x" }, -{ 0x41c0, 0xf1c0, 0x0000, 0x0000, {EAC}, "LEA %e,A%x" }, -{ 0x4100, 0xf1c0, 0x0000, 0x0000, {EADI_L}, "CHKL %e,R%x" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 5: miscellaneous quick, branch & trap instructions */ -static Optable t5[] = { -{ 0x5000, 0xf1c0, 0x0000, 0x0000, {EADA}, "ADDB $Q#%q,%e" }, -{ 0x5100, 0xf1c0, 0x0000, 0x0000, {EADA}, "SUBB $Q#%q,%e" }, - -{ 0x50c8, 0xf1f8, 0x0000, 0x0000, {BR16}, "DB%c R%y,%t" }, -{ 0x51c8, 0xf1f8, 0x0000, 0x0000, {BR16}, "DB%c R%y,%t" }, - -{ 0x5000, 0xf1c0, 0x0000, 0x0000, {EAA}, "ADDB $Q#%q,%e" }, -{ 0x5040, 0xf1c0, 0x0000, 0x0000, {EAA}, "ADDW $Q#%q,%e" }, -{ 0x5080, 0xf1c0, 0x0000, 0x0000, {EAA}, "ADDL $Q#%q,%e" }, -{ 0x5100, 0xf1c0, 0x0000, 0x0000, {EAA}, "SUBB $Q#%q,%e" }, -{ 0x5140, 0xf1c0, 0x0000, 0x0000, {EAA}, "SUBW $Q#%q,%e" }, -{ 0x5180, 0xf1c0, 0x0000, 0x0000, {EAA}, "SUBL $Q#%q,%e" }, - -{ 0x50fa, 0xf0ff, 0x0000, 0x0000, {I16}, "TRAP%cW %i" }, -{ 0x50fb, 0xf0ff, 0x0000, 0x0000, {I32}, "TRAP%cL %i" }, -{ 0x50fc, 0xf0ff, 0x0000, 0x0000, {0}, "TRAP%c" }, - -{ 0x50c0, 0xf0c0, 0x0000, 0x0000, {EADA}, "S%c %e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 6: branch instructions */ -static Optable t6[] = { -{ 0x6000, 0xff00, 0x0000, 0x0000, {BR8}, "BRA %t" }, -{ 0x6100, 0xff00, 0x0000, 0x0000, {BR8}, "BSR %t" }, -{ 0x6000, 0xf000, 0x0000, 0x0000, {BR8}, "B%c %t" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 7: move quick */ -static Optable t7[] = { -{ 0x7000, 0xf100, 0x0000, 0x0000, {OP8}, "MOVL $Q%i,R%x" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 8: BCD operations, DIV, and OR instructions */ -static Optable t8[] = { -{ 0x8100, 0xf1f8, 0x0000, 0x0000, {0}, "SBCDB R%y,R%x" }, -{ 0x8108, 0xf1f8, 0x0000, 0x0000, {0}, "SBCDB -(A%y),-(A%x)" }, -{ 0x8140, 0xf1f8, 0x0000, 0x0000, {I16}, "PACK R%y,R%x,%i" }, -{ 0x8148, 0xf1f8, 0x0000, 0x0000, {I16}, "PACK -(A%y),-(A%x),%i" }, -{ 0x8180, 0xf1f8, 0x0000, 0x0000, {I16}, "UNPK R%y,R%x,%i" }, -{ 0x8188, 0xf1f8, 0x0000, 0x0000, {I16}, "UNPK -(A%y),-(A%x),%i" }, - -{ 0x80c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "DIVUW %e,R%x" }, -{ 0x81c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "DIVSW %e,R%x" }, - -{ 0x8000, 0xf100, 0x0000, 0x0000, {EADI}, "OR%s %e,R%x" }, -{ 0x8100, 0xf100, 0x0000, 0x0000, {EAMA}, "OR%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 9: subtract instruction */ -static Optable t9[] = { -{ 0x90c0, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "SUBW %e,A%x" }, -{ 0x91c0, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "SUBL %e,A%x" }, - -{ 0x9100, 0xf138, 0x0000, 0x0000, {0}, "SUBX%s R%y,R%x" }, -{ 0x9108, 0xf138, 0x0000, 0x0000, {0}, "SUBX%s -(A%y),-(A%x)" }, - -{ 0x9000, 0xf100, 0x0000, 0x0000, {EAALL}, "SUB%s %e,R%x" }, -{ 0x9100, 0xf100, 0x0000, 0x0000, {EAMA}, "SUB%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class b: CMP & EOR */ -static Optable tb[] = { -{ 0xb000, 0xf1c0, 0x0000, 0x0000, {EADI}, "CMPB R%x,%e" }, -{ 0xb040, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "CMPW R%x,%e" }, -{ 0xb080, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "CMPL R%x,%e" }, -{ 0xb0c0, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "CMPW A%x,%e" }, -{ 0xb1c0, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "CMPL A%x,%e" }, - -{ 0xb108, 0xf138, 0x0000, 0x0000, {0}, "CMP%s (A%y)+,(A%x)+" }, - -{ 0xb100, 0xf100, 0x0000, 0x0000, {EADA}, "EOR%s %e,R%x" }, -{ 0,0,0,0,{0},0 }, -}; - /* class c: AND, MUL, BCD & Exchange */ -static Optable tc[] = { -{ 0xc100, 0xf1f8, 0x0000, 0x0000, {0}, "ABCDB R%y,R%x" }, -{ 0xc108, 0xf1f8, 0x0000, 0x0000, {0}, "ABCDB -(A%y),-(A%x)" }, -{ 0xc140, 0xf1f8, 0x0000, 0x0000, {0}, "EXG R%x,R%y" }, -{ 0xc148, 0xf1f8, 0x0000, 0x0000, {0}, "EXG A%x,A%y" }, -{ 0xc188, 0xf1f8, 0x0000, 0x0000, {0}, "EXG R%x,A%y" }, - -{ 0xc0c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "MULUW %e,R%x" }, -{ 0xc1c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "MULSW %e,R%x" }, - -{ 0xc000, 0xf100, 0x0000, 0x0000, {EADI}, "AND%s %e,R%x" }, -{ 0xc100, 0xf100, 0x0000, 0x0000, {EAMA}, "AND%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class d: addition */ -static Optable td[] = { -{ 0xd000, 0xf1c0, 0x0000, 0x0000, {EADI}, "ADDB %e,R%x" }, -{ 0xd0c0, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "ADDW %e,A%x" }, -{ 0xd1c0, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "ADDL %e,A%x" }, - -{ 0xd100, 0xf138, 0x0000, 0x0000, {0}, "ADDX%s R%y,R%x" }, -{ 0xd108, 0xf138, 0x0000, 0x0000, {0}, "ADDX%s -(A%y),-(A%x)" }, - -{ 0xd000, 0xf100, 0x0000, 0x0000, {EAALL}, "ADD%s %e,R%x" }, -{ 0xd100, 0xf100, 0x0000, 0x0000, {EAMA}, "ADD%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class e: shift, rotate, bit field operations */ -static Optable te[] = { -{ 0xe8c0, 0xffc0, 0x0820, 0xfe38, {EACD}, "BFTST %e{R%u:R%a}" }, -{ 0xe8c0, 0xffc0, 0x0800, 0xfe20, {EACD}, "BFTST %e{R%u:%w}" }, -{ 0xe8c0, 0xffc0, 0x0020, 0xf838, {EACD}, "BFTST %e{%o:R%a}" }, -{ 0xe8c0, 0xffc0, 0x0000, 0xf820, {EACD}, "BFTST %e{%o:%w}" }, - -{ 0xe9c0, 0xffc0, 0x0820, 0x8e38, {EACD}, "BFEXTU %e{R%u:R%a},%r" }, -{ 0xe9c0, 0xffc0, 0x0800, 0x8e20, {EACD}, "BFEXTU %e{R%u:%w},%r" }, -{ 0xe9c0, 0xffc0, 0x0020, 0x8838, {EACD}, "BFEXTU %e{%o:R%a},%r" }, -{ 0xe9c0, 0xffc0, 0x0000, 0x8820, {EACD}, "BFEXTU %e{%o:%w},%r" }, - -{ 0xeac0, 0xffc0, 0x0820, 0xfe38, {EACAD}, "BFCHG %e{R%u:R%a}" }, -{ 0xeac0, 0xffc0, 0x0800, 0xfe20, {EACAD}, "BFCHG %e{R%u:%w}" }, -{ 0xeac0, 0xffc0, 0x0020, 0xf838, {EACAD}, "BFCHG %e{%o:R%a}" }, -{ 0xeac0, 0xffc0, 0x0000, 0xf820, {EACAD}, "BFCHG %e{%o:%w}" }, - -{ 0xebc0, 0xffc0, 0x0820, 0x8e38, {EACD}, "BFEXTS %e{R%u:R%a},%r" }, -{ 0xebc0, 0xffc0, 0x0800, 0x8e20, {EACD}, "BFEXTS %e{R%u:%w},%r" }, -{ 0xebc0, 0xffc0, 0x0020, 0x8838, {EACD}, "BFEXTS %e{%o:R%a},%r" }, -{ 0xebc0, 0xffc0, 0x0000, 0x8820, {EACD}, "BFEXTS %e{%o:%w},%r" }, - -{ 0xecc0, 0xffc0, 0x0820, 0xfe38, {EACAD}, "BFCLR %e{R%u:R%a}" }, -{ 0xecc0, 0xffc0, 0x0800, 0xfe20, {EACAD}, "BFCLR %e{R%u:%w}" }, -{ 0xecc0, 0xffc0, 0x0020, 0xf838, {EACAD}, "BFCLR %e{%o:R%a}" }, -{ 0xecc0, 0xffc0, 0x0000, 0xf820, {EACAD}, "BFCLR %e{%o:%w}" }, - -{ 0xedc0, 0xffc0, 0x0820, 0x8e38, {EACAD}, "BFFFO %e{R%u:R%a},%r" }, -{ 0xedc0, 0xffc0, 0x0800, 0x8e20, {EACAD}, "BFFFO %e{R%u:%w},%r" }, -{ 0xedc0, 0xffc0, 0x0020, 0x8838, {EACAD}, "BFFFO %e{%o:R%a},%r" }, -{ 0xedc0, 0xffc0, 0x0000, 0x8820, {EACAD}, "BFFFO %e{%o:%w},%r" }, - -{ 0xeec0, 0xffc0, 0x0820, 0xfe38, {EACAD}, "BFSET %e{R%u:R%a}" }, -{ 0xeec0, 0xffc0, 0x0800, 0xfe20, {EACAD}, "BFSET %e{R%u:%w}" }, -{ 0xeec0, 0xffc0, 0x0020, 0xf838, {EACAD}, "BFSET %e{%o:R%a}" }, -{ 0xeec0, 0xffc0, 0x0000, 0xf820, {EACAD}, "BFSET %e{%o:%w}" }, - -{ 0xefc0, 0xffc0, 0x0820, 0x8e38, {EACAD}, "BFINS %r,%e{R%u:R%a}" }, -{ 0xefc0, 0xffc0, 0x0800, 0x8e20, {EACAD}, "BFINS %r,%e{R%u:%w}" }, -{ 0xefc0, 0xffc0, 0x0020, 0x8838, {EACAD}, "BFINS %r,%e{%o:R%a}" }, -{ 0xefc0, 0xffc0, 0x0000, 0x8820, {EACAD}, "BFINS %r,%e{%o:%w}" }, - -{ 0xe0c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "AS%dW %e" }, -{ 0xe2c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "LS%dW %e" }, -{ 0xe4c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "ROX%dW %e" }, -{ 0xe6c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "RO%dW %e" }, - -{ 0xe000, 0xf038, 0x0000, 0x0000, {0}, "AS%d%s #%q,R%y" }, -{ 0xe008, 0xf038, 0x0000, 0x0000, {0}, "LS%d%s #%q,R%y" }, -{ 0xe010, 0xf038, 0x0000, 0x0000, {0}, "ROX%d%s #%q,R%y" }, -{ 0xe018, 0xf038, 0x0000, 0x0000, {0}, "RO%d%s #%q,R%y" }, -{ 0xe020, 0xf038, 0x0000, 0x0000, {0}, "AS%d%s R%x,R%y" }, -{ 0xe028, 0xf038, 0x0000, 0x0000, {0}, "LS%d%s R%x,R%y" }, -{ 0xe030, 0xf038, 0x0000, 0x0000, {0}, "ROX%d%s R%x,R%y" }, -{ 0xe038, 0xf038, 0x0000, 0x0000, {0}, "RO%d%s R%x,R%y" }, -{ 0,0,0,0,{0},0 }, -}; - /* class f: coprocessor and mmu instructions */ -static Optable tf[] = { -{ 0xf280, 0xffff, 0x0000, 0xffff, {0}, "FNOP" }, -{ 0xf200, 0xffff, 0x5c00, 0xfc00, {0}, "FMOVECRX %k,F%D" }, -{ 0xf27a, 0xffff, 0x0000, 0xffc0, {I16}, "FTRAP%P %i" }, -{ 0xf27b, 0xffff, 0x0000, 0xffc0, {I32}, "FTRAP%P %i" }, -{ 0xf27c, 0xffff, 0x0000, 0xffc0, {0}, "FTRAP%P" }, - -{ 0xf248, 0xfff8, 0x0000, 0xffc0, {BR16}, "FDB%P R%y,%t" }, -{ 0xf620, 0xfff8, 0x8000, 0x8fff, {0}, "MOVE16 (A%y)+,(%r)+" }, -{ 0xf500, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSHN (A%y)" }, -{ 0xf508, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSH (A%y)" }, -{ 0xf510, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSHAN" }, -{ 0xf518, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSHA" }, -{ 0xf548, 0xfff8, 0x0000, 0x0000, {0}, "PTESTW (A%y)" }, -{ 0xf568, 0xfff8, 0x0000, 0x0000, {0}, "PTESTR (A%y)" }, -{ 0xf600, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 (A%y)+,$%i" }, -{ 0xf608, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 $%i,(A%y)-" }, -{ 0xf610, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 (A%y),$%i" }, -{ 0xf618, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 $%i,(A%y)" }, - -{ 0xf000, 0xffc0, 0x0800, 0xffff, {EACA}, "PMOVE %e,TT0" }, -{ 0xf000, 0xffc0, 0x0900, 0xffff, {EACA}, "PMOVEFD %e,TT0" }, -{ 0xf000, 0xffc0, 0x0a00, 0xffff, {EACA}, "PMOVE TT0,%e" }, -{ 0xf000, 0xffc0, 0x0b00, 0xffff, {EACA}, "PMOVEFD TT0,%e" }, -{ 0xf000, 0xffc0, 0x0c00, 0xffff, {EACA}, "PMOVE %e,TT1" }, -{ 0xf000, 0xffc0, 0x0d00, 0xffff, {EACA}, "PMOVEFD %e,TT1" }, -{ 0xf000, 0xffc0, 0x0e00, 0xffff, {EACA}, "PMOVE TT1,%e" }, -{ 0xf000, 0xffc0, 0x0f00, 0xffff, {EACA}, "PMOVEFD TT1,%e" }, -{ 0xf000, 0xffc0, 0x2400, 0xffff, {0}, "PFLUSHA" }, -{ 0xf000, 0xffc0, 0x2800, 0xffff, {EACA}, "PVALID VAL,%e" }, -{ 0xf000, 0xffc0, 0x6000, 0xffff, {EACA}, "PMOVE %e,MMUSR" }, -{ 0xf000, 0xffc0, 0x6200, 0xffff, {EACA}, "PMOVE MMUSR,%e" }, -{ 0xf000, 0xffc0, 0x2800, 0xfff8, {EACA}, "PVALID A%a,%e" }, -{ 0xf000, 0xffc0, 0x2000, 0xffe0, {EACA}, "PLOADW %L,%e" }, -{ 0xf000, 0xffc0, 0x2200, 0xffe0, {EACA}, "PLOADR %L,%e" }, -{ 0xf000, 0xffc0, 0x8000, 0xffe0, {EACA}, "PTESTW %L,%e,#0" }, -{ 0xf000, 0xffc0, 0x8200, 0xffe0, {EACA}, "PTESTR %L,%e,#0" }, -{ 0xf000, 0xffc0, 0x3000, 0xfe00, {0}, "PFLUSH %L,#%I" }, -{ 0xf000, 0xffc0, 0x3800, 0xfe00, {EACA}, "PFLUSH %L,#%I,%e" }, -{ 0xf000, 0xffc0, 0x8000, 0xe300, {EACA}, "PTESTW %L,%e,#%Z" }, -{ 0xf000, 0xffc0, 0x8100, 0xe300, {EACA}, "PTESTW %L,%e,#%Z,A%h" }, -{ 0xf000, 0xffc0, 0x8200, 0xe300, {EACA}, "PTESTR %L,%e,#%Z" }, -{ 0xf000, 0xffc0, 0x8300, 0xe300, {EACA}, "PTESTR %L,%e,#%Z,A%h" }, -{ 0xf000, 0xffc0, 0x4000, 0xc3ff, {EACA}, "PMOVE %e,%H" }, -{ 0xf000, 0xffc0, 0x4100, 0xc3ff, {EACA}, "PMOVEFD %e,%H" }, -{ 0xf000, 0xffc0, 0x4200, 0xc3ff, {EACA}, "PMOVE %H,%e" }, - - /* floating point (coprocessor 1)*/ - -{ 0xf200, 0xffc0, 0x8400, 0xffff, {EAALL_L}, "FMOVEL %e,FPIAR" }, -{ 0xf200, 0xffc0, 0x8800, 0xffff, {EADI_L}, "FMOVEL %e,FPSR" }, -{ 0xf200, 0xffc0, 0x9000, 0xffff, {EADI_L}, "FMOVEL %e,FPCR" }, -{ 0xf200, 0xffc0, 0xa400, 0xffff, {EAA}, "FMOVEL FPIAR,%e" }, -{ 0xf200, 0xffc0, 0xa800, 0xffff, {EADA}, "FMOVEL FPSR,%e" }, -{ 0xf200, 0xffc0, 0xb000, 0xffff, {EADA}, "FMOVEL FPCR,%e" }, - -{ 0xf240, 0xffc0, 0x0000, 0xffc0, {EADA}, "FS%P %e" }, - -{ 0xf200, 0xffc0, 0xd000, 0xff00, {EACPI}, "FMOVEMX %e,%m" }, -{ 0xf200, 0xffc0, 0xd800, 0xff00, {EACPI}, "FMOVEMX %e,R%K" }, -{ 0xf200, 0xffc0, 0xe000, 0xff00, {EAPI}, "FMOVEMX %m,-(A%y)" }, -{ 0xf200, 0xffc0, 0xe800, 0xff00, {EAPI}, "FMOVEMX R%K,-(A%y)" }, -{ 0xf200, 0xffc0, 0xf000, 0xff00, {EACAPD}, "FMOVEMX %m,%e" }, -{ 0xf200, 0xffc0, 0xf800, 0xff00, {EACAPD}, "FMOVEMX R%K,%e" }, - -{ 0xf200, 0xffc0, 0x6800, 0xfc00, {EAMA}, "FMOVEX F%D,%e" }, -{ 0xf200, 0xffc0, 0x6c00, 0xfc00, {EAMA}, "FMOVEP F%D,%e,{%k}" }, -{ 0xf200, 0xffc0, 0x7400, 0xfc00, {EAMA}, "FMOVED F%D,%e" }, -{ 0xf200, 0xffc0, 0x7c00, 0xfc00, {EAMA}, "FMOVEP F%D,%e,{R%K}" }, - -{ 0xf200, 0xffc0, 0x8000, 0xe3ff, {EAM}, "FMOVEML #%B,%e" }, -{ 0xf200, 0xffc0, 0xa000, 0xe3ff, {EAMA}, "FMOVEML %e,#%B" }, - -{ 0xf200, 0xffc0, 0x0000, 0xe07f, {0}, "FMOVE F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0001, 0xe07f, {0}, "FINTX %F" }, -{ 0xf200, 0xffc0, 0x0002, 0xe07f, {0}, "FSINHX %F" }, -{ 0xf200, 0xffc0, 0x0003, 0xe07f, {0}, "FINTRZ %F" }, -{ 0xf200, 0xffc0, 0x0004, 0xe07f, {0}, "FSQRTX %F" }, -{ 0xf200, 0xffc0, 0x0006, 0xe07f, {0}, "FLOGNP1X %F" }, -{ 0xf200, 0xffc0, 0x0009, 0xe07f, {0}, "FTANHX %F" }, -{ 0xf200, 0xffc0, 0x000a, 0xe07f, {0}, "FATANX %F" }, -{ 0xf200, 0xffc0, 0x000c, 0xe07f, {0}, "FASINX %F" }, -{ 0xf200, 0xffc0, 0x000d, 0xe07f, {0}, "FATANHX %F" }, -{ 0xf200, 0xffc0, 0x000e, 0xe07f, {0}, "FSINX %F" }, -{ 0xf200, 0xffc0, 0x000f, 0xe07f, {0}, "FTANX %F" }, -{ 0xf200, 0xffc0, 0x0010, 0xe07f, {0}, "FETOXX %F" }, -{ 0xf200, 0xffc0, 0x0011, 0xe07f, {0}, "FTWOTOXX %F" }, -{ 0xf200, 0xffc0, 0x0012, 0xe07f, {0}, "FTENTOXX %F" }, -{ 0xf200, 0xffc0, 0x0014, 0xe07f, {0}, "FLOGNX %F" }, -{ 0xf200, 0xffc0, 0x0015, 0xe07f, {0}, "FLOG10X %F" }, -{ 0xf200, 0xffc0, 0x0016, 0xe07f, {0}, "FLOG2X %F" }, -{ 0xf200, 0xffc0, 0x0018, 0xe07f, {0}, "FABSX %F" }, -{ 0xf200, 0xffc0, 0x0019, 0xe07f, {0}, "FCOSHX %F" }, -{ 0xf200, 0xffc0, 0x001a, 0xe07f, {0}, "FNEGX %F" }, -{ 0xf200, 0xffc0, 0x001c, 0xe07f, {0}, "FACOSX %F" }, -{ 0xf200, 0xffc0, 0x001d, 0xe07f, {0}, "FCOSX %F" }, -{ 0xf200, 0xffc0, 0x001e, 0xe07f, {0}, "FGETEXPX %F" }, -{ 0xf200, 0xffc0, 0x001f, 0xe07f, {0}, "FGETMANX %F" }, -{ 0xf200, 0xffc0, 0x0020, 0xe07f, {0}, "FDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0021, 0xe07f, {0}, "FMODX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0022, 0xe07f, {0}, "FADDX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0023, 0xe07f, {0}, "FMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0024, 0xe07f, {0}, "FSGLDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0025, 0xe07f, {0}, "FREMX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0026, 0xe07f, {0}, "FSCALEX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0027, 0xe07f, {0}, "FSGLMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0028, 0xe07f, {0}, "FSUBX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0038, 0xe07f, {0}, "FCMPX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x003a, 0xe07f, {0}, "FTSTX F%B" }, -{ 0xf200, 0xffc0, 0x0040, 0xe07f, {0}, "FSMOVE F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0041, 0xe07f, {0}, "FSSQRTX %F"}, -{ 0xf200, 0xffc0, 0x0044, 0xe07f, {0}, "FDMOVE F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0045, 0xe07f, {0}, "FDSQRTX %F" }, -{ 0xf200, 0xffc0, 0x0058, 0xe07f, {0}, "FSABSX %F" }, -{ 0xf200, 0xffc0, 0x005a, 0xe07f, {0}, "FSNEGX %F" }, -{ 0xf200, 0xffc0, 0x005c, 0xe07f, {0}, "FDABSX %F" }, -{ 0xf200, 0xffc0, 0x005e, 0xe07f, {0}, "FDNEGX %F" }, -{ 0xf200, 0xffc0, 0x0060, 0xe07f, {0}, "FSDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0062, 0xe07f, {0}, "FSADDX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0063, 0xe07f, {0}, "FSMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0064, 0xe07f, {0}, "FDDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0066, 0xe07f, {0}, "FDADDX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0067, 0xe07f, {0}, "FDMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0068, 0xe07f, {0}, "FSSUBX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x006c, 0xe07f, {0}, "FDSUBX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x4000, 0xe07f, {EAFLT}, "FMOVE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4001, 0xe07f, {EAFLT}, "FINT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4002, 0xe07f, {EAFLT}, "FSINH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4003, 0xe07f, {EAFLT}, "FINTRZ%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4004, 0xe07f, {EAFLT}, "FSQRT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4006, 0xe07f, {EAFLT}, "FLOGNP1%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4009, 0xe07f, {EAFLT}, "FTANH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400a, 0xe07f, {EAFLT}, "FATAN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400c, 0xe07f, {EAFLT}, "FASIN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400d, 0xe07f, {EAFLT}, "FATANH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400e, 0xe07f, {EAFLT}, "FSIN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400f, 0xe07f, {EAFLT}, "FTAN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4010, 0xe07f, {EAFLT}, "FETOX%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4011, 0xe07f, {EAFLT}, "FTWOTOX%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4012, 0xe07f, {EAFLT}, "FTENTOX%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4014, 0xe07f, {EAFLT}, "FLOGN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4015, 0xe07f, {EAFLT}, "FLOG10%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4016, 0xe07f, {EAFLT}, "FLOG2%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4018, 0xe07f, {EAFLT}, "FABS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4019, 0xe07f, {EAFLT}, "FCOSH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401a, 0xe07f, {EAFLT}, "FNEG%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401c, 0xe07f, {EAFLT}, "FACOS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401d, 0xe07f, {EAFLT}, "FCOS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401e, 0xe07f, {EAFLT}, "FGETEXP%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401f, 0xe07f, {EAFLT}, "FGETMAN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4020, 0xe07f, {EAFLT}, "FDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4021, 0xe07f, {EAFLT}, "FMOD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4022, 0xe07f, {EAFLT}, "FADD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4023, 0xe07f, {EAFLT}, "FMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4024, 0xe07f, {EAFLT}, "FSGLDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4025, 0xe07f, {EAFLT}, "FREM%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4026, 0xe07f, {EAFLT}, "FSCALE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4027, 0xe07f, {EAFLT}, "FSGLMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4028, 0xe07f, {EAFLT}, "FSUB%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4038, 0xe07f, {EAFLT}, "FCMP%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x403a, 0xe07f, {EAFLT}, "FTST%S %e" }, -{ 0xf200, 0xffc0, 0x4040, 0xe07f, {EAFLT}, "FSMOVE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4041, 0xe07f, {EAFLT}, "FSSQRT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4044, 0xe07f, {EAFLT}, "FDMOVE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4045, 0xe07f, {EAFLT}, "FDSQRT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4058, 0xe07f, {EAFLT}, "FSABS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x405a, 0xe07f, {EAFLT}, "FSNEG%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x405c, 0xe07f, {EAFLT}, "FDABS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x405e, 0xe07f, {EAFLT}, "FDNEG%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4060, 0xe07f, {EAFLT}, "FSDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4062, 0xe07f, {EAFLT}, "FSADD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4063, 0xe07f, {EAFLT}, "FSMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4064, 0xe07f, {EAFLT}, "FDDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4066, 0xe07f, {EAFLT}, "FDADD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4067, 0xe07f, {EAFLT}, "FDMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4068, 0xe07f, {EAFLT}, "FSSUB%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x406c, 0xe07f, {EAFLT}, "FDSUB%S %e,F%D" }, - -{ 0xf200, 0xffc0, 0x0030, 0xe078, {0}, "FSINCOSX F%B,F%a:F%D" }, -{ 0xf200, 0xffc0, 0x4030, 0xe078, {EAFLT}, "FSINCOS%S %e,F%a:F%D" }, - -{ 0xf200, 0xffc0, 0x6000, 0xe000, {EADA}, "FMOVE%S F%D,%e" }, - -{ 0xf300, 0xffc0, 0x0000, 0x0000, {EACAPD}, "FSAVE %e" }, -{ 0xf340, 0xffc0, 0x0000, 0x0000, {EACAPI}, "FRESTORE %e" }, - -{ 0xf280, 0xffc0, 0x0000, 0x0000, {BR16}, "FB%p %t" }, -{ 0xf2c0, 0xffc0, 0x0000, 0x0000, {BR32}, "FB%p %t" }, - -{ 0xf408, 0xff38, 0x0000, 0x0000, {0}, "CINVL %C,(A%y)" }, -{ 0xf410, 0xff38, 0x0000, 0x0000, {0}, "CINVP %C,(A%y)" }, -{ 0xf418, 0xff38, 0x0000, 0x0000, {0}, "CINVA %C" }, -{ 0xf428, 0xff38, 0x0000, 0x0000, {0}, "CPUSHL %C,(A%y)" }, -{ 0xf430, 0xff38, 0x0000, 0x0000, {0}, "CPUSHP %C,(A%y)" }, -{ 0xf438, 0xff38, 0x0000, 0x0000, {0}, "CPUSHA %C" }, -{ 0,0,0,0,{0},0 }, -}; - -static Optable *optables[] = -{ - t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, 0, tb, tc, td, te, tf, -}; - -static Map *mymap; - -static int -dumpinst(Inst *ip, char *buf, int n) -{ - int i; - - if (n <= 0) - return 0; - - *buf++ = '#'; - for (i = 0; i < ip->n && i*4+1 < n-4; i++, buf += 4) - _hexify(buf, ip->raw[i], 3); - *buf = 0; - return i*4+1; -} - -static int -getword(Inst *ip, uvlong offset) -{ - if (ip->n < nelem(ip->raw)) { - if (get2(mymap, offset, &ip->raw[ip->n++]) > 0) - return 1; - werrstr("can't read instruction: %r"); - } else - werrstr("instruction too big: %r"); - return -1; -} - -static int -getshorts(Inst *ip, void *where, int n) -{ - if (ip->n+n < nelem(ip->raw)) { - if (get1(mymap, ip->addr+ip->n*2, (uchar*)&ip->raw[ip->n], n*2) < 0) { - werrstr("can't read instruction: %r"); - return 0; - } - memmove(where, &ip->raw[ip->n], n*2); - ip->n += n; - return 1; - } - werrstr("instruction too big: %r"); - return 0; -} - -static int -i8(Inst *ip, long *l) -{ - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - *l = ip->raw[ip->n-1]&0xff; - if (*l&0x80) - *l |= ~0xff; - return 1; -} - -static int -i16(Inst *ip, long *l) -{ - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - *l = ip->raw[ip->n-1]; - if (*l&0x8000) - *l |= ~0xffff; - return 1; -} -static int -i32(Inst *ip, long *l) -{ - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - *l = (ip->raw[ip->n-2]<<16)|ip->raw[ip->n-1]; - return 1; -} - -static int -getimm(Inst *ip, Operand *ap, int mode) -{ - ap->eatype = IMM; - switch(mode) - { - case EAM_B: /* byte */ - case EAALL_B: - return i8(ip, &ap->immediate); - case EADI_W: /* word */ - case EAALL_W: - return i16(ip, &ap->immediate); - case EADI_L: /* long */ - case EAALL_L: - return i32(ip, &ap->immediate); - case EAFLT: /* floating point - size in bits 10-12 or word 1 */ - switch((ip->raw[1]>>10)&0x07) - { - case 0: /* long integer */ - return i32(ip, &ap->immediate); - case 1: /* single precision real */ - ap->eatype = IREAL; - return getshorts(ip, ap->floater, 2); - case 2: /* extended precision real - not supported */ - ap->eatype = IEXT; - return getshorts(ip, ap->floater, 6); - case 3: /* packed decimal real - not supported */ - ap->eatype = IPACK; - return getshorts(ip, ap->floater, 12); - case 4: /* integer word */ - return i16(ip, &ap->immediate); - case 5: /* double precision real */ - ap->eatype = IDBL; - return getshorts(ip, ap->floater, 4); - case 6: /* integer byte */ - return i8(ip, &ap->immediate); - default: - ip->errmsg = "bad immediate float data"; - return -1; - } - /* not reached */ - case IV: /* size encoded in bits 6&7 of opcode word */ - default: - switch((ip->raw[0]>>6)&0x03) - { - case 0x00: /* integer byte */ - return i8(ip, &ap->immediate); - case 0x01: /* integer word */ - return i16(ip, &ap->immediate); - case 0x02: /* integer long */ - return i32(ip, &ap->immediate); - default: - ip->errmsg = "bad immediate size"; - return -1; - } - /* not reached */ - } -} - -static int -getdisp(Inst *ip, Operand *ap) -{ - short ext; - - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - ext = ip->raw[ip->n-1]; - ap->ext = ext; - if ((ext&0x100) == 0) { /* indexed with 7-bit displacement */ - ap->disp = ext&0x7f; - if (ap->disp&0x40) - ap->disp |= ~0x7f; - return 1; - } - switch(ext&0x30) /* first (inner) displacement */ - { - case 0x10: - break; - case 0x20: - if (i16(ip, &ap->disp) < 0) - return -1; - break; - case 0x30: - if (i32(ip, &ap->disp) < 0) - return -1; - break; - default: - ip->errmsg = "bad EA displacement"; - return -1; - } - switch (ext&0x03) /* outer displacement */ - { - case 0x02: /* 16 bit displacement */ - return i16(ip, &ap->outer); - case 0x03: /* 32 bit displacement */ - return i32(ip, &ap->outer); - default: - break; - } - return 1; -} - -static int -ea(Inst *ip, int ea, Operand *ap, int mode) -{ - int type, size; - - type = 0; - ap->ext = 0; - switch((ea>>3)&0x07) - { - case 0x00: - ap->eatype = Dreg; - type = Dn; - break; - case 0x01: - ap->eatype = Areg; - type = An; - break; - case 0x02: - ap->eatype = AInd; - type = Ind; - break; - case 0x03: - ap->eatype = APinc; - type = Pinc; - break; - case 0x04: - ap->eatype = APdec; - type = Pdec; - break; - case 0x05: - ap->eatype = ADisp; - type = Bdisp; - if (i16(ip, &ap->disp) < 0) - return -1; - break; - case 0x06: - ap->eatype = BXD; - type = Bdisp; - if (getdisp(ip, ap) < 0) - return -1; - break; - case 0x07: - switch(ea&0x07) - { - case 0x00: - type = Abs; - ap->eatype = ABS; - if (i16(ip, &ap->immediate) < 0) - return -1; - break; - case 0x01: - type = Abs; - ap->eatype = ABS; - if (i32(ip, &ap->immediate) < 0) - return -1; - break; - case 0x02: - type = PCrel; - ap->eatype = PDisp; - if (i16(ip, &ap->disp) < 0) - return -1; - break; - case 0x03: - type = PCrel; - ap->eatype = PXD; - if (getdisp(ip, ap) < 0) - return -1; - break; - case 0x04: - type = Imm; - if (getimm(ip, ap, mode) < 0) - return -1; - break; - default: - ip->errmsg = "bad EA mode"; - return -1; - } - } - /* Allowable floating point EAs are restricted for packed, - * extended, and double precision operands - */ - if (mode == EAFLT) { - size = (ip->raw[1]>>10)&0x07; - if (size == 2 || size == 3 || size == 5) - mode = EAM; - else - mode = EADI; - } - if (!(validea[mode]&type)) { - ip->errmsg = "invalid EA"; - return -1; - } - return 1; -} - -static int -decode(Inst *ip, Optable *op) -{ - int i, t, mode; - Operand *ap; - short opcode; - - opcode = ip->raw[0]; - for (i = 0; i < nelem(op->opdata) && op->opdata[i]; i++) { - ap = &ip->and[i]; - mode = op->opdata[i]; - switch(mode) - { - case EAPI: /* normal EA modes */ - case EACA: - case EACAD: - case EACAPI: - case EACAPD: - case EAMA: - case EADA: - case EAA: - case EAC: - case EACPI: - case EACD: - case EAD: - case EAM: - case EAM_B: - case EADI: - case EADI_L: - case EADI_W: - case EAALL: - case EAALL_L: - case EAALL_W: - case EAALL_B: - case EAFLT: - if (ea(ip, opcode&0x3f, ap, mode) < 0) - return -1; - break; - case EADDA: /* stupid bit flop required */ - t = ((opcode>>9)&0x07)|((opcode>>3)&0x38); - if (ea(ip, t, ap, EADA)< 0) - return -1; - break; - case BREAC: /* EAC JMP or CALL operand */ - if (ea(ip, opcode&0x3f, ap, EAC) < 0) - return -1; - break; - case OP8: /* weird movq instruction */ - ap->eatype = IMM; - ap->immediate = opcode&0xff; - if (opcode&0x80) - ap->immediate |= ~0xff; - break; - case I8: /* must be two-word opcode */ - ap->eatype = IMM; - ap->immediate = ip->raw[1]&0xff; - if (ap->immediate&0x80) - ap->immediate |= ~0xff; - break; - case I16: /* 16 bit immediate */ - case BR16: - ap->eatype = IMM; - if (i16(ip, &ap->immediate) < 0) - return -1; - break; - case C16: /* CAS2 16 bit immediate */ - ap->eatype = IMM; - if (i16(ip, &ap->immediate) < 0) - return -1; - if (ap->immediate & 0x0e38) { - ip->errmsg = "bad CAS2W operand"; - return 0; - } - break; - case I32: /* 32 bit immediate */ - case BR32: - ap->eatype = IMM; - if (i32(ip, &ap->immediate) < 0) - return -1; - break; - case IV: /* immediate data depends on size field */ - if (getimm(ip, ap, IV) < 0) - return -1; - break; - case BR8: /* branch displacement format */ - ap->eatype = IMM; - ap->immediate = opcode&0xff; - if (ap->immediate == 0) { - if (i16(ip, &ap->immediate) < 0) - return -1; - } else if (ap->immediate == 0xff) { - if (i32(ip, &ap->immediate) < 0) - return -1; - } else if (ap->immediate & 0x80) - ap->immediate |= ~0xff; - break; - case STACK: /* Dummy operand type for Return instructions */ - default: - break; - } - } - return 1; -} - -static Optable * -instruction(Inst *ip) -{ - ushort opcode, op2; - Optable *op; - int class; - - ip->n = 0; - if (getword(ip, ip->addr) < 0) - return 0; - opcode = ip->raw[0]; - if (get2(mymap, ip->addr+2, &op2) < 0) - op2 = 0; - class = (opcode>>12)&0x0f; - for (op = optables[class]; op && op->format; op++) { - if (op->opcode != (opcode&op->mask0)) - continue; - if (op->op2 != (op2&op->mask1)) - continue; - if (op->mask1) - ip->raw[ip->n++] = op2; - return op; - } - ip->errmsg = "Invalid opcode"; - return 0; -} - -#pragma varargck argpos bprint 2 - -static void -bprint(Inst *i, char *fmt, ...) -{ - va_list arg; - - va_start(arg, fmt); - i->curr = vseprint(i->curr, i->end, fmt, arg); - va_end(arg); -} - -static char *regname[] = -{ - "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "A0", - "A1", "A2", "A3", "A4", "A5", "A6", "A7", "PC", "SB" -}; - -static void -plocal(Inst *ip, Operand *ap) -{ - int ret; - long offset; - uvlong moved; - Symbol s; - - offset = ap->disp; - if (!findsym(ip->addr, CTEXT, &s)) - goto none; - - moved = pc2sp(ip->addr); - if (moved == -1) - goto none; - - if (offset > moved) { /* above frame - must be argument */ - offset -= moved; - ret = getauto(&s, offset-mach->szaddr, CPARAM, &s); - } else /* below frame - must be automatic */ - ret = getauto(&s, moved-offset, CPARAM, &s); - if (ret) - bprint(ip, "%s+%lux", s.name, offset); - else -none: bprint(ip, "%lux", ap->disp); -} - -/* - * this guy does all the work of printing the base and index component - * of an EA. - */ -static int -pidx(Inst *ip, int ext, int reg, char *bfmt, char *ifmt, char *nobase) -{ - char *s; - int printed; - char buf[512]; - - printed = 1; - if (ext&0x80) { /* Base suppressed */ - if (reg == 16) - bprint(ip, bfmt, "(ZPC)"); - else if (nobase) - bprint(ip, nobase); - else - printed = 0; - } else /* format base reg */ - bprint(ip, bfmt, regname[reg]); - if (ext & 0x40) /* index suppressed */ - return printed; - switch ((ext>>9)&0x03) - { - case 0x01: - s = "*2"; - break; - case 0x02: - s = "*4"; - break; - case 0x03: - s = "*8"; - break; - default: - if (ext&0x80) - s = "*1"; - else - s = ""; - break; - } - sprint(buf, "%s.%c%s", regname[(ext>>12)&0x0f], (ext&0x800) ? 'L' : 'W', s); - if (!printed) - bprint(ip, ifmt, buf); - else - bprint(ip, "(%s)", buf); - return 1; -} - -static void -prindex(Inst *ip, int reg, Operand *ap) -{ - short ext; - int left; - int disp; - - left = ip->end-ip->curr; - if (left <= 0) - return; - ext = ap->ext; - disp = ap->disp; - /* look for static base register references */ - if ((ext&0xa0) == 0x20 && reg == 14 && mach->sb && disp) { - reg = 17; /* "A6" -> "SB" */ - disp += mach->sb; - } - if ((ext&0x100) == 0) { /* brief form */ - if (reg == 15) - plocal(ip, ap); - else if (disp) - ip->curr += symoff(ip->curr, left, disp, CANY); - pidx(ip, ext&0xff00, reg, "(%s)", "(%s)", 0); - return; - } - switch(ext&0x3f) /* bd size, && i/is */ - { - case 0x10: - if (!pidx(ip, ext, reg, "(%s)", "(%s)", 0)) - bprint(ip, "#0"); - break; - case 0x11: - if (pidx(ip, ext, reg, "((%s)", "((%s)", 0)) - bprint(ip, ")"); - else - bprint(ip, "#0"); - break; - case 0x12: - case 0x13: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - if (pidx(ip, ext, reg, "((%s)", "((%s)", 0)) - bprint(ip, ")"); - break; - case 0x15: - if (!pidx(ip, ext, reg, "((%s))", "(%s)", 0)) - bprint(ip, "#0"); - break; - case 0x16: - case 0x17: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - pidx(ip, ext, reg, "((%s))", "(%s)", 0); - break; - case 0x20: - case 0x30: - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, left, disp, CANY); - pidx(ip, ext, reg, "(%s)", "(%s)", 0); - break; - case 0x21: - case 0x31: - *ip->curr++ = '('; - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, left-1, disp, CANY); - pidx(ip, ext, reg, "(%s)", "(%s)", 0); - bprint(ip, ")"); - break; - case 0x22: - case 0x23: - case 0x32: - case 0x33: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - bprint(ip, "("); - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY); - pidx(ip, ext, reg, "(%s)", "(%s)", 0); - bprint(ip, ")"); - break; - case 0x25: - case 0x35: - *ip->curr++ = '('; - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, left-1, disp, CANY); - if (!pidx(ip, ext, reg, "(%s))", "(%s)", "())")) - bprint(ip, ")"); - break; - case 0x26: - case 0x27: - case 0x36: - case 0x37: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - bprint(ip, "("); - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY); - pidx(ip, ext, reg, "(%s))", "(%s)", "())"); - break; - default: - bprint(ip, "??%x??", ext); - ip->errmsg = "bad EA"; - break; - } -} - -static void -pea(int reg, Inst *ip, Operand *ap) -{ - int i, left; - - left = ip->end-ip->curr; - if (left < 0) - return; - switch(ap->eatype) - { - case Dreg: - bprint(ip, "R%d", reg); - break; - case Areg: - bprint(ip, "A%d", reg); - break; - case AInd: - bprint(ip, "(A%d)", reg); - break; - case APinc: - bprint(ip, "(A%d)+", reg); - break; - case APdec: - bprint(ip, "-(A%d)", reg); - break; - case PDisp: - ip->curr += symoff(ip->curr, left, ip->addr+2+ap->disp, CANY); - break; - case PXD: - prindex(ip, 16, ap); - break; - case ADisp: /* references off the static base */ - if (reg == 6 && mach->sb && ap->disp) { - ip->curr += symoff(ip->curr, left, ap->disp+mach->sb, CANY); - bprint(ip, "(SB)"); - break; - } - /* reference autos and parameters off the stack */ - if (reg == 7) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, left, ap->disp, CANY); - bprint(ip, "(A%d)", reg); - break; - case BXD: - prindex(ip, reg+8, ap); - break; - case ABS: - ip->curr += symoff(ip->curr, left, ap->immediate, CANY); - bprint(ip, "($0)"); - break; - case IMM: - *ip->curr++ = '$'; - ip->curr += symoff(ip->curr, left-1, ap->immediate, CANY); - break; - case IREAL: - *ip->curr++ = '$'; - ip->curr += beieeesftos(ip->curr, left-1, (void*) ap->floater); - break; - case IDBL: - *ip->curr++ = '$'; - ip->curr += beieeedftos(ip->curr, left-1, (void*) ap->floater); - break; - case IPACK: - bprint(ip, "$#"); - for (i = 0; i < 24 && ip->curr < ip->end-1; i++) { - _hexify(ip->curr, ap->floater[i], 1); - ip->curr += 2; - } - break; - case IEXT: - bprint(ip, "$#"); - ip->curr += beieee80ftos(ip->curr, left-2, (void*)ap->floater); - break; - default: - bprint(ip, "??%x??", ap->eatype); - ip->errmsg = "bad EA type"; - break; - } -} - -static char *cctab[] = { "F", "T", "HI", "LS", "CC", "CS", "NE", "EQ", - "VC", "VS", "PL", "MI", "GE", "LT", "GT", "LE" }; -static char *fcond[] = -{ - "F", "EQ", "OGT", "OGE", "OLT", "OLE", "OGL", "OR", - "UN", "UEQ", "UGT", "UGE", "ULT", "ULE", "NE", "T", - "SF", "SEQ", "GT", "GE", "LT", "LE", "GL", "GLE", - "NGLE", "NGL", "NLE", "NLT", "NGE", "NGT", "SNE", "ST" -}; -static char *cachetab[] = { "NC", "DC", "IC", "BC" }; -static char *mmutab[] = { "TC", "??", "SRP", "CRP" }; -static char *crtab0[] = -{ - "SFC", "DFC", "CACR", "TC", "ITT0", "ITT1", "DTT0", "DTT1", -}; -static char *crtab1[] = -{ - "USP", "VBR", "CAAR", "MSP", "ISP", "MMUSR", "URP", "SRP", -}; -static char typetab[] = { 'L', 'S', 'X', 'P', 'W', 'D', 'B', '?', }; -static char sztab[] = {'?', 'B', 'W', 'L', '?' }; - -static void -formatins(char *fmt, Inst *ip) -{ - short op, w1; - int r1, r2; - int currand; - - op = ip->raw[0]; - w1 = ip->raw[1]; - currand = 0; - for (; *fmt && ip->curr < ip->end; fmt++) { - if (*fmt != '%') - *ip->curr++ = *fmt; - else switch(*++fmt) - { - case '%': - *ip->curr++ = '%'; - break; - case 'a': /* register number; word 1:[0-2] */ - *ip->curr++ = (w1&0x07)+'0'; - break; - case 'c': /* condition code; opcode: [8-11] */ - bprint(ip, cctab[(op>>8)&0x0f]); - break; - case 'd': /* shift direction; opcode: [8] */ - if (op&0x100) - *ip->curr++ = 'L'; - else - *ip->curr++ = 'R'; - break; - case 'e': /* source effective address */ - pea(op&0x07, ip, &ip->and[currand++]); - break; - case 'f': /* trap vector; op code: [0-3] */ - bprint(ip, "%x", op&0x0f); - break; - case 'h': /* register number; word 1: [5-7] */ - *ip->curr++ = (w1>>5)&0x07+'0'; - break; - case 'i': /* immediate operand */ - ip->curr += symoff(ip->curr, ip->end-ip->curr, - ip->and[currand++].immediate, CANY); - break; - case 'j': /* data registers; word 1: [0-2] & [12-14] */ - r1 = w1&0x07; - r2 = (w1>>12)&0x07; - if (r1 == r2) - bprint(ip, "R%d", r1); - else - bprint(ip, "R%d:R%d", r2, r1); - break; - case 'k': /* k factor; word 1 [0-6] */ - bprint(ip, "%x", w1&0x7f); - break; - case 'm': /* register mask; word 1 [0-7] */ - bprint(ip, "%x", w1&0xff); - break; - case 'o': /* bit field offset; word1: [6-10] */ - bprint(ip, "%d", (w1>>6)&0x3f); - break; - case 'p': /* conditional predicate; opcode: [0-5] - only bits 0-4 are defined */ - bprint(ip, fcond[op&0x1f]); - break; - case 'q': /* 3-bit immediate value; opcode[9-11] */ - r1 = (op>>9)&0x07; - if (r1 == 0) - *ip->curr++ = '8'; - else - *ip->curr++ = r1+'0'; - break; - case 'r': /* register type & number; word 1: [12-15] */ - bprint(ip, regname[(w1>>12)&0x0f]); - break; - case 's': /* size; opcode [6-7] */ - *ip->curr = sztab[((op>>6)&0x03)+1]; - if (*ip->curr++ == '?') - ip->errmsg = "bad size code"; - break; - case 't': /* text offset */ - ip->curr += symoff(ip->curr, ip->end-ip->curr, - ip->and[currand++].immediate+ip->addr+2, CTEXT); - break; - case 'u': /* register number; word 1: [6-8] */ - *ip->curr++ = ((w1>>6)&0x07)+'0'; - break; - case 'w': /* bit field width; word 1: [0-4] */ - bprint(ip, "%d", w1&0x0f); - break; - case 'x': /* register number; opcode: [9-11] */ - *ip->curr++ = ((op>>9)&0x07)+'0'; - break; - case 'y': /* register number; opcode: [0-2] */ - *ip->curr++ = (op&0x07)+'0'; - break; - case 'z': /* shift count; opcode: [9-11] */ - *ip->curr++ = ((op>>9)&0x07)+'0'; - break; - case 'A': /* register number; word 2: [0-2] */ - *ip->curr++ = (ip->raw[2]&0x07)+'0'; - break; - case 'B': /* float source reg; word 1: [10-12] */ - *ip->curr++ = ((w1>>10)&0x07)+'0'; - break; - case 'C': /* cache identifier; opcode: [6-7] */ - bprint(ip, cachetab[(op>>6)&0x03]); - break; - case 'D': /* float dest reg; word 1: [7-9] */ - *ip->curr++ = ((w1>>7)&0x07)+'0'; - break; - case 'E': /* destination EA; opcode: [6-11] */ - pea((op>>9)&0x07, ip, &ip->and[currand++]); - break; - case 'F': /* float dest register(s); word 1: [7-9] & [10-12] */ - r1 = (w1>>7)&0x07; - r2 = (w1>>10)&0x07; - if (r1 == r2) - bprint(ip, "F%d", r1); - else - bprint(ip, "F%d,F%d", r2, r1); - break; - case 'H': /* MMU register; word 1 [10-13] */ - bprint(ip, mmutab[(w1>>10)&0x03]); - if (ip->curr[-1] == '?') - ip->errmsg = "bad mmu register"; - break; - case 'I': /* MMU function code mask; word 1: [5-8] */ - bprint(ip, "%x", (w1>>4)&0x0f); - break; - case 'K': /* dynamic k-factor register; word 1: [5-8] */ - bprint(ip, "%d", (w1>>4)&0x0f); - break; - case 'L': /* MMU function code; word 1: [0-6] */ - if (w1&0x10) - bprint(ip, "%x", w1&0x0f); - else if (w1&0x08) - bprint(ip, "R%d",w1&0x07); - else if (w1&0x01) - bprint(ip, "DFC"); - else - bprint(ip, "SFC"); - break; - case 'N': /* control register; word 1: [0-11] */ - r1 = w1&0xfff; - if (r1&0x800) - bprint(ip, crtab1[r1&0x07]); - else - bprint(ip, crtab0[r1&0x07]); - break; - case 'P': /* conditional predicate; word 1: [0-5] */ - bprint(ip, fcond[w1&0x1f]); - break; - case 'R': /* register type & number; word 2 [12-15] */ - bprint(ip, regname[(ip->raw[2]>>12)&0x0f]); - break; - case 'S': /* float source type code; word 1: [10-12] */ - *ip->curr = typetab[(w1>>10)&0x07]; - if (*ip->curr++ == '?') - ip->errmsg = "bad float type"; - break; - case 'U': /* register number; word 2: [6-8] */ - *ip->curr++ = ((ip->raw[2]>>6)&0x07)+'0'; - break; - case 'Z': /* ATC level number; word 1: [10-12] */ - bprint(ip, "%x", (w1>>10)&0x07); - break; - case '1': /* effective address in second operand*/ - pea(op&0x07, ip, &ip->and[1]); - break; - default: - bprint(ip, "%%%c", *fmt); - break; - } - } - *ip->curr = 0; /* there's always room for 1 byte */ -} - -static int -dispsize(Inst *ip) -{ - ushort ext; - static int dsize[] = {0, 0, 1, 2}; /* in words */ - - if (get2(mymap, ip->addr+ip->n*2, &ext) < 0) - return -1; - if ((ext&0x100) == 0) - return 1; - return dsize[(ext>>4)&0x03]+dsize[ext&0x03]+1; -} - -static int -immsize(Inst *ip, int mode) -{ - static int fsize[] = { 2, 2, 6, 12, 1, 4, 1, -1 }; - static int isize[] = { 1, 1, 2, -1 }; - - switch(mode) - { - case EAM_B: /* byte */ - case EAALL_B: - case EADI_W: /* word */ - case EAALL_W: - return 1; - case EADI_L: /* long */ - case EAALL_L: - return 2; - case EAFLT: /* floating point - size in bits 10-12 or word 1 */ - return fsize[(ip->raw[1]>>10)&0x07]; - case IV: /* size encoded in bits 6&7 of opcode word */ - default: - return isize[(ip->raw[0]>>6)&0x03]; - } -} - -static int -easize(Inst *ip, int ea, int mode) -{ - switch((ea>>3)&0x07) - { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - return 0; - case 0x05: - return 1; - case 0x06: - return dispsize(ip); - case 0x07: - switch(ea&0x07) - { - case 0x00: - case 0x02: - return 1; - case 0x01: - return 2; - case 0x03: - return dispsize(ip); - case 0x04: - return immsize(ip, mode); - default: - return -1; - } - } - return -1; -} - -static int -instrsize(Inst *ip, Optable *op) -{ - int i, t, mode; - short opcode; - - opcode = ip->raw[0]; - for (i = 0; i < nelem(op->opdata) && op->opdata[i]; i++) { - mode = op->opdata[i]; - switch(mode) - { - case EAPI: /* normal EA modes */ - case EACA: - case EACAD: - case EACAPI: - case EACAPD: - case EAMA: - case EADA: - case EAA: - case EAC: - case EACPI: - case EACD: - case EAD: - case EAM: - case EAM_B: - case EADI: - case EADI_L: - case EADI_W: - case EAALL: - case EAALL_L: - case EAALL_W: - case EAALL_B: - case EAFLT: - t = easize(ip, opcode&0x3f, mode); - if (t < 0) - return -1; - ip->n += t; - break; - case EADDA: /* stupid bit flop required */ - t = ((opcode>>9)&0x07)|((opcode>>3)&0x38); - t = easize(ip, t, mode); - if (t < 0) - return -1; - ip->n += t; - break; - case BREAC: /* EAC JMP or CALL operand */ - /* easy displacements for follow set */ - if ((opcode&0x038) == 0x28 || (opcode&0x3f) == 0x3a) { - if (i16(ip, &ip->and[i].immediate) < 0) - return -1; - } else { - t = easize(ip, opcode&0x3f, mode); - if (t < 0) - return -1; - ip->n += t; - } - break; - case I16: /* 16 bit immediate */ - case C16: /* CAS2 16 bit immediate */ - ip->n++; - break; - case BR16: /* 16 bit branch displacement */ - if (i16(ip, &ip->and[i].immediate) < 0) - return -1; - break; - case BR32: /* 32 bit branch displacement */ - if (i32(ip, &ip->and[i].immediate) < 0) - return -1; - break; - case I32: /* 32 bit immediate */ - ip->n += 2; - break; - case IV: /* immediate data depends on size field */ - t = (ip->raw[0]>>6)&0x03; - if (t < 2) - ip->n++; - else if (t == 2) - ip->n += 2; - else - return -1; - break; - case BR8: /* loony branch displacement format */ - t = opcode&0xff; - if (t == 0) { - if (i16(ip, &ip->and[i].immediate) < 0) - return -1; - } else if (t == 0xff) { - if (i32(ip, &ip->and[i].immediate) < 0) - return -1; - } else { - ip->and[i].immediate = t; - if (t & 0x80) - ip->and[i].immediate |= ~0xff; - } - break; - case STACK: /* Dummy operand for Return instructions */ - case OP8: /* weird movq instruction */ - case I8: /* must be two-word opcode */ - default: - break; - } - } - return 1; -} - -static int -eaval(Inst *ip, Operand *ap, Rgetter rget) -{ - int reg; - char buf[8]; - - reg = ip->raw[0]&0x07; - switch(ap->eatype) - { - case AInd: - sprint(buf, "A%d", reg); - return (*rget)(mymap, buf); - case PDisp: - return ip->addr+2+ap->disp; - case ADisp: - sprint(buf, "A%d", reg); - return ap->disp+(*rget)(mymap, buf); - case ABS: - return ap->immediate; - default: - return 0; - } -} - -static int -m68020instlen(Map *map, uvlong pc) -{ - Inst i; - Optable *op; - - mymap = map; - i.addr = pc; - i.errmsg = 0; - op = instruction(&i); - if (op && instrsize(&i, op) > 0) - return i.n*2; - return -1; -} - -static int -m68020foll(Map *map, uvlong pc, Rgetter rget, uvlong *foll) -{ - int j; - Inst i; - ulong l; - Optable *op; - - mymap = map; - i.addr = pc; - i.errmsg = 0; - op = instruction(&i); - if (op == 0 || instrsize(&i, op) < 0) - return -1; - for (j = 0; j < nelem(op->opdata) && op->opdata[j]; j++) { - switch(op->opdata[j]) - { - case BREAC: /* CALL, JMP, JSR */ - foll[0] = pc+2+eaval(&i, &i.and[j], rget); - return 1; - case BR8: /* Bcc, BSR, & BRA */ - case BR16: /* FBcc, FDBcc, DBcc */ - case BR32: /* FBcc */ - foll[0] = pc+i.n*2; - foll[1] = pc+2+i.and[j].immediate; - return 2; - case STACK: /* RTR, RTS, RTD */ - if (get4(map, (*rget)(map, mach->sp), &l) < 0) - return -1; - *foll = l; - return 1; - default: - break; - } - } - foll[0] = pc+i.n*2; - return 1; -} - -static int -m68020inst(Map *map, uvlong pc, char modifier, char *buf, int n) -{ - Inst i; - Optable *op; - - USED(modifier); - mymap = map; - i.addr = pc; - i.curr = buf; - i.end = buf+n-1; - i.errmsg = 0; - op = instruction(&i); - if (!op) - return -1; - if (decode(&i, op) > 0) - formatins(op->format, &i); - if (i.errmsg) { - if (i.curr != buf) - bprint(&i, "\t\t;"); - bprint(&i, "%s: ", i.errmsg); - dumpinst(&i, i.curr, i.end-i.curr); - } - return i.n*2; -} - -static int -m68020das(Map *map, uvlong pc, char *buf, int n) -{ - Inst i; - Optable *op; - - mymap = map; - i.addr = pc; - i.curr = buf; - i.end = buf+n-1; - i.errmsg = 0; - - op = instruction(&i); - if (!op) - return -1; - decode(&i, op); - if (i.errmsg) - bprint(&i, "%s: ", i.errmsg); - dumpinst(&i, i.curr, i.end-i.curr); - return i.n*2; -} diff --git a/utils/libmach/2obj.c b/utils/libmach/2obj.c deleted file mode 100644 index ad3540b7..00000000 --- a/utils/libmach/2obj.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 2obj.c - identify and parse a 68020 object file - */ -#include <lib9.h> -#include <bio.h> -#include <mach.h> -#include "2c/2.out.h" -#include "obj.h" - -typedef struct Addr Addr; -struct Addr -{ - char sym; - char flags; -}; -static Addr addr(Biobuf *); -static char type2char(int); -static void skip(Biobuf*, int); - -int -_is2(char *t) -{ - uchar *s = (uchar *)t; - - return s[0] == (ANAME&0xff) /* aslo = ANAME */ - && s[1] == ((ANAME>>8)&0xff) /* ashi = ANAME */ - && s[2] == D_FILE /* type */ - && s[3] == 1 /* sym */ - && s[4] == '<'; /* name of file */ -} - -int -_read2(Biobuf *bp, Prog *p) -{ - int as, n, c; - Addr a; - - as = Bgetc(bp); /* as(low) */ - if(as < 0) - return 0; - c = Bgetc(bp); /* as(high) */ - if(c < 0) - return 0; - as |= ((c & 0xff) << 8); - p->kind = aNone; - p->sig = 0; - if(as == ANAME || as == ASIGNAME){ - if(as == ASIGNAME){ - Bread(bp, &p->sig, 4); - p->sig = beswal(p->sig); - } - p->kind = aName; - p->type = type2char(Bgetc(bp)); /* type */ - p->sym = Bgetc(bp); /* sym */ - n = 0; - for(;;) { - as = Bgetc(bp); - if(as < 0) - return 0; - n++; - if(as == 0) - break; - } - p->id = malloc(n); - if(p->id == 0) - return 0; - Bseek(bp, -n, 1); - if(Bread(bp, p->id, n) != n) - return 0; - return 1; - } - if(as == ATEXT) - p->kind = aText; - else if(as == AGLOBL) - p->kind = aData; - skip(bp, 4); /*lineno: low, high, lowhigh, highigh*/ - a = addr(bp); - addr(bp); - if(!(a.flags & T_SYM)) - p->kind = aNone; - p->sym = a.sym; - return 1; -} - -static Addr -addr(Biobuf *bp) -{ - Addr a; - int t; - long off; - - a.flags = Bgetc(bp); /* flags */ - a.sym = -1; - off = 0; - if(a.flags & T_FIELD) - skip(bp, 2); - if(a.flags & T_INDEX) - skip(bp, 7); - if(a.flags & T_OFFSET){ - off = Bgetc(bp); - off |= Bgetc(bp) << 8; - off |= Bgetc(bp) << 16; - off |= Bgetc(bp) << 24; - if(off < 0) - off = -off; - } - if(a.flags & T_SYM) - a.sym = Bgetc(bp); - if(a.flags & T_FCONST) - skip(bp, 8); - else if(a.flags & T_SCONST) - skip(bp, NSNAME); - else{ - t = Bgetc(bp); - if(a.flags & T_TYPE) - t |= Bgetc(bp) << 8; - t &= D_MASK; - if(a.sym > 0 && (t==D_PARAM || t==D_AUTO)) - _offset(a.sym, off); - } - return a; -} - -static char -type2char(int t) -{ - switch(t){ - case D_EXTERN: return 'U'; - case D_STATIC: return 'b'; - case D_AUTO: return 'a'; - case D_PARAM: return 'p'; - default: return UNKNOWN; - } -} - -static void -skip(Biobuf *bp, int n) -{ - while (n-- > 0) - Bgetc(bp); -} diff --git a/utils/libmach/5db.c b/utils/libmach/5db.c index d3628749..fb6bf899 100644 --- a/utils/libmach/5db.c +++ b/utils/libmach/5db.c @@ -122,7 +122,7 @@ char* shtype[4] = static char *hb[4] = { - "???", "HU", "B", "H" + "?", "HU", "B", "H" }; static @@ -134,18 +134,26 @@ char* addsub[2] = int armclass(long w) { - int op; + int op, done; op = (w >> 25) & 0x7; switch(op) { case 0: /* data processing r,r,r */ op = ((w >> 4) & 0xf); if(op == 0x9) { - op = 48+16; /* mul */ + op = 48+16; /* mul, swp or *rex */ + if((w & 0x0ff00fff) == 0x01900f9f) { + op = 93; /* ldrex */ + break; + } + if((w & 0x0ff00ff0) == 0x01800f90) { + op = 94; /* strex */ + break; + } if(w & (1<<24)) { op += 2; if(w & (1<<22)) - op++; /* swap */ + op++; /* swpb */ break; } if(w & (1<<23)) { /* mullu */ @@ -173,12 +181,38 @@ armclass(long w) op = (48) + ((w >> 21) & 0xf); break; case 2: /* load/store byte/word i(r) */ + if ((w & 0xffffff8f) == 0xf57ff00f) { /* barriers, clrex */ + done = 1; + switch ((w >> 4) & 7) { + case 1: + op = 95; /* clrex */ + break; + case 4: + op = 96; /* dsb */ + break; + case 5: + op = 97; /* dmb */ + break; + case 6: + op = 98; /* isb */ + break; + default: + done = 0; + break; + } + if (done) + break; + } op = (48+24) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2); break; case 3: /* load/store byte/word (r)(r) */ op = (48+24+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2); break; case 4: /* block data transfer (r)(r) */ + if ((w & 0xfe50ffff) == 0xf8100a00) { /* v7 RFE */ + op = 99; + break; + } op = (48+24+4+4) + ((w >> 20) & 0x1); break; case 5: /* branch / branch link */ @@ -187,7 +221,7 @@ armclass(long w) case 7: /* coprocessor crap */ op = (48+24+4+4+2+2) + ((w >> 3) & 0x2) + ((w >> 20) & 0x1); break; - default: + default: op = (48+24+4+4+2+2+4+4); break; } @@ -450,10 +484,10 @@ armco(Opcode *o, Instr *i) /* coprocessor instructions */ p = (i->w >> 5) & 0x7; if(i->w&(1<<4)) { op = (i->w >> 21) & 0x07; - snprint(buf, sizeof(buf), "#%x, #%x, R%d, C(%d), C(%d), #%x\n", cp, op, i->rd, i->rn, i->rs, p); + snprint(buf, sizeof(buf), "#%x, #%x, R%d, C(%d), C(%d), #%x", cp, op, i->rd, i->rn, i->rs, p); } else { op = (i->w >> 20) & 0x0f; - snprint(buf, sizeof(buf), "#%x, #%x, C(%d), C(%d), C(%d), #%x\n", cp, op, i->rd, i->rn, i->rs, p); + snprint(buf, sizeof(buf), "#%x, #%x, C(%d), C(%d), C(%d), #%x", cp, op, i->rd, i->rn, i->rs, p); } format(o->o, i, buf); } @@ -601,19 +635,16 @@ armaddr(Map *map, Rgetter rget, Instr *i) char buf[8]; ulong rn; - sprint(buf, "R%ld", (i->w >> 16) & 0xf); + snprint(buf, sizeof(buf), "R%ld", (i->w >> 16) & 0xf); rn = rget(map, buf); - if((i->w & (1<<24)) == 0) { /* POSTIDX */ - sprint(buf, "R%ld", rn); - return rget(map, buf); - } + if((i->w & (1<<24)) == 0) /* POSTIDX */ + return rn; if((i->w & (1<<25)) == 0) { /* OFFSET */ - sprint(buf, "R%ld", rn); if(i->w & (1U<<23)) - return rget(map, buf) + (i->w & BITS(0,11)); - return rget(map, buf) - (i->w & BITS(0,11)); + return rn + (i->w & BITS(0,11)); + return rn - (i->w & BITS(0,11)); } else { /* REGOFF */ ulong index = 0; uchar c; @@ -822,8 +853,22 @@ static Opcode opcodes[] = "MULL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)", "MULAL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)", -/* 48+24+4+4+2+2+4+4 */ +/* 48+24+4+4+2+2+4+4 = 92 */ "UNK", armunk, 0, "", + + /* new v7 arch instructions */ +/* 93 */ + "LDREX", armdpi, 0, "(R%n),R%d", + "STREX", armdpi, 0, "R%s,(R%n),R%d", + "CLREX", armunk, 0, "", + +/* 96 */ + "DSB", armunk, 0, "", + "DMB", armunk, 0, "", + "ISB", armunk, 0, "", + +/* 99 */ + "RFEV7%P%a", armbdt, 0, "(R%n)", }; static void diff --git a/utils/libmach/5obj.c b/utils/libmach/5obj.c index ca1f2ab5..4cf69409 100644 --- a/utils/libmach/5obj.c +++ b/utils/libmach/5obj.c @@ -3,7 +3,7 @@ */ #include <lib9.h> #include <bio.h> -#include <mach.h> +#include "mach.h" #include "5c/5.out.h" #include "obj.h" diff --git a/utils/libmach/6.c b/utils/libmach/6.c index 816566e4..914bbddf 100644 --- a/utils/libmach/6.c +++ b/utils/libmach/6.c @@ -104,8 +104,8 @@ Mach mamd64= 0, /* link register */ "setSB", /* static base register name (bogus anyways) */ 0, /* static base register value */ - 0x1000, /* page size */ - 0xFFFFFFFF80110000U, /* kernel base */ + 0x200000, /* page size */ + 0xFFFFFFFFF0110000U, /* kernel base */ 0xFFFF800000000000U, /* kernel text mask */ 0x00007FFFFFFFF000U, /* user stack top */ 1, /* quantization of pc */ diff --git a/utils/libmach/6obj.c b/utils/libmach/6obj.c index d4c72af6..24a458c2 100644 --- a/utils/libmach/6obj.c +++ b/utils/libmach/6obj.c @@ -3,7 +3,7 @@ */ #include <lib9.h> #include <bio.h> -#include <mach.h> +#include "mach.h" #include "6c/6.out.h" #include "obj.h" diff --git a/utils/libmach/8db.c b/utils/libmach/8db.c index 8cdcf9d2..50befdb4 100644 --- a/utils/libmach/8db.c +++ b/utils/libmach/8db.c @@ -2018,7 +2018,7 @@ prinstr(Instr *ip, char *fmt) if (ip->reg < 4 || ip->reg == 6 || ip->reg == 7) bprint(ip, "DR%d",ip->reg); else - bprint(ip, "???"); + bprint(ip, "?"); break; case 'I': bprint(ip, "$"); @@ -2057,7 +2057,7 @@ prinstr(Instr *ip, char *fmt) if (ip->reg == 6 || ip->reg == 7) bprint(ip, "TR%d",ip->reg); else - bprint(ip, "???"); + bprint(ip, "?"); break; case 'W': if (ip->osize == 'Q' || ip->osize == 'L' && ip->rex & REXW) @@ -2094,7 +2094,7 @@ prinstr(Instr *ip, char *fmt) if (ip->reg < 6) bprint(ip,"%s",sreg[ip->reg]); else - bprint(ip,"???"); + bprint(ip,"?"); break; case 'p': /* diff --git a/utils/libmach/8obj.c b/utils/libmach/8obj.c index 1735ff4b..11e69113 100644 --- a/utils/libmach/8obj.c +++ b/utils/libmach/8obj.c @@ -3,7 +3,7 @@ */ #include <lib9.h> #include <bio.h> -#include <mach.h> +#include "mach.h" #include "8c/8.out.h" #include "obj.h" diff --git a/utils/libmach/9.c b/utils/libmach/9.c index cafa3a93..6a46a005 100644 --- a/utils/libmach/9.c +++ b/utils/libmach/9.c @@ -5,7 +5,7 @@ #include <lib9.h> #include <bio.h> #include "ureg9.h" -#include <mach.h> +#include "mach.h" #define REGOFF(x) offsetof(struct Ureg, x) diff --git a/utils/libmach/a.out.h b/utils/libmach/a.out.h deleted file mode 100644 index 59077860..00000000 --- a/utils/libmach/a.out.h +++ /dev/null @@ -1,46 +0,0 @@ -typedef struct Exec Exec; -struct Exec -{ - long magic; /* magic number */ - long text; /* size of text segment */ - long data; /* size of initialized data */ - long bss; /* size of uninitialized data */ - long syms; /* size of symbol table */ - long entry; /* entry point */ - long spsz; /* size of pc/sp offset table */ - long pcsz; /* size of pc/line number table */ -}; - -#define HDR_MAGIC 0x00008000 /* header expansion */ - -#define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7)) -#define A_MAGIC _MAGIC(0, 8) /* 68020 */ -#define I_MAGIC _MAGIC(0, 11) /* intel 386 */ -#define J_MAGIC _MAGIC(0, 12) /* intel 960 (retired) */ -#define K_MAGIC _MAGIC(0, 13) /* sparc */ -#define V_MAGIC _MAGIC(0, 16) /* mips 3000 BE */ -#define X_MAGIC _MAGIC(0, 17) /* att dsp 3210 (retired) */ -#define M_MAGIC _MAGIC(0, 18) /* mips 4000 BE */ -#define D_MAGIC _MAGIC(0, 19) /* amd 29000 (retired) */ -#define E_MAGIC _MAGIC(0, 20) /* arm */ -#define Q_MAGIC _MAGIC(0, 21) /* powerpc */ -#define N_MAGIC _MAGIC(0, 22) /* mips 4000 LE */ -#define L_MAGIC _MAGIC(0, 23) /* dec alpha */ -#define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */ -#define U_MAGIC _MAGIC(0, 25) /* sparc64 */ -#define S_MAGIC _MAGIC(HDR_MAGIC, 26) /* amd64 */ -#define T_MAGIC _MAGIC(HDR_MAGIC, 27) /* powerpc64 */ - -#define MIN_MAGIC 8 -#define MAX_MAGIC 27 /* <= 90 */ - -#define DYN_MAGIC 0x80000000 /* dlm */ - -typedef struct Sym Sym; -struct Sym -{ - vlong value; - uint sig; - char type; - char *name; -}; diff --git a/utils/libmach/ar.h b/utils/libmach/ar.h deleted file mode 100644 index cd538fab..00000000 --- a/utils/libmach/ar.h +++ /dev/null @@ -1,17 +0,0 @@ -#define ARMAG "!<arch>\n" -#define SARMAG 8 - -#define ARFMAG "`\n" -#define SARNAME 16 - -struct ar_hdr -{ - char name[SARNAME]; - char date[12]; - char uid[6]; - char gid[6]; - char mode[8]; - char size[10]; - char fmag[2]; -}; -#define SAR_HDR (SARNAME+44) diff --git a/utils/libmach/elf.h b/utils/libmach/elf.h index 5d755b7a..6bd483d2 100644 --- a/utils/libmach/elf.h +++ b/utils/libmach/elf.h @@ -80,8 +80,10 @@ enum { S370 = 9, /* Amdhal */ SPARC64 = 18, /* Sun SPARC v9 */ POWER = 20, /* PowerPC */ - ARM = 40, /* ARM */ + POWER64 = 21, /* PowerPC64 */ + ARM = 40, /* ARM */ AMD64 = 62, /* Amd64 */ + ARM64 = 183, /* ARM64 */ NO_VERSION = 0, /* version, ident[VERSION] */ CURRENT = 1, diff --git a/utils/libmach/executable.c b/utils/libmach/executable.c index a6a2be31..b9954f0a 100644 --- a/utils/libmach/executable.c +++ b/utils/libmach/executable.c @@ -60,7 +60,6 @@ extern Mach mmips; extern Mach mmips2le; extern Mach mmips2be; extern Mach msparc; -extern Mach m68020; extern Mach mi386; extern Mach mamd64; extern Mach marm; @@ -141,24 +140,6 @@ ExecTable exectab[] = sizeof(struct sparcexec), beswal, sparcboot }, - { A_MAGIC, /* 68020 2.out & boot image */ - "68020 plan 9 executable", - "68020 plan 9 dlm", - F68020, - 1, - &m68020, - sizeof(Exec), - beswal, - common }, - { 0xFEEDFACE, /* Next boot image */ - "next plan 9 boot image", - nil, - FNEXTB, - 0, - &m68020, - sizeof(struct nextexec), - beswal, - nextboot }, { I_MAGIC, /* I386 8.out & boot image */ "386 plan 9 executable", "386 plan 9 dlm", @@ -364,12 +345,6 @@ commonboot(Fhdr *fp) fp->name = "ARM plan 9 boot image"; fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize); return; - case FALPHA: - fp->type = FALPHAB; - fp->txtaddr = (u32int)fp->entry; - fp->name = "alpha plan 9 boot image"; - fp->dataddr = fp->txtaddr+fp->txtsz; - break; case FPOWER: fp->type = FPOWERB; fp->txtaddr = (u32int)fp->entry; @@ -601,6 +576,10 @@ elfdotout(int fd, Fhdr *fp, ExecHdr *hp) mach = &mamd64; fp->type = FAMD64; break; + case ARM: + mach = &marm; + fp->type = FARM; + break; default: return 0; } diff --git a/utils/libmach/kdb.c b/utils/libmach/kdb.c index 80a4110b..68a25ed9 100644 --- a/utils/libmach/kdb.c +++ b/utils/libmach/kdb.c @@ -734,7 +734,7 @@ storea(Instr *i, char *m) /* page 74 */ if(i->i == 0) bprint(i, "%s\tR%d, (R%d+R%d, %d)", m, i->rd, i->rs1, i->rs2, i->asi); else - bprint(i, "%s\tR%d, %d(R%d, %d), ???", m, i->rd, i->simm13, i->rs1, i->asi); + bprint(i, "%s\tR%d, %d(R%d, %d), ?", m, i->rd, i->simm13, i->rs1, i->asi); } static void diff --git a/utils/libmach/kobj.c b/utils/libmach/kobj.c index f9790a23..51dccbd2 100644 --- a/utils/libmach/kobj.c +++ b/utils/libmach/kobj.c @@ -3,7 +3,7 @@ */ #include <lib9.h> #include <bio.h> -#include <mach.h> +#include "mach.h" #include "kc/k.out.h" #include "obj.h" diff --git a/utils/libmach/map.c b/utils/libmach/map.c index e1d6010e..12bee1be 100644 --- a/utils/libmach/map.c +++ b/utils/libmach/map.c @@ -83,21 +83,19 @@ attachproc(int pid, int kflag, int corefd, Fhdr *fp) int fd; Map *map; uvlong n; - int mode; map = newmap(0, 4); if (!map) return 0; - if(kflag) { + if(kflag) regs = "kregs"; - mode = OREAD; - } else { + else regs = "regs"; - mode = ORDWR; - } if (mach->regsize) { sprint(buf, "/proc/%d/%s", pid, regs); - fd = open(buf, mode); + fd = open(buf, ORDWR); + if(fd < 0) + fd = open(buf, OREAD); if(fd < 0) { free(map); return 0; @@ -106,7 +104,9 @@ attachproc(int pid, int kflag, int corefd, Fhdr *fp) } if (mach->fpregsize) { sprint(buf, "/proc/%d/fpregs", pid); - fd = open(buf, mode); + fd = open(buf, ORDWR); + if(fd < 0) + fd = open(buf, OREAD); if(fd < 0) { close(map->seg[0].fd); free(map); diff --git a/utils/libmach/mkfile b/utils/libmach/mkfile index a5e87357..9114ed66 100644 --- a/utils/libmach/mkfile +++ b/utils/libmach/mkfile @@ -2,7 +2,6 @@ LIB=libmach.a OFILES=\ - 2.$O\ 4.$O\ 5.$O\ 6.$O\ @@ -12,14 +11,12 @@ OFILES=\ q.$O\ t.$O\ v.$O\ - 2db.$O\ 5db.$O\ 8db.$O\ kdb.$O\ qdb.$O\ tdb.$O\ vdb.$O\ - 2obj.$O\ 5obj.$O\ 6obj.$O\ 8obj.$O\ @@ -37,7 +34,7 @@ OFILES=\ executable.$O\ vcodas.$O\ -HFILES=../include/mach.h ../include/a.out.h bootexec.h elf.h ureg2.h ureg4.h ureg6.h ureg8.h uregk.h uregv.h ureg5.h +HFILES=../include/mach.h ../include/a.out.h bootexec.h elf.h ureg4.h ureg6.h ureg8.h uregk.h uregv.h ureg5.h <$ROOT/mkfiles/mksyslib-$SHELLTYPE CFLAGS= $CFLAGS -I../include -I.. diff --git a/utils/libmach/obj.c b/utils/libmach/obj.c index fcb6dba8..7b1f1b62 100644 --- a/utils/libmach/obj.c +++ b/utils/libmach/obj.c @@ -3,6 +3,7 @@ * routines universal to all object files */ #include <lib9.h> +#include <ctype.h> #include <bio.h> #include <ar.h> #include "mach.h" @@ -19,19 +20,16 @@ enum HASHMUL = 79L, }; -int _is2(char*), /* in [$OS].c */ - _is5(char*), +/* in [$OS].c */ +int _is5(char*), _is6(char*), - _is7(char*), _is8(char*), _is9(char*), _isk(char*), _isq(char*), _isv(char*), - _read2(Biobuf*, Prog*), _read5(Biobuf*, Prog*), _read6(Biobuf*, Prog*), - _read7(Biobuf*, Prog*), _read8(Biobuf*, Prog*), _read9(Biobuf*, Prog*), _readk(Biobuf*, Prog*), @@ -50,7 +48,7 @@ struct Obj /* functions to handle each intermediate (.$O) file */ static Obj obj[] = { /* functions to identify and parse each type of obj */ - /*[Obj68020]*/ "68020 .2", _is2, _read2, + /*[Obj68020]*/ {0, 0,}, /*[ObjSparc]*/ "sparc .k", _isk, _readk, /*[ObjMips]*/ "mips .v", _isv, _readv, /*[Obj386]*/ "386 .8", _is8, _read8, diff --git a/utils/libmach/qdb.c b/utils/libmach/qdb.c index 14291486..636b5510 100644 --- a/utils/libmach/qdb.c +++ b/utils/libmach/qdb.c @@ -672,7 +672,7 @@ static char ir2[] = "R%a,R%d"; /* reverse of IBM order */ static char ir3[] = "R%b,R%a,R%d"; static char ir3r[] = "R%a,R%b,R%d"; static char il3[] = "R%b,R%s,R%a"; -static char il2u[] = "%I,R%a,R%d"; +static char il2u[] = "%I,R%d,R%a"; static char il3s[] = "$%k,R%s,R%a"; static char il2[] = "R%s,R%a"; static char icmp3[] = "R%a,R%b,%D"; @@ -857,6 +857,8 @@ static Opcode opcodes[] = { {31, 659, ALL, "MOVW", gen, "SEG(R%b),R%d"}, {31, 323, ALL, "MOVW", gen, "DCR(%Q),R%d"}, {31, 451, ALL, "MOVW", gen, "R%s,DCR(%Q)"}, + {31, 259, ALL, "MOVW", gen, "DCR(R%a),R%d"}, + {31, 387, ALL, "MOVW", gen, "R%s,DCR(R%a)"}, {31, 144, ALL, "MOVFL", gen, "R%s,%m,CR"}, {63, 70, ALL, "MTFSB0%C", gencc, "%D"}, {63, 38, ALL, "MTFSB1%C", gencc, "%D"}, diff --git a/utils/libmach/qobj.c b/utils/libmach/qobj.c index e5a2222b..79d1c640 100644 --- a/utils/libmach/qobj.c +++ b/utils/libmach/qobj.c @@ -4,7 +4,7 @@ */ #include <lib9.h> #include <bio.h> -#include <mach.h> +#include "mach.h" #include "qc/q.out.h" #include "obj.h" diff --git a/utils/libmach/setmach.c b/utils/libmach/setmach.c index 4332dc9d..7247881c 100644 --- a/utils/libmach/setmach.c +++ b/utils/libmach/setmach.c @@ -15,10 +15,10 @@ struct machtab Machdata *machdata; /* machine functions */ }; -extern Mach mmips, msparc, m68020, mi386, mamd64, - marm, mmips2be, mmips2le, mpower, mpower64, malpha, msparc64; -extern Machdata mipsmach, sparcmach, m68020mach, i386mach, - armmach, mipsmach2le, powermach, alphamach, sparc64mach; +extern Mach mmips, msparc, mi386, mamd64, + marm, mmips2be, mmips2le, mpower, mpower64; +extern Machdata mipsmach, sparcmach, i386mach, + armmach, mipsmach2le, powermach; /* * machine selection table. machines with native disassemblers should @@ -27,18 +27,6 @@ extern Machdata mipsmach, sparcmach, m68020mach, i386mach, */ Machtab machines[] = { - { "68020", /*68020*/ - F68020, - F68020B, - A68020, - &m68020, - &m68020mach, }, - { "68020", /*Next 68040 bootable*/ - F68020, - FNEXTB, - A68020, - &m68020, - &m68020mach, }, { "mips2LE", /*plan 9 mips2 little endian*/ FMIPS2LE, 0, diff --git a/utils/libmach/sym.c b/utils/libmach/sym.c index 751d933d..5651d4e6 100644 --- a/utils/libmach/sym.c +++ b/utils/libmach/sym.c @@ -188,8 +188,6 @@ syminit(int fd, Fhdr *fp) } pclineend = pcline+fp->lnpcsz; } - if(fp->type == FARM) /* thumb pc table */ - thumbpctab(&b, fp); return nsym; } diff --git a/utils/libmach/ureg2.h b/utils/libmach/ureg2.h deleted file mode 100644 index e237cb3d..00000000 --- a/utils/libmach/ureg2.h +++ /dev/null @@ -1,28 +0,0 @@ -struct Ureg -{ - ulong r0; - ulong r1; - ulong r2; - ulong r3; - ulong r4; - ulong r5; - ulong r6; - ulong r7; - ulong a0; - ulong a1; - ulong a2; - ulong a3; - ulong a4; - ulong a5; - ulong a6; - ulong sp; - ulong usp; - ulong magic; /* for db to find bottom of ureg */ - ushort sr; - ulong pc; - ushort vo; -#ifndef UREGVARSZ -#define UREGVARSZ 23 /* for 68040; 15 is enough on 68020 */ -#endif - uchar microstate[UREGVARSZ]; /* variable-sized portion */ -}; diff --git a/utils/libmach/vobj.c b/utils/libmach/vobj.c index 39f132e7..3deadb58 100644 --- a/utils/libmach/vobj.c +++ b/utils/libmach/vobj.c @@ -3,7 +3,7 @@ */ #include <lib9.h> #include <bio.h> -#include <mach.h> +#include "mach.h" #include "vc/v.out.h" #include "obj.h" @@ -41,7 +41,7 @@ _readv(Biobuf *bp, Prog *p) if(as == ANAME || as == ASIGNAME){ if(as == ASIGNAME){ Bread(bp, &p->sig, 4); - p->sig = beswal(p->sig); + p->sig = leswal(p->sig); } p->kind = aName; p->type = type2char(Bgetc(bp)); /* type */ diff --git a/utils/mk/Posix.c b/utils/mk/Posix.c index 63ad17f5..95e1919e 100644 --- a/utils/mk/Posix.c +++ b/utils/mk/Posix.c @@ -317,7 +317,8 @@ membername(char *s, int fd, char *sz) t = atol(sz); if(t&01) t++; stab = malloc(t); - read(fd, stab, t); + if(read(fd, stab, t) != t) + {} return nil; } else if(s[0] == '/' && stab != nil) { /* index into string table */ diff --git a/utils/mkfile b/utils/mkfile index bf6be6eb..b697b42f 100644 --- a/utils/mkfile +++ b/utils/mkfile @@ -10,19 +10,6 @@ ALWAYS=\ libregexp\ iar\ cc\ - 0a\ - 0c\ - 0l\ - 1a\ - 1c\ - 1l\ - 2a\ - 2c\ - 2l\ - 5a\ - 5c\ - 5l\ -# 5i\ 5coff\ 5cv\ sqz\ @@ -44,6 +31,9 @@ ALWAYS=\ # NOTPLAN9=\ iyacc\ + 5a\ + 5c\ + 5l\ 8a\ 8c\ 8l\ @@ -79,6 +69,14 @@ NTONLY=\ test\ tr\ +# +# Thumb-1 +# +OBSOLETE=\ + ta\ + tc\ + tl\ + all:QV: all-$TARGMODEL clean:QV: clean-$TARGMODEL install:QV: install-$TARGMODEL diff --git a/utils/nm/nm.c b/utils/nm/nm.c index 147d1d3a..d20e3c84 100644 --- a/utils/nm/nm.c +++ b/utils/nm/nm.c @@ -147,7 +147,7 @@ dofile(Biobuf *bp) * this screws up on 'z' records when aflag == 1 */ int -cmp(const void *vs, const void *vt) +cmp(void *vs, void *vt) { Sym **s, **t; diff --git a/utils/qa/Ins b/utils/qa/Ins deleted file mode 100644 index d113e845..00000000 --- a/utils/qa/Ins +++ /dev/null @@ -1,203 +0,0 @@ -a OR XO(31,10) -abs OR XO(31,360) -ae OR XO(31,138) -ai 0 D(12) + - -ai. 0 D(13) -ame OR XO(31,234) -and R X(31,28) -andc R X(31,60) - -andil. 0 D(28,0) -andiu. 0 D(29,0) -aze OR XO(31,202) -cal 0 D(14) - -cau 0 D(15) -cax OR XO(31,266) -cmp 0 X(31,0) -cmpi 0 D(11) - -cmpl 0 X(31,32) -cmpli 0 D(10) -cntlz R X(31,26) -crand 0 XL(19,257) - -crandc 0 XL(19,129) -creqv 0 XL(19,289) -crnand 0 XL(19,225) -crnor 0 XL(19,33) - -cror 0 XL(19,449) -crorc 0 XL(19,417) -crxor 0 XL(19,193) -div OR XO(31,331) - -divs OR XO(31,331) -doz OR XO(31,264) -dozi 0 D(9) - -eqv R X(31,284) -exts R X(31,922) -fa R A(63,21) -fabs R X(63,264) -fcmpo 0 X(63,32) - -fcmpu 0 X(63,0) -fd R A(63,8) -fm R A(63,5) -fma R A(63,29) - -fmr R X(63,72) -fms R A(63,28) -fnabs R X(63,136) -fneg R X(63,40) - -fnma R A(63,31) -fnms R A(63,30) -frsp R X(63,12) -fs R A(63,20) - -l 0 D(32) -lbrx 0 X(31,534) -lbz 0 D(34) -lbzu 0 D(35) - -lbzux 0 X(31,119) -lbzx 0 X(31,87) -lfd 0 D(50) -lfdu 0 D(51) - -lfdux 0 X(31,631) -lfdx 0 X(31,599) -lfs 0 D(48) -lfsu 0 D(49) - -lfsux 0 X(31,567) -lfsx 0 X(31,535) -lha 0 D(42) -lhau 0 D(43) - -lhaux 0 X(31,375) -lhax 0 X(31,343) -lhbrx 0 X(31,790) -lhz 0 D(40) - -lhzu 0 D(41) -lhzux 0 X(31,311) -lhzx 0 X(31,279) -lm 0 D(46) - -lscbx R X(31,277) -lsi 0 X(31,597) -lsx 0 X(31,533) -lu 0 D(33) - -lux 0 X(31,55) -lx 0 X(31,23) -maskg R X(31,29) -maskir R X(31,541) - -mcrf 0 XL(19,0) -mcrfs 0 X(63,64) -mcrxr 0 X(31,512) -mfcr 0 X(31,19) - -mffs R X(63,583) -mfmsr 0 X(31,83) -mfspr 0 X(31,339) -mtcrf 0 XFX(31,144) - -mtfsb0 R X(63,70) -mtfsb1 R X(63,38) -mtfsf R XFL(63,711) -mtfsfi R X(63,134) - -mtspr 0 X(31,467) -mul OR XO(31,107) -muli 0 D(7) -muls OR XO(31,235) - -nabs OR XO(31,488) -nand R X(31,476) -neg OR XO(31,104) - -nor R X(31,124) -or R X(31,444) -orc R X(31,412) -oril 0 D(24) - -oriu 0 D(25) -rlmi R M(20) -rlinm R M(21) -rlmi R M(22) - -rlnm R M(23) -rrib R X(31,537) -sf OR XO(31,8) -sfe OR XO(31,36) - -sfi 0 D(8) -sfme OR XO(31,232) -sfze OR XO(31,200) -sl R X(31,24) - -sle R X(31,153) -sleq R X(31,217) -sliq R X(31,184) -slliq R X(31,248) - -sllq R X(31,216) -slq R X(31,152) -sr R X(31,536) -sra R X(31,792) - -srai R X(31,824) -sraiq R X(31,952) -sraq R X(31,920) -sre R X(31,665) - -srea R X(31,921) -sreq R X(31,729) -sriq R X(31,696) -srliq R X(31,760) -srlq R X(31,728) - -srq R X(31,664) -st 0 D(36) -stb 0 D(38) -stbrx 0 X(31,662) - -stbu 0 D(39) -stbux 0 X(31,247) -stbx 0 X(31,215) -stfd 0 D(54) - -stfdu 0 D(55) -stfdux 0 X(31,759) -stfdx 0 X(31,727) -stfs 0 D(52) - -stfsu 0 D(53) -stfsux 0 X(31,695) -stfsx 0 X(31,663) -sth 0 D(44) - -sthbrx 0 X(31,918) -sthu 0 D(45) -sthux 0 X(31,439) -sthx 0 X(3,407) - -stm 0 D(47) -stsi 0 X(31,725) -stsx 0 X(31,661) -stu 0 D(37) - -stux 0 X(31,183) -stx 0 X(31,151) -svc 0 SC(17) -t 0 X(31,4) -ti 0 D(3) -xor R X(31,316) -xoril 0 D(26) -xoriu 0 D(27) diff --git a/utils/qa/branch b/utils/qa/branch deleted file mode 100644 index 8092a2c5..00000000 --- a/utils/qa/branch +++ /dev/null @@ -1,37 +0,0 @@ -BO operand encodings - -0+y 0000y decrement CTR, then branch if CTR != 0 && condition is false -2+y 0001y decrement CTR, then branch if CTR == 0 && condition is false -4+y 0010y branch if condition is false -8+y 0100y decrement CTR, then branch if CTR != 0 && condition is true -10+y 0101y decrement CTR, then branch if CTR == 0 && condition is true -12+y 0110y branch if condition is true -16+y 1000y decrement CTR, then branch if CTR != 0 -18+y 1001y decrement CTR, then branch if CTR == 0 -20 10100 branch always - -y=0: - BCx with negative displacement: branch probably taken - all other cases: branch not taken - -y=1: - reverse prediction - -predict to be taken if - ((BO[0] & BO[2]) | sign(displacement)) xor y - -CR field bit: - -lt 0 -gt 1 -eq 2 -so 3 -un 3 (after fp comparison) - -CR fields: - -cr0 0 -cr1 4 -cr2 8 -... -cr7 28 diff --git a/utils/qa/lex.c b/utils/qa/lex.c index 5f1dd202..afa3a708 100644 --- a/utils/qa/lex.c +++ b/utils/qa/lex.c @@ -679,7 +679,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { ALLOCN(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } } diff --git a/utils/qc/gc.h b/utils/qc/gc.h index f82e2e1c..64a88a16 100644 --- a/utils/qc/gc.h +++ b/utils/qc/gc.h @@ -27,10 +27,12 @@ typedef struct Rgn Rgn; struct Adr { - long offset; - double dval; - char sval[NSNAME]; - +/* union */ +/* { */ + long offset; + double dval; + char sval[NSNAME]; +/* }; */ Sym* sym; char type; char reg; @@ -55,7 +57,7 @@ struct Prog struct Case { Case* link; - long val; + vlong val; long label; char def; char isv; @@ -64,7 +66,7 @@ struct Case struct C1 { - long val; + vlong val; long label; }; @@ -107,9 +109,11 @@ struct Reg long regu; long loop; /* could be shorter */ - Reg* log5; - int active; - +/* union */ +/* { */ + Reg* log5; + long active; +/* }; */ Reg* p1; Reg* p2; Reg* p2link; @@ -267,7 +271,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void swit2(C1*, int, long, Node*, Node*); @@ -279,7 +283,6 @@ int mulcon(Node*, Node*); Multab* mulcon0(Node*, long); int mulcon1(Node*, long, Node*); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); diff --git a/utils/qc/list.c b/utils/qc/list.c index f0f98a13..cf573e33 100644 --- a/utils/qc/list.c +++ b/utils/qc/list.c @@ -70,7 +70,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a <= ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/qc/peep.c b/utils/qc/peep.c index 89fc431a..6a1e64f8 100644 --- a/utils/qc/peep.c +++ b/utils/qc/peep.c @@ -425,8 +425,6 @@ subprop(Reg *r0) case AREMU: case ARLWNM: case ARLWNMCC: - case ARLWMI: - case ARLWMICC: case AFADD: case AFADDS: @@ -624,7 +622,6 @@ copyu(Prog *p, Adr *v, Adr *s) print(" (?)"); return 2; - case ANOP: /* read, write */ case AMOVW: case AMOVH: @@ -669,6 +666,12 @@ copyu(Prog *p, Adr *v, Adr *s) return 1; return 0; + case ARLWMI: /* read read rar */ + case ARLWMICC: + if(copyas(&p->to, v)) + return 2; + /* fall through */ + case AADD: /* read read write */ case AADDC: case AADDE: @@ -696,8 +699,6 @@ copyu(Prog *p, Adr *v, Adr *s) case ADIVWU: case AREM: case AREMU: - case ARLWMI: - case ARLWMICC: case ARLWNM: case ARLWNMCC: diff --git a/utils/qc/swt.c b/utils/qc/swt.c index f0edacc8..53105643 100644 --- a/utils/qc/swt.c +++ b/utils/qc/swt.c @@ -240,23 +240,6 @@ loop: } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0)); - p->from.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { if(a->op == OCONST && typev[a->type->etype]) { @@ -657,8 +640,8 @@ maxround(long max, long v) w = SZ_LONG; if((debug['8'] || hasdoubled) && !debug['4']) w = SZ_DOUBLE; - v += w-1; + v = round(v, w); if(v > max) - max = round(v, w); + return v; return max; } diff --git a/utils/qc/txt.c b/utils/qc/txt.c index 1c6f4d7f..d85b66e9 100644 --- a/utils/qc/txt.c +++ b/utils/qc/txt.c @@ -15,6 +15,7 @@ ginit(void) thestring = "power"; exregoffset = REGEXT; exfregoffset = FREGEXT; + newvlongcode = 1; listinit(); nstring = 0; mnstring = 0; @@ -27,6 +28,8 @@ ginit(void) lastp = P; tfield = types[TLONG]; + typeswitch = typechlv; + zprog.link = P; zprog.as = AGOK; zprog.reg = NREG; @@ -1534,6 +1537,7 @@ gopcode64(int o, Node *f1, Node *f2, Node *t) } } +int samaddr(Node *f, Node *t) { diff --git a/utils/ql/Ins b/utils/ql/Ins deleted file mode 100644 index d113e845..00000000 --- a/utils/ql/Ins +++ /dev/null @@ -1,203 +0,0 @@ -a OR XO(31,10) -abs OR XO(31,360) -ae OR XO(31,138) -ai 0 D(12) + - -ai. 0 D(13) -ame OR XO(31,234) -and R X(31,28) -andc R X(31,60) - -andil. 0 D(28,0) -andiu. 0 D(29,0) -aze OR XO(31,202) -cal 0 D(14) - -cau 0 D(15) -cax OR XO(31,266) -cmp 0 X(31,0) -cmpi 0 D(11) - -cmpl 0 X(31,32) -cmpli 0 D(10) -cntlz R X(31,26) -crand 0 XL(19,257) - -crandc 0 XL(19,129) -creqv 0 XL(19,289) -crnand 0 XL(19,225) -crnor 0 XL(19,33) - -cror 0 XL(19,449) -crorc 0 XL(19,417) -crxor 0 XL(19,193) -div OR XO(31,331) - -divs OR XO(31,331) -doz OR XO(31,264) -dozi 0 D(9) - -eqv R X(31,284) -exts R X(31,922) -fa R A(63,21) -fabs R X(63,264) -fcmpo 0 X(63,32) - -fcmpu 0 X(63,0) -fd R A(63,8) -fm R A(63,5) -fma R A(63,29) - -fmr R X(63,72) -fms R A(63,28) -fnabs R X(63,136) -fneg R X(63,40) - -fnma R A(63,31) -fnms R A(63,30) -frsp R X(63,12) -fs R A(63,20) - -l 0 D(32) -lbrx 0 X(31,534) -lbz 0 D(34) -lbzu 0 D(35) - -lbzux 0 X(31,119) -lbzx 0 X(31,87) -lfd 0 D(50) -lfdu 0 D(51) - -lfdux 0 X(31,631) -lfdx 0 X(31,599) -lfs 0 D(48) -lfsu 0 D(49) - -lfsux 0 X(31,567) -lfsx 0 X(31,535) -lha 0 D(42) -lhau 0 D(43) - -lhaux 0 X(31,375) -lhax 0 X(31,343) -lhbrx 0 X(31,790) -lhz 0 D(40) - -lhzu 0 D(41) -lhzux 0 X(31,311) -lhzx 0 X(31,279) -lm 0 D(46) - -lscbx R X(31,277) -lsi 0 X(31,597) -lsx 0 X(31,533) -lu 0 D(33) - -lux 0 X(31,55) -lx 0 X(31,23) -maskg R X(31,29) -maskir R X(31,541) - -mcrf 0 XL(19,0) -mcrfs 0 X(63,64) -mcrxr 0 X(31,512) -mfcr 0 X(31,19) - -mffs R X(63,583) -mfmsr 0 X(31,83) -mfspr 0 X(31,339) -mtcrf 0 XFX(31,144) - -mtfsb0 R X(63,70) -mtfsb1 R X(63,38) -mtfsf R XFL(63,711) -mtfsfi R X(63,134) - -mtspr 0 X(31,467) -mul OR XO(31,107) -muli 0 D(7) -muls OR XO(31,235) - -nabs OR XO(31,488) -nand R X(31,476) -neg OR XO(31,104) - -nor R X(31,124) -or R X(31,444) -orc R X(31,412) -oril 0 D(24) - -oriu 0 D(25) -rlmi R M(20) -rlinm R M(21) -rlmi R M(22) - -rlnm R M(23) -rrib R X(31,537) -sf OR XO(31,8) -sfe OR XO(31,36) - -sfi 0 D(8) -sfme OR XO(31,232) -sfze OR XO(31,200) -sl R X(31,24) - -sle R X(31,153) -sleq R X(31,217) -sliq R X(31,184) -slliq R X(31,248) - -sllq R X(31,216) -slq R X(31,152) -sr R X(31,536) -sra R X(31,792) - -srai R X(31,824) -sraiq R X(31,952) -sraq R X(31,920) -sre R X(31,665) - -srea R X(31,921) -sreq R X(31,729) -sriq R X(31,696) -srliq R X(31,760) -srlq R X(31,728) - -srq R X(31,664) -st 0 D(36) -stb 0 D(38) -stbrx 0 X(31,662) - -stbu 0 D(39) -stbux 0 X(31,247) -stbx 0 X(31,215) -stfd 0 D(54) - -stfdu 0 D(55) -stfdux 0 X(31,759) -stfdx 0 X(31,727) -stfs 0 D(52) - -stfsu 0 D(53) -stfsux 0 X(31,695) -stfsx 0 X(31,663) -sth 0 D(44) - -sthbrx 0 X(31,918) -sthu 0 D(45) -sthux 0 X(31,439) -sthx 0 X(3,407) - -stm 0 D(47) -stsi 0 X(31,725) -stsx 0 X(31,661) -stu 0 D(37) - -stux 0 X(31,183) -stx 0 X(31,151) -svc 0 SC(17) -t 0 X(31,4) -ti 0 D(3) -xor R X(31,316) -xoril 0 D(26) -xoriu 0 D(27) diff --git a/utils/ql/Notes b/utils/ql/Notes deleted file mode 100644 index 1620b508..00000000 --- a/utils/ql/Notes +++ /dev/null @@ -1,21 +0,0 @@ -possible input transformations - adde $-1,X => addme X - adde $0,X => addze X - subw $s,X => addw $-s,X - orn $v,X => or $~v,X - -qa: - subc r1,$s,r2 => subc $s,r1,r2 - movw sreg(Rn),Rm => movw sreg(NREG),Rn,Rm [and v.v.] - -others? - andn $m => and $~m - slw $sh,s,a => rliwnm - srw $sh,s,a => rliwnm - -support for C_LCON needed since addresses are literals? - -- moves -- branch distance - -- could rewrite movwu x,d(r) as movw $d,tmp; movwu x,(tmp+d) when d is large? diff --git a/utils/ql/Plan9.c b/utils/ql/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/ql/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/ql/Posix.c b/utils/ql/Posix.c deleted file mode 100644 index 0da0ee0c..00000000 --- a/utils/ql/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fails if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} diff --git a/utils/ql/asm.c b/utils/ql/asm.c index be1a57a1..abcab5e3 100644 --- a/utils/ql/asm.c +++ b/utils/ql/asm.c @@ -1,6 +1,5 @@ #include "l.h" -#define KMASK 0xF0000000 #define JMPSZ sizeof(u32int) /* size of bootstrap jump section */ #define LPUT(c)\ @@ -45,6 +44,14 @@ entryvalue(void) return s->value; } +static void +elf32jmp(Putl putl) +{ + /* describe a tiny text section at end with jmp to start; see below */ + elf32phdr(putl, PT_LOAD, HEADR+textsize-JMPSZ, 0xFFFFFFFC, 0xFFFFFFFC, + JMPSZ, JMPSZ, R|X, 0); /* text */ +} + void asmb(void) { @@ -86,17 +93,13 @@ asmb(void) if (prevpc & (1<<31) && (pc & (1<<31)) == 0) { char *tn; - tn = "?none?"; + tn = "??none??"; if(curtext != P && curtext->from.sym != S) tn = curtext->from.sym->name; Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn); } prevpc = pc; } - /* for virtex 4, inject a jmp instruction after other text */ - if(HEADTYPE == 6) - /* branch to absolute entry address (0xfffe2100) */ - lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2); if(debug['a']) Bprint(&bso, "\n"); @@ -107,7 +110,13 @@ asmb(void) curtext = P; switch(HEADTYPE) { case 6: + /* + * but first, for virtex 4, inject a jmp instruction after + * other text: branch to absolute entry address (0xfffe2100). + */ + lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2); textsize += JMPSZ; + cflush(); /* fall through */ case 0: case 1: @@ -315,180 +324,16 @@ asmb(void) break; case 5: /* - * customised for blue/gene, - * notably the alignment and KMASK masking. + * intended for blue/gene */ - strnput("\177ELF", 4); /* e_ident */ - CPUT(1); /* class = 32 bit */ - CPUT(2); /* data = MSB */ - CPUT(1); /* version = CURRENT */ - strnput("", 9); - lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ - lput(1L); /* version = CURRENT */ - lput(entryvalue() & ~KMASK); /* entry vaddr */ - lput(52L); /* offset to first phdr */ - - if(debug['S']){ - lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */ - lput(0L); /* flags = PPC */ - lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ - lput((3L<<16)|40L); /* # Phdrs & Shdr size */ - lput((3L<<16)|2L); /* # Shdrs & shdr string size */ - } - else{ - lput(0L); - lput(0L); /* flags = PPC */ - lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ - lput((3L<<16)|0L); /* # Phdrs & Shdr size */ - lput((3L<<16)|0L); /* # Shdrs & shdr string size */ - } - - lput(1L); /* text - type = PT_LOAD */ - lput(HEADR); /* file offset */ - lput(INITTEXT & ~KMASK); /* vaddr */ - lput(INITTEXT); /* paddr */ - lput(textsize); /* file size */ - lput(textsize); /* memory size */ - lput(0x05L); /* protections = RX */ - lput(0x10000L); /* alignment */ - - lput(1L); /* data - type = PT_LOAD */ - lput(HEADR+textsize); /* file offset */ - lput(INITDAT & ~KMASK); /* vaddr */ - lput(INITDAT); /* paddr */ - lput(datsize); /* file size */ - lput(datsize); /* memory size */ - lput(0x07L); /* protections = RWX */ - lput(0x10000L); /* alignment */ - - lput(0L); /* data - type = PT_NULL */ - lput(HEADR+textsize+datsize); /* file offset */ - lput(0L); /* vaddr */ - lput(0L); /* paddr */ - lput(symsize); /* symbol table size */ - lput(lcsize); /* line number size */ - lput(0x04L); /* protections = R */ - lput(0x04L); /* alignment code?? */ - cflush(); - - if(!debug['S']) - break; - - seek(cout, HEADR+textsize+datsize+symsize, 0); - lput(1); /* Section name (string tbl index) */ - lput(1); /* Section type */ - lput(2|4); /* Section flags */ - lput(INITTEXT & ~KMASK); /* Section virtual addr at execution */ - lput(HEADR); /* Section file offset */ - lput(textsize); /* Section size in bytes */ - lput(0); /* Link to another section */ - lput(0); /* Additional section information */ - lput(0x10000L); /* Section alignment */ - lput(0); /* Entry size if section holds table */ - - lput(7); /* Section name (string tbl index) */ - lput(1); /* Section type */ - lput(2|1); /* Section flags */ - lput(INITDAT & ~KMASK); /* Section virtual addr at execution */ - lput(HEADR+textsize); /* Section file offset */ - lput(datsize); /* Section size in bytes */ - lput(0); /* Link to another section */ - lput(0); /* Additional section information */ - lput(0x10000L); /* Section alignment */ - lput(0); /* Entry size if section holds table */ - - /* string section header */ - lput(12); /* Section name (string tbl index) */ - lput(3); /* Section type */ - lput(1 << 5); /* Section flags */ - lput(0); /* Section virtual addr at execution */ - lput(HEADR+textsize+datsize+symsize+3*40); /* Section file offset */ - lput(14); /* Section size in bytes */ - lput(0); /* Link to another section */ - lput(0); /* Additional section information */ - lput(1); /* Section alignment */ - lput(0); /* Entry size if section holds table */ - - /* string table */ - cput(0); - strnput(".text", 5); - cput(0); - strnput(".data", 5); - cput(0); - strnput(".strtab", 7); - cput(0); - cput(0); - + elf32(POWER, ELFDATA2MSB, 0, nil); break; case 6: /* - * customised for virtex 4 boot, - * notably the alignment and KMASK masking. + * intended for virtex 4 boot */ - strnput("\177ELF", 4); /* e_ident */ - CPUT(1); /* class = 32 bit */ - CPUT(2); /* data = MSB */ - CPUT(1); /* version = CURRENT */ - strnput("", 9); - lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ - lput(1L); /* version = CURRENT */ - lput(entryvalue()); /* entry vaddr */ - lput(52L); /* offset to first phdr */ - - debug['S'] = 1; /* no symbol table */ - if(debug['S']){ - lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */ - lput(0L); /* flags = PPC */ - lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ - lput((4L<<16)|40L); /* # Phdrs & Shdr size */ - lput((4L<<16)|2L); /* # Shdrs & shdr string size */ - } - else{ - lput(0L); - lput(0L); /* flags = PPC */ - lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ - lput((4L<<16)|0L); /* # Phdrs & Shdr size */ - lput((4L<<16)|0L); /* # Shdrs & shdr string size */ - } - - lput(1L); /* text - type = PT_LOAD */ - lput(HEADR); /* file offset */ - lput(INITTEXT); /* vaddr */ - lput(INITTEXT); /* paddr */ - lput(textsize-JMPSZ); /* file size */ - lput(textsize-JMPSZ); /* memory size */ - lput(0x05L); /* protections = RX */ - lput(0); /* alignment */ - - lput(1L); /* data - type = PT_LOAD */ - lput(HEADR+textsize); /* file offset */ - lput(INITDAT); /* vaddr */ - lput(INITDAT); /* paddr */ - lput(datsize); /* file size */ - lput(datsize+bsssize); /* memory size */ - lput(0x07L); /* protections = RWX */ - lput(0); /* alignment */ - - lput(0L); /* data - type = PT_NULL */ - lput(HEADR+textsize+datsize); /* file offset */ - lput(0L); /* vaddr */ - lput(0L); /* paddr */ - lput(symsize); /* symbol table size */ - lput(lcsize); /* line number size */ - lput(0x04L); /* protections = R */ - lput(0x04L); /* alignment code?? */ - - /* add tiny text section at end with jmp to start */ - lput(1L); /* text - type = PT_LOAD */ - lput(HEADR+textsize-JMPSZ); /* file offset */ - lput(0xFFFFFFFC); /* vaddr */ - lput(0xFFFFFFFC); /* paddr */ - lput(JMPSZ); /* file size */ - lput(JMPSZ); /* memory size */ - lput(0x05L); /* protections = RX */ - lput(0); /* disable alignment */ - - cflush(); + debug['S'] = 1; /* symbol table */ + elf32(POWER, ELFDATA2MSB, 1, elf32jmp); break; } cflush(); @@ -523,13 +368,50 @@ wput(long l) } void -lput(long l) +wputl(long l) { + cbp[0] = l; + cbp[1] = l>>8; + cbp += 2; + cbc -= 2; + if(cbc <= 0) + cflush(); +} +void +lput(long l) +{ LPUT(l); } void +lputl(long c) +{ + cbp[0] = (c); + cbp[1] = (c)>>8; + cbp[2] = (c)>>16; + cbp[3] = (c)>>24; + cbp += 4; + cbc -= 4; + if(cbc <= 0) + cflush(); +} + +void +llput(vlong v) +{ + lput(v>>32); + lput(v); +} + +void +llputl(vlong v) +{ + lputl(v); + lputl(v>>32); +} + +void cflush(void) { int n; @@ -665,12 +547,12 @@ asmlc(void) if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { if(p->as == ATEXT) curtext = p; - if(debug['L']) + if(debug['V']) Bprint(&bso, "%6lux %P\n", p->pc, p); continue; } - if(debug['L']) + if(debug['V']) Bprint(&bso, "\t\t%6ld", lcsize); v = (p->pc - oldpc) / MINLC; while(v) { @@ -678,7 +560,7 @@ asmlc(void) if(v < 127) s = v; CPUT(s+128); /* 129-255 +pc */ - if(debug['L']) + if(debug['V']) Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); v -= s; lcsize++; @@ -692,7 +574,7 @@ asmlc(void) CPUT(s>>16); CPUT(s>>8); CPUT(s); - if(debug['L']) { + if(debug['V']) { if(s > 0) Bprint(&bso, " lc+%ld(%d,%ld)\n", s, 0, s); @@ -707,14 +589,14 @@ asmlc(void) } if(s > 0) { CPUT(0+s); /* 1-64 +lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); Bprint(&bso, "%6lux %P\n", p->pc, p); } } else { CPUT(64-s); /* 65-128 -lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); Bprint(&bso, "%6lux %P\n", p->pc, p); @@ -727,7 +609,7 @@ asmlc(void) CPUT(s); lcsize++; } - if(debug['v'] || debug['L']) + if(debug['v'] || debug['V']) Bprint(&bso, "lcsize = %ld\n", lcsize); Bflush(&bso); } diff --git a/utils/ql/l.h b/utils/ql/l.h index 4ef775c0..6a33c606 100644 --- a/utils/ql/l.h +++ b/utils/ql/l.h @@ -1,11 +1,14 @@ #include <lib9.h> #include <bio.h> #include "../qc/q.out.h" +#include "../8l/elf.h" #ifndef EXTERN #define EXTERN extern #endif +#define LIBNAMELEN 300 + typedef struct Adr Adr; typedef struct Sym Sym; typedef struct Autom Auto; @@ -186,6 +189,7 @@ EXTERN int HEADTYPE; /* type of header */ EXTERN long INITDAT; /* data location */ EXTERN long INITRND; /* data round above text location */ EXTERN long INITTEXT; /* text location */ +EXTERN long INITTEXTP; /* text location (physical) */ EXTERN char* INITENTRY; /* entry point */ EXTERN long autosize; EXTERN Biobuf bso; @@ -259,6 +263,7 @@ int Rconv(Fmt*); int aclass(Adr*); void addhist(long, int); void histtoauto(void); +void addlibpath(char*); void addnop(Prog*); void append(Prog*, Prog*); void asmb(void); @@ -285,7 +290,9 @@ long entryvalue(void); void errorexit(void); void exchange(Prog*); void export(void); +int fileexists(char*); int find1(long, int); +char* findlib(char*); void follow(void); void gethunk(void); double ieeedtod(Ieee*); @@ -297,7 +304,10 @@ void loadlib(void); void listinit(void); void initmuldiv(void); Sym* lookup(char*, int); +void llput(vlong); +void llputl(vlong); void lput(long); +void lputl(long); void mkfwd(void); void* mysbrk(ulong); void names(void); @@ -321,9 +331,11 @@ int relinv(int); long rnd(long, long); void sched(Prog*, Prog*); void span(void); +void strnput(char*, int); void undef(void); void undefsym(Sym*); void wput(long); +void wputl(long); void xdefine(char*, int, long); void xfol(Prog*); void zerosig(char*); diff --git a/utils/ql/list.c b/utils/ql/list.c index 04139dfc..90fa2af3 100644 --- a/utils/ql/list.c +++ b/utils/ql/list.c @@ -63,7 +63,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/ql/mkfile b/utils/ql/mkfile index 1296b005..183d1a90 100644 --- a/utils/ql/mkfile +++ b/utils/ql/mkfile @@ -15,6 +15,7 @@ OFILES=\ cnam.$O\ sched.$O\ $TARGMODEL.$O\ + elf.$O\ HFILES=\ l.h\ @@ -27,10 +28,15 @@ BIN=$ROOT/$OBJDIR/bin <$ROOT/mkfiles/mkone-$SHELLTYPE -CFLAGS= $CFLAGS -I../include +CFLAGS= $CFLAGS -I../include -I. enam.$O: ../qc/enam.c $CC $CFLAGS ../qc/enam.c +elf.$O: ../ld/elf.c + $CC $CFLAGS ../ld/elf.c #cnam.c: l.h # rc mkcname + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/ql/obj.c b/utils/ql/obj.c index 8026a0de..620d6536 100644 --- a/utils/ql/obj.c +++ b/utils/ql/obj.c @@ -14,6 +14,10 @@ char symname[] = SYMDEF; char thechar = 'q'; char *thestring = "power"; +char** libdir; +int nlibdir = 0; +static int maxlibdir = 0; + /* * -H0 -T0x200000 -R0 is boot * -H1 -T0x100000 -R4 is Be boot @@ -26,6 +30,13 @@ char *thestring = "power"; * appropriate for virtex 4 boot */ +void +usage(void) +{ + diag("usage: %s [-options] objects", argv0); + errorexit(); +} + static int isobjfile(char *f) { @@ -53,6 +64,7 @@ main(int argc, char *argv[]) { int c; char *a; + char name[LIBNAMELEN]; Binit(&bso, 1, OWRITE); cout = -1; @@ -62,6 +74,7 @@ main(int argc, char *argv[]) curtext = P; HEADTYPE = -1; INITTEXT = -1; + INITTEXTP = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; @@ -85,6 +98,11 @@ main(int argc, char *argv[]) if(a) INITTEXT = atolwhex(a); break; + case 'P': + a = ARGF(); + if(a) + INITTEXTP = atolwhex(a); + break; case 'D': a = ARGF(); if(a) @@ -100,6 +118,9 @@ main(int argc, char *argv[]) if(a) HEADTYPE = atolwhex(a); break; + case 'L': + addlibpath(EARGF(usage())); + break; case 'x': /* produce export table */ doexp = 1; if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) @@ -112,12 +133,20 @@ main(int argc, char *argv[]) break; } ARGEND USED(argc); - if(*argv == 0) { - diag("usage: ql [-options] objects"); - errorexit(); - } + if(*argv == 0) + usage(); if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; + a = getenv("ccroot"); + if(a != nil && *a != '\0') { + if(!fileexists(a)) { + diag("nonexistent $ccroot: %s", a); + errorexit(); + } + }else + a = ""; + snprint(name, sizeof(name), "%s/%s/lib", a, thestring); + addlibpath(name); r0iszero = debug['0'] == 0; if(HEADTYPE == -1) { if(debug['U']) @@ -180,8 +209,16 @@ main(int argc, char *argv[]) INITRND = 0; break; case 5: /* elf executable */ + HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16); + if(INITTEXT == -1) + INITTEXT = 0x00400000L+HEADR; + if(INITDAT == -1) + INITDAT = 0x10000000; + if(INITRND == -1) + INITRND = 0; + break; case 6: /* elf for virtex 4 */ - HEADR = rnd(52L+3*32L, 16); + HEADR = rnd(Ehdr32sz+4*Phdr32sz, 16); /* extra phdr for JMP */ if(INITTEXT == -1) INITTEXT = 0x00400000L+HEADR; if(INITDAT == -1) @@ -190,6 +227,8 @@ main(int argc, char *argv[]) INITRND = 0; break; } + if (INITTEXTP == -1) + INITTEXTP = INITTEXT; if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", INITDAT, INITRND); @@ -214,7 +253,7 @@ main(int argc, char *argv[]) outfile = "q.out"; cout = create(outfile, 1, 0775); if(cout < 0) { - diag("%s: cannot create", outfile); + diag("cannot create %s: %r", outfile); errorexit(); } nuxiinit(); @@ -230,7 +269,7 @@ main(int argc, char *argv[]) INITENTRY = "_mainp"; if(!debug['l']) lookup(INITENTRY, 0)->type = SXREF; - } else + } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9')) lookup(INITENTRY, 0)->type = SXREF; while(*argv) @@ -281,6 +320,42 @@ out: } void +addlibpath(char *arg) +{ + char **p; + + if(nlibdir >= maxlibdir) { + if(maxlibdir == 0) + maxlibdir = 8; + else + maxlibdir *= 2; + p = malloc(maxlibdir*sizeof(*p)); + if(p == nil) { + diag("out of memory"); + errorexit(); + } + memmove(p, libdir, nlibdir*sizeof(*p)); + free(libdir); + libdir = p; + } + libdir[nlibdir++] = strdup(arg); +} + +char* +findlib(char *file) +{ + int i; + char name[LIBNAMELEN]; + + for(i = 0; i < nlibdir; i++) { + snprint(name, sizeof(name), "%s/%s", libdir[i], file); + if(fileexists(name)) + return libdir[i]; + } + return nil; +} + +void loadlib(void) { int i; @@ -321,25 +396,26 @@ objfile(char *file) int f, work; Sym *s; char magbuf[SARMAG]; - char name[100], pname[150]; + char name[LIBNAMELEN], pname[LIBNAMELEN]; struct ar_hdr arhdr; char *e, *start, *stop; - if(file[0] == '-' && file[1] == 'l') { - if(debug['9']) - sprint(name, "/%s/lib/lib", thestring); - else - sprint(name, "/usr/%clib/lib", thechar); - strcat(name, file+2); - strcat(name, ".a"); - file = name; - } if(debug['v']) Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); Bflush(&bso); + if(file[0] == '-' && file[1] == 'l') { + snprint(pname, sizeof(pname), "lib%s.a", file+2); + e = findlib(pname); + if(e == nil) { + diag("cannot find library: %s", file); + errorexit(); + } + snprint(name, sizeof(name), "%s/%s", e, pname); + file = name; + } f = open(file, 0); if(f < 0) { - diag("cannot open file: %s", file); + diag("cannot open %s: %r", file); errorexit(); } l = read(f, magbuf, SARMAG); @@ -425,7 +501,7 @@ int zaddr(uchar *p, Adr *a, Sym *h[]) { int i, c; - long l; + int l; Sym *s; Auto *u; @@ -516,25 +592,24 @@ out: void addlib(char *obj) { - char name[1024], comp[256], *p; - int i; + char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name; + int i, search; if(histfrogp <= 0) return; + name = fn1; + search = 0; if(histfrog[0]->name[1] == '/') { sprint(name, ""); i = 1; - } else - if(histfrog[0]->name[1] == '.') { + } else if(histfrog[0]->name[1] == '.') { sprint(name, "."); i = 0; } else { - if(debug['9']) - sprint(name, "/%s/lib", thestring); - else - sprint(name, "/usr/%clib", thechar); + sprint(name, ""); i = 0; + search = 1; } for(; i<histfrogp; i++) { @@ -557,13 +632,25 @@ addlib(char *obj) memmove(p+strlen(thestring), p+2, strlen(p+2)+1); memmove(p, thestring, strlen(thestring)); } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { + if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) { diag("library component too long"); return; } - strcat(name, "/"); - strcat(name, comp); + if(i > 0 || !search) + strcat(fn1, "/"); + strcat(fn1, comp); + } + + cleanname(name); + + if(search){ + p = findlib(name); + if(p != nil){ + snprint(fn2, sizeof(fn2), "%s/%s", p, name); + name = fn2; + } } + for(i=0; i<libraryp; i++) if(strcmp(name, library[i]) == 0) return; @@ -1065,8 +1152,7 @@ lookup(char *symb, int v) for(p=symb; c = *p; p++) h = h+h+h + c; l = (p - symb) + 1; - if(h < 0) - h = ~h; + h &= 0xffffff; h %= NHASH; for(s = hash[h]; s != S; s = s->link) if(s->version == v) diff --git a/utils/rcsh/glob.c b/utils/rcsh/glob.c index 7640eeb1..6e9e7b67 100644 --- a/utils/rcsh/glob.c +++ b/utils/rcsh/glob.c @@ -20,7 +20,7 @@ deglob(char *s) } int -globcmp(const void *s, const void *t) +globcmp(void *s, void *t) { return strcmp(*(char**)s, *(char**)t); } diff --git a/utils/sqz/sqz.c b/utils/sqz/sqz.c index d5777a26..f7bfa637 100644 --- a/utils/sqz/sqz.c +++ b/utils/sqz/sqz.c @@ -284,7 +284,7 @@ analyse(ulong *prog, int nw, Squeeze *sq3, Squeeze *sq4, Word **top) } static int -wdcmp(const void *a, const void *b) +wdcmp(void *a, void *b) { return (*(Word**)b)->freq - (*(Word**)a)->freq; } @@ -308,7 +308,7 @@ collate(Word **tab, int nv) } static int -tabcmp(const void *a, const void *b) +tabcmp(void *a, void *b) { ulong av, bv; diff --git a/utils/tc/gc.h b/utils/tc/gc.h index a4135374..9564a449 100644 --- a/utils/tc/gc.h +++ b/utils/tc/gc.h @@ -264,7 +264,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void casf(void); @@ -295,7 +295,7 @@ int Rconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); Bits mkvar(Adr*, int); diff --git a/utils/tc/list.c b/utils/tc/list.c index 1078423e..1124aaac 100644 --- a/utils/tc/list.c +++ b/utils/tc/list.c @@ -78,7 +78,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/tc/reg.c b/utils/tc/reg.c index 54bc76a7..42d25a20 100644 --- a/utils/tc/reg.c +++ b/utils/tc/reg.c @@ -18,7 +18,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; diff --git a/utils/tc/swt.c b/utils/tc/swt.c index 04d879c2..b69a48b6 100644 --- a/utils/tc/swt.c +++ b/utils/tc/swt.c @@ -1,7 +1,7 @@ #include "gc.h" int -swcmp(const void *a1, const void *a2) +swcmp(void *a1, void *a2) { C1 *p1, *p2; diff --git a/utils/tc/txt.c b/utils/tc/txt.c index 7f186bd4..85b38897 100644 --- a/utils/tc/txt.c +++ b/utils/tc/txt.c @@ -1036,6 +1036,7 @@ gopcode2(int o, Node *f1, Node *f2, Node *t) // regfree(&nod); } +int samaddr(Node *f, Node *t) { diff --git a/utils/tl/asm.c b/utils/tl/asm.c new file mode 100644 index 00000000..66a7f0c6 --- /dev/null +++ b/utils/tl/asm.c @@ -0,0 +1,1801 @@ +#include "l.h" + +long OFFSET; + +static Prog *PP; + +long +entryvalue(void) +{ + char *a; + Sym *s; + + a = INITENTRY; + if(*a >= '0' && *a <= '9') + return atolwhex(a); + s = lookup(a, 0); + if(s->type == 0) + return INITTEXT; + switch(s->type) { + case STEXT: + case SLEAF: + break; + case SDATA: + if(dlm) + return s->value+INITDAT; + default: + diag("entry not text: %s", s->name); + } + return s->value; +} + +void +asmb(void) +{ + Prog *p; + long t, etext; + Optab *o; + + if(debug['v']) + Bprint(&bso, "%5.2f asm\n", cputime()); + Bflush(&bso); + OFFSET = HEADR; + seek(cout, OFFSET, 0); + pc = INITTEXT; + for(p = firstp; p != P; p = p->link) { + setarch(p); + if(p->as == ATEXT) { + curtext = p; + autosize = p->to.offset + 4; + } + if(p->pc != pc) { + diag("phase error %lux sb %lux", + p->pc, pc); + if(!debug['a']) + prasm(curp); + pc = p->pc; + } + curp = p; + o = oplook(p); /* could probably avoid this call */ + if(thumb) + thumbasmout(p, o); + else + asmout(p, o); + pc += o->size; + } + while(pc-INITTEXT < textsize) { + cput(0); + pc++; + } + + if(debug['a']) + Bprint(&bso, "\n"); + Bflush(&bso); + cflush(); + + /* output strings in text segment */ + etext = INITTEXT + textsize; + for(t = pc; t < etext; t += sizeof(buf)-100) { + if(etext-t > sizeof(buf)-100) + datblk(t, sizeof(buf)-100, 1); + else + datblk(t, etext-t, 1); + } + + curtext = P; + switch(HEADTYPE) { + case 0: + case 1: + case 2: + case 5: + OFFSET = HEADR+textsize; + seek(cout, OFFSET, 0); + break; + case 3: + OFFSET = rnd(HEADR+textsize, 4096); + seek(cout, OFFSET, 0); + break; + } + if(dlm){ + char buf[8]; + + write(cout, buf, INITDAT-textsize); + textsize = INITDAT; + } + for(t = 0; t < datsize; t += sizeof(buf)-100) { + if(datsize-t > sizeof(buf)-100) + datblk(t, sizeof(buf)-100, 0); + else + datblk(t, datsize-t, 0); + } + cflush(); + + symsize = 0; + lcsize = 0; + if(!debug['s']) { + if(debug['v']) + Bprint(&bso, "%5.2f sym\n", cputime()); + Bflush(&bso); + switch(HEADTYPE) { + case 0: + case 1: + case 4: + case 5: + debug['s'] = 1; + break; + case 2: + OFFSET = HEADR+textsize+datsize; + seek(cout, OFFSET, 0); + break; + case 3: + OFFSET += rnd(datsize, 4096); + seek(cout, OFFSET, 0); + break; + } + if(!debug['s']) + asmsym(); + if(debug['v']) + Bprint(&bso, "%5.2f pc\n", cputime()); + Bflush(&bso); + if(!debug['s']) + asmlc(); + if(!debug['s']) + asmthumbmap(); + if(dlm) + asmdyn(); + cflush(); + } + else if(dlm){ + seek(cout, HEADR+textsize+datsize, 0); + asmdyn(); + cflush(); + } + + curtext = P; + if(debug['v']) + Bprint(&bso, "%5.2f header\n", cputime()); + Bflush(&bso); + OFFSET = 0; + seek(cout, OFFSET, 0); + switch(HEADTYPE) { + case 0: /* no header */ + break; + case 1: /* aif for risc os */ + lputl(0xe1a00000); /* NOP - decompress code */ + lputl(0xe1a00000); /* NOP - relocation code */ + lputl(0xeb000000 + 12); /* BL - zero init code */ + lputl(0xeb000000 + + (entryvalue() + - INITTEXT + + HEADR + - 12 + - 8) / 4); /* BL - entry code */ + + lputl(0xef000011); /* SWI - exit code */ + lputl(textsize+HEADR); /* text size */ + lputl(datsize); /* data size */ + lputl(0); /* sym size */ + + lputl(bsssize); /* bss size */ + lputl(0); /* sym type */ + lputl(INITTEXT-HEADR); /* text addr */ + lputl(0); /* workspace - ignored */ + + lputl(32); /* addr mode / data addr flag */ + lputl(0); /* data addr */ + for(t=0; t<2; t++) + lputl(0); /* reserved */ + + for(t=0; t<15; t++) + lputl(0xe1a00000); /* NOP - zero init code */ + lputl(0xe1a0f00e); /* B (R14) - zero init return */ + break; + case 2: /* plan 9 */ + if(dlm) + lput(0x80000000|0x647); /* magic */ + else + lput(0x647); /* magic */ + lput(textsize); /* sizes */ + lput(datsize); + lput(bsssize); + lput(symsize); /* nsyms */ + lput(entryvalue()); /* va of entry */ + lput(0L); + lput(lcsize); + break; + case 3: /* boot for NetBSD */ + lput((143<<16)|0413); /* magic */ + lputl(rnd(HEADR+textsize, 4096)); + lputl(rnd(datsize, 4096)); + lputl(bsssize); + lputl(symsize); /* nsyms */ + lputl(entryvalue()); /* va of entry */ + lputl(0L); + lputl(0L); + break; + case 4: /* boot for IXP1200 */ + break; + case 5: /* boot for ipaq */ + lputl(0xe3300000); /* nop */ + lputl(0xe3300000); /* nop */ + lputl(0xe3300000); /* nop */ + lputl(0xe3300000); /* nop */ + break; + } + cflush(); + if(debug['c']){ + print("textsize=%ld\n", textsize); + print("datsize=%ld\n", datsize); + print("bsssize=%ld\n", bsssize); + print("symsize=%ld\n", symsize); + print("lcsize=%ld\n", lcsize); + print("total=%ld\n", textsize+datsize+bsssize+symsize+lcsize); + } +} + +void +strnput(char *s, int n) +{ + for(; *s; s++){ + cput(*s); + n--; + } + for(; n > 0; n--) + cput(0); +} + +void +cput(int c) +{ + cbp[0] = c; + cbp++; + cbc--; + if(cbc <= 0) + cflush(); +} + +/* +void +cput(long c) +{ + *cbp++ = c; + if(--cbc <= 0) + cflush(); +} +*/ + +void +wput(long l) +{ + + cbp[0] = l>>8; + cbp[1] = l; + cbp += 2; + cbc -= 2; + if(cbc <= 0) + cflush(); +} + +void +hput(long l) +{ + + cbp[0] = l>>8; + cbp[1] = l; + cbp += 2; + cbc -= 2; + if(cbc <= 0) + cflush(); +} + +void +lput(long l) +{ + + cbp[0] = l>>24; + cbp[1] = l>>16; + cbp[2] = l>>8; + cbp[3] = l; + cbp += 4; + cbc -= 4; + if(cbc <= 0) + cflush(); +} + +void +lputl(long l) +{ + + cbp[3] = l>>24; + cbp[2] = l>>16; + cbp[1] = l>>8; + cbp[0] = l; + cbp += 4; + cbc -= 4; + if(cbc <= 0) + cflush(); +} + +void +cflush(void) +{ + int n; + + /* no bug if cbc < 0 since obuf(cbuf) followed by ibuf in buf! */ + n = sizeof(buf.cbuf) - cbc; + if(n) + write(cout, buf.cbuf, n); + cbp = buf.cbuf; + cbc = sizeof(buf.cbuf); +} + +void +nopstat(char *f, Count *c) +{ + if(c->outof) + Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f, + c->outof - c->count, c->outof, + (double)(c->outof - c->count)/c->outof); +} + +void +asmsym(void) +{ + Prog *p; + Auto *a; + Sym *s; + int h; + + s = lookup("etext", 0); + if(s->type == STEXT) + putsymb(s->name, 'T', s->value, s->version); + + for(h=0; h<NHASH; h++) + for(s=hash[h]; s!=S; s=s->link) + switch(s->type) { + case SCONST: + putsymb(s->name, 'D', s->value, s->version); + continue; + + case SDATA: + putsymb(s->name, 'D', s->value+INITDAT, s->version); + continue; + + case SBSS: + putsymb(s->name, 'B', s->value+INITDAT, s->version); + continue; + + case SSTRING: + putsymb(s->name, 'T', s->value, s->version); + continue; + + case SFILE: + putsymb(s->name, 'f', s->value, s->version); + continue; + } + + for(p=textp; p!=P; p=p->cond) { + s = p->from.sym; + if(s->type != STEXT && s->type != SLEAF) + continue; + + /* filenames first */ + for(a=p->to.autom; a; a=a->link) + if(a->type == D_FILE) + putsymb(a->asym->name, 'z', a->aoffset, 0); + else + if(a->type == D_FILE1) + putsymb(a->asym->name, 'Z', a->aoffset, 0); + + if(s->type == STEXT) + putsymb(s->name, 'T', s->value, s->version); + else + putsymb(s->name, 'L', s->value, s->version); + + /* frame, auto and param after */ + putsymb(".frame", 'm', p->to.offset+4, 0); + for(a=p->to.autom; a; a=a->link) + if(a->type == D_AUTO) + putsymb(a->asym->name, 'a', -a->aoffset, 0); + else + if(a->type == D_PARAM) + putsymb(a->asym->name, 'p', a->aoffset, 0); + } + if(debug['v'] || debug['n']) + Bprint(&bso, "symsize = %lud\n", symsize); + Bflush(&bso); +} + +void +putsymb(char *s, int t, long v, int ver) +{ + int i, f; + + if(t == 'f') + s++; + lput(v); + if(ver) + t += 'a' - 'A'; + cput(t+0x80); /* 0x80 is variable length */ + + if(t == 'Z' || t == 'z') { + cput(s[0]); + for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { + cput(s[i]); + cput(s[i+1]); + } + cput(0); + cput(0); + i++; + } + else { + for(i=0; s[i]; i++) + cput(s[i]); + cput(0); + } + symsize += 4 + 1 + i + 1; + + if(debug['n']) { + if(t == 'z' || t == 'Z') { + Bprint(&bso, "%c %.8lux ", t, v); + for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) { + f = ((s[i]&0xff) << 8) | (s[i+1]&0xff); + Bprint(&bso, "/%x", f); + } + Bprint(&bso, "\n"); + return; + } + if(ver) + Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver); + else + Bprint(&bso, "%c %.8lux %s\n", t, v, s); + } +} + +#define MINLC 4 +void +asmlc(void) +{ + long oldpc, oldlc; + Prog *p; + long v, s; + + oldpc = INITTEXT; + oldlc = 0; + for(p = firstp; p != P; p = p->link) { + setarch(p); + if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { + if(p->as == ATEXT) + curtext = p; + if(debug['L']) + Bprint(&bso, "%6lux %P\n", + p->pc, p); + continue; + } + if(debug['L']) + Bprint(&bso, "\t\t%6ld", lcsize); + v = (p->pc - oldpc) / MINLC; + while(v) { + s = 127; + if(v < 127) + s = v; + cput(s+128); /* 129-255 +pc */ + if(debug['L']) + Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); + v -= s; + lcsize++; + } + s = p->line - oldlc; + oldlc = p->line; + oldpc = p->pc + MINLC; + if(s > 64 || s < -64) { + cput(0); /* 0 vv +lc */ + cput(s>>24); + cput(s>>16); + cput(s>>8); + cput(s); + if(debug['L']) { + if(s > 0) + Bprint(&bso, " lc+%ld(%d,%ld)\n", + s, 0, s); + else + Bprint(&bso, " lc%ld(%d,%ld)\n", + s, 0, s); + Bprint(&bso, "%6lux %P\n", + p->pc, p); + } + lcsize += 5; + continue; + } + if(s > 0) { + cput(0+s); /* 1-64 +lc */ + if(debug['L']) { + Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); + Bprint(&bso, "%6lux %P\n", + p->pc, p); + } + } else { + cput(64-s); /* 65-128 -lc */ + if(debug['L']) { + Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); + Bprint(&bso, "%6lux %P\n", + p->pc, p); + } + } + lcsize++; + } + while(lcsize & 1) { + s = 129; + cput(s); + lcsize++; + } + if(debug['v'] || debug['L']) + Bprint(&bso, "lcsize = %ld\n", lcsize); + Bflush(&bso); +} + +static void +outt(long f, long l) +{ + if(debug['L']) + Bprint(&bso, "tmap: %lux-%lux\n", f, l); + lput(f); + lput(l); +} + +void +asmthumbmap(void) +{ + long pc, lastt; + Prog *p; + + if(!seenthumb) + return; + pc = 0; + lastt = -1; + for(p = firstp; p != P; p = p->link){ + pc = p->pc - INITTEXT; + if(p->as == ATEXT){ + setarch(p); + if(thumb){ + if(p->from.sym->foreign){ // 8 bytes of ARM first + if(lastt >= 0){ + outt(lastt, pc-1); + lastt = -1; + } + pc += 8; + } + if(lastt < 0) + lastt = pc; + } + else{ + if(p->from.sym->foreign){ // 4 bytes of THUMB first + if(lastt < 0) + lastt = pc; + pc += 4; + } + if(lastt >= 0){ + outt(lastt, pc-1); + lastt = -1; + } + } + } + } + if(lastt >= 0) + outt(lastt, pc+1); +} + +void +datblk(long s, long n, int str) +{ + Sym *v; + Prog *p; + char *cast; + long a, l, fl, j, d; + int i, c; + + memset(buf.dbuf, 0, n+100); + for(p = datap; p != P; p = p->link) { + if(str != (p->from.sym->type == SSTRING)) + continue; + curp = p; + a = p->from.sym->value + p->from.offset; + l = a - s; + c = p->reg; + i = 0; + if(l < 0) { + if(l+c <= 0) + continue; + while(l < 0) { + l++; + i++; + } + } + if(l >= n) + continue; + if(p->as != AINIT && p->as != ADYNT) { + for(j=l+(c-i)-1; j>=l; j--) + if(buf.dbuf[j]) { + print("%P\n", p); + diag("multiple initialization"); + break; + } + } + switch(p->to.type) { + default: + diag("unknown mode in initialization%P", p); + break; + + case D_FCONST: + switch(c) { + default: + case 4: + fl = ieeedtof(p->to.ieee); + cast = (char*)&fl; + for(; i<c; i++) { + buf.dbuf[l] = cast[fnuxi4[i]]; + l++; + } + break; + case 8: + cast = (char*)p->to.ieee; + for(; i<c; i++) { + buf.dbuf[l] = cast[fnuxi8[i]]; + l++; + } + break; + } + break; + + case D_SCONST: + for(; i<c; i++) { + buf.dbuf[l] = p->to.sval[i]; + l++; + } + break; + + case D_CONST: + d = p->to.offset; + v = p->to.sym; + if(v) { + switch(v->type) { + case SUNDEF: + ckoff(v, d); + d += v->value; + break; + case STEXT: + case SLEAF: + d += v->value; +#ifdef CALLEEBX + d += fnpinc(v); +#else + if(v->thumb) + d++; // T bit +#endif + break; + case SSTRING: + d += v->value; + break; + case SDATA: + case SBSS: + d += v->value + INITDAT; + break; + } + if(dlm) + dynreloc(v, a+INITDAT, 1); + } + cast = (char*)&d; + switch(c) { + default: + diag("bad nuxi %d %d%P", c, i, curp); + break; + case 1: + for(; i<c; i++) { + buf.dbuf[l] = cast[inuxi1[i]]; + l++; + } + break; + case 2: + for(; i<c; i++) { + buf.dbuf[l] = cast[inuxi2[i]]; + l++; + } + break; + case 4: + for(; i<c; i++) { + buf.dbuf[l] = cast[inuxi4[i]]; + l++; + } + break; + } + break; + } + } + write(cout, buf.dbuf, n); +} + +void +asmout(Prog *p, Optab *o) +{ + long o1, o2, o3, o4, o5, o6, v; + int r, rf, rt, rt2; + Sym *s; + +PP = p; + o1 = 0; + o2 = 0; + o3 = 0; + o4 = 0; + o5 = 0; + o6 = 0; + armsize += o->size; +if(debug['P']) print("%ulx: %P type %d\n", (ulong)(p->pc), p, o->type); + switch(o->type) { + default: + diag("unknown asm %d", o->type); + prasm(p); + break; + + case 0: /* pseudo ops */ +if(debug['G']) print("%ulx: %s: arm %d %d %d %d\n", (ulong)(p->pc), p->from.sym->name, p->from.sym->thumb, p->from.sym->foreign, p->from.sym->fnptr, p->from.sym->used); + break; + + case 1: /* op R,[R],R */ + o1 = oprrr(p->as, p->scond); + rf = p->from.reg; + rt = p->to.reg; + r = p->reg; + if(p->to.type == D_NONE) + rt = 0; + if(p->as == AMOVW || p->as == AMVN) + r = 0; + else if(r == NREG) + r = rt; + o1 |= rf | (r<<16) | (rt<<12); + break; + + case 2: /* movbu $I,[R],R */ + aclass(&p->from); + o1 = oprrr(p->as, p->scond); + o1 |= immrot(instoffset); + rt = p->to.reg; + r = p->reg; + if(p->to.type == D_NONE) + rt = 0; + if(p->as == AMOVW || p->as == AMVN) + r = 0; + else if(r == NREG) + r = rt; + o1 |= (r<<16) | (rt<<12); + break; + + case 3: /* add R<<[IR],[R],R */ + mov: + aclass(&p->from); + o1 = oprrr(p->as, p->scond); + o1 |= p->from.offset; + rt = p->to.reg; + r = p->reg; + if(p->to.type == D_NONE) + rt = 0; + if(p->as == AMOVW || p->as == AMVN) + r = 0; + else if(r == NREG) + r = rt; + o1 |= (r<<16) | (rt<<12); + break; + + case 4: /* add $I,[R],R */ + aclass(&p->from); + o1 = oprrr(AADD, p->scond); + o1 |= immrot(instoffset); + r = p->from.reg; + if(r == NREG) + r = o->param; + o1 |= r << 16; + o1 |= p->to.reg << 12; + break; + + case 5: /* bra s */ + v = -8; + if(p->cond == UP) { + s = p->to.sym; + if(s->type != SUNDEF) + diag("bad branch sym type"); + v = (ulong)s->value >> (Roffset-2); + dynreloc(s, p->pc, 0); + } + else if(p->cond != P) + v = (p->cond->pc - pc) - 8; +#ifdef CALLEEBX + if(p->as == ABL) + v += fninc(p->to.sym); +#endif + o1 = opbra(p->as, p->scond); + o1 |= (v >> 2) & 0xffffff; + break; + + case 6: /* b ,O(R) -> add $O,R,PC */ + aclass(&p->to); + o1 = oprrr(AADD, p->scond); + o1 |= immrot(instoffset); + o1 |= p->to.reg << 16; + o1 |= REGPC << 12; + break; + + case 7: /* bl ,O(R) -> mov PC,link; add $O,R,PC */ + aclass(&p->to); + o1 = oprrr(AADD, p->scond); + o1 |= immrot(0); + o1 |= REGPC << 16; + o1 |= REGLINK << 12; + + o2 = oprrr(AADD, p->scond); + o2 |= immrot(instoffset); + o2 |= p->to.reg << 16; + o2 |= REGPC << 12; + break; + + case 8: /* sll $c,[R],R -> mov (R<<$c),R */ + aclass(&p->from); + o1 = oprrr(p->as, p->scond); + r = p->reg; + if(r == NREG) + r = p->to.reg; + o1 |= r; + o1 |= (instoffset&31) << 7; + o1 |= p->to.reg << 12; + break; + + case 9: /* sll R,[R],R -> mov (R<<R),R */ + o1 = oprrr(p->as, p->scond); + r = p->reg; + if(r == NREG) + r = p->to.reg; + o1 |= r; + o1 |= (p->from.reg << 8) | (1<<4); + o1 |= p->to.reg << 12; + break; + + case 10: /* swi [$con] */ + o1 = oprrr(p->as, p->scond); + if(p->to.type != D_NONE) { + aclass(&p->to); + o1 |= instoffset & 0xffffff; + } + break; + + case 11: /* word */ + switch(aclass(&p->to)) { + case C_LCON: + if(!dlm) + break; + if(p->to.name != D_EXTERN && p->to.name != D_STATIC) + break; + case C_ADDR: + if(p->to.sym->type == SUNDEF) + ckoff(p->to.sym, p->to.offset); + dynreloc(p->to.sym, p->pc, 1); + } + o1 = instoffset; + break; + + case 12: /* movw $lcon, reg */ + o1 = omvl(p, &p->from, p->to.reg); + break; + + case 13: /* op $lcon, [R], R */ + o1 = omvl(p, &p->from, REGTMP); + if(!o1) + break; + o2 = oprrr(p->as, p->scond); + o2 |= REGTMP; + r = p->reg; + if(p->as == AMOVW || p->as == AMVN) + r = 0; + else if(r == NREG) + r = p->to.reg; + o2 |= r << 16; + if(p->to.type != D_NONE) + o2 |= p->to.reg << 12; + break; + + case 14: /* movb/movbu/movh/movhu R,R */ + o1 = oprrr(ASLL, p->scond); + + if(p->as == AMOVBU || p->as == AMOVHU) + o2 = oprrr(ASRL, p->scond); + else + o2 = oprrr(ASRA, p->scond); + + r = p->to.reg; + o1 |= (p->from.reg)|(r<<12); + o2 |= (r)|(r<<12); + if(p->as == AMOVB || p->as == AMOVBU) { + o1 |= (24<<7); + o2 |= (24<<7); + } else { + o1 |= (16<<7); + o2 |= (16<<7); + } + break; + + case 15: /* mul r,[r,]r */ + o1 = oprrr(p->as, p->scond); + rf = p->from.reg; + rt = p->to.reg; + r = p->reg; + if(r == NREG) + r = rt; + if(rt == r) { + r = rf; + rf = rt; + } + if(0) + if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) { + diag("bad registers in MUL"); + prasm(p); + } + o1 |= (rf<<8) | r | (rt<<16); + break; + + + case 16: /* div r,[r,]r */ + o1 = 0xf << 28; + o2 = 0; + break; + + case 17: + o1 = oprrr(p->as, p->scond); + rf = p->from.reg; + rt = p->to.reg; + rt2 = p->to.offset; + r = p->reg; + o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12); + break; + + case 20: /* mov/movb/movbu R,O(R) */ + aclass(&p->to); + r = p->to.reg; + if(r == NREG) + r = o->param; + o1 = osr(p->as, p->from.reg, instoffset, r, p->scond); + break; + + case 21: /* mov/movbu O(R),R -> lr */ + aclass(&p->from); + r = p->from.reg; + if(r == NREG) + r = o->param; + o1 = olr(instoffset, r, p->to.reg, p->scond); + if(p->as != AMOVW) + o1 |= 1<<22; + break; + + case 22: /* movb/movh/movhu O(R),R -> lr,shl,shr */ + aclass(&p->from); + r = p->from.reg; + if(r == NREG) + r = o->param; + o1 = olr(instoffset, r, p->to.reg, p->scond); + + o2 = oprrr(ASLL, p->scond); + o3 = oprrr(ASRA, p->scond); + r = p->to.reg; + if(p->as == AMOVB) { + o2 |= (24<<7)|(r)|(r<<12); + o3 |= (24<<7)|(r)|(r<<12); + } else { + o2 |= (16<<7)|(r)|(r<<12); + if(p->as == AMOVHU) + o3 = oprrr(ASRL, p->scond); + o3 |= (16<<7)|(r)|(r<<12); + } + break; + + case 23: /* movh/movhu R,O(R) -> sb,sb */ + aclass(&p->to); + r = p->to.reg; + if(r == NREG) + r = o->param; + o1 = osr(AMOVH, p->from.reg, instoffset, r, p->scond); + + o2 = oprrr(ASRL, p->scond); + o2 |= (8<<7)|(p->from.reg)|(REGTMP<<12); + + o3 = osr(AMOVH, REGTMP, instoffset+1, r, p->scond); + break; + + case 30: /* mov/movb/movbu R,L(R) */ + o1 = omvl(p, &p->to, REGTMP); + if(!o1) + break; + r = p->to.reg; + if(r == NREG) + r = o->param; + o2 = osrr(p->from.reg, REGTMP,r, p->scond); + if(p->as != AMOVW) + o2 |= 1<<22; + break; + + case 31: /* mov/movbu L(R),R -> lr[b] */ + case 32: /* movh/movb L(R),R -> lr[b] */ + o1 = omvl(p, &p->from, REGTMP); + if(!o1) + break; + r = p->from.reg; + if(r == NREG) + r = o->param; + o2 = olrr(REGTMP,r, p->to.reg, p->scond); + if(p->as == AMOVBU || p->as == AMOVB) + o2 |= 1<<22; + if(o->type == 31) + break; + + o3 = oprrr(ASLL, p->scond); + + if(p->as == AMOVBU || p->as == AMOVHU) + o4 = oprrr(ASRL, p->scond); + else + o4 = oprrr(ASRA, p->scond); + + r = p->to.reg; + o3 |= (r)|(r<<12); + o4 |= (r)|(r<<12); + if(p->as == AMOVB || p->as == AMOVBU) { + o3 |= (24<<7); + o4 |= (24<<7); + } else { + o3 |= (16<<7); + o4 |= (16<<7); + } + break; + + case 33: /* movh/movhu R,L(R) -> sb, sb */ + o1 = omvl(p, &p->to, REGTMP); + if(!o1) + break; + r = p->to.reg; + if(r == NREG) + r = o->param; + o2 = osrr(p->from.reg, REGTMP, r, p->scond); + o2 |= (1<<22) ; + + o3 = oprrr(ASRL, p->scond); + o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12); + o3 |= (1<<6); /* ROR 8 */ + + o4 = oprrr(AADD, p->scond); + o4 |= (REGTMP << 12) | (REGTMP << 16); + o4 |= immrot(1); + + o5 = osrr(p->from.reg, REGTMP,r,p->scond); + o5 |= (1<<22); + + o6 = oprrr(ASRL, p->scond); + o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12); + o6 |= (1<<6); /* ROL 8 */ + + break; + + case 34: /* mov $lacon,R */ + o1 = omvl(p, &p->from, REGTMP); + if(!o1) + break; + + o2 = oprrr(AADD, p->scond); + o2 |= REGTMP; + r = p->from.reg; + if(r == NREG) + r = o->param; + o2 |= r << 16; + if(p->to.type != D_NONE) + o2 |= p->to.reg << 12; + break; + + case 35: /* mov PSR,R */ + o1 = (2<<23) | (0xf<<16) | (0<<0); + o1 |= (p->scond & C_SCOND) << 28; + o1 |= (p->from.reg & 1) << 22; + o1 |= p->to.reg << 12; + break; + + case 36: /* mov R,PSR */ + o1 = (2<<23) | (0x29f<<12) | (0<<4); + if(p->scond & C_FBIT) + o1 ^= 0x010 << 12; + o1 |= (p->scond & C_SCOND) << 28; + o1 |= (p->to.reg & 1) << 22; + o1 |= p->from.reg << 0; + break; + + case 37: /* mov $con,PSR */ + aclass(&p->from); + o1 = (2<<23) | (0x29f<<12) | (0<<4); + if(p->scond & C_FBIT) + o1 ^= 0x010 << 12; + o1 |= (p->scond & C_SCOND) << 28; + o1 |= immrot(instoffset); + o1 |= (p->to.reg & 1) << 22; + o1 |= p->from.reg << 0; + break; + + case 38: /* movm $con,oreg -> stm */ + o1 = (0x4 << 25); + o1 |= p->from.offset & 0xffff; + o1 |= p->to.reg << 16; + aclass(&p->to); + goto movm; + + case 39: /* movm oreg,$con -> ldm */ + o1 = (0x4 << 25) | (1 << 20); + o1 |= p->to.offset & 0xffff; + o1 |= p->from.reg << 16; + aclass(&p->from); + movm: + if(instoffset != 0) + diag("offset must be zero in MOVM"); + o1 |= (p->scond & C_SCOND) << 28; + if(p->scond & C_PBIT) + o1 |= 1 << 24; + if(p->scond & C_UBIT) + o1 |= 1 << 23; + if(p->scond & C_SBIT) + o1 |= 1 << 22; + if(p->scond & C_WBIT) + o1 |= 1 << 21; + break; + + case 40: /* swp oreg,reg,reg */ + aclass(&p->from); + if(instoffset != 0) + diag("offset must be zero in SWP"); + o1 = (0x2<<23) | (0x9<<4); + if(p->as != ASWPW) + o1 |= 1 << 22; + o1 |= p->from.reg << 16; + o1 |= p->reg << 0; + o1 |= p->to.reg << 12; + o1 |= (p->scond & C_SCOND) << 28; + break; + + case 41: /* rfe -> movm.s.w.u 0(r13),[r15] */ + o1 = 0xe8fd8000; + break; + + case 50: /* floating point store */ + v = regoff(&p->to); + r = p->to.reg; + if(r == NREG) + r = o->param; + o1 = ofsr(p->as, p->from.reg, v, r, p->scond, p); + break; + + case 51: /* floating point load */ + v = regoff(&p->from); + r = p->from.reg; + if(r == NREG) + r = o->param; + o1 = ofsr(p->as, p->to.reg, v, r, p->scond, p) | (1<<20); + break; + + case 52: /* floating point store, long offset UGLY */ + o1 = omvl(p, &p->to, REGTMP); + if(!o1) + break; + r = p->to.reg; + if(r == NREG) + r = o->param; + o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r; + o3 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p); + break; + + case 53: /* floating point load, long offset UGLY */ + o1 = omvl(p, &p->from, REGTMP); + if(!o1) + break; + r = p->from.reg; + if(r == NREG) + r = o->param; + o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r; + o3 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20); + break; + + case 54: /* floating point arith */ + o1 = oprrr(p->as, p->scond); + if(p->from.type == D_FCONST) { + rf = chipfloat(p->from.ieee); + if(rf < 0){ + diag("invalid floating-point immediate\n%P", p); + rf = 0; + } + rf |= (1<<3); + } else + rf = p->from.reg; + rt = p->to.reg; + r = p->reg; + if(p->to.type == D_NONE) + rt = 0; /* CMP[FD] */ + else if(o1 & (1<<15)) + r = 0; /* monadic */ + else if(r == NREG) + r = rt; + o1 |= rf | (r<<16) | (rt<<12); + break; + + case 55: /* floating point fix and float */ + o1 = oprrr(p->as, p->scond); + rf = p->from.reg; + rt = p->to.reg; + if(p->to.type == D_NONE){ + rt = 0; + diag("to.type==D_NONE (asm/fp)"); + } + if(p->from.type == D_REG) + o1 |= (rf<<12) | (rt<<16); + else + o1 |= rf | (rt<<12); + break; + + case 56: /* move to FP[CS]R */ + o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4); + o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12); + break; + + case 57: /* move from FP[CS]R */ + o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4); + o1 |= ((p->from.reg+1)<<21) | (p->to.reg<<12) | (1<<20); + break; + case 58: /* movbu R,R */ + o1 = oprrr(AAND, p->scond); + o1 |= immrot(0xff); + rt = p->to.reg; + r = p->from.reg; + if(p->to.type == D_NONE) + rt = 0; + if(r == NREG) + r = rt; + o1 |= (r<<16) | (rt<<12); + break; + + case 59: /* movw/bu R<<I(R),R -> ldr indexed */ + if(p->from.reg == NREG) { + if(p->as != AMOVW) + diag("byte MOV from shifter operand"); + goto mov; + } + if(p->from.offset&(1<<4)) + diag("bad shift in LDR"); + o1 = olrr(p->from.offset, p->from.reg, p->to.reg, p->scond); + if(p->as == AMOVBU) + o1 |= 1<<22; + break; + + case 60: /* movb R(R),R -> ldrsb indexed */ + if(p->from.reg == NREG) { + diag("byte MOV from shifter operand"); + goto mov; + } + if(p->from.offset&(~0xf)) + diag("bad shift in LDRSB"); + o1 = olhrr(p->from.offset, p->from.reg, p->to.reg, p->scond); + o1 ^= (1<<5)|(1<<6); + break; + + case 61: /* movw/b/bu R,R<<[IR](R) -> str indexed */ + if(p->to.reg == NREG) + diag("MOV to shifter operand"); + o1 = osrr(p->from.reg, p->to.offset, p->to.reg, p->scond); + if(p->as == AMOVB || p->as == AMOVBU) + o1 |= 1<<22; + break; + + case 62: /* case R -> movw R<<2(PC),PC */ + o1 = olrr(p->from.reg, REGPC, REGPC, p->scond); + o1 |= 2<<7; + break; + + case 63: /* bcase */ + if(p->cond != P) { + o1 = p->cond->pc; + if(dlm) + dynreloc(S, p->pc, 1); + } + break; + + /* reloc ops */ + case 64: /* mov/movb/movbu R,addr */ + o1 = omvl(p, &p->to, REGTMP); + if(!o1) + break; + o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond); + break; + + case 65: /* mov/movbu addr,R */ + case 66: /* movh/movhu/movb addr,R */ + o1 = omvl(p, &p->from, REGTMP); + if(!o1) + break; + o2 = olr(0, REGTMP, p->to.reg, p->scond); + if(p->as == AMOVBU || p->as == AMOVB) + o2 |= 1<<22; + if(o->type == 65) + break; + + o3 = oprrr(ASLL, p->scond); + + if(p->as == AMOVBU || p->as == AMOVHU) + o4 = oprrr(ASRL, p->scond); + else + o4 = oprrr(ASRA, p->scond); + + r = p->to.reg; + o3 |= (r)|(r<<12); + o4 |= (r)|(r<<12); + if(p->as == AMOVB || p->as == AMOVBU) { + o3 |= (24<<7); + o4 |= (24<<7); + } else { + o3 |= (16<<7); + o4 |= (16<<7); + } + break; + + case 67: /* movh/movhu R,addr -> sb, sb */ + o1 = omvl(p, &p->to, REGTMP); + if(!o1) + break; + o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond); + + o3 = oprrr(ASRL, p->scond); + o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12); + o3 |= (1<<6); /* ROR 8 */ + + o4 = oprrr(AADD, p->scond); + o4 |= (REGTMP << 12) | (REGTMP << 16); + o4 |= immrot(1); + + o5 = osr(p->as, p->from.reg, 0, REGTMP, p->scond); + + o6 = oprrr(ASRL, p->scond); + o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12); + o6 |= (1<<6); /* ROL 8 */ + break; + + case 68: /* floating point store -> ADDR */ + o1 = omvl(p, &p->to, REGTMP); + if(!o1) + break; + o2 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p); + break; + + case 69: /* floating point load <- ADDR */ + o1 = omvl(p, &p->from, REGTMP); + if(!o1) + break; + o2 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20); + break; + + /* ArmV4 ops: */ + case 70: /* movh/movhu R,O(R) -> strh */ + aclass(&p->to); + r = p->to.reg; + if(r == NREG) + r = o->param; + o1 = oshr(p->from.reg, instoffset, r, p->scond); + break; + case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */ + aclass(&p->from); + r = p->from.reg; + if(r == NREG) + r = o->param; + o1 = olhr(instoffset, r, p->to.reg, p->scond); + if(p->as == AMOVB) + o1 ^= (1<<5)|(1<<6); + else if(p->as == AMOVH) + o1 ^= (1<<6); + break; + case 72: /* movh/movhu R,L(R) -> strh */ + o1 = omvl(p, &p->to, REGTMP); + if(!o1) + break; + r = p->to.reg; + if(r == NREG) + r = o->param; + o2 = oshrr(p->from.reg, REGTMP,r, p->scond); + break; + case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */ + o1 = omvl(p, &p->from, REGTMP); + if(!o1) + break; + r = p->from.reg; + if(r == NREG) + r = o->param; + o2 = olhrr(REGTMP, r, p->to.reg, p->scond); + if(p->as == AMOVB) + o2 ^= (1<<5)|(1<<6); + else if(p->as == AMOVH) + o2 ^= (1<<6); + break; + case 74: /* bx $I */ +#ifdef CALLEEBX + diag("bx $i case (arm)"); +#endif + if(!seenthumb) + diag("ABX $I and seenthumb==0"); + v = p->cond->pc; + if(p->to.sym->thumb) + v |= 1; // T bit + o1 = olr(8, REGPC, REGTMP, p->scond&C_SCOND); // mov 8(PC), Rtmp + o2 = oprrr(AADD, p->scond) | immrot(8) | (REGPC<<16) | (REGLINK<<12); // add 8,PC, LR + o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // bx Rtmp + o4 = opbra(AB, 14); // B over o6 + o5 = v; + break; + case 75: /* bx O(R) */ + aclass(&p->to); + if(instoffset != 0) + diag("non-zero offset in ABX"); +/* + o1 = oprrr(AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR + o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R +*/ + // p->to.reg may be REGLINK + o1 = oprrr(AADD, p->scond); + o1 |= immrot(instoffset); + o1 |= p->to.reg << 16; + o1 |= REGTMP << 12; + o2 = oprrr(AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR + o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // BX Rtmp + break; + case 76: /* bx O(R) when returning from fn*/ + if(!seenthumb) + diag("ABXRET and seenthumb==0"); + aclass(&p->to); +// print("ARM BXRET %d(R%d)\n", instoffset, p->to.reg); + if(instoffset != 0) + diag("non-zero offset in ABXRET"); + // o1 = olr(instoffset, p->to.reg, REGTMP, p->scond); // mov O(R), Rtmp + o1 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R + break; + } + + v = p->pc; + switch(o->size) { + default: + if(debug['a']) + Bprint(&bso, " %.8lux:\t\t%P\n", v, p); + break; + case 4: + if(debug['a']) + Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p); + lputl(o1); + break; + case 8: + if(debug['a']) + Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p); + lputl(o1); + lputl(o2); + break; + case 12: + if(debug['a']) + Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p); + lputl(o1); + lputl(o2); + lputl(o3); + break; + case 16: + if(debug['a']) + Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n", + v, o1, o2, o3, o4, p); + lputl(o1); + lputl(o2); + lputl(o3); + lputl(o4); + break; + case 20: + if(debug['a']) + Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", + v, o1, o2, o3, o4, o5, p); + lputl(o1); + lputl(o2); + lputl(o3); + lputl(o4); + lputl(o5); + break; + case 24: + if(debug['a']) + Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", + v, o1, o2, o3, o4, o5, o6, p); + lputl(o1); + lputl(o2); + lputl(o3); + lputl(o4); + lputl(o5); + lputl(o6); + break; + } +} + +long +oprrr(int a, int sc) +{ + long o; + + o = (sc & C_SCOND) << 28; + if(sc & C_SBIT) + o |= 1 << 20; + if(sc & (C_PBIT|C_WBIT)) + diag(".P/.W on dp instruction"); + switch(a) { + case AMULU: + case AMUL: return o | (0x0<<21) | (0x9<<4); + case AMULA: return o | (0x1<<21) | (0x9<<4); + case AMULLU: return o | (0x4<<21) | (0x9<<4); + case AMULL: return o | (0x6<<21) | (0x9<<4); + case AMULALU: return o | (0x5<<21) | (0x9<<4); + case AMULAL: return o | (0x7<<21) | (0x9<<4); + case AAND: return o | (0x0<<21); + case AEOR: return o | (0x1<<21); + case ASUB: return o | (0x2<<21); + case ARSB: return o | (0x3<<21); + case AADD: return o | (0x4<<21); + case AADC: return o | (0x5<<21); + case ASBC: return o | (0x6<<21); + case ARSC: return o | (0x7<<21); + case ATST: return o | (0x8<<21) | (1<<20); + case ATEQ: return o | (0x9<<21) | (1<<20); + case ACMP: return o | (0xa<<21) | (1<<20); + case ACMN: return o | (0xb<<21) | (1<<20); + case AORR: return o | (0xc<<21); + case AMOVW: return o | (0xd<<21); + case ABIC: return o | (0xe<<21); + case AMVN: return o | (0xf<<21); + case ASLL: return o | (0xd<<21) | (0<<5); + case ASRL: return o | (0xd<<21) | (1<<5); + case ASRA: return o | (0xd<<21) | (2<<5); + case ASWI: return o | (0xf<<24); + + case AADDD: return o | (0xe<<24) | (0x0<<20) | (1<<8) | (1<<7); + case AADDF: return o | (0xe<<24) | (0x0<<20) | (1<<8); + case AMULD: return o | (0xe<<24) | (0x1<<20) | (1<<8) | (1<<7); + case AMULF: return o | (0xe<<24) | (0x1<<20) | (1<<8); + case ASUBD: return o | (0xe<<24) | (0x2<<20) | (1<<8) | (1<<7); + case ASUBF: return o | (0xe<<24) | (0x2<<20) | (1<<8); + case ADIVD: return o | (0xe<<24) | (0x4<<20) | (1<<8) | (1<<7); + case ADIVF: return o | (0xe<<24) | (0x4<<20) | (1<<8); + case ACMPD: + case ACMPF: return o | (0xe<<24) | (0x9<<20) | (0xF<<12) | (1<<8) | (1<<4); /* arguably, ACMPF should expand to RNDF, CMPD */ + + case AMOVF: + case AMOVDF: return o | (0xe<<24) | (0x0<<20) | (1<<15) | (1<<8); + case AMOVD: + case AMOVFD: return o | (0xe<<24) | (0x0<<20) | (1<<15) | (1<<8) | (1<<7); + + case AMOVWF: return o | (0xe<<24) | (0<<20) | (1<<8) | (1<<4); + case AMOVWD: return o | (0xe<<24) | (0<<20) | (1<<8) | (1<<4) | (1<<7); + case AMOVFW: return o | (0xe<<24) | (1<<20) | (1<<8) | (1<<4); + case AMOVDW: return o | (0xe<<24) | (1<<20) | (1<<8) | (1<<4) | (1<<7); + } + diag("bad rrr %d", a); + prasm(curp); + return 0; +} + +long +opbra(int a, int sc) +{ + + if(sc & (C_SBIT|C_PBIT|C_WBIT)) + diag(".S/.P/.W on bra instruction"); + sc &= C_SCOND; + if(a == ABL) + return (sc<<28)|(0x5<<25)|(0x1<<24); + if(sc != 0xe) + diag(".COND on bcond instruction"); + switch(a) { + case ABEQ: return (0x0<<28)|(0x5<<25); + case ABNE: return (0x1<<28)|(0x5<<25); + case ABCS: return (0x2<<28)|(0x5<<25); + case ABHS: return (0x2<<28)|(0x5<<25); + case ABCC: return (0x3<<28)|(0x5<<25); + case ABLO: return (0x3<<28)|(0x5<<25); + case ABMI: return (0x4<<28)|(0x5<<25); + case ABPL: return (0x5<<28)|(0x5<<25); + case ABVS: return (0x6<<28)|(0x5<<25); + case ABVC: return (0x7<<28)|(0x5<<25); + case ABHI: return (0x8<<28)|(0x5<<25); + case ABLS: return (0x9<<28)|(0x5<<25); + case ABGE: return (0xa<<28)|(0x5<<25); + case ABLT: return (0xb<<28)|(0x5<<25); + case ABGT: return (0xc<<28)|(0x5<<25); + case ABLE: return (0xd<<28)|(0x5<<25); + case AB: return (0xe<<28)|(0x5<<25); + } + diag("bad bra %A", a); + prasm(curp); + return 0; +} + +long +olr(long v, int b, int r, int sc) +{ + long o; + + if(sc & C_SBIT) + diag(".S on LDR/STR instruction"); + o = (sc & C_SCOND) << 28; + if(!(sc & C_PBIT)) + o |= 1 << 24; + if(!(sc & C_UBIT)) + o |= 1 << 23; + if(sc & C_WBIT) + o |= 1 << 21; + o |= (0x1<<26) | (1<<20); + if(v < 0) { + v = -v; + o ^= 1 << 23; + } + if(v >= (1<<12)) + diag("literal span too large: %d (R%d)\n%P", v, b, PP); + o |= v; + o |= b << 16; + o |= r << 12; + return o; +} + +long +olhr(long v, int b, int r, int sc) +{ + long o; + + if(sc & C_SBIT) + diag(".S on LDRH/STRH instruction"); + o = (sc & C_SCOND) << 28; + if(!(sc & C_PBIT)) + o |= 1 << 24; + if(sc & C_WBIT) + o |= 1 << 21; + o |= (1<<23) | (1<<20)|(0xb<<4); + if(v < 0) { + v = -v; + o ^= 1 << 23; + } + if(v >= (1<<8)) + diag("literal span too large: %d (R%d)\n%P", v, b, PP); + o |= (v&0xf)|((v>>4)<<8)|(1<<22); + o |= b << 16; + o |= r << 12; + return o; +} + +long +osr(int a, int r, long v, int b, int sc) +{ + long o; + + o = olr(v, b, r, sc) ^ (1<<20); + if(a != AMOVW) + o |= 1<<22; + return o; +} + +long +oshr(int r, long v, int b, int sc) +{ + long o; + + o = olhr(v, b, r, sc) ^ (1<<20); + return o; +} + + +long +osrr(int r, int i, int b, int sc) +{ + + return olr(i, b, r, sc) ^ ((1<<25) | (1<<20)); +} + +long +oshrr(int r, int i, int b, int sc) +{ + return olhr(i, b, r, sc) ^ ((1<<22) | (1<<20)); +} + +long +olrr(int i, int b, int r, int sc) +{ + + return olr(i, b, r, sc) ^ (1<<25); +} + +long +olhrr(int i, int b, int r, int sc) +{ + return olhr(i, b, r, sc) ^ (1<<22); +} + +long +ofsr(int a, int r, long v, int b, int sc, Prog *p) +{ + long o; + + if(sc & C_SBIT) + diag(".S on FLDR/FSTR instruction"); + o = (sc & C_SCOND) << 28; + if(!(sc & C_PBIT)) + o |= 1 << 24; + if(sc & C_WBIT) + o |= 1 << 21; + o |= (6<<25) | (1<<24) | (1<<23); + if(v < 0) { + v = -v; + o ^= 1 << 23; + } + if(v & 3) + diag("odd offset for floating point op: %d\n%P", v, p); + else if(v >= (1<<10)) + diag("literal span too large: %d\n%P", v, p); + o |= (v>>2) & 0xFF; + o |= b << 16; + o |= r << 12; + o |= 1 << 8; + + switch(a) { + default: + diag("bad fst %A", a); + case AMOVD: + o |= 1<<15; + case AMOVF: + break; + } + return o; +} + +long +omvl(Prog *p, Adr *a, int dr) +{ + long v, o1; + if(!p->cond) { + aclass(a); + v = immrot(~instoffset); + if(v == 0) { + diag("missing literal"); + prasm(p); + return 0; + } + o1 = oprrr(AMVN, p->scond&C_SCOND); + o1 |= v; + o1 |= dr << 12; + } else { + v = p->cond->pc - p->pc - 8; + o1 = olr(v, REGPC, dr, p->scond&C_SCOND); + } + return o1; +} + +static Ieee chipfloats[] = { + {0x00000000, 0x00000000}, /* 0 */ + {0x00000000, 0x3ff00000}, /* 1 */ + {0x00000000, 0x40000000}, /* 2 */ + {0x00000000, 0x40080000}, /* 3 */ + {0x00000000, 0x40100000}, /* 4 */ + {0x00000000, 0x40140000}, /* 5 */ + {0x00000000, 0x3fe00000}, /* .5 */ + {0x00000000, 0x40240000}, /* 10 */ +}; + +int +chipfloat(Ieee *e) +{ + Ieee *p; + int n; + + for(n = sizeof(chipfloats)/sizeof(chipfloats[0]); --n >= 0;){ + p = &chipfloats[n]; + if(p->l == e->l && p->h == e->h) + return n; + } + return -1; +} diff --git a/utils/tl/l.h b/utils/tl/l.h new file mode 100644 index 00000000..72e6ed28 --- /dev/null +++ b/utils/tl/l.h @@ -0,0 +1,444 @@ +#include <lib9.h> +#include <bio.h> +#include "../5c/5.out.h" + +#ifndef EXTERN +#define EXTERN extern +#endif + +/* do not undefine this - code will be removed eventually */ +#define CALLEEBX + +typedef struct Adr Adr; +typedef struct Sym Sym; +typedef struct Autom Auto; +typedef struct Prog Prog; +typedef struct Optab Optab; +typedef struct Oprang Oprang; +typedef uchar Opcross[32][2][32]; +typedef struct Count Count; +typedef struct Use Use; + +#define P ((Prog*)0) +#define S ((Sym*)0) +#define U ((Use*)0) +#define TNAME (curtext&&curtext->from.sym?curtext->from.sym->name:noname) + +struct Adr +{ + union + { + long u0offset; + char* u0sval; + Ieee* u0ieee; + } u0; + union + { + Auto* u1autom; + Sym* u1sym; + } u1; + char type; + char reg; + char name; + char class; +}; + +#define offset u0.u0offset +#define sval u0.u0sval +#define ieee u0.u0ieee + +#define autom u1.u1autom +#define sym u1.u1sym + +struct Prog +{ + Adr from; + Adr to; + union + { + long u0regused; + Prog* u0forwd; + } u0; + Prog* cond; + Prog* link; + long pc; + long line; + uchar mark; + uchar optab; + uchar as; + uchar scond; + uchar reg; + uchar align; +}; +#define regused u0.u0regused +#define forwd u0.u0forwd + +struct Sym +{ + char *name; + short type; + short version; + short become; + short frame; + uchar subtype; + ushort file; + long value; + long sig; + uchar used; + uchar thumb; // thumb code + uchar foreign; // called by arm if thumb, by thumb if arm + uchar fnptr; // used as fn ptr + Use* use; + Sym* link; +}; + +#define SIGNINTERN (1729*325*1729) + +struct Autom +{ + Sym* asym; + Auto* link; + long aoffset; + short type; +}; +struct Optab +{ + char as; + char a1; + char a2; + char a3; + char type; + char size; + char param; + char flag; +}; +struct Oprang +{ + Optab* start; + Optab* stop; +}; +struct Count +{ + long count; + long outof; +}; +struct Use +{ + Prog* p; /* use */ + Prog* ct; /* curtext */ + Use* link; +}; + +enum +{ + STEXT = 1, + SDATA, + SBSS, + SDATA1, + SXREF, + SLEAF, + SFILE, + SCONST, + SSTRING, + SUNDEF, + SREMOVED, + + SIMPORT, + SEXPORT, + + LFROM = 1<<0, + LTO = 1<<1, + LPOOL = 1<<2, + V4 = 1<<3, /* arm v4 arch */ + + C_NONE = 0, + C_REG, + C_REGREG, + C_SHIFT, + C_FREG, + C_PSR, + C_FCR, + + C_RCON, /* 0xff rotated */ + C_NCON, /* ~RCON */ + C_SCON, /* 0xffff */ + C_BCON, /* thumb */ + C_LCON, + C_FCON, + C_GCON, /* thumb */ + + C_RACON, + C_SACON, /* thumb */ + C_LACON, + C_GACON, /* thumb */ + + C_RECON, + C_LECON, + + C_SBRA, + C_LBRA, + C_GBRA, /* thumb */ + + C_HAUTO, /* halfword insn offset (-0xff to 0xff) */ + C_FAUTO, /* float insn offset (0 to 0x3fc, word aligned) */ + C_HFAUTO, /* both H and F */ + C_SAUTO, /* -0xfff to 0xfff */ + C_LAUTO, + + C_HEXT, + C_FEXT, + C_HFEXT, + C_SEXT, + C_LEXT, + + C_HOREG, + C_FOREG, + C_HFOREG, + C_SOREG, + C_ROREG, + C_SROREG, /* both S and R */ + C_LOREG, + C_GOREG, /* thumb */ + + C_PC, + C_SP, + C_HREG, + C_OFFPC, /* thumb */ + + C_ADDR, /* relocatable address */ + + C_GOK, + +/* mark flags */ + FOLL = 1<<0, + LABEL = 1<<1, + LEAF = 1<<2, + + BIG = (1<<12)-4, + STRINGSZ = 200, + NHASH = 10007, + NHUNK = 100000, + MINSIZ = 64, + NENT = 100, + MAXIO = 8192, + MAXHIST = 20, /* limit of path elements for history symbols */ + + Roffset = 22, /* no. bits for offset in relocation address */ + Rindex = 10, /* no. bits for index in relocation address */ +}; + +EXTERN union +{ + struct + { + uchar obuf[MAXIO]; /* output buffer */ + uchar ibuf[MAXIO]; /* input buffer */ + } u; + char dbuf[1]; +} buf; + +#define cbuf u.obuf +#define xbuf u.ibuf + +#define setarch(p) if((p)->as==ATEXT) thumb=(p)->reg&ALLTHUMBS +#define setthumb(p) if((p)->as==ATEXT) seenthumb|=(p)->reg&ALLTHUMBS + +#ifndef COFFCVT + +EXTERN long HEADR; /* length of header */ +EXTERN int HEADTYPE; /* type of header */ +EXTERN long INITDAT; /* data location */ +EXTERN long INITRND; /* data round above text location */ +EXTERN long INITTEXT; /* text location */ +EXTERN char* INITENTRY; /* entry point */ +EXTERN long autosize; +EXTERN Biobuf bso; +EXTERN long bsssize; +EXTERN int cbc; +EXTERN uchar* cbp; +EXTERN int cout; +EXTERN Auto* curauto; +EXTERN Auto* curhist; +EXTERN Prog* curp; +EXTERN Prog* curtext; +EXTERN Prog* datap; +EXTERN long datsize; +EXTERN char debug[128]; +EXTERN Prog* etextp; +EXTERN Prog* firstp; +EXTERN char fnuxi4[4]; +EXTERN char fnuxi8[8]; +EXTERN char* noname; +EXTERN Sym* hash[NHASH]; +EXTERN Sym* histfrog[MAXHIST]; +EXTERN int histfrogp; +EXTERN int histgen; +EXTERN char* library[50]; +EXTERN char* libraryobj[50]; +EXTERN int libraryp; +EXTERN int xrefresolv; +EXTERN char* hunk; +EXTERN char inuxi1[1]; +EXTERN char inuxi2[2]; +EXTERN char inuxi4[4]; +EXTERN Prog* lastp; +EXTERN long lcsize; +EXTERN char literal[32]; +EXTERN int nerrors; +EXTERN long nhunk; +EXTERN long instoffset; +EXTERN Opcross opcross[8]; +EXTERN Oprang oprange[ALAST]; +EXTERN Oprang thumboprange[ALAST]; +EXTERN char* outfile; +EXTERN long pc; +EXTERN uchar repop[ALAST]; +EXTERN long symsize; +EXTERN Prog* textp; +EXTERN long textsize; +EXTERN long thunk; +EXTERN int version; +EXTERN char xcmp[C_GOK+1][C_GOK+1]; +EXTERN Prog zprg; +EXTERN int dtype; +EXTERN int armv4; +EXTERN int thumb; +EXTERN int seenthumb; +EXTERN int armsize; + +EXTERN int doexp, dlm; +EXTERN int imports, nimports; +EXTERN int exports, nexports; +EXTERN char* EXPTAB; +EXTERN Prog undefp; + +#define UP (&undefp) + +extern char* anames[]; +extern Optab optab[]; +extern Optab thumboptab[]; + +void addpool(Prog*, Adr*); +EXTERN Prog* blitrl; +EXTERN Prog* elitrl; + +void initdiv(void); +EXTERN Prog* prog_div; +EXTERN Prog* prog_divu; +EXTERN Prog* prog_mod; +EXTERN Prog* prog_modu; + +#pragma varargck type "A" int +#pragma varargck type "C" int +#pragma varargck type "D" Adr* +#pragma varargck type "N" Adr* +#pragma varargck type "P" Prog* +#pragma varargck type "S" char* + +int Aconv(Fmt*); +int Cconv(Fmt*); +int Dconv(Fmt*); +int Nconv(Fmt*); +int Pconv(Fmt*); +int Sconv(Fmt*); +int aclass(Adr*); +int thumbaclass(Adr*, Prog*); +void addhist(long, int); +void append(Prog*, Prog*); +void asmb(void); +void asmdyn(void); +void asmlc(void); +void asmthumbmap(void); +void asmout(Prog*, Optab*); +void thumbasmout(Prog*, Optab*); +void asmsym(void); +long atolwhex(char*); +Prog* brloop(Prog*); +void buildop(void); +void thumbbuildop(void); +void buildrep(int, int); +void cflush(void); +void ckoff(Sym*, long); +int chipfloat(Ieee*); +int cmp(int, int); +int compound(Prog*); +double cputime(void); +void datblk(long, long, int); +void diag(char*, ...); +void divsig(void); +void dodata(void); +void doprof1(void); +void doprof2(void); +void dynreloc(Sym*, long, int); +long entryvalue(void); +void errorexit(void); +void exchange(Prog*); +void export(void); +int find1(long, int); +void follow(void); +void gethunk(void); +void histtoauto(void); +void hputl(int); +double ieeedtod(Ieee*); +long ieeedtof(Ieee*); +void import(void); +int isnop(Prog*); +void ldobj(int, long, char*); +void loadlib(void); +void listinit(void); +Sym* lookup(char*, int); +void cput(int); +void hput(long); +void lput(long); +void lputl(long); +void mkfwd(void); +void* mysbrk(ulong); +void names(void); +void nocache(Prog*); +void nuxiinit(void); +void objfile(char*); +int ocmp(void*, void*); +long opirr(int); +Optab* oplook(Prog*); +long oprrr(int, int); +long olr(long, int, int, int); +long olhr(long, int, int, int); +long olrr(int, int, int, int); +long olhrr(int, int, int, int); +long osr(int, int, long, int, int); +long oshr(int, long, int, int); +long ofsr(int, int, long, int, int, Prog*); +long osrr(int, int, int, int); +long oshrr(int, int, int, int); +long omvl(Prog*, Adr*, int); +void patch(void); +void prasm(Prog*); +void prepend(Prog*, Prog*); +Prog* prg(void); +int pseudo(Prog*); +void putsymb(char*, int, long, int); +void readundefs(char*, int); +long regoff(Adr*); +int relinv(int); +long rnd(long, long); +void span(void); +void strnput(char*, int); +void undef(void); +void undefsym(Sym*); +void wput(long); +void xdefine(char*, int, long); +void xfol(Prog*); +void zerosig(char*); +void noops(void); +long immrot(ulong); +long immaddr(long); +long opbra(int, int); +int brextra(Prog*); +int isbranch(Prog*); +int fnpinc(Sym *); +int fninc(Sym *); +void thumbcount(void); +void reachable(void); +void fnptrs(void); + +#endif diff --git a/utils/tl/list.c b/utils/tl/list.c new file mode 100644 index 00000000..d8eb5f2b --- /dev/null +++ b/utils/tl/list.c @@ -0,0 +1,360 @@ +#include "l.h" + +void +listinit(void) +{ + + fmtinstall('A', Aconv); + fmtinstall('C', Cconv); + fmtinstall('D', Dconv); + fmtinstall('P', Pconv); + fmtinstall('S', Sconv); + fmtinstall('N', Nconv); +} + +void +prasm(Prog *p) +{ + print("%P\n", p); +} + +int +Pconv(Fmt *fp) +{ + char str[STRINGSZ], *s; + Prog *p; + int a; + + p = va_arg(fp->args, Prog*); + curp = p; + a = p->as; + switch(a) { + default: + s = str; + s += sprint(s, "(%ld)", p->line); + if(p->reg == NREG) + sprint(s, " %A%C %D,%D", + a, p->scond, &p->from, &p->to); + else + if(p->from.type != D_FREG) + sprint(s, " %A%C %D,R%d,%D", + a, p->scond, &p->from, p->reg, &p->to); + else + sprint(s, " %A%C %D,F%d,%D", + a, p->scond, &p->from, p->reg, &p->to); + break; + + case ASWPW: + case ASWPBU: + sprint(str, "(%ld) %A%C R%d,%D,%D", + p->line, a, p->scond, p->reg, &p->from, &p->to); + break; + + case ADATA: + case AINIT: + case ADYNT: + sprint(str, "(%ld) %A%C %D/%d,%D", + p->line, a, p->scond, &p->from, p->reg, &p->to); + break; + + case AWORD: + sprint(str, "WORD %ld", p->to.offset); + break; + + case ADWORD: + sprint(str, "DWORD %ld %ld", p->from.offset, p->to.offset); + break; + } + return fmtstrcpy(fp, str); +} + +int +Aconv(Fmt *fp) +{ + char *s; + int a; + + a = va_arg(fp->args, int); + s = "?"; + if(a >= AXXX && a < ALAST) + s = anames[a]; + return fmtstrcpy(fp, s); +} + +char* strcond[16] = +{ + ".EQ", + ".NE", + ".HS", + ".LO", + ".MI", + ".PL", + ".VS", + ".VC", + ".HI", + ".LS", + ".GE", + ".LT", + ".GT", + ".LE", + "", + ".NV" +}; + +int +Cconv(Fmt *fp) +{ + char s[20]; + int c; + + c = va_arg(fp->args, int); + strcpy(s, strcond[c & C_SCOND]); + if(c & C_SBIT) + strcat(s, ".S"); + if(c & C_PBIT) + strcat(s, ".P"); + if(c & C_WBIT) + strcat(s, ".W"); + if(c & C_UBIT) /* ambiguous with FBIT */ + strcat(s, ".U"); + return fmtstrcpy(fp, s); +} + +int +Dconv(Fmt *fp) +{ + char str[STRINGSZ]; + char *op; + Adr *a; + long v; + + a = va_arg(fp->args, Adr*); + switch(a->type) { + + default: + sprint(str, "GOK-type(%d)", a->type); + break; + + case D_NONE: + str[0] = 0; + if(a->name != D_NONE || a->reg != NREG || a->sym != S) + sprint(str, "%N(R%d)(NONE)", a, a->reg); + break; + + case D_CONST: + if(a->reg == NREG) + sprint(str, "$%N", a); + else + sprint(str, "$%N(R%d)", a, a->reg); + break; + + case D_SHIFT: + v = a->offset; + op = "<<>>->@>" + (((v>>5) & 3) << 1); + if(v & (1<<4)) + sprint(str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15); + else + sprint(str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31); + if(a->reg != NREG) + sprint(str+strlen(str), "(R%d)", a->reg); + break; + + case D_OCONST: + sprint(str, "$*$%N", a); + if(a->reg != NREG) + sprint(str, "%N(R%d)(CONST)", a, a->reg); + break; + + case D_OREG: + if(a->reg != NREG) + sprint(str, "%N(R%d)", a, a->reg); + else + sprint(str, "%N", a); + break; + + case D_REG: + sprint(str, "R%d", a->reg); + if(a->name != D_NONE || a->sym != S) + sprint(str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_REGREG: + sprint(str, "(R%d,R%d)", a->reg, (int)a->offset); + if(a->name != D_NONE || a->sym != S) + sprint(str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_FREG: + sprint(str, "F%d", a->reg); + if(a->name != D_NONE || a->sym != S) + sprint(str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_PSR: + switch(a->reg) { + case 0: + sprint(str, "CPSR"); + break; + case 1: + sprint(str, "SPSR"); + break; + default: + sprint(str, "PSR%d", a->reg); + break; + } + if(a->name != D_NONE || a->sym != S) + sprint(str, "%N(PSR%d)(REG)", a, a->reg); + break; + + case D_FPCR: + switch(a->reg){ + case 0: + sprint(str, "FPSR"); + break; + case 1: + sprint(str, "FPCR"); + break; + default: + sprint(str, "FCR%d", a->reg); + break; + } + if(a->name != D_NONE || a->sym != S) + sprint(str, "%N(FCR%d)(REG)", a, a->reg); + + break; + + case D_BRANCH: /* botch */ + if(curp->cond != P) { + v = curp->cond->pc; + if(a->sym != S) + sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v); + else + sprint(str, "%.5lux(BRANCH)", v); + } else + if(a->sym != S) + sprint(str, "%s+%ld(APC)", a->sym->name, a->offset); + else + sprint(str, "%ld(APC)", a->offset); + break; + + case D_FCONST: + sprint(str, "$%e", ieeedtod(a->ieee)); + break; + + case D_SCONST: + sprint(str, "$\"%S\"", a->sval); + break; + } + return fmtstrcpy(fp, str); +} + +int +Nconv(Fmt *fp) +{ + char str[STRINGSZ]; + Adr *a; + Sym *s; + + a = va_arg(fp->args, Adr*); + s = a->sym; + switch(a->name) { + default: + sprint(str, "GOK-name(%d)", a->name); + break; + + case D_NONE: + sprint(str, "%ld", a->offset); + break; + + case D_EXTERN: + if(s == S) + sprint(str, "%ld(SB)", a->offset); + else + sprint(str, "%s+%ld(SB)", s->name, a->offset); + break; + + case D_STATIC: + if(s == S) + sprint(str, "<>+%ld(SB)", a->offset); + else + sprint(str, "%s<>+%ld(SB)", s->name, a->offset); + break; + + case D_AUTO: + if(s == S) + sprint(str, "%ld(SP)", a->offset); + else + sprint(str, "%s-%ld(SP)", s->name, -a->offset); + break; + + case D_PARAM: + if(s == S) + sprint(str, "%ld(FP)", a->offset); + else + sprint(str, "%s+%ld(FP)", s->name, a->offset); + break; + } + return fmtstrcpy(fp, str); +} + +int +Sconv(Fmt *fp) +{ + int i, c; + char str[STRINGSZ], *p, *a; + + a = va_arg(fp->args, char*); + p = str; + for(i=0; i<sizeof(long); i++) { + c = a[i] & 0xff; + if(c >= 'a' && c <= 'z' || + c >= 'A' && c <= 'Z' || + c >= '0' && c <= '9' || + c == ' ' || c == '%') { + *p++ = c; + continue; + } + *p++ = '\\'; + switch(c) { + case 0: + *p++ = 'z'; + continue; + case '\\': + case '"': + *p++ = c; + continue; + case '\n': + *p++ = 'n'; + continue; + case '\t': + *p++ = 't'; + continue; + } + *p++ = (c>>6) + '0'; + *p++ = ((c>>3) & 7) + '0'; + *p++ = (c & 7) + '0'; + } + *p = 0; + return fmtstrcpy(fp, str); +} + +void +diag(char *fmt, ...) +{ + char buf[STRINGSZ], *tn; + va_list arg; + + tn = "??none??"; + if(curtext != P && curtext->from.sym != S) + tn = curtext->from.sym->name; + va_start(arg, fmt); + vseprint(buf, buf+sizeof(buf), fmt, arg); + va_end(arg); + print("%s: %s\n", tn, buf); + + nerrors++; + if(nerrors > 10) { + print("too many errors\n"); + errorexit(); + } +} diff --git a/utils/tl/mkfile b/utils/tl/mkfile new file mode 100644 index 00000000..9d165849 --- /dev/null +++ b/utils/tl/mkfile @@ -0,0 +1,34 @@ +<../../mkconfig + +TARG=5l + +OFILES=\ + asm.$O\ + list.$O\ + noop.$O\ + obj.$O\ + optab.$O\ + pass.$O\ + span.$O\ + enam.$O\ + $TARGMODEL.$O\ + thumb.$O\ + +HFILES=\ + l.h\ + ../5c/5.out.h\ + ../include/ar.h\ + +LIBS=bio 9 # order is important + +CFLAGS=$CFLAGS -I../include -I. + +BIN=$ROOT/$OBJDIR/bin + +<$ROOT/mkfiles/mkone-$SHELLTYPE + +enam.$O: ../5c/enam.c + $CC $CFLAGS ../5c/enam.c + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/tl/noop.c b/utils/tl/noop.c new file mode 100644 index 00000000..08ef6dbe --- /dev/null +++ b/utils/tl/noop.c @@ -0,0 +1,894 @@ +#include "l.h" + +static Sym* sym_div; +static Sym* sym_divu; +static Sym* sym_mod; +static Sym* sym_modu; + +static void setdiv(int); + +static Prog * +movrr(Prog *q, int rs, int rd, Prog *p) +{ + if(q == nil) + q = prg(); + q->as = AMOVW; + q->line = p->line; + q->from.type = D_REG; + q->from.reg = rs; + q->to.type = D_REG; + q->to.reg = rd; + q->link = p->link; + return q; +} + +static Prog * +fnret(Prog *q, int rs, int foreign, Prog *p) +{ + q = movrr(q, rs, REGPC, p); + if(foreign){ // BX rs + q->as = ABXRET; + q->from.type = D_NONE; + q->from.reg = NREG; + q->to.reg = rs; + } + return q; +} + +static Prog * +aword(long w, Prog *p) +{ + Prog *q; + + q = prg(); + q->as = AWORD; + q->line = p->line; + q->from.type = D_NONE; + q->reg = NREG; + q->to.type = D_CONST; + q->to.offset = w; + q->link = p->link; + p->link = q; + return q; +} + +static Prog * +adword(long w1, long w2, Prog *p) +{ + Prog *q; + + q = prg(); + q->as = ADWORD; + q->line = p->line; + q->from.type = D_CONST; + q->from.offset = w1; + q->reg = NREG; + q->to.type = D_CONST; + q->to.offset = w2; + q->link = p->link; + p->link = q; + return q; +} + +void +noops(void) +{ + Prog *p, *q, *q1, *q2; + int o, curframe, curbecome, maxbecome, foreign; + + /* + * find leaf subroutines + * become sizes + * frame sizes + * strip NOPs + * expand RET + * expand BECOME pseudo + */ + + if(debug['v']) + Bprint(&bso, "%5.2f noops\n", cputime()); + Bflush(&bso); + + curframe = 0; + curbecome = 0; + maxbecome = 0; + curtext = 0; + + q = P; + for(p = firstp; p != P; p = p->link) { + setarch(p); + + /* find out how much arg space is used in this TEXT */ + if(p->to.type == D_OREG && p->to.reg == REGSP) + if(p->to.offset > curframe) + curframe = p->to.offset; + + switch(p->as) { + case ATEXT: + if(curtext && curtext->from.sym) { + curtext->from.sym->frame = curframe; + curtext->from.sym->become = curbecome; + if(curbecome > maxbecome) + maxbecome = curbecome; + } + curframe = 0; + curbecome = 0; + + p->mark |= LEAF; + curtext = p; + break; + + case ARET: + /* special form of RET is BECOME */ + if(p->from.type == D_CONST) + if(p->from.offset > curbecome) + curbecome = p->from.offset; + break; + + case ADIV: + case ADIVU: + case AMOD: + case AMODU: + q = p; + if(prog_div == P) + initdiv(); + if(curtext != P) + curtext->mark &= ~LEAF; + setdiv(p->as); + continue; + + case ANOP: + q1 = p->link; + q->link = q1; /* q is non-nop */ + q1->mark |= p->mark; + continue; + + case ABL: + case ABX: + if(curtext != P) + curtext->mark &= ~LEAF; + + case ABCASE: + case AB: + + case ABEQ: + case ABNE: + case ABCS: + case ABHS: + case ABCC: + case ABLO: + case ABMI: + case ABPL: + case ABVS: + case ABVC: + case ABHI: + case ABLS: + case ABGE: + case ABLT: + case ABGT: + case ABLE: + + q1 = p->cond; + if(q1 != P) { + while(q1->as == ANOP) { + q1 = q1->link; + p->cond = q1; + } + } + break; + } + q = p; + } + + if(curtext && curtext->from.sym) { + curtext->from.sym->frame = curframe; + curtext->from.sym->become = curbecome; + if(curbecome > maxbecome) + maxbecome = curbecome; + } + + if(debug['b']) + print("max become = %d\n", maxbecome); + xdefine("ALEFbecome", STEXT, maxbecome); + + curtext = 0; + for(p = firstp; p != P; p = p->link) { + setarch(p); + switch(p->as) { + case ATEXT: + curtext = p; + break; + case ABL: + // case ABX: + if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) { + o = maxbecome - curtext->from.sym->frame; + if(o <= 0) + break; + /* calling a become or calling a variable */ + if(p->to.sym == S || p->to.sym->become) { + curtext->to.offset += o; + if(debug['b']) { + curp = p; + print("%D calling %D increase %d\n", + &curtext->from, &p->to, o); + } + } + } + break; + } + } + + for(p = firstp; p != P; p = p->link) { + setarch(p); + o = p->as; + switch(o) { + case ATEXT: + curtext = p; + autosize = p->to.offset + 4; + if(autosize <= 4) + if(curtext->mark & LEAF) { + p->to.offset = -4; + autosize = 0; + } + + if(!autosize && !(curtext->mark & LEAF)) { + if(debug['v']) + Bprint(&bso, "save suppressed in: %s\n", + curtext->from.sym->name); + Bflush(&bso); + curtext->mark |= LEAF; + } +#ifdef CALLEEBX + if(p->from.sym->foreign){ + if(thumb) + // don't allow literal pool to seperate these + p = adword(0xe28f7001, 0xe12fff17, p); // arm add 1, pc, r7 and bx r7 + // p = aword(0xe12fff17, aword(0xe28f7001, p)); // arm add 1, pc, r7 and bx r7 + else + p = aword(0x4778, p); // thumb bx pc and 2 bytes padding + } +#endif + if(curtext->mark & LEAF) { + if(curtext->from.sym) + curtext->from.sym->type = SLEAF; +#ifdef optimise_time + if(autosize) { + q = prg(); + q->as = ASUB; + q->line = p->line; + q->from.type = D_CONST; + q->from.offset = autosize; + q->to.type = D_REG; + q->to.reg = REGSP; + + q->link = p->link; + p->link = q; + } + break; +#else + if(!autosize) + break; +#endif + } + + if(thumb){ + if(!(curtext->mark & LEAF)){ + q = movrr(nil, REGLINK, REGTMPT-1, p); + p->link = q; + q1 = prg(); + q1->as = AMOVW; + q1->line = p->line; + q1->from.type = D_REG; + q1->from.reg = REGTMPT-1; + q1->to.type = D_OREG; + q1->to.name = D_NONE; + q1->to.reg = REGSP; + q1->to.offset = 0; + q1->link = q->link; + q->link = q1; + } + if(autosize){ + q2 = prg(); + q2->as = ASUB; + q2->line = p->line; + q2->from.type = D_CONST; + q2->from.offset = autosize; + q2->to.type = D_REG; + q2->to.reg = REGSP; + q2->link = p->link; + p->link = q2; + } + break; + } + + q1 = prg(); + q1->as = AMOVW; + q1->scond |= C_WBIT; + q1->line = p->line; + q1->from.type = D_REG; + q1->from.reg = REGLINK; + q1->to.type = D_OREG; + q1->to.offset = -autosize; + q1->to.reg = REGSP; + q1->link = p->link; + p->link = q1; + break; + + case ARET: + nocache(p); + foreign = seenthumb && curtext->from.sym != S && (curtext->from.sym->foreign || curtext->from.sym->fnptr); +// print("%s %d %d\n", curtext->from.sym->name, curtext->from.sym->foreign, curtext->from.sym->fnptr); + if(p->from.type == D_CONST) + goto become; + if(curtext->mark & LEAF) { + if(!autosize) { + if(thumb){ + p = fnret(p, REGLINK, foreign, p); + break; + } +// if(foreign) print("ABXRET 1 %s\n", curtext->from.sym->name); + p->as = foreign ? ABXRET : AB; + p->from = zprg.from; + p->to.type = D_OREG; + p->to.offset = 0; + p->to.reg = REGLINK; + break; + } + +#ifdef optimise_time + p->as = AADD; + p->from.type = D_CONST; + p->from.offset = autosize; + p->to.type = D_REG; + p->to.reg = REGSP; + if(thumb){ + p->link = fnret(nil, REGLINK, foreign, p); + break; + } + q = prg(); +// if(foreign) print("ABXRET 2 %s\n", curtext->from.sym->name); + q->as = foreign ? ABXRET : AB; + q->scond = p->scond; + q->line = p->line; + q->to.type = D_OREG; + q->to.offset = 0; + q->to.reg = REGLINK; + + q->link = p->link; + p->link = q; + + break; +#endif + } + if(thumb){ + if(curtext->mark & LEAF){ + if(autosize){ + p->as = AADD; + p->from.type = D_CONST; + p->from.offset = autosize; + p->to.type = D_REG; + p->to.reg = REGSP; + q = nil; + } + else + q = p; + q = fnret(q, REGLINK, foreign, p); + if(q != p) + p->link = q; + } + else{ + p->as = AMOVW; + p->from.type = D_OREG; + p->from.name = D_NONE; + p->from.reg = REGSP; + p->from.offset = 0; + p->to.type = D_REG; + p->to.reg = REGTMPT-1; + if(autosize){ + q = prg(); + q->as = AADD; + q->from.type = D_CONST; + q->from.offset = autosize; + q->to.type = D_REG; + q->to.reg = REGSP; + q->link = p->link; + p->link = q; + } + else + q = p; + q1 = fnret(nil, REGTMPT-1, foreign, p); + q1->link = q->link; + q->link = q1; + } + break; + } + if(foreign) { +// if(foreign) print("ABXRET 3 %s\n", curtext->from.sym->name); +#define R 1 + p->as = AMOVW; + p->from.type = D_OREG; + p->from.name = D_NONE; + p->from.reg = REGSP; + p->from.offset = 0; + p->to.type = D_REG; + p->to.reg = R; + q = prg(); + q->as = AADD; + q->scond = p->scond; + q->line = p->line; + q->from.type = D_CONST; + q->from.offset = autosize; + q->to.type = D_REG; + q->to.reg = REGSP; + q->link = p->link; + p->link = q; + q1 = prg(); + q1->as = ABXRET; + q1->scond = p->scond; + q1->line = p->line; + q1->to.type = D_OREG; + q1->to.offset = 0; + q1->to.reg = R; + q1->link = q->link; + q->link = q1; +#undef R + } + else { + p->as = AMOVW; + p->scond |= C_PBIT; + p->from.type = D_OREG; + p->from.offset = autosize; + p->from.reg = REGSP; + p->to.type = D_REG; + p->to.reg = REGPC; + } + break; + + become: + if(foreign){ + diag("foreign become - help"); + break; + } + if(thumb){ + diag("thumb become - help"); + break; + } + print("arm become\n"); + if(curtext->mark & LEAF) { + + if(!autosize) { + p->as = AB; + p->from = zprg.from; + break; + } + +#ifdef optimise_time + q = prg(); + q->scond = p->scond; + q->line = p->line; + q->as = AB; + q->from = zprg.from; + q->to = p->to; + q->cond = p->cond; + q->link = p->link; + p->link = q; + + p->as = AADD; + p->from = zprg.from; + p->from.type = D_CONST; + p->from.offset = autosize; + p->to = zprg.to; + p->to.type = D_REG; + p->to.reg = REGSP; + + break; +#endif + } + q = prg(); + q->scond = p->scond; + q->line = p->line; + q->as = AB; + q->from = zprg.from; + q->to = p->to; + q->cond = p->cond; + q->link = p->link; + p->link = q; + if(thumb){ + q1 = prg(); + q1->line = p->line; + q1->as = AADD; + q1->from.type = D_CONST; + q1->from.offset = autosize; + q1->to.type = D_REG; + q1->to.reg = REGSP; + p->as = AMOVW; + p->line = p->line; + p->from.type = D_OREG; + p->from.name = D_NONE; + p->from.reg = REGSP; + p->from.offset = 0; + p->to.type = D_REG; + p->to.reg = REGTMPT-1; + q1->link = q; + p->link = q1; + q2 = movrr(nil, REGTMPT-1, REGLINK, p); + q2->link = q; + q1->link = q2; + break; + } + p->as = AMOVW; + p->scond |= C_PBIT; + p->from = zprg.from; + p->from.type = D_OREG; + p->from.offset = autosize; + p->from.reg = REGSP; + p->to = zprg.to; + p->to.type = D_REG; + p->to.reg = REGLINK; + + break; + + case ADIV: + case ADIVU: + case AMOD: + case AMODU: + if(debug['M']) + break; + if(p->from.type != D_REG) + break; + if(p->to.type != D_REG) + break; + q1 = p; + + /* MOV a,4(SP) */ + q = prg(); + q->link = p->link; + p->link = q; + p = q; + + p->as = AMOVW; + p->line = q1->line; + p->from.type = D_REG; + p->from.reg = q1->from.reg; + p->to.type = D_OREG; + p->to.reg = REGSP; + p->to.offset = 4; + + /* MOV b,REGTMP */ + q = prg(); + q->link = p->link; + p->link = q; + p = q; + + p->as = AMOVW; + p->line = q1->line; + p->from.type = D_REG; + p->from.reg = q1->reg; + if(q1->reg == NREG) + p->from.reg = q1->to.reg; + p->to.type = D_REG; + p->to.reg = prog_div != UP && prog_div->from.sym->thumb ? REGTMPT : REGTMP; + p->to.offset = 0; + + /* CALL appropriate */ + q = prg(); + q->link = p->link; + p->link = q; + p = q; + +#ifdef CALLEEBX + p->as = ABL; +#else + if(prog_div != UP && prog_div->from.sym->thumb) + p->as = thumb ? ABL : ABX; + else + p->as = thumb ? ABX : ABL; +#endif + p->line = q1->line; + p->to.type = D_BRANCH; + p->cond = p; + switch(o) { + case ADIV: + p->cond = prog_div; + p->to.sym = sym_div; + break; + case ADIVU: + p->cond = prog_divu; + p->to.sym = sym_divu; + break; + case AMOD: + p->cond = prog_mod; + p->to.sym = sym_mod; + break; + case AMODU: + p->cond = prog_modu; + p->to.sym = sym_modu; + break; + } + + /* MOV REGTMP, b */ + q = prg(); + q->link = p->link; + p->link = q; + p = q; + + p->as = AMOVW; + p->line = q1->line; + p->from.type = D_REG; + p->from.reg = prog_div != UP && prog_div->from.sym->thumb ? REGTMPT : REGTMP; + p->from.offset = 0; + p->to.type = D_REG; + p->to.reg = q1->to.reg; + + /* ADD $8,SP */ + q = prg(); + q->link = p->link; + p->link = q; + p = q; + + p->as = AADD; + p->from.type = D_CONST; + p->from.reg = NREG; + p->from.offset = 8; + p->reg = NREG; + p->to.type = D_REG; + p->to.reg = REGSP; + + /* SUB $8,SP */ + q1->as = ASUB; + q1->from.type = D_CONST; + q1->from.offset = 8; + q1->from.reg = NREG; + q1->reg = NREG; + q1->to.type = D_REG; + q1->to.reg = REGSP; + + break; + case AMOVW: + if(thumb){ + Adr *a = &p->from; + + if(a->type == D_CONST && ((a->name == D_NONE && a->reg == REGSP) || a->name == D_AUTO || a->name == D_PARAM) && (a->offset & 3)) + diag("SP offset not multiple of 4"); + } + break; + case AMOVB: + case AMOVBU: + case AMOVH: + case AMOVHU: + if(thumb){ + if(p->from.type == D_OREG && (p->from.name == D_AUTO || p->from.name == D_PARAM || (p->from.name == D_CONST && p->from.reg == REGSP))){ + q = prg(); + *q = *p; + if(p->from.name == D_AUTO) + q->from.offset += autosize; + else if(p->from.name == D_PARAM) + q->from.offset += autosize+4; + q->from.name = D_NONE; + q->from.reg = REGTMPT; + p = movrr(p, REGSP, REGTMPT, p); + q->link = p->link; + p->link = q; + } + if(p->to.type == D_OREG && (p->to.name == D_AUTO || p->to.name == D_PARAM || (p->to.name == D_CONST && p->to.reg == REGSP))){ + q = prg(); + *q = *p; + if(p->to.name == D_AUTO) + q->to.offset += autosize; + else if(p->to.name == D_PARAM) + q->to.offset += autosize+4; + q->to.name = D_NONE; + q->to.reg = REGTMPT; + p = movrr(p, REGSP, REGTMPT, p); + q->link = p->link; + p->link = q; + if(q->to.offset < 0 || q->to.offset > 255){ // complicated + p->to.reg = REGTMPT+1; // mov sp, r8 + q1 = prg(); + q1->line = p->line; + q1->as = AMOVW; + q1->from.type = D_CONST; + q1->from.offset = q->to.offset; + q1->to.type = D_REG; + q1->to.reg = REGTMPT; // mov $o, r7 + p->link = q1; + q1->link = q; + q1 = prg(); + q1->line = p->line; + q1->as = AADD; + q1->from.type = D_REG; + q1->from.reg = REGTMPT+1; + q1->to.type = D_REG; + q1->to.reg = REGTMPT; // add r8, r7 + p->link->link = q1; + q1->link = q; + q->to.offset = 0; // mov* r, 0(r7) + /* phew */ + } + } + } + break; + case AMOVM: + if(thumb){ + if(p->from.type == D_OREG){ + if(p->from.offset == 0) + p->from.type = D_REG; + else + diag("non-zero AMOVM offset"); + } + else if(p->to.type == D_OREG){ + if(p->to.offset == 0) + p->to.type = D_REG; + else + diag("non-zero AMOVM offset"); + } + } + break; + case AB: + if(thumb && p->to.type == D_OREG){ + if(p->to.offset == 0){ + p->as = AMOVW; + p->from.type = D_REG; + p->from.reg = p->to.reg; + p->to.type = D_REG; + p->to.reg = REGPC; + } + else{ + p->as = AADD; + p->from.type = D_CONST; + p->from.offset = p->to.offset; + p->reg = p->to.reg; + p->to.type = D_REG; + p->to.reg = REGTMPT-1; + q = prg(); + q->as = AMOVW; + q->line = p->line; + q->from.type = D_REG; + q->from.reg = REGTMPT-1; + q->to.type = D_REG; + q->to.reg = REGPC; + q->link = p->link; + p->link = q; + } + } + if(seenthumb && !thumb && p->to.type == D_OREG && p->to.reg == REGLINK){ + // print("warn %s: b (R%d) assuming a return\n", curtext->from.sym->name, p->to.reg); + p->as = ABXRET; + } + break; + case ABL: + case ABX: + if(thumb && p->to.type == D_OREG){ + if(p->to.offset == 0){ + p->as = o; + p->from.type = D_NONE; + p->to.type = D_REG; + } + else{ + p->as = AADD; + p->from.type = D_CONST; + p->from.offset = p->to.offset; + p->reg = p->to.reg; + p->to.type = D_REG; + p->to.reg = REGTMPT-1; + q = prg(); + q->as = o; + q->line = p->line; + q->from.type = D_NONE; + q->to.type = D_REG; + q->to.reg = REGTMPT-1; + q->link = p->link; + p->link = q; + } + } + break; + } + } +} + +static void +sigdiv(char *n) +{ + Sym *s; + + s = lookup(n, 0); + if(s->type == STEXT){ + if(s->sig == 0) + s->sig = SIGNINTERN; + } + else if(s->type == 0 || s->type == SXREF) + s->type = SUNDEF; +} + +void +divsig(void) +{ + sigdiv("_div"); + sigdiv("_divu"); + sigdiv("_mod"); + sigdiv("_modu"); +} + +static void +sdiv(Sym *s) +{ + if(s->type == 0 || s->type == SXREF){ + /* undefsym(s); */ + s->type = SXREF; + if(s->sig == 0) + s->sig = SIGNINTERN; + s->subtype = SIMPORT; + } + else if(s->type != STEXT) + diag("undefined: %s", s->name); +} + +void +initdiv(void) +{ + Sym *s2, *s3, *s4, *s5; + Prog *p; + + if(prog_div != P) + return; + sym_div = s2 = lookup("_div", 0); + sym_divu = s3 = lookup("_divu", 0); + sym_mod = s4 = lookup("_mod", 0); + sym_modu = s5 = lookup("_modu", 0); + if(dlm) { + sdiv(s2); if(s2->type == SXREF) prog_div = UP; + sdiv(s3); if(s3->type == SXREF) prog_divu = UP; + sdiv(s4); if(s4->type == SXREF) prog_mod = UP; + sdiv(s5); if(s5->type == SXREF) prog_modu = UP; + } + for(p = firstp; p != P; p = p->link) + if(p->as == ATEXT) { + if(p->from.sym == s2) + prog_div = p; + if(p->from.sym == s3) + prog_divu = p; + if(p->from.sym == s4) + prog_mod = p; + if(p->from.sym == s5) + prog_modu = p; + } + if(prog_div == P) { + diag("undefined: %s", s2->name); + prog_div = curtext; + } + if(prog_divu == P) { + diag("undefined: %s", s3->name); + prog_divu = curtext; + } + if(prog_mod == P) { + diag("undefined: %s", s4->name); + prog_mod = curtext; + } + if(prog_modu == P) { + diag("undefined: %s", s5->name); + prog_modu = curtext; + } +} + +static void +setdiv(int as) +{ + Prog *p = nil; + + switch(as){ + case ADIV: p = prog_div; break; + case ADIVU: p = prog_divu; break; + case AMOD: p = prog_mod; break; + case AMODU: p = prog_modu; break; + } + if(p != UP && thumb != p->from.sym->thumb) + p->from.sym->foreign = 1; +} + +void +nocache(Prog *p) +{ + p->optab = 0; + p->from.class = 0; + p->to.class = 0; +} diff --git a/utils/2l/obj.c b/utils/tl/obj.c index 9cc85565..35c5f558 100644 --- a/utils/2l/obj.c +++ b/utils/tl/obj.c @@ -8,28 +8,52 @@ char *noname = "<none>"; char symname[] = SYMDEF; -char thechar = '2'; -char *thestring = "68020"; +char thechar = '5'; +char *thestring = "arm"; /* - * -H0 -T0x40004C -D0x10000000 is garbage unix - * -H1 -T0x80020000 -R4 is garbage format - * -H2 -T8224 -R8192 is plan9 format - * -H3 -Tx -Rx is next boot + * -H1 -T0x10005000 -R4 is aif for risc os + * -H2 -T4128 -R4096 is plan9 format + * -H3 -T0xF0000020 -R4 is NetBSD format + * -H4 is IXP1200 (raw) + * -H5 -T0xC0008010 -R1024 is ipaq */ +static int +isobjfile(char *f) +{ + int n, v; + Biobuf *b; + char buf1[5], buf2[SARMAG]; + + b = Bopen(f, OREAD); + if(b == nil) + return 0; + n = Bread(b, buf1, 5); + if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<')) + v = 1; /* good enough for our purposes */ + else{ + Bseek(b, 0, 0); + n = Bread(b, buf2, SARMAG); + v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0; + } + Bterm(b); + return v; +} + void main(int argc, char *argv[]) { - int i, c; + int c; char *a; Binit(&bso, 1, OWRITE); + srand(time(0)); cout = -1; listinit(); - memset(debug, 0, sizeof(debug)); + outfile = 0; nerrors = 0; - outfile = "2.out"; + curtext = P; HEADTYPE = -1; INITTEXT = -1; INITDAT = -1; @@ -42,7 +66,7 @@ main(int argc, char *argv[]) if(c >= 0 && c < sizeof(debug)) debug[c]++; break; - case 'o': /* output to (next arg) */ + case 'o': outfile = ARGF(); break; case 'E': @@ -50,11 +74,6 @@ main(int argc, char *argv[]) if(a) INITENTRY = a; break; - case 'H': - a = ARGF(); - if(a) - HEADTYPE = atolwhex(a); - break; case 'T': a = ARGF(); if(a) @@ -70,149 +89,130 @@ main(int argc, char *argv[]) if(a) INITRND = atolwhex(a); break; + case 'H': + a = ARGF(); + if(a) + HEADTYPE = atolwhex(a); + /* do something about setting INITTEXT */ + break; + case 'x': /* produce export table */ + doexp = 1; + if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) + readundefs(ARGF(), SEXPORT); + break; + case 'u': /* produce dynamically loadable module */ + dlm = 1; + debug['l']++; + if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) + readundefs(ARGF(), SIMPORT); + break; } ARGEND USED(argc); if(*argv == 0) { - diag("usage: 2l [-options] objects"); + diag("usage: 5l [-options] objects"); errorexit(); } if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; if(HEADTYPE == -1) { if(debug['U']) - HEADTYPE = 2; + HEADTYPE = 0; if(debug['B']) - HEADTYPE = 2; + HEADTYPE = 1; if(debug['9']) HEADTYPE = 2; } - if(INITDAT != -1 && INITRND == -1) - INITRND = 0; switch(HEADTYPE) { default: - diag("unknown -H option %d", HEADTYPE); + diag("unknown -H option"); errorexit(); - - case 0: /* this is garbage */ - HEADR = 20L+56L; + case 0: /* no header */ + HEADR = 0L; if(INITTEXT == -1) - INITTEXT = 0x40004CL; + INITTEXT = 0; if(INITDAT == -1) - INITDAT = 0x10000000L; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; + INITDAT = 0; if(INITRND == -1) - INITRND = 0; + INITRND = 4; break; - case 1: /* plan9 boot data goes into text */ - HEADR = 32L; + case 1: /* aif for risc os */ + HEADR = 128L; if(INITTEXT == -1) - INITTEXT = 8224; + INITTEXT = 0x10005000 + HEADR; if(INITDAT == -1) INITDAT = 0; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; if(INITRND == -1) - INITRND = 8192; + INITRND = 4; break; case 2: /* plan 9 */ HEADR = 32L; if(INITTEXT == -1) - INITTEXT = 8224; + INITTEXT = 4128; if(INITDAT == -1) INITDAT = 0; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; if(INITRND == -1) - INITRND = 8192; + INITRND = 4096; break; - case 3: /* next boot */ - HEADR = 28+124+192+24; + case 3: /* boot for NetBSD */ + HEADR = 32L; if(INITTEXT == -1) - INITTEXT = 0x04002000; + INITTEXT = 0xF0000020L; if(INITDAT == -1) INITDAT = 0; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; if(INITRND == -1) - INITRND = 8192L; + INITRND = 4096; break; - case 4: /* preprocess pilot */ - HEADR = 32L; + case 4: /* boot for IXP1200 */ + HEADR = 0L; if(INITTEXT == -1) - INITTEXT = 0; + INITTEXT = 0x0; + if(INITDAT == -1) + INITDAT = 0; + if(INITRND == -1) + INITRND = 4; + break; + case 5: /* boot for ipaq */ + HEADR = 16L; + if(INITTEXT == -1) + INITTEXT = 0xC0008010; if(INITDAT == -1) INITDAT = 0; - if(INITDAT != 0 && INITRND == -1) - INITRND = 0; if(INITRND == -1) - INITRND = 32; + INITRND = 1024; break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", INITDAT, INITRND); if(debug['v']) - Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", + Bprint(&bso, "HEADER = -H0x%d -T0x%lux -D0x%lux -R0x%lux\n", HEADTYPE, INITTEXT, INITDAT, INITRND); Bflush(&bso); - for(i=1; optab[i].as; i++) - if(i != optab[i].as) { - diag("phase error in optab: %d", i); - errorexit(); - } - - zprg.link = P; - zprg.pcond = P; - zprg.back = 2; zprg.as = AGOK; + zprg.scond = 14; + zprg.reg = NREG; + zprg.from.name = D_NONE; zprg.from.type = D_NONE; - zprg.from.index = D_NONE; + zprg.from.reg = NREG; zprg.to = zprg.from; - - memset(special, 0, sizeof(special)); - special[D_CCR] = 1; - special[D_SR] = 1; - special[D_SFC] = 1; - special[D_CACR] = 1; - special[D_USP] = 1; - special[D_VBR] = 1; - special[D_CAAR] = 1; - special[D_MSP] = 1; - special[D_ISP] = 1; - special[D_DFC] = 1; - special[D_FPCR] = 1; - special[D_FPSR] = 1; - special[D_FPIAR] = 1; - special[D_TC] = 1; - special[D_ITT0] = 1; - special[D_ITT1] = 1; - special[D_DTT0] = 1; - special[D_DTT1] = 1; - special[D_MMUSR] = 1; - special[D_URP] = 1; - special[D_SRP] = 1; - memset(simple, 0177, sizeof(simple)); - for(i=0; i<8; i++) { - simple[D_R0+i] = i; - simple[D_F0+i] = i+0100; - simple[D_A0+i] = i+010; - simple[D_A0+I_INDIR+i] = i+020; - simple[D_A0+I_INDINC+i] = i+030; - simple[D_A0+I_INDDEC+i] = i+040; - } - nuxiinit(); + buildop(); + thumbbuildop(); // could build on demand histgen = 0; textp = P; datap = P; pc = 0; + dtype = 4; + if(outfile == 0) + outfile = "5.out"; cout = create(outfile, 1, 0775); if(cout < 0) { - diag("cannot create %s", outfile); + diag("%s: cannot create", outfile); errorexit(); } + nuxiinit(); + version = 0; cbp = buf.cbuf; cbc = sizeof(buf.cbuf); @@ -234,30 +234,56 @@ main(int argc, char *argv[]) loadlib(); firstp = firstp->link; if(firstp == P) - errorexit(); + goto out; + if(doexp || dlm){ + EXPTAB = "_exporttab"; + zerosig(EXPTAB); + zerosig("etext"); + zerosig("edata"); + zerosig("end"); + if(dlm){ + initdiv(); + import(); + HEADTYPE = 2; + INITTEXT = INITDAT = 0; + INITRND = 8; + INITENTRY = EXPTAB; + } + else + divsig(); + export(); + } patch(); if(debug['p']) if(debug['1']) doprof1(); else doprof2(); - follow(); + if(debug['u']) + reachable(); dodata(); - dostkoff(); + if(seenthumb && debug['f']) + fnptrs(); + follow(); + if(firstp == P) + goto out; + noops(); span(); asmb(); undef(); + +out: + if(debug['c']){ + thumbcount(); + print("ARM size = %d\n", armsize); + } if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); - Bprint(&bso, "%ld+%ld = %ld data statements\n", - ndata, ncase, ndata+ncase); - Bprint(&bso, "%ld symbols\n", nsymbol); Bprint(&bso, "%ld memory used\n", thunk); Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); } Bflush(&bso); - errorexit(); } @@ -333,6 +359,8 @@ objfile(char *file) return; } + if(debug['v']) + Bprint(&bso, "%5.2f ldlib: %s\n", cputime(), file); l = read(f, &arhdr, SAR_HDR); if(l != SAR_HDR) { diag("%s: short read on archive file symbol header", file); @@ -405,115 +433,108 @@ out: int zaddr(uchar *p, Adr *a, Sym *h[]) { - int c, t, i; + int i, c; long l; Sym *s; Auto *u; - t = p[0]; - - /* - * first try the high-time formats - */ - if(t == 0) { - a->index = D_NONE; - a->type = p[1]; - return 2; - } - if(t == T_OFFSET) { - a->index = D_NONE; - a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24); - a->type = p[5]; - return 6; - } - if(t == (T_OFFSET|T_SYM)) { - a->index = D_NONE; - a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24); - s = h[p[5]]; - a->sym = s; - a->type = p[6]; - c = 7; - goto dosym; - } - if(t == T_SYM) { - a->index = D_NONE; - s = h[p[1]]; - a->sym = s; - a->type = p[2]; - c = 3; - goto dosym; + c = p[2]; + if(c < 0 || c > NSYM){ + print("sym out of range: %d\n", c); + p[0] = ALAST+1; + return 0; } - if(t == (T_INDEX|T_OFFSET|T_SYM)) { - a->index = p[1] | (p[2]<<8); - a->scale = p[3]; - a->displace = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24); - a->offset = p[8] | (p[9]<<8) | (p[10]<<16) | (p[11]<<24); - s = h[p[12]]; - a->sym = s; - a->type = p[13]; - c = 14; - goto dosym; + a->type = p[0]; + a->reg = p[1]; + a->sym = h[c]; + a->name = p[3]; + c = 4; + + if(a->reg < 0 || a->reg > NREG) { + print("register out of range %d\n", a->reg); + p[0] = ALAST+1; + return 0; /* force real diagnostic */ } - /* - * now do it the hard way - */ - c = 1; - a->index = D_NONE; - if(t & T_FIELD) { - a->field = p[c] | (p[c+1]<<8); - c += 2; - } - if(t & T_INDEX) { - a->index = p[c] | (p[c+1]<<8); - a->scale = p[c+2]; - a->displace = p[c+3] | (p[c+4]<<8) | (p[c+5]<<16) | (p[c+6]<<24); - c += 7; + if(a->type == D_CONST || a->type == D_OCONST) { + if(a->name == D_EXTERN || a->name == D_STATIC) { + s = a->sym; + if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF)) { + if(0 && !s->fnptr && s->name[0] != '.') + print("%s used as function pointer\n", s->name); + s->fnptr = 1; // over the top cos of SXREF + } + } } - if(t & T_OFFSET) { - a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); + + switch(a->type) { + default: + print("unknown type %d\n", a->type); + p[0] = ALAST+1; + return 0; /* force real diagnostic */ + + case D_NONE: + case D_REG: + case D_FREG: + case D_PSR: + case D_FPCR: + break; + + case D_REGREG: + a->offset = p[4]; + c++; + break; + + case D_BRANCH: + case D_OREG: + case D_CONST: + case D_OCONST: + case D_SHIFT: + a->offset = p[4] | (p[5]<<8) | + (p[6]<<16) | (p[7]<<24); c += 4; - } - if(t & T_SYM) { - a->sym = h[p[c]]; - c += 1; - } - if(t & T_FCONST) { - a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); - a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24); - c += 8; - a->type = D_FCONST; - } else - if(t & T_SCONST) { - for(i=0; i<NSNAME; i++) - a->scon[i] = p[c+i]; + break; + + case D_SCONST: + while(nhunk < NSNAME) + gethunk(); + a->sval = (char*)hunk; + nhunk -= NSNAME; + hunk += NSNAME; + + memmove(a->sval, p+4, NSNAME); c += NSNAME; - a->type = D_SCONST; - } else - if(t & T_TYPE) { - a->type = p[c] | (p[c+1]<<8); - c += 2; - } else { - a->type = p[c]; - c++; + break; + + case D_FCONST: + while(nhunk < sizeof(Ieee)) + gethunk(); + a->ieee = (Ieee*)hunk; + nhunk -= NSNAME; + hunk += NSNAME; + + a->ieee->l = p[4] | (p[5]<<8) | + (p[6]<<16) | (p[7]<<24); + a->ieee->h = p[8] | (p[9]<<8) | + (p[10]<<16) | (p[11]<<24); + c += 8; + break; } s = a->sym; if(s == S) return c; - -dosym: - t = a->type & D_MASK; - if(t != D_AUTO && t != D_PARAM) + i = a->name; + if(i != D_AUTO && i != D_PARAM) return c; + l = a->offset; - for(u=curauto; u; u=u->link) { + for(u=curauto; u; u=u->link) if(u->asym == s) - if(u->type == t) { + if(u->type == i) { if(u->aoffset > l) u->aoffset = l; return c; } - } while(nhunk < sizeof(Auto)) gethunk(); @@ -525,7 +546,7 @@ dosym: curauto = u; u->asym = s; u->aoffset = l; - u->type = t; + u->type = i; return c; } @@ -596,6 +617,7 @@ addlib(char *obj) libraryobj[libraryp] = p; libraryp++; } + void addhist(long line, int type) { @@ -672,6 +694,14 @@ out: histfrog[histfrogp-1] = s; } +void +nopout(Prog *p) +{ + p->as = ANOP; + p->from.type = D_NONE; + p->to.type = D_NONE; +} + uchar* readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) { @@ -689,24 +719,39 @@ readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) return stop + n; } +static void puntfp(Prog *); + void ldobj(int f, long c, char *pn) { - Prog *p; - Sym *h[NSYM], *s; - int v, o, r; - long ipc, lv; - double dv; + long ipc; + Prog *p, *t; uchar *bloc, *bsize, *stop; + Sym *h[NSYM], *s, *di; + int v, o, r, skip; + ulong sig; + static int files; + static char **filen; + char **nfilen; + + if((files&15) == 0){ + nfilen = malloc((files+16)*sizeof(char*)); + memmove(nfilen, filen, files*sizeof(char*)); + free(filen); + filen = nfilen; + } + filen[files++] = strdup(pn); bsize = buf.xbuf; bloc = buf.xbuf; + di = S; newloop: memset(h, 0, sizeof(h)); version++; histfrogp = 0; ipc = pc; + skip = 0; loop: if(c <= 0) @@ -719,36 +764,35 @@ loop: bloc = buf.xbuf; goto loop; } - o = bloc[0] | (bloc[1] << 8); + o = bloc[0]; /* as */ if(o <= AXXX || o >= ALAST) { - if(o < 0) - goto eof; - diag("%s: opcode out of range %d", pn, o); - print(" probably not a .2 file\n"); + diag("%s: line %ld: opcode out of range %d", pn, pc-ipc, o); + print(" probably not a .5 file\n"); errorexit(); } - if(o == ANAME || o == ASIGNAME) { - if(o == ASIGNAME) { + sig = 0; + if(o == ASIGNAME){ + sig = bloc[1] | (bloc[2]<<8) | (bloc[3]<<16) | (bloc[4]<<24); bloc += 4; c -= 4; } - stop = memchr(&bloc[4], 0, bsize-&bloc[4]); + stop = memchr(&bloc[3], 0, bsize-&bloc[3]); if(stop == 0){ bsize = readsome(f, buf.xbuf, bloc, bsize, c); if(bsize == 0) goto eof; bloc = buf.xbuf; - stop = memchr(&bloc[4], 0, bsize-&bloc[4]); + stop = memchr(&bloc[3], 0, bsize-&bloc[3]); if(stop == 0){ fprint(2, "%s: name too long\n", pn); errorexit(); } } - v = bloc[2]; /* type */ - o = bloc[3]; /* sym */ - bloc += 4; - c -= 4; + v = bloc[1]; /* type */ + o = bloc[2]; /* sym */ + bloc += 3; + c -= 3; r = 0; if(v == D_STATIC) @@ -757,6 +801,13 @@ loop: c -= &stop[1] - bloc; bloc = stop + 1; + if(sig != 0){ + if(s->sig != 0 && s->sig != sig) + diag("incompatible type signatures %lux(%s) and %lux(%s) for %s", s->sig, filen[s->file], sig, pn, s->name); + s->sig = sig; + s->file = files-1; + } + if(debug['W']) print(" ANAME %s\n", s->name); h[o] = s; @@ -777,24 +828,32 @@ loop: goto loop; } - while(nhunk < sizeof(Prog)) + if(nhunk < sizeof(Prog)) gethunk(); p = (Prog*)hunk; nhunk -= sizeof(Prog); hunk += sizeof(Prog); p->as = o; - p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24); - p->back = 2; - r = zaddr(bloc+6, &p->from, h) + 6; + p->scond = bloc[1]; + p->reg = bloc[2]; + p->line = bloc[3] | (bloc[4]<<8) | (bloc[5]<<16) | (bloc[6]<<24); + + r = zaddr(bloc+7, &p->from, h) + 7; r += zaddr(bloc+r, &p->to, h); bloc += r; c -= r; + if(p->reg > NREG) + diag("register out of range %d", p->reg); + + p->link = P; + p->cond = P; + if(debug['W']) print("%P\n", p); - switch(p->as) { + switch(o) { case AHISTORY: if(p->to.offset == -1) { addlib(pn); @@ -819,216 +878,244 @@ loop: case AGLOBL: s = p->from.sym; + if(s == S) { + diag("GLOBL must have a name\n%P", p); + errorexit(); + } if(s->type == 0 || s->type == SXREF) { s->type = SBSS; s->value = 0; } if(s->type != SBSS) { - diag("%s: redefinition: %s in %s", - pn, s->name, TNAME); + diag("redefinition: %s\n%P", s->name, p); s->type = SBSS; s->value = 0; } if(p->to.offset > s->value) s->value = p->to.offset; - goto loop; + break; - case ABCASE: - ncase++; - goto casdef; + case ADYNT: + if(p->to.sym == S) { + diag("DYNT without a sym\n%P", p); + break; + } + di = p->to.sym; + p->reg = 4; + if(di->type == SXREF) { + if(debug['z']) + Bprint(&bso, "%P set to %d\n", p, dtype); + di->type = SCONST; + di->value = dtype; + dtype += 4; + } + if(p->from.sym == S) + break; + + p->from.offset = di->value; + p->from.sym->type = SDATA; + if(curtext == P) { + diag("DYNT not in text: %P", p); + break; + } + p->to.sym = curtext->from.sym; + p->to.type = D_CONST; + p->link = datap; + datap = p; + break; + case AINIT: + if(p->from.sym == S) { + diag("INIT without a sym\n%P", p); + break; + } + if(di == S) { + diag("INIT without previous DYNT\n%P", p); + break; + } + p->from.offset = di->value; + p->from.sym->type = SDATA; + p->link = datap; + datap = p; + break; + case ADATA: + if(p->from.sym == S) { + diag("DATA without a sym\n%P", p); + break; + } p->link = datap; datap = p; - ndata++; - goto loop; + break; case AGOK: - diag("%s: unknown opcode in %s", pn, TNAME); + diag("unknown opcode\n%P", p); + p->pc = pc; pc++; - goto loop; + break; case ATEXT: + setarch(p); + setthumb(p); + p->align = 4; if(curtext != P) { histtoauto(); curtext->to.autom = curauto; curauto = 0; } + skip = 0; curtext = p; + autosize = (p->to.offset+3L) & ~3L; + p->to.offset = autosize; + autosize += 4; + s = p->from.sym; + if(s == S) { + diag("TEXT must have a name\n%P", p); + errorexit(); + } + if(s->type != 0 && s->type != SXREF) { + if(p->reg & DUPOK) { + skip = 1; + goto casedef; + } + diag("redefinition: %s\n%P", s->name, p); + } + s->type = STEXT; + s->value = pc; + s->thumb = thumb; lastp->link = p; lastp = p; p->pc = pc; - s = p->from.sym; - if(s->type != 0 && s->type != SXREF) - diag("%s: redefinition: %s", pn, s->name); - s->type = STEXT; - s->value = p->pc; pc++; - p->pcond = P; if(textp == P) { textp = p; etextp = p; goto loop; } - etextp->pcond = p; + etextp->cond = p; etextp = p; - goto loop; + break; - case AJSR: - p->as = ABSR; - - case ABSR: - if(p->to.index != D_NONE) - p->as = AJSR; - if(p->to.type != D_EXTERN && p->to.type != D_STATIC) - p->as = AJSR; - goto casdef; - - case AMOVL: - case AMOVB: - case AMOVW: - if(p->from.type != D_CONST) - goto casdef; - lv = p->from.offset; - if(lv >= -128 && lv < 128) - if(p->to.type >= D_R0 && p->to.type < D_R0+8) - if(p->to.index == D_NONE) { - p->from.type = D_QUICK; - goto casdef; + case ASUB: + if(p->from.type == D_CONST) + if(p->from.name == D_NONE) + if(p->from.offset < 0) { + p->from.offset = -p->from.offset; + p->as = AADD; } + goto casedef; - if(lv >= -0x7fff && lv <= 0x7fff) - if(p->to.type >= D_A0 && p->to.type < D_A0+8) - if(p->to.index == D_NONE) - if(p->as == AMOVL) - p->as = AMOVW; - goto casdef; - - case AADDB: - case AADDL: - case AADDW: - if(p->from.type != D_CONST) - goto casdef; - lv = p->from.offset; - if(lv < 0) { - lv = -lv; - p->from.offset = lv; - if(p->as == AADDB) - p->as = ASUBB; - else - if(p->as == AADDW) - p->as = ASUBW; - else - if(p->as == AADDL) - p->as = ASUBL; - } - if(lv > 0) - if(lv <= 8) - p->from.type = D_QUICK; - goto casdef; - - case ASUBB: - case ASUBL: - case ASUBW: - if(p->from.type != D_CONST) - goto casdef; - lv = p->from.offset; - if(lv < 0) { - lv = -lv; - p->from.offset = lv; - if(p->as == ASUBB) - p->as = AADDB; - else - if(p->as == ASUBW) - p->as = AADDW; - else - if(p->as == ASUBL) - p->as = AADDL; - } - if(lv > 0) - if(lv <= 8) - p->from.type = D_QUICK; - goto casdef; - - case AROTRB: - case AROTRL: - case AROTRW: - case AROTLB: - case AROTLL: - case AROTLW: - - case AASLB: - case AASLL: - case AASLW: - case AASRB: - case AASRL: - case AASRW: - case ALSLB: - case ALSLL: - case ALSLW: - case ALSRB: - case ALSRL: - case ALSRW: + case AADD: if(p->from.type == D_CONST) - if(p->from.offset > 0) - if(p->from.offset <= 8) - p->from.type = D_QUICK; - goto casdef; - - case ATSTL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) { - p->as = ACMPW; - p->from = p->to; - p->to.type = D_CONST; - p->to.offset = 0; + if(p->from.name == D_NONE) + if(p->from.offset < 0) { + p->from.offset = -p->from.offset; + p->as = ASUB; } - goto casdef; - - case ACMPL: - if(p->to.type != D_CONST) - goto casdef; - lv = p->to.offset; - if(lv >= -0x7fff && lv <= 0x7fff) - if(p->from.type >= D_A0 && p->from.type < D_A0+8) - if(p->from.index == D_NONE) - p->as = ACMPW; - goto casdef; - - case ACLRL: - if(p->to.type >= D_A0 && p->to.type < D_A0+8) { - p->as = AMOVW; - p->from.type = D_CONST; + goto casedef; + + case AMOVWD: + case AMOVWF: + case AMOVDW: + case AMOVFW: + case AMOVFD: + case AMOVDF: + // case AMOVF: + // case AMOVD: + case ACMPF: + case ACMPD: + case AADDF: + case AADDD: + case ASUBF: + case ASUBD: + case AMULF: + case AMULD: + case ADIVF: + case ADIVD: + if(thumb) + puntfp(p); + goto casedef; + + case AMOVF: + if(thumb) + puntfp(p); + if(skip) + goto casedef; + + if(p->from.type == D_FCONST && chipfloat(p->from.ieee) < 0) { + /* size sb 9 max */ + sprint(literal, "$%lux", ieeedtof(p->from.ieee)); + s = lookup(literal, 0); + if(s->type == 0) { + s->type = SBSS; + s->value = 4; + t = prg(); + t->as = ADATA; + t->line = p->line; + t->from.type = D_OREG; + t->from.sym = s; + t->from.name = D_EXTERN; + t->reg = 4; + t->to = p->from; + t->link = datap; + datap = t; + } + p->from.type = D_OREG; + p->from.sym = s; + p->from.name = D_EXTERN; p->from.offset = 0; } - goto casdef; - - casdef: - default: - if(p->from.type == D_FCONST) - if(optab[p->as].fas != AXXX) { - dv = ieeedtod(&p->from.ieee); - if(dv >= -(1L<<30) && dv <= (1L<<30)) { - lv = dv; - if(lv == dv) { - p->as = optab[p->as].fas; - p->from.type = D_CONST; - p->from.offset = lv; - p->from.displace = 0; - } + goto casedef; + + case AMOVD: + if(thumb) + puntfp(p); + if(skip) + goto casedef; + + if(p->from.type == D_FCONST && chipfloat(p->from.ieee) < 0) { + /* size sb 18 max */ + sprint(literal, "$%lux.%lux", + p->from.ieee->l, p->from.ieee->h); + s = lookup(literal, 0); + if(s->type == 0) { + s->type = SBSS; + s->value = 8; + t = prg(); + t->as = ADATA; + t->line = p->line; + t->from.type = D_OREG; + t->from.sym = s; + t->from.name = D_EXTERN; + t->reg = 8; + t->to = p->from; + t->link = datap; + datap = t; } + p->from.type = D_OREG; + p->from.sym = s; + p->from.name = D_EXTERN; + p->from.offset = 0; } + goto casedef; + + default: + casedef: + if(skip) + nopout(p); + if(p->to.type == D_BRANCH) p->to.offset += ipc; lastp->link = p; lastp = p; p->pc = pc; pc++; - goto loop; + break; } - /* not reached */ + goto loop; eof: - diag("%s: truncated object file in %s", pn, TNAME); + diag("truncated object file: %s", pn); } Sym* @@ -1037,7 +1124,7 @@ lookup(char *symb, int v) Sym *s; char *p; long h; - int l, c; + int c, l; h = v; for(p=symb; c = *p; p++) @@ -1057,15 +1144,17 @@ lookup(char *symb, int v) nhunk -= sizeof(Sym); hunk += sizeof(Sym); - s->name = malloc(l + 1); + s->name = malloc(l); memmove(s->name, symb, l); s->link = hash[h]; s->type = 0; s->version = v; s->value = 0; + s->sig = 0; + s->used = s->thumb = s->foreign = s->fnptr = 0; + s->use = nil; hash[h] = s; - nsymbol++; return s; } @@ -1084,28 +1173,6 @@ prg(void) return p; } -Prog* -copyp(Prog *q) -{ - Prog *p; - - p = prg(); - *p = *q; - return p; -} - -Prog* -appendp(Prog *q) -{ - Prog *p; - - p = prg(); - p->link = q->link; - q->link = p; - p->line = q->line; - return p; -} - void gethunk(void) { @@ -1141,44 +1208,78 @@ doprof1(void) s = lookup("__mcount", 0); n = 1; for(p = firstp->link; p != P; p = p->link) { + setarch(p); if(p->as == ATEXT) { q = prg(); - q->as = AADDL; + q->line = p->line; + q->link = datap; + datap = q; + q->as = ADATA; + q->from.type = D_OREG; + q->from.name = D_EXTERN; + q->from.offset = n*4; + q->from.sym = s; + q->reg = 4; + q->to = p->from; + q->to.type = D_CONST; + + q = prg(); q->line = p->line; q->pc = p->pc; q->link = p->link; p->link = q; - q->from.type = D_CONST; - q->from.offset = 1; - q->to.type = D_EXTERN; - q->to.sym = s; - q->to.offset = n*4 + 4; + p = q; + p->as = AMOVW; + p->from.type = D_OREG; + p->from.name = D_EXTERN; + p->from.sym = s; + p->from.offset = n*4 + 4; + p->to.type = D_REG; + p->to.reg = thumb ? REGTMPT : REGTMP; q = prg(); - q->as = ADATA; q->line = p->line; - q->link = datap; - datap = q; - q->from.type = D_EXTERN; - q->from.sym = s; - q->from.offset = n*4; - q->from.displace = 4; - q->to.type = D_EXTERN; - q->to.sym = p->from.sym; + q->pc = p->pc; + q->link = p->link; + p->link = q; + p = q; + p->as = AADD; + p->from.type = D_CONST; + p->from.offset = 1; + p->to.type = D_REG; + p->to.reg = thumb ? REGTMPT : REGTMP; + + q = prg(); + q->line = p->line; + q->pc = p->pc; + q->link = p->link; + p->link = q; + p = q; + p->as = AMOVW; + p->from.type = D_REG; + p->from.reg = thumb ? REGTMPT : REGTMP; + p->to.type = D_OREG; + p->to.name = D_EXTERN; + p->to.sym = s; + p->to.offset = n*4 + 4; + n += 2; continue; } } q = prg(); q->line = 0; - q->as = ADATA; q->link = datap; datap = q; - q->from.type = D_EXTERN; + + q->as = ADATA; + q->from.type = D_OREG; + q->from.name = D_EXTERN; q->from.sym = s; - q->from.displace = 4; + q->reg = 4; q->to.type = D_CONST; q->to.offset = n; + s->type = SBSS; s->value = n*4; } @@ -1198,24 +1299,25 @@ doprof2(void) diag("_profin/_profout not defined"); return; } - ps2 = P; ps4 = P; for(p = firstp; p != P; p = p->link) { + setarch(p); if(p->as == ATEXT) { if(p->from.sym == s2) { ps2 = p; - p->from.displace = 1; + p->reg = 1; } if(p->from.sym == s4) { ps4 = p; - p->from.displace = 1; + p->reg = 1; } } } for(p = firstp; p != P; p = p->link) { + setarch(p); if(p->as == ATEXT) { - if(p->from.displace != 0) { + if(p->reg & NOPROF) { for(;;) { q = p->link; if(q == P) @@ -1227,38 +1329,41 @@ doprof2(void) continue; } + /* + * BL profin, R2 + */ q = prg(); q->line = p->line; q->pc = p->pc; q->link = p->link; p->link = q; p = q; - p->as = ABSR; + p->as = ABL; p->to.type = D_BRANCH; - p->pcond = ps2; + p->cond = ps2; p->to.sym = s2; continue; } - if(p->as == ARTS) { + if(p->as == ARET) { /* - * RTS + * RET */ q = prg(); - q->as = ARTS; + q->as = ARET; q->from = p->from; q->to = p->to; q->link = p->link; p->link = q; /* - * BSR profout + * BL profout */ - p->as = ABSR; + p->as = ABL; p->from = zprg.from; p->to = zprg.to; p->to.type = D_BRANCH; - p->pcond = ps4; + p->cond = ps4; p->to.sym = s4; p = q; @@ -1268,37 +1373,28 @@ doprof2(void) } } -long -reuse(Prog *r, Sym *s) -{ - Prog *p; - - - if(r == P) - return 0; - for(p = datap; p != r; p = p->link) - if(p->to.sym == s) - return p->from.offset; - return 0; -} - void nuxiinit(void) { + int i, c; for(i=0; i<4; i++) { - c = find1(0x01020304L, i+1); - if(i >= 2) - inuxi2[i-2] = c; - if(i >= 3) - inuxi1[i-3] = c; + c = find1(0x04030201L, i+1); + if(i < 2) + inuxi2[i] = c; + if(i < 1) + inuxi1[i] = c; inuxi4[i] = c; - fnuxi8[i] = c+4; - fnuxi8[i+4] = c; - c = find2(0x01020304L, i+1); - gnuxi8[i] = c+4; - gnuxi8[i+4] = c; + fnuxi4[i] = c; + if(!debug['d']){ + fnuxi8[i] = c; + fnuxi8[i+4] = c+4; + } + else{ + fnuxi8[i] = c+4; /* ms word first, then ls, even in little endian mode */ + fnuxi8[i+4] = c; + } } if(debug['v']) { Bprint(&bso, "inuxi = "); @@ -1310,12 +1406,12 @@ nuxiinit(void) Bprint(&bso, " "); for(i=0; i<4; i++) Bprint(&bso, "%d", inuxi4[i]); - Bprint(&bso, "\n[fg]nuxi = "); - for(i=0; i<8; i++) - Bprint(&bso, "%d", fnuxi8[i]); + Bprint(&bso, "\nfnuxi = "); + for(i=0; i<4; i++) + Bprint(&bso, "%d", fnuxi4[i]); Bprint(&bso, " "); for(i=0; i<8; i++) - Bprint(&bso, "%d", gnuxi8[i]); + Bprint(&bso, "%d", fnuxi8[i]); Bprint(&bso, "\n"); } Bflush(&bso); @@ -1334,35 +1430,19 @@ find1(long l, int c) return 0; } -int -find2(long l, int c) -{ - short *p; - int i; - - p = (short*)&l; - for(i=0; i<4; i+=2) { - if(((*p >> 8) & 0xff) == c) - return i; - if((*p++ & 0xff) == c) - return i+1; - } - return 0; -} - long -ieeedtof(Ieee *e) +ieeedtof(Ieee *ieeep) { int exp; long v; - if(e->h == 0) + if(ieeep->h == 0) return 0; - exp = (e->h>>20) & ((1L<<11)-1L); + exp = (ieeep->h>>20) & ((1L<<11)-1L); exp -= (1L<<10) - 2L; - v = (e->h & 0xfffffL) << 3; - v |= (e->l >> 29) & 0x7L; - if((e->l >> 28) & 1) { + v = (ieeep->h & 0xfffffL) << 3; + v |= (ieeep->l >> 29) & 0x7L; + if((ieeep->l >> 28) & 1) { v++; if(v & 0x800000L) { v = (v & 0x7fffffL) >> 1; @@ -1372,7 +1452,7 @@ ieeedtof(Ieee *e) if(exp <= -126 || exp >= 130) diag("double fp to single fp overflow"); v |= ((exp + 126) & 0xffL) << 23; - v |= e->h & 0x80000000L; + v |= ieeep->h & 0x80000000L; return v; } @@ -1400,3 +1480,79 @@ ieeedtod(Ieee *ieeep) exp -= (1L<<10) - 2L; return ldexp(fr, exp); } + +static void +puntfp(Prog *p) +{ + USED(p); + /* floating point - punt for now */ + curtext->reg = NREG; /* ARM */ + curtext->from.sym->thumb = 0; + thumb = 0; + // print("%s: generating ARM code (contains floating point ops %d)\n", curtext->from.sym->name, p->line); +} + +void +undefsym(Sym *s) +{ + int n; + + n = imports; + if(s->value != 0) + diag("value != 0 on SXREF"); + if(n >= 1<<Rindex) + diag("import index %d out of range", n); + s->value = n<<Roffset; + s->type = SUNDEF; + imports++; +} + +void +zerosig(char *sp) +{ + Sym *s; + + s = lookup(sp, 0); + s->sig = 0; +} + +void +readundefs(char *f, int t) +{ + int i, n; + Sym *s; + Biobuf *b; + char *l, buf[256], *fields[64]; + + if(f == nil) + return; + b = Bopen(f, OREAD); + if(b == nil){ + diag("could not open %s: %r", f); + errorexit(); + } + while((l = Brdline(b, '\n')) != nil){ + n = Blinelen(b); + if(n >= sizeof(buf)){ + diag("%s: line too long", f); + errorexit(); + } + memmove(buf, l, n); + buf[n-1] = '\0'; + n = getfields(buf, fields, nelem(fields), 1, " \t\r\n"); + if(n == nelem(fields)){ + diag("%s: bad format", f); + errorexit(); + } + for(i = 0; i < n; i++){ + s = lookup(fields[i], 0); + s->type = SXREF; + s->subtype = t; + if(t == SIMPORT) + nimports++; + else + nexports++; + } + } + Bterm(b); +} diff --git a/utils/tl/optab.c b/utils/tl/optab.c new file mode 100644 index 00000000..65ad3447 --- /dev/null +++ b/utils/tl/optab.c @@ -0,0 +1,253 @@ +#include "l.h" + +Optab optab[] = +{ + { ATEXT, C_LEXT, C_NONE, C_LCON, 0, 0, 0 }, + { ATEXT, C_LEXT, C_REG, C_LCON, 0, 0, 0 }, + { ATEXT, C_ADDR, C_NONE, C_LCON, 0, 0, 0 }, + { ATEXT, C_ADDR, C_REG, C_LCON, 0, 0, 0 }, + + { AADD, C_REG, C_REG, C_REG, 1, 4, 0 }, + { AADD, C_REG, C_NONE, C_REG, 1, 4, 0 }, + { AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0 }, + { AMVN, C_REG, C_NONE, C_REG, 1, 4, 0 }, + { ACMP, C_REG, C_REG, C_NONE, 1, 4, 0 }, + + { AADD, C_RCON, C_REG, C_REG, 2, 4, 0 }, + { AADD, C_RCON, C_NONE, C_REG, 2, 4, 0 }, + { AMOVW, C_RCON, C_NONE, C_REG, 2, 4, 0 }, + { AMVN, C_RCON, C_NONE, C_REG, 2, 4, 0 }, + { ACMP, C_RCON, C_REG, C_NONE, 2, 4, 0 }, + + { AADD, C_SHIFT,C_REG, C_REG, 3, 4, 0 }, + { AADD, C_SHIFT,C_NONE, C_REG, 3, 4, 0 }, + { AMVN, C_SHIFT,C_NONE, C_REG, 3, 4, 0 }, + { ACMP, C_SHIFT,C_REG, C_NONE, 3, 4, 0 }, + + { AMOVW, C_RECON,C_NONE, C_REG, 4, 4, REGSB }, + { AMOVW, C_RACON,C_NONE, C_REG, 4, 4, REGSP }, + + { AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, LPOOL }, + { ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0 }, + { ABX, C_NONE, C_NONE, C_SBRA, 74, 20, 0 }, + { ABEQ, C_NONE, C_NONE, C_SBRA, 5, 4, 0 }, + + { AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL }, + { ABL, C_NONE, C_NONE, C_ROREG, 7, 8, 0 }, + { ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0 }, + { ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0 }, + + { ASLL, C_RCON, C_REG, C_REG, 8, 4, 0 }, + { ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0 }, + + { ASLL, C_REG, C_NONE, C_REG, 9, 4, 0 }, + { ASLL, C_REG, C_REG, C_REG, 9, 4, 0 }, + + { ASWI, C_NONE, C_NONE, C_NONE, 10, 4, 0 }, + { ASWI, C_NONE, C_NONE, C_LOREG, 10, 4, 0 }, + + { AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0 }, + { AWORD, C_NONE, C_NONE, C_GCON, 11, 4, 0 }, + { AWORD, C_NONE, C_NONE, C_LEXT, 11, 4, 0 }, + { AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0 }, + + { AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0 }, + { AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM }, + + { AADD, C_NCON, C_REG, C_REG, 13, 8, 0 }, + { AADD, C_NCON, C_NONE, C_REG, 13, 8, 0 }, + { AMVN, C_NCON, C_NONE, C_REG, 13, 8, 0 }, + { ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0 }, + { AADD, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM }, + { AADD, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM }, + { AMVN, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM }, + { ACMP, C_LCON, C_REG, C_NONE, 13, 8, 0, LFROM }, + + { AMOVB, C_REG, C_NONE, C_REG, 14, 8, 0 }, + { AMOVBU, C_REG, C_NONE, C_REG, 58, 4, 0 }, + { AMOVH, C_REG, C_NONE, C_REG, 14, 8, 0 }, + { AMOVHU, C_REG, C_NONE, C_REG, 14, 8, 0 }, + + { AMUL, C_REG, C_REG, C_REG, 15, 4, 0 }, + { AMUL, C_REG, C_NONE, C_REG, 15, 4, 0 }, + + { ADIV, C_REG, C_REG, C_REG, 16, 4, 0 }, + { ADIV, C_REG, C_NONE, C_REG, 16, 4, 0 }, + + { AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0 }, + + { AMOVW, C_REG, C_NONE, C_SEXT, 20, 4, REGSB }, + { AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP }, + { AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0 }, + { AMOVB, C_REG, C_NONE, C_SEXT, 20, 4, REGSB }, + { AMOVB, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP }, + { AMOVB, C_REG, C_NONE, C_SOREG, 20, 4, 0 }, + { AMOVBU, C_REG, C_NONE, C_SEXT, 20, 4, REGSB }, + { AMOVBU, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP }, + { AMOVBU, C_REG, C_NONE, C_SOREG, 20, 4, 0 }, + + { AMOVW, C_SEXT, C_NONE, C_REG, 21, 4, REGSB }, + { AMOVW, C_SAUTO,C_NONE, C_REG, 21, 4, REGSP }, + { AMOVW, C_SOREG,C_NONE, C_REG, 21, 4, 0 }, + { AMOVBU, C_SEXT, C_NONE, C_REG, 21, 4, REGSB }, + { AMOVBU, C_SAUTO,C_NONE, C_REG, 21, 4, REGSP }, + { AMOVBU, C_SOREG,C_NONE, C_REG, 21, 4, 0 }, + + { AMOVB, C_SEXT, C_NONE, C_REG, 22, 12, REGSB }, + { AMOVB, C_SAUTO,C_NONE, C_REG, 22, 12, REGSP }, + { AMOVB, C_SOREG,C_NONE, C_REG, 22, 12, 0 }, + { AMOVH, C_SEXT, C_NONE, C_REG, 22, 12, REGSB }, + { AMOVH, C_SAUTO,C_NONE, C_REG, 22, 12, REGSP }, + { AMOVH, C_SOREG,C_NONE, C_REG, 22, 12, 0 }, + { AMOVHU, C_SEXT, C_NONE, C_REG, 22, 12, REGSB }, + { AMOVHU, C_SAUTO,C_NONE, C_REG, 22, 12, REGSP }, + { AMOVHU, C_SOREG,C_NONE, C_REG, 22, 12, 0 }, + + { AMOVH, C_REG, C_NONE, C_SEXT, 23, 12, REGSB }, + { AMOVH, C_REG, C_NONE, C_SAUTO, 23, 12, REGSP }, + { AMOVH, C_REG, C_NONE, C_SOREG, 23, 12, 0 }, + { AMOVHU, C_REG, C_NONE, C_SEXT, 23, 12, REGSB }, + { AMOVHU, C_REG, C_NONE, C_SAUTO, 23, 12, REGSP }, + { AMOVHU, C_REG, C_NONE, C_SOREG, 23, 12, 0 }, + + { AMOVW, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, + { AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, + { AMOVB, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, + { AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, + { AMOVBU, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, + { AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, + + { AMOVW, C_LEXT, C_NONE, C_REG, 31, 8, REGSB, LFROM }, + { AMOVW, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, + { AMOVW, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, + { AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM }, + { AMOVBU, C_LEXT, C_NONE, C_REG, 31, 8, REGSB, LFROM }, + { AMOVBU, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, + { AMOVBU, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, + { AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM }, + + { AMOVB, C_LEXT, C_NONE, C_REG, 32, 16, REGSB, LFROM }, + { AMOVB, C_LAUTO,C_NONE, C_REG, 32, 16, REGSP, LFROM }, + { AMOVB, C_LOREG,C_NONE, C_REG, 32, 16, 0, LFROM }, + { AMOVB, C_ADDR, C_NONE, C_REG, 66, 16, 0, LFROM }, + { AMOVH, C_LEXT, C_NONE, C_REG, 32, 16, REGSB, LFROM }, + { AMOVH, C_LAUTO,C_NONE, C_REG, 32, 16, REGSP, LFROM }, + { AMOVH, C_LOREG,C_NONE, C_REG, 32, 16, 0, LFROM }, + { AMOVH, C_ADDR, C_NONE, C_REG, 66, 16, 0, LFROM }, + { AMOVHU, C_LEXT, C_NONE, C_REG, 32, 16, REGSB, LFROM }, + { AMOVHU, C_LAUTO,C_NONE, C_REG, 32, 16, REGSP, LFROM }, + { AMOVHU, C_LOREG,C_NONE, C_REG, 32, 16, 0, LFROM }, + { AMOVHU, C_ADDR, C_NONE, C_REG, 66, 16, 0, LFROM }, + + { AMOVH, C_REG, C_NONE, C_LEXT, 33, 24, REGSB, LTO }, + { AMOVH, C_REG, C_NONE, C_LAUTO, 33, 24, REGSP, LTO }, + { AMOVH, C_REG, C_NONE, C_LOREG, 33, 24, 0, LTO }, + { AMOVH, C_REG, C_NONE, C_ADDR, 67, 24, 0, LTO }, + { AMOVHU, C_REG, C_NONE, C_LEXT, 33, 24, REGSB, LTO }, + { AMOVHU, C_REG, C_NONE, C_LAUTO, 33, 24, REGSP, LTO }, + { AMOVHU, C_REG, C_NONE, C_LOREG, 33, 24, 0, LTO }, + { AMOVHU, C_REG, C_NONE, C_ADDR, 67, 24, 0, LTO }, + + { AMOVW, C_LECON,C_NONE, C_REG, 34, 8, REGSB, LFROM }, + { AMOVW, C_LACON,C_NONE, C_REG, 34, 8, REGSP, LFROM }, + + { AMOVW, C_PSR, C_NONE, C_REG, 35, 4, 0 }, + { AMOVW, C_REG, C_NONE, C_PSR, 36, 4, 0 }, + { AMOVW, C_RCON, C_NONE, C_PSR, 37, 4, 0 }, + + { AMOVM, C_LCON, C_NONE, C_SOREG, 38, 4, 0 }, + { AMOVM, C_SOREG,C_NONE, C_LCON, 39, 4, 0 }, + + { ASWPW, C_SOREG,C_REG, C_REG, 40, 4, 0 }, + + { ARFE, C_NONE, C_NONE, C_NONE, 41, 4, 0 }, + + { AMOVF, C_FREG, C_NONE, C_FEXT, 50, 4, REGSB }, + { AMOVF, C_FREG, C_NONE, C_FAUTO, 50, 4, REGSP }, + { AMOVF, C_FREG, C_NONE, C_FOREG, 50, 4, 0 }, + + { AMOVF, C_FEXT, C_NONE, C_FREG, 51, 4, REGSB }, + { AMOVF, C_FAUTO,C_NONE, C_FREG, 51, 4, REGSP }, + { AMOVF, C_FOREG,C_NONE, C_FREG, 51, 4, 0 }, + + { AMOVF, C_FREG, C_NONE, C_LEXT, 52, 12, REGSB, LTO }, + { AMOVF, C_FREG, C_NONE, C_LAUTO, 52, 12, REGSP, LTO }, + { AMOVF, C_FREG, C_NONE, C_LOREG, 52, 12, 0, LTO }, + + { AMOVF, C_LEXT, C_NONE, C_FREG, 53, 12, REGSB, LFROM }, + { AMOVF, C_LAUTO,C_NONE, C_FREG, 53, 12, REGSP, LFROM }, + { AMOVF, C_LOREG,C_NONE, C_FREG, 53, 12, 0, LFROM }, + + { AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO }, + { AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM }, + + { AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0 }, + { AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0 }, + { AADDF, C_FCON, C_NONE, C_FREG, 54, 4, 0 }, + { AADDF, C_FCON, C_REG, C_FREG, 54, 4, 0 }, + { AMOVF, C_FCON, C_NONE, C_FREG, 54, 4, 0 }, + { AMOVF, C_FREG, C_NONE, C_FREG, 54, 4, 0 }, + + { ACMPF, C_FREG, C_REG, C_NONE, 54, 4, 0 }, + { ACMPF, C_FCON, C_REG, C_NONE, 54, 4, 0 }, + + { AMOVFW, C_FREG, C_NONE, C_REG, 55, 4, 0 }, + { AMOVFW, C_REG, C_NONE, C_FREG, 55, 4, 0 }, + + { AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0 }, + { AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0 }, + + { AMOVW, C_SHIFT,C_NONE, C_REG, 59, 4, 0 }, + { AMOVBU, C_SHIFT,C_NONE, C_REG, 59, 4, 0 }, + + { AMOVB, C_SHIFT,C_NONE, C_REG, 60, 4, 0 }, + + { AMOVW, C_REG, C_NONE, C_SHIFT, 61, 4, 0 }, + { AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0 }, + { AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0 }, + + { ACASE, C_REG, C_NONE, C_NONE, 62, 4, 0 }, + { ABCASE, C_NONE, C_NONE, C_SBRA, 63, 4, 0 }, + + { AMOVH, C_REG, C_NONE, C_HEXT, 70, 4, REGSB, V4 }, + { AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, V4 }, + { AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, V4 }, + { AMOVHU, C_REG, C_NONE, C_HEXT, 70, 4, REGSB, V4 }, + { AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, V4 }, + { AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, V4 }, + + { AMOVB, C_HEXT, C_NONE, C_REG, 71, 4, REGSB, V4 }, + { AMOVB, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, V4 }, + { AMOVB, C_HOREG,C_NONE, C_REG, 71, 4, 0, V4 }, + { AMOVH, C_HEXT, C_NONE, C_REG, 71, 4, REGSB, V4 }, + { AMOVH, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, V4 }, + { AMOVH, C_HOREG,C_NONE, C_REG, 71, 4, 0, V4 }, + { AMOVHU, C_HEXT, C_NONE, C_REG, 71, 4, REGSB, V4 }, + { AMOVHU, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, V4 }, + { AMOVHU, C_HOREG,C_NONE, C_REG, 71, 4, 0, V4 }, + + { AMOVH, C_REG, C_NONE, C_LEXT, 72, 8, REGSB, LTO|V4 }, + { AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO|V4 }, + { AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO|V4 }, + { AMOVHU, C_REG, C_NONE, C_LEXT, 72, 8, REGSB, LTO|V4 }, + { AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO|V4 }, + { AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO|V4 }, + + { AMOVB, C_LEXT, C_NONE, C_REG, 73, 8, REGSB, LFROM|V4 }, + { AMOVB, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 }, + { AMOVB, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 }, + { AMOVH, C_LEXT, C_NONE, C_REG, 73, 8, REGSB, LFROM|V4 }, + { AMOVH, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 }, + { AMOVH, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 }, + { AMOVHU, C_LEXT, C_NONE, C_REG, 73, 8, REGSB, LFROM|V4 }, + { AMOVHU, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 }, + { AMOVHU, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 }, + + { AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 }, +}; diff --git a/utils/tl/pass.c b/utils/tl/pass.c new file mode 100644 index 00000000..e4322df5 --- /dev/null +++ b/utils/tl/pass.c @@ -0,0 +1,942 @@ +#include "l.h" + +void +dodata(void) +{ + int i, t; + Sym *s; + Prog *p; + long orig, v; + + if(debug['v']) + Bprint(&bso, "%5.2f dodata\n", cputime()); + Bflush(&bso); + for(p = datap; p != P; p = p->link) { + s = p->from.sym; + if(p->as == ADYNT || p->as == AINIT) + s->value = dtype; + if(s->type == SBSS) + s->type = SDATA; + if(s->type != SDATA) + diag("initialize non-data (%d): %s\n%P", + s->type, s->name, p); + v = p->from.offset + p->reg; + if(v > s->value) + diag("initialize bounds (%ld): %s\n%P", + s->value, s->name, p); + if((s->type == SBSS || s->type == SDATA) && (p->to.type == D_CONST || p->to.type == D_OCONST) && (p->to.name == D_EXTERN || p->to.name == D_STATIC)){ + s = p->to.sym; + if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF)) + s->fnptr = 1; + } + } + + if(debug['t']) { + /* + * pull out string constants + */ + for(p = datap; p != P; p = p->link) { + s = p->from.sym; + if(p->to.type == D_SCONST) + s->type = SSTRING; + } + } + + /* + * pass 1 + * assign 'small' variables to data segment + * (rational is that data segment is more easily + * addressed through offset on R12) + */ + orig = 0; + for(i=0; i<NHASH; i++) + for(s = hash[i]; s != S; s = s->link) { + t = s->type; + if(t != SDATA && t != SBSS) + continue; + v = s->value; + if(v == 0) { + diag("%s: no size", s->name); + v = 1; + } + while(v & 3) + v++; + s->value = v; + if(v > MINSIZ) + continue; + s->value = orig; + orig += v; + s->type = SDATA1; + } + + /* + * pass 2 + * assign large 'data' variables to data segment + */ + for(i=0; i<NHASH; i++) + for(s = hash[i]; s != S; s = s->link) { + t = s->type; + if(t != SDATA) { + if(t == SDATA1) + s->type = SDATA; + continue; + } + v = s->value; + s->value = orig; + orig += v; + } + + while(orig & 7) + orig++; + datsize = orig; + + /* + * pass 3 + * everything else to bss segment + */ + for(i=0; i<NHASH; i++) + for(s = hash[i]; s != S; s = s->link) { + if(s->type != SBSS) + continue; + v = s->value; + s->value = orig; + orig += v; + } + while(orig & 7) + orig++; + bsssize = orig-datsize; + + xdefine("setR12", SDATA, 0L+BIG); + xdefine("bdata", SDATA, 0L); + xdefine("edata", SDATA, datsize); + xdefine("end", SBSS, datsize+bsssize); + xdefine("etext", STEXT, 0L); +} + +void +undef(void) +{ + int i; + Sym *s; + + for(i=0; i<NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->type == SXREF) + diag("%s: not defined", s->name); +} + +Prog* +brchain(Prog *p) +{ + int i; + + for(i=0; i<20; i++) { + if(p == P || p->as != AB) + return p; + p = p->cond; + } + return P; +} + +int +relinv(int a) +{ + switch(a) { + case ABEQ: return ABNE; + case ABNE: return ABEQ; + case ABCS: return ABCC; + case ABHS: return ABLO; + case ABCC: return ABCS; + case ABLO: return ABHS; + case ABMI: return ABPL; + case ABPL: return ABMI; + case ABVS: return ABVC; + case ABVC: return ABVS; + case ABHI: return ABLS; + case ABLS: return ABHI; + case ABGE: return ABLT; + case ABLT: return ABGE; + case ABGT: return ABLE; + case ABLE: return ABGT; + } + diag("unknown relation: %s", anames[a]); + return a; +} + +void +follow(void) +{ + if(debug['v']) + Bprint(&bso, "%5.2f follow\n", cputime()); + Bflush(&bso); + + firstp = prg(); + lastp = firstp; + xfol(textp); + + firstp = firstp->link; + lastp->link = P; +} + +void +xfol(Prog *p) +{ + Prog *q, *r; + int a, i; + +loop: + if(p == P) + return; + setarch(p); + a = p->as; + if(a == ATEXT) + curtext = p; + if(a == AB) { + q = p->cond; + if(q != P) { + p->mark |= FOLL; + p = q; + if(!(p->mark & FOLL)) + goto loop; + } + } + if(p->mark & FOLL) { + for(i=0,q=p; i<4; i++,q=q->link) { + if(q == lastp) + break; + a = q->as; + if(a == ANOP) { + i--; + continue; + } + if(a == AB || (a == ARET && q->scond == 14) || a == ARFE) + goto copy; + if(!q->cond || (q->cond->mark&FOLL)) + continue; + if(a != ABEQ && a != ABNE) + continue; + copy: + for(;;) { + r = prg(); + *r = *p; + if(!(r->mark&FOLL)) + print("cant happen 1\n"); + r->mark |= FOLL; + if(p != q) { + p = p->link; + lastp->link = r; + lastp = r; + continue; + } + lastp->link = r; + lastp = r; + if(a == AB || (a == ARET && q->scond == 14) || a == ARFE) + return; + r->as = ABNE; + if(a == ABNE) + r->as = ABEQ; + r->cond = p->link; + r->link = p->cond; + if(!(r->link->mark&FOLL)) + xfol(r->link); + if(!(r->cond->mark&FOLL)) + print("cant happen 2\n"); + return; + } + } + a = AB; + q = prg(); + q->as = a; + q->line = p->line; + q->to.type = D_BRANCH; + q->to.offset = p->pc; + q->cond = p; + p = q; + } + p->mark |= FOLL; + lastp->link = p; + lastp = p; + if(a == AB || (a == ARET && p->scond == 14) || a == ARFE){ + return; + } + if(p->cond != P) + if(a != ABL && a != ABX && p->link != P) { + q = brchain(p->link); + if(a != ATEXT && a != ABCASE) + if(q != P && (q->mark&FOLL)) { + p->as = relinv(a); + p->link = p->cond; + p->cond = q; + } + xfol(p->link); + q = brchain(p->cond); + if(q == P) + q = p->cond; + if(q->mark&FOLL) { + p->cond = q; + return; + } + p = q; + goto loop; + } + p = p->link; + goto loop; +} + +void +patch(void) +{ + long c, vexit; + Prog *p, *q; + Sym *s, *s1; + int a; + + if(debug['v']) + Bprint(&bso, "%5.2f patch\n", cputime()); + Bflush(&bso); + mkfwd(); + s = lookup("exit", 0); + vexit = s->value; + for(p = firstp; p != P; p = p->link) { + setarch(p); + a = p->as; + if(a == ATEXT) + curtext = p; + if(seenthumb && a == ABL){ + // if((s = p->to.sym) != S && (s1 = curtext->from.sym) != S) + // print("%s calls %s\n", s1->name, s->name); + if((s = p->to.sym) != S && (s1 = curtext->from.sym) != S && s->thumb != s1->thumb) + s->foreign = 1; + } + if((a == ABL || a == ABX || a == AB || a == ARET) && + p->to.type != D_BRANCH && p->to.sym != S) { + s = p->to.sym; + switch(s->type) { + default: + diag("undefined: %s\n%P", s->name, p); + s->type = STEXT; + s->value = vexit; + break; + case STEXT: + p->to.offset = s->value; + p->to.type = D_BRANCH; + break; + case SUNDEF: + if(p->as != ABL) + diag("help: SUNDEF in AB || ARET"); + p->to.offset = 0; + p->to.type = D_BRANCH; + p->cond = UP; + break; + } + } + if(p->to.type != D_BRANCH || p->cond == UP) + continue; + c = p->to.offset; + for(q = firstp; q != P;) { + if(q->forwd != P) + if(c >= q->forwd->pc) { + q = q->forwd; + continue; + } + if(c == q->pc) + break; + q = q->link; + } + if(q == P) { + diag("branch out of range %ld\n%P", c, p); + p->to.type = D_NONE; + } + p->cond = q; + } + + for(p = firstp; p != P; p = p->link) { + setarch(p); + a = p->as; + if(p->as == ATEXT) + curtext = p; + if(seenthumb && a == ABL) { +#ifdef CALLEEBX + if(0) + {} +#else + if((s = p->to.sym) != S && (s->foreign || s->fnptr)) + p->as = ABX; +#endif + else if(p->to.type == D_OREG) + p->as = ABX; + } + if(p->cond != P && p->cond != UP) { + p->cond = brloop(p->cond); + if(p->cond != P) + if(p->to.type == D_BRANCH) + p->to.offset = p->cond->pc; + } + } +} + +#define LOG 5 +void +mkfwd(void) +{ + Prog *p; + long dwn[LOG], cnt[LOG], i; + Prog *lst[LOG]; + + for(i=0; i<LOG; i++) { + if(i == 0) + cnt[i] = 1; else + cnt[i] = LOG * cnt[i-1]; + dwn[i] = 1; + lst[i] = P; + } + i = 0; + for(p = firstp; p != P; p = p->link) { + if(p->as == ATEXT) + curtext = p; + i--; + if(i < 0) + i = LOG-1; + p->forwd = P; + dwn[i]--; + if(dwn[i] <= 0) { + dwn[i] = cnt[i]; + if(lst[i] != P) + lst[i]->forwd = p; + lst[i] = p; + } + } +} + +Prog* +brloop(Prog *p) +{ + Prog *q; + int c; + + for(c=0; p!=P;) { + if(p->as != AB) + return p; + q = p->cond; + if(q <= p) { + c++; + if(q == p || c > 5000) + break; + } + p = q; + } + return P; +} + +long +atolwhex(char *s) +{ + long n; + int f; + + n = 0; + f = 0; + while(*s == ' ' || *s == '\t') + s++; + if(*s == '-' || *s == '+') { + if(*s++ == '-') + f = 1; + while(*s == ' ' || *s == '\t') + s++; + } + if(s[0]=='0' && s[1]){ + if(s[1]=='x' || s[1]=='X'){ + s += 2; + for(;;){ + if(*s >= '0' && *s <= '9') + n = n*16 + *s++ - '0'; + else if(*s >= 'a' && *s <= 'f') + n = n*16 + *s++ - 'a' + 10; + else if(*s >= 'A' && *s <= 'F') + n = n*16 + *s++ - 'A' + 10; + else + break; + } + } else + while(*s >= '0' && *s <= '7') + n = n*8 + *s++ - '0'; + } else + while(*s >= '0' && *s <= '9') + n = n*10 + *s++ - '0'; + if(f) + n = -n; + return n; +} + +long +rnd(long v, long r) +{ + long c; + + if(r <= 0) + return v; + v += r - 1; + c = v % r; + if(c < 0) + c += r; + v -= c; + return v; +} + +#define Reachable(n) if((s = lookup(n, 0)) != nil) s->used++ + +static void +rused(Adr *a) +{ + Sym *s = a->sym; + + if(s == S) + return; + if(a->type == D_OREG || a->type == D_OCONST || a->type == D_CONST){ + if(a->name == D_EXTERN || a->name == D_STATIC){ + if(s->used == 0) + s->used = 1; + } + } + else if(a->type == D_BRANCH){ + if(s->used == 0) + s->used = 1; + } +} + +void +reachable() +{ + Prog *p, *prev, *prevt, *nextt, *q; + Sym *s, *s0; + int i, todo; + char *a; + + Reachable("_div"); + Reachable("_divu"); + Reachable("_mod"); + Reachable("_modu"); + a = INITENTRY; + if(*a >= '0' && *a <= '9') + return; + s = lookup(a, 0); + if(s == nil) + return; + if(s->type == 0){ + s->used = 1; // to stop asm complaining + for(p = firstp; p != P && p->as != ATEXT; p = p->link) + ; + if(p == nil) + return; + s = p->from.sym; + } + s->used = 1; + do{ + todo = 0; + for(p = firstp; p != P; p = p->link){ + if(p->as == ATEXT && (s0 = p->from.sym)->used == 1){ + todo = 1; + for(q = p->link; q != P && q->as != ATEXT; q = q->link){ + rused(&q->from); + rused(&q->to); + } + s0->used = 2; + } + } + for(p = datap; p != P; p = p->link){ + if((s0 = p->from.sym)->used == 1){ + todo = 1; + for(q = p; q != P; q = q->link){ // data can be scattered + if(q->from.sym == s0) + rused(&q->to); + } + s0->used = 2; + } + } + }while(todo); + prev = nil; + prevt = nextt = nil; + for(p = firstp; p != P; ){ + if(p->as == ATEXT){ + prevt = nextt; + nextt = p; + } + if(p->as == ATEXT && (s0 = p->from.sym)->used == 0){ + s0->type = SREMOVED; + for(q = p->link; q != P && q->as != ATEXT; q = q->link) + ; + if(q != p->cond) + diag("bad ptr in reachable()"); + if(prev == nil) + firstp = q; + else + prev->link = q; + if(q == nil) + lastp = prev; + if(prevt == nil) + textp = q; + else + prevt->cond = q; + if(q == nil) + etextp = prevt; + nextt = prevt; + if(debug['V']) + print("%s unused\n", s0->name); + p = q; + } + else{ + prev = p; + p = p->link; + } + } + prevt = nil; + for(p = datap; p != nil; ){ + if((s0 = p->from.sym)->used == 0){ + s0->type = SREMOVED; + prev = prevt; + for(q = p; q != nil; q = q->link){ + if(q->from.sym == s0){ + if(prev == nil) + datap = q->link; + else + prev->link = q->link; + } + else + prev = q; + } + if(debug['V']) + print("%s unused (data)\n", s0->name); + p = prevt->link; + } + else{ + prevt = p; + p = p->link; + } + } + for(i=0; i<NHASH; i++){ + for(s = hash[i]; s != S; s = s->link){ + if(s->used == 0) + s->type = SREMOVED; + } + } +} + +static void +fused(Adr *a, Prog *p, Prog *ct) +{ + Sym *s = a->sym; + Use *u; + + if(s == S) + return; + if(a->type == D_OREG || a->type == D_OCONST || a->type == D_CONST){ + if(a->name == D_EXTERN || a->name == D_STATIC){ + u = malloc(sizeof(Use)); + u->p = p; + u->ct = ct; + u->link = s->use; + s->use = u; + } + } + else if(a->type == D_BRANCH){ + u = malloc(sizeof(Use)); + u->p = p; + u->ct = ct; + u->link = s->use; + s->use = u; + } +} + +static int +ckfpuse(Prog *p, Prog *ct, Sym *fp, Sym *r) +{ + int reg; + + USED(fp); + USED(ct); + if(p->from.sym == r && p->as == AMOVW && (p->from.type == D_CONST || p->from.type == D_OREG) && p->reg == NREG && p->to.type == D_REG){ + reg = p->to.reg; + for(p = p->link; p != P && p->as != ATEXT; p = p->link){ + if((p->as == ABL || p->as == ABX) && p->to.type == D_OREG && p->to.reg == reg) + return 1; + if(!debug['F'] && (isbranch(p) || p->as == ARET)){ + // print("%s: branch %P in %s\n", fp->name, p, ct->from.sym->name); + return 0; + } + if((p->from.type == D_REG || p->from.type == D_OREG) && p->from.reg == reg){ + if(!debug['F'] && p->to.type != D_REG){ + // print("%s: store %P in %s\n", fp->name, p, ct->from.sym->name); + return 0; + } + reg = p->to.reg; + } + } + } + // print("%s: no MOVW O(R), R\n", fp->name); + return debug['F']; +} + +static void +setfpuse(Prog *p, Sym *fp, Sym *r) +{ + int reg; + + if(p->from.sym == r && p->as == AMOVW && (p->from.type == D_CONST || p->from.type == D_OREG) && p->reg == NREG && p->to.type == D_REG){ + reg = p->to.reg; + for(p = p->link; p != P && p->as != ATEXT; p = p->link){ + if((p->as == ABL || p->as == ABX) && p->to.type == D_OREG && p->to.reg == reg){ + fp->fnptr = 0; + p->as = ABL; // safe to do so +// print("simplified %s call\n", fp->name); + break; + } + if(!debug['F'] && (isbranch(p) || p->as == ARET)) + diag("bad setfpuse call"); + if((p->from.type == D_REG || p->from.type == D_OREG) && p->from.reg == reg){ + if(!debug['F'] && p->to.type != D_REG) + diag("bad setfpuse call"); + reg = p->to.reg; + } + } + } +} + +static int +cksymuse(Sym *s, int t) +{ + Prog *p; + + for(p = datap; p != P; p = p->link){ + if(p->from.sym == s && p->to.sym != nil && strcmp(p->to.sym->name, ".string") != 0 && p->to.sym->thumb != t){ + // print("%s %s %d %d ", p->from.sym->name, p->to.sym->name, p->to.sym->thumb, t); + return 0; + } + } + return 1; +} + +/* check the use of s at the given point */ +static int +ckuse(Sym *s, Sym *s0, Use *u) +{ + Sym *s1; + + s1 = u->p->from.sym; +// print("ckuse %s %s %s\n", s->name, s0->name, s1 ? s1->name : "nil"); + if(u->ct == nil){ /* in data area */ + if(s0 == s && !cksymuse(s1, s0->thumb)){ + // print("%s: cksymuse fails\n", s0->name); + return 0; + } + for(u = s1->use; u != U; u = u->link) + if(!ckuse(s1, s0, u)) + return 0; + } + else{ /* in text area */ + if(u->ct->from.sym->thumb != s0->thumb){ + // print("%s(%d): foreign call %s(%d)\n", s0->name, s0->thumb, u->ct->from.sym->name, u->ct->from.sym->thumb); + return 0; + } + return ckfpuse(u->p, u->ct, s0, s); + } + return 1; +} + +static void +setuse(Sym *s, Sym *s0, Use *u) +{ + Sym *s1; + + s1 = u->p->from.sym; + if(u->ct == nil){ /* in data area */ + for(u = s1->use; u != U; u = u->link) + setuse(s1, s0, u); + } + else{ /* in text area */ + setfpuse(u->p, s0, s); + } +} + +/* detect BX O(R) which can be done as BL O(R) */ +void +fnptrs() +{ + int i; + Sym *s; + Prog *p; + Use *u; + + for(i=0; i<NHASH; i++){ + for(s = hash[i]; s != S; s = s->link){ + if(s->fnptr && (s->type == STEXT || s->type == SLEAF || s->type == SCONST)){ + // print("%s : fnptr %d %d\n", s->name, s->thumb, s->foreign); + } + } + } + /* record use of syms */ + for(p = firstp; p != P; p = p->link){ + if(p->as == ATEXT) + curtext = p; + else{ + fused(&p->from, p, curtext); + fused(&p->to, p, curtext); + } + } + for(p = datap; p != P; p = p->link) + fused(&p->to, p, nil); + + /* now look for fn ptrs */ + for(i=0; i<NHASH; i++){ + for(s = hash[i]; s != S; s = s->link){ + if(s->fnptr && (s->type == STEXT || s->type == SLEAF || s->type == SCONST)){ + for(u = s->use; u != U; u = u->link){ + if(!ckuse(s, s, u)) + break; + } + if(u == U){ // can simplify + for(u = s->use; u != U; u = u->link) + setuse(s, s, u); + } + } + } + } + + /* now free Use structures */ +} + +void +import(void) +{ + int i; + Sym *s; + + for(i = 0; i < NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){ + undefsym(s); + Bprint(&bso, "IMPORT: %s sig=%lux v=%ld\n", s->name, s->sig, s->value); + } +} + +void +ckoff(Sym *s, long v) +{ + if(v < 0 || v >= 1<<Roffset) + diag("relocation offset %ld for %s out of range", v, s->name); +} + +static Prog* +newdata(Sym *s, int o, int w, int t) +{ + Prog *p; + + p = prg(); + p->link = datap; + datap = p; + p->as = ADATA; + p->reg = w; + p->from.type = D_OREG; + p->from.name = t; + p->from.sym = s; + p->from.offset = o; + p->to.type = D_CONST; + p->to.name = D_NONE; + return p; +} + +void +export(void) +{ + int i, j, n, off, nb, sv, ne; + Sym *s, *et, *str, **esyms; + Prog *p; + char buf[NSNAME], *t; + + n = 0; + for(i = 0; i < NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + n++; + esyms = malloc(n*sizeof(Sym*)); + ne = n; + n = 0; + for(i = 0; i < NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + esyms[n++] = s; + for(i = 0; i < ne-1; i++) + for(j = i+1; j < ne; j++) + if(strcmp(esyms[i]->name, esyms[j]->name) > 0){ + s = esyms[i]; + esyms[i] = esyms[j]; + esyms[j] = s; + } + + nb = 0; + off = 0; + et = lookup(EXPTAB, 0); + if(et->type != 0 && et->type != SXREF) + diag("%s already defined", EXPTAB); + et->type = SDATA; + str = lookup(".string", 0); + if(str->type == 0) + str->type = SDATA; + sv = str->value; + for(i = 0; i < ne; i++){ + s = esyms[i]; + Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type); + + /* signature */ + p = newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + p->to.offset = s->sig; + + /* address */ + p = newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + p->to.name = D_EXTERN; + p->to.sym = s; + + /* string */ + t = s->name; + n = strlen(t)+1; + for(;;){ + buf[nb++] = *t; + sv++; + if(nb >= NSNAME){ + p = newdata(str, sv-NSNAME, NSNAME, D_STATIC); + p->to.type = D_SCONST; + p->to.sval = malloc(NSNAME); + memmove(p->to.sval, buf, NSNAME); + nb = 0; + } + if(*t++ == 0) + break; + } + + /* name */ + p = newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + p->to.name = D_STATIC; + p->to.sym = str; + p->to.offset = sv-n; + } + + if(nb > 0){ + p = newdata(str, sv-nb, nb, D_STATIC); + p->to.type = D_SCONST; + p->to.sval = malloc(NSNAME); + memmove(p->to.sval, buf, nb); + } + + for(i = 0; i < 3; i++){ + newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + } + et->value = off; + if(sv == 0) + sv = 1; + str->value = sv; + exports = ne; + free(esyms); +} diff --git a/utils/tl/span.c b/utils/tl/span.c new file mode 100644 index 00000000..85f27621 --- /dev/null +++ b/utils/tl/span.c @@ -0,0 +1,1262 @@ +#include "l.h" + +static struct { + ulong start; + ulong size; + ulong extra; +} pool; + +int checkpool(Prog*, int); +int flushpool(Prog*, int, int); + +int +isbranch(Prog *p) +{ + int as = p->as; + return (as >= ABEQ && as <= ABLE) || as == AB || as == ABL || as == ABX; +} + +static int +ispad(Prog *p) +{ + if(p->as != AMOVW) + return 0; + if(p->from.type != D_REG || p->from.reg != REGSB) + return 0; + if(p->to.type != D_REG || p->to.reg != REGSB) + return 0; + return 1; +} + +int +fninc(Sym *s) +{ + if(thumb){ + if(s->thumb){ + if(s->foreign) + return 8; + else + return 0; + } + else{ + if(s->foreign) + return 0; + else + diag("T A !foreign in fninc"); + } + } + else{ + if(s->thumb){ + if(s->foreign) + return 0; + else + diag("A T !foreign in fninc"); + } + else{ + if(s->foreign) + return 4; + else + return 0; + } + } + return 0; +} + +int +fnpinc(Sym *s) +{ + if(!s->fnptr){ // a simplified case BX O(R) -> BL O(R) + if(!debug['f']) + diag("fnptr == 0 in fnpinc"); + if(s->foreign) + diag("bad usage in fnpinc %s %d %d %d", s->name, s->used, s->foreign, s->thumb); + return 0; + } + /* 0, 1, 2, 3 squared */ + if(s->thumb) + return s->foreign ? 9 : 1; + else + return s->foreign ? 4 : 0; +} + +static Prog * +pad(Prog *p, int pc) +{ + Prog *q; + + q = prg(); + q->as = AMOVW; + q->line = p->line; + q->from.type = D_REG; + q->from.reg = REGSB; + q->to.type = D_REG; + q->to.reg = REGSB; + q->pc = pc; + q->link = p->link; + return q; +} + +static int +scan(Prog *op, Prog *p, int c) +{ + Prog *q; + + for(q = op->link; q != p; q = q->link){ + q->pc = c; + c += oplook(q)->size; + nocache(q); + } + return c; +} + +/* size of a case statement including jump table */ +static long +casesz(Prog *p) +{ + int jt = 0; + long n = 0; + Optab *o; + + for( ; p != P; p = p->link){ + if(p->as == ABCASE) + jt = 1; + else if(jt) + break; + o = oplook(p); + n += o->size; + } + return n; +} + +void +span(void) +{ + Prog *p, *op; + Sym *setext, *s; + Optab *o; + int m, bflag, i; + long c, otxt, v; + int lastthumb = -1; + + if(debug['v']) + Bprint(&bso, "%5.2f span\n", cputime()); + Bflush(&bso); + + bflag = 0; + c = INITTEXT; + op = nil; + otxt = c; + for(p = firstp; p != P; op = p, p = p->link) { + setarch(p); + p->pc = c; + o = oplook(p); + m = o->size; + // must check literal pool here in case p generates many instructions + if(blitrl){ + if(thumb && isbranch(p)) + pool.extra += brextra(p); + if(checkpool(op, p->as == ACASE ? casesz(p) : m)) + c = p->pc = scan(op, p, c); + } + if(m == 0) { + if(p->as == ATEXT) { + if(blitrl && lastthumb != -1 && lastthumb != thumb){ // flush literal pool + if(flushpool(op, 0, 1)) + c = p->pc = scan(op, p, c); + } + lastthumb = thumb; + curtext = p; + autosize = p->to.offset + 4; + if(p->from.sym != S) + p->from.sym->value = c; + /* need passes to resolve branches */ + if(c-otxt >= 1L<<17) + bflag = 1; + otxt = c; + if(thumb && blitrl) + pool.extra += brextra(p); + continue; + } + diag("zero-width instruction\n%P", p); + continue; + } + switch(o->flag & (LFROM|LTO|LPOOL)) { + case LFROM: + addpool(p, &p->from); + break; + case LTO: + addpool(p, &p->to); + break; + case LPOOL: + if ((p->scond&C_SCOND) == 14) + flushpool(p, 0, 0); + break; + } + if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14) + flushpool(p, 0, 0); + c += m; + if(blitrl && p->link == P){ + if(thumb && isbranch(p)) + pool.extra += brextra(p); + checkpool(p, 0); + } + } + + /* + * if any procedure is large enough to + * generate a large SBRA branch, then + * generate extra passes putting branches + * around jmps to fix. this is rare. + */ + while(bflag) { + if(debug['v']) + Bprint(&bso, "%5.2f span1\n", cputime()); + bflag = 0; + c = INITTEXT; + for(p = firstp; p != P; p = p->link) { + setarch(p); + p->pc = c; + if(thumb && isbranch(p)) + nocache(p); + o = oplook(p); +/* very larg branches + if(o->type == 6 && p->cond) { + otxt = p->cond->pc - c; + if(otxt < 0) + otxt = -otxt; + if(otxt >= (1L<<17) - 10) { + q = prg(); + q->link = p->link; + p->link = q; + q->as = AB; + q->to.type = D_BRANCH; + q->cond = p->cond; + p->cond = q; + q = prg(); + q->link = p->link; + p->link = q; + q->as = AB; + q->to.type = D_BRANCH; + q->cond = q->link->link; + bflag = 1; + } + } + */ + m = o->size; + if(m == 0) { + if(p->as == ATEXT) { + curtext = p; + autosize = p->to.offset + 4; + if(p->from.sym != S) + p->from.sym->value = c; + continue; + } + diag("zero-width instruction\n%P", p); + continue; + } + c += m; + } + } + + if(seenthumb){ // branch resolution + int passes = 0; + int lastc = 0; + int again; + Prog *oop; + + loop: + passes++; + if(passes > 150){ + diag("span looping !"); + errorexit(); + } + c = INITTEXT; + oop = op = nil; + again = 0; + for(p = firstp; p != P; oop = op, op = p, p = p->link){ + setarch(p); + if(p->pc != c) + again = 1; + p->pc = c; + if(thumb && isbranch(p)) + nocache(p); + o = oplook(p); + m = o->size; + if(passes == 1 && thumb && isbranch(p)){ // start conservative so unneeded alignment is not added + if(p->as == ABL) + m = 4; + else + m = 2; + p->align = 0; + } + if(p->align){ + if((p->align == 4 && (c&3)) || (p->align == 2 && !(c&3))){ + if(ispad(op)){ + oop->link = p; + op = oop; + c -= 2; + p->pc = c; + } + else{ + op->link = pad(op, c); + op = op->link; + c += 2; + p->pc = c; + } + again = 1; + } + } + if(m == 0) { + if(p->as == ATEXT) { + curtext = p; + autosize = p->to.offset + 4; + if(p->from.sym != S) + p->from.sym->value = c; + continue; + } + } + c += m; + } + if(c != lastc || again){ + lastc = c; + goto loop; + } + } + + if(0 && seenthumb){ // rm redundant padding - obsolete + int d; + + op = nil; + d = 0; + for(p = firstp; p != P; op = p, p = p->link){ + p->pc -= d; + if(p->as == ATEXT){ + if(p->from.sym != S) + p->from.sym->value -= d; +// if(p->from.sym != S) print("%s %ux %d %d %d\n", p->from.sym->name ? p->from.sym->name : "?", p->from.sym->value, p->from.sym->thumb, p->from.sym->foreign, p->from.sym->fnptr); + } + if(ispad(p) && p->link != P && ispad(p->link)){ + op->link = p->link->link; + d += 4; + p = op; + } + } + // print("%d bytes removed (padding)\n", d); + c -= d; + } + + if(debug['t']) { + /* + * add strings to text segment + */ + c = rnd(c, 8); + for(i=0; i<NHASH; i++) + for(s = hash[i]; s != S; s = s->link) { + if(s->type != SSTRING) + continue; + v = s->value; + while(v & 3) + v++; + s->value = c; + c += v; + } + } + + c = rnd(c, 8); + + setext = lookup("etext", 0); + if(setext != S) { + setext->value = c; + textsize = c - INITTEXT; + } + if(INITRND) + INITDAT = rnd(c, INITRND); + if(debug['v']) + Bprint(&bso, "tsize = %lux\n", textsize); + Bflush(&bso); +} + +/* + * when the first reference to the literal pool threatens + * to go out of range of a 12-bit PC-relative offset, + * drop the pool now, and branch round it. + * this happens only in extended basic blocks that exceed 4k. + */ +int +checkpool(Prog *p, int sz) +{ + if(thumb){ + if(pool.size >= 0x3fc || (p->pc+sz+pool.extra+2+2)+(pool.size-4)-pool.start-4 >= 0x3fc) + return flushpool(p, 1, 0); + else if(p->link == P) + return flushpool(p, 2, 0); + return 0; + } + if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0) + return flushpool(p, 1, 0); + else if(p->link == P) + return flushpool(p, 2, 0); + return 0; +} + +int +flushpool(Prog *p, int skip, int force) +{ + Prog *q; + + if(blitrl) { + if(skip){ + if(0 && skip==1)print("note: flush literal pool at %lux: len=%lud ref=%lux\n", p->pc+4, pool.size, pool.start); + q = prg(); + q->as = AB; + q->to.type = D_BRANCH; + q->cond = p->link; + q->link = blitrl; + blitrl = q; + } + else if(!force && (p->pc+pool.size-pool.start < (thumb ? 0x3fc+4-pool.extra : 2048))) + return 0; + elitrl->link = p->link; + p->link = blitrl; + blitrl = 0; /* BUG: should refer back to values until out-of-range */ + elitrl = 0; + pool.size = 0; + pool.start = 0; + pool.extra = 0; + return 1; + } + return 0; +} + +void +addpool(Prog *p, Adr *a) +{ + Prog *q, t; + int c; + + if(thumb) + c = thumbaclass(a, p); + else + c = aclass(a); + + t = zprg; + t.as = AWORD; + + switch(c) { + default: + t.to = *a; + break; + + case C_SROREG: + case C_LOREG: + case C_ROREG: + case C_FOREG: + case C_SOREG: + case C_HOREG: + case C_GOREG: + case C_FAUTO: + case C_SAUTO: + case C_LAUTO: + case C_LACON: + case C_GACON: + t.to.type = D_CONST; + t.to.offset = instoffset; + break; + } + + for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */ + if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) { + p->cond = q; + return; + } + + q = prg(); + *q = t; + q->pc = pool.size; + + if(blitrl == P) { + blitrl = q; + pool.start = p->pc; + q->align = 4; + } else + elitrl->link = q; + elitrl = q; + pool.size += 4; + + p->cond = q; +} + +void +xdefine(char *p, int t, long v) +{ + Sym *s; + + s = lookup(p, 0); + if(s->type == 0 || s->type == SXREF) { + s->type = t; + s->value = v; + } +} + +long +regoff(Adr *a) +{ + + instoffset = 0; + aclass(a); + return instoffset; +} + +long +immrot(ulong v) +{ + int i; + + for(i=0; i<16; i++) { + if((v & ~0xff) == 0) + return (i<<8) | v | (1<<25); + v = (v<<2) | (v>>30); + } + return 0; +} + +long +immaddr(long v) +{ + if(v >= 0 && v <= 0xfff) + return (v & 0xfff) | + (1<<24) | /* pre indexing */ + (1<<23); /* pre indexing, up */ + if(v >= -0xfff && v < 0) + return (-v & 0xfff) | + (1<<24); /* pre indexing */ + return 0; +} + +int +immfloat(long v) +{ + return (v & 0xC03) == 0; /* offset will fit in floating-point load/store */ +} + +int +immhalf(long v) +{ + if(v >= 0 && v <= 0xff) + return v| + (1<<24)| /* pre indexing */ + (1<<23); /* pre indexing, up */ + if(v >= -0xff && v < 0) + return (-v & 0xff)| + (1<<24); /* pre indexing */ + return 0; +} + +int +aclass(Adr *a) +{ + Sym *s; + int t; + + switch(a->type) { + case D_NONE: + return C_NONE; + + case D_REG: + return C_REG; + + case D_REGREG: + return C_REGREG; + + case D_SHIFT: + return C_SHIFT; + + case D_FREG: + return C_FREG; + + case D_FPCR: + return C_FCR; + + case D_OREG: + switch(a->name) { + case D_EXTERN: + case D_STATIC: + if(a->sym == 0 || a->sym->name == 0) { + print("null sym external\n"); + print("%D\n", a); + return C_GOK; + } + s = a->sym; + t = s->type; + if(t == 0 || t == SXREF) { + diag("undefined external: %s in %s", + s->name, TNAME); + s->type = SDATA; + } + if(dlm) { + switch(t) { + default: + instoffset = s->value + a->offset + INITDAT; + break; + case SUNDEF: + case STEXT: + case SCONST: + case SLEAF: + case SSTRING: + instoffset = s->value + a->offset; + break; + } + return C_ADDR; + } + instoffset = s->value + a->offset - BIG; + t = immaddr(instoffset); + if(t) { + if(immhalf(instoffset)) + return immfloat(t) ? C_HFEXT : C_HEXT; + if(immfloat(t)) + return C_FEXT; + return C_SEXT; + } + return C_LEXT; + case D_AUTO: + instoffset = autosize + a->offset; + t = immaddr(instoffset); + if(t){ + if(immhalf(instoffset)) + return immfloat(t) ? C_HFAUTO : C_HAUTO; + if(immfloat(t)) + return C_FAUTO; + return C_SAUTO; + } + return C_LAUTO; + + case D_PARAM: + instoffset = autosize + a->offset + 4L; + t = immaddr(instoffset); + if(t){ + if(immhalf(instoffset)) + return immfloat(t) ? C_HFAUTO : C_HAUTO; + if(immfloat(t)) + return C_FAUTO; + return C_SAUTO; + } + return C_LAUTO; + case D_NONE: + instoffset = a->offset; + t = immaddr(instoffset); + if(t) { + if(immhalf(instoffset)) /* n.b. that it will also satisfy immrot */ + return immfloat(t) ? C_HFOREG : C_HOREG; + if(immfloat(t)) + return C_FOREG; /* n.b. that it will also satisfy immrot */ + t = immrot(instoffset); + if(t) + return C_SROREG; + if(immhalf(instoffset)) + return C_HOREG; + return C_SOREG; + } + t = immrot(instoffset); + if(t) + return C_ROREG; + return C_LOREG; + } + return C_GOK; + + case D_PSR: + return C_PSR; + + case D_OCONST: + switch(a->name) { + case D_EXTERN: + case D_STATIC: + s = a->sym; + t = s->type; + if(t == 0 || t == SXREF) { + diag("undefined external: %s in %s", + s->name, TNAME); + s->type = SDATA; + } + instoffset = s->value + a->offset + INITDAT; + if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) { + instoffset = s->value + a->offset; +#ifdef CALLEEBX + instoffset += fnpinc(s); +#else + if(s->thumb) + instoffset++; // T bit +#endif + return C_LCON; + } + return C_LCON; + } + return C_GOK; + + case D_FCONST: + return C_FCON; + + case D_CONST: + switch(a->name) { + + case D_NONE: + instoffset = a->offset; + if(a->reg != NREG) + goto aconsize; + + t = immrot(instoffset); + if(t) + return C_RCON; + t = immrot(~instoffset); + if(t) + return C_NCON; + return C_LCON; + + case D_EXTERN: + case D_STATIC: + s = a->sym; + if(s == S) + break; + t = s->type; + switch(t) { + case 0: + case SXREF: + diag("undefined external: %s in %s", + s->name, TNAME); + s->type = SDATA; + break; + case SUNDEF: + case STEXT: + case SSTRING: + case SCONST: + case SLEAF: + instoffset = s->value + a->offset; +#ifdef CALLEEBX + instoffset += fnpinc(s); +#else + if(s->thumb) + instoffset++; // T bit +#endif + return C_LCON; + } + if(!dlm) { + instoffset = s->value + a->offset - BIG; + t = immrot(instoffset); + if(t && instoffset != 0) + return C_RECON; + } + instoffset = s->value + a->offset + INITDAT; + return C_LCON; + + case D_AUTO: + instoffset = autosize + a->offset; + goto aconsize; + + case D_PARAM: + instoffset = autosize + a->offset + 4L; + aconsize: + t = immrot(instoffset); + if(t) + return C_RACON; + return C_LACON; + } + return C_GOK; + + case D_BRANCH: + return C_SBRA; + } + return C_GOK; +} + +Optab* +oplook(Prog *p) +{ + int a1, a2, a3, r; + char *c1, *c3; + Optab *o, *e; + Optab *otab; + Oprang *orange; + + if(thumb){ + otab = thumboptab; + orange = thumboprange; + } + else{ + otab = optab; + orange = oprange; + } + a1 = p->optab; + if(a1) + return otab+(a1-1); + a1 = p->from.class; + if(a1 == 0) { + if(thumb) + a1 = thumbaclass(&p->from, p) + 1; + else + a1 = aclass(&p->from) + 1; + p->from.class = a1; + } + a1--; + a3 = p->to.class; + if(a3 == 0) { + if(thumb) + a3 = thumbaclass(&p->to, p) + 1; + else + a3 = aclass(&p->to) + 1; + p->to.class = a3; + } + a3--; + a2 = C_NONE; + if(p->reg != NREG) + a2 = C_REG; + r = p->as; + o = orange[r].start; + if(o == 0) { + a1 = opcross[repop[r]][a1][a2][a3]; + if(a1) { + p->optab = a1+1; + return otab+a1; + } + o = orange[r].stop; /* just generate an error */ + } + if(0) { + print("oplook %A %d %d %d\n", + (int)p->as, a1, a2, a3); + print(" %d %d\n", p->from.type, p->to.type); + } + e = orange[r].stop; + c1 = xcmp[a1]; + c3 = xcmp[a3]; + for(; o<e; o++) + if(o->a2 == a2) + if(c1[o->a1]) + if(c3[o->a3]) { + p->optab = (o-otab)+1; + return o; + } + diag("illegal combination %A %d %d %d", + p->as, a1, a2, a3); + prasm(p); + if(o == 0) + o = otab; + return o; +} + +int +cmp(int a, int b) +{ + + if(a == b) + return 1; + switch(a) { + case C_LCON: + if(b == C_RCON || b == C_NCON) + return 1; + break; + case C_LACON: + if(b == C_RACON) + return 1; + break; + case C_LECON: + if(b == C_RECON) + return 1; + break; + + case C_HFEXT: + return b == C_HEXT || b == C_FEXT; + case C_FEXT: + case C_HEXT: + return b == C_HFEXT; + case C_SEXT: + return cmp(C_HFEXT, b); + case C_LEXT: + return cmp(C_SEXT, b); + + case C_HFAUTO: + return b == C_HAUTO || b == C_FAUTO; + case C_FAUTO: + case C_HAUTO: + return b == C_HFAUTO; + case C_SAUTO: + return cmp(C_HFAUTO, b); + case C_LAUTO: + return cmp(C_SAUTO, b); + + case C_HFOREG: + return b == C_HOREG || b == C_FOREG; + case C_FOREG: + case C_HOREG: + return b == C_HFOREG; + case C_SROREG: + return cmp(C_SOREG, b) || cmp(C_ROREG, b); + case C_SOREG: + case C_ROREG: + return b == C_SROREG || cmp(C_HFOREG, b); + case C_LOREG: + return cmp(C_SROREG, b); + + case C_LBRA: + if(b == C_SBRA) + return 1; + break; + case C_GBRA: + if(b == C_SBRA || b == C_LBRA) + return 1; + + case C_HREG: + return cmp(C_SP, b) || cmp(C_PC, b); + + } + return 0; +} + +int +ocmp(void *a1, void *a2) +{ + Optab *p1, *p2; + int n; + + p1 = (Optab*)a1; + p2 = (Optab*)a2; + n = p1->as - p2->as; + if(n) + return n; + n = (p2->flag&V4) - (p1->flag&V4); /* architecture version */ + if(n) + return n; + n = p1->a1 - p2->a1; + if(n) + return n; + n = p1->a2 - p2->a2; + if(n) + return n; + n = p1->a3 - p2->a3; + if(n) + return n; + return 0; +} + +void +buildop(void) +{ + int i, n, r; + + armv4 = !debug['h']; + for(i=0; i<C_GOK; i++) + for(n=0; n<C_GOK; n++) + xcmp[i][n] = cmp(n, i); + for(n=0; optab[n].as != AXXX; n++) + if((optab[n].flag & V4) && !armv4) { + optab[n].as = AXXX; + break; + } + qsort(optab, n, sizeof(optab[0]), ocmp); + for(i=0; i<n; i++) { + r = optab[i].as; + oprange[r].start = optab+i; + while(optab[i].as == r) + i++; + oprange[r].stop = optab+i; + i--; + + switch(r) + { + default: + diag("unknown op in build: %A", r); + errorexit(); + case AADD: + oprange[AAND] = oprange[r]; + oprange[AEOR] = oprange[r]; + oprange[ASUB] = oprange[r]; + oprange[ARSB] = oprange[r]; + oprange[AADC] = oprange[r]; + oprange[ASBC] = oprange[r]; + oprange[ARSC] = oprange[r]; + oprange[AORR] = oprange[r]; + oprange[ABIC] = oprange[r]; + break; + case ACMP: + oprange[ATST] = oprange[r]; + oprange[ATEQ] = oprange[r]; + oprange[ACMN] = oprange[r]; + break; + case AMVN: + break; + case ABEQ: + oprange[ABNE] = oprange[r]; + oprange[ABCS] = oprange[r]; + oprange[ABHS] = oprange[r]; + oprange[ABCC] = oprange[r]; + oprange[ABLO] = oprange[r]; + oprange[ABMI] = oprange[r]; + oprange[ABPL] = oprange[r]; + oprange[ABVS] = oprange[r]; + oprange[ABVC] = oprange[r]; + oprange[ABHI] = oprange[r]; + oprange[ABLS] = oprange[r]; + oprange[ABGE] = oprange[r]; + oprange[ABLT] = oprange[r]; + oprange[ABGT] = oprange[r]; + oprange[ABLE] = oprange[r]; + break; + case ASLL: + oprange[ASRL] = oprange[r]; + oprange[ASRA] = oprange[r]; + break; + case AMUL: + oprange[AMULU] = oprange[r]; + break; + case ADIV: + oprange[AMOD] = oprange[r]; + oprange[AMODU] = oprange[r]; + oprange[ADIVU] = oprange[r]; + break; + case AMOVW: + case AMOVB: + case AMOVBU: + case AMOVH: + case AMOVHU: + break; + case ASWPW: + oprange[ASWPBU] = oprange[r]; + break; + case AB: + case ABL: + case ABX: + case ABXRET: + case ASWI: + case AWORD: + case AMOVM: + case ARFE: + case ATEXT: + case ACASE: + case ABCASE: + break; + case AADDF: + oprange[AADDD] = oprange[r]; + oprange[ASUBF] = oprange[r]; + oprange[ASUBD] = oprange[r]; + oprange[AMULF] = oprange[r]; + oprange[AMULD] = oprange[r]; + oprange[ADIVF] = oprange[r]; + oprange[ADIVD] = oprange[r]; + oprange[AMOVFD] = oprange[r]; + oprange[AMOVDF] = oprange[r]; + break; + + case ACMPF: + oprange[ACMPD] = oprange[r]; + break; + + case AMOVF: + oprange[AMOVD] = oprange[r]; + break; + + case AMOVFW: + oprange[AMOVWF] = oprange[r]; + oprange[AMOVWD] = oprange[r]; + oprange[AMOVDW] = oprange[r]; + break; + + case AMULL: + oprange[AMULA] = oprange[r]; + oprange[AMULAL] = oprange[r]; + oprange[AMULLU] = oprange[r]; + oprange[AMULALU] = oprange[r]; + break; + } + } +} + +/* +void +buildrep(int x, int as) +{ + Opcross *p; + Optab *e, *s, *o; + int a1, a2, a3, n; + + if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) { + diag("assumptions fail in buildrep"); + errorexit(); + } + repop[as] = x; + p = (opcross + x); + s = oprange[as].start; + e = oprange[as].stop; + for(o=e-1; o>=s; o--) { + n = o-optab; + for(a2=0; a2<2; a2++) { + if(a2) { + if(o->a2 == C_NONE) + continue; + } else + if(o->a2 != C_NONE) + continue; + for(a1=0; a1<32; a1++) { + if(!xcmp[a1][o->a1]) + continue; + for(a3=0; a3<32; a3++) + if(xcmp[a3][o->a3]) + (*p)[a1][a2][a3] = n; + } + } + } + oprange[as].start = 0; +} +*/ + +enum{ + ABSD = 0, + ABSU = 1, + RELD = 2, + RELU = 3, +}; + +int modemap[4] = { 0, 1, -1, 2, }; + +typedef struct Reloc Reloc; + +struct Reloc +{ + int n; + int t; + uchar *m; + ulong *a; +}; + +Reloc rels; + +static void +grow(Reloc *r) +{ + int t; + uchar *m, *nm; + ulong *a, *na; + + t = r->t; + r->t += 64; + m = r->m; + a = r->a; + r->m = nm = malloc(r->t*sizeof(uchar)); + r->a = na = malloc(r->t*sizeof(ulong)); + memmove(nm, m, t*sizeof(uchar)); + memmove(na, a, t*sizeof(ulong)); + free(m); + free(a); +} + +void +dynreloc(Sym *s, long v, int abs) +{ + int i, k, n; + uchar *m; + ulong *a; + Reloc *r; + + if(v&3) + diag("bad relocation address"); + v >>= 2; + if(s != S && s->type == SUNDEF) + k = abs ? ABSU : RELU; + else + k = abs ? ABSD : RELD; + /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */ + k = modemap[k]; + r = &rels; + n = r->n; + if(n >= r->t) + grow(r); + m = r->m; + a = r->a; + for(i = n; i > 0; i--){ + if(v < a[i-1]){ /* happens occasionally for data */ + m[i] = m[i-1]; + a[i] = a[i-1]; + } + else + break; + } + m[i] = k; + a[i] = v; + r->n++; +} + +static int +sput(char *s) +{ + char *p; + + p = s; + while(*s) + cput(*s++); + cput(0); + return s-p+1; +} + +void +asmdyn() +{ + int i, n, t, c; + Sym *s; + ulong la, ra, *a; + vlong off; + uchar *m; + Reloc *r; + + cflush(); + off = seek(cout, 0, 1); + lput(0); + t = 0; + lput(imports); + t += 4; + for(i = 0; i < NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->type == SUNDEF){ + lput(s->sig); + t += 4; + t += sput(s->name); + } + + la = 0; + r = &rels; + n = r->n; + m = r->m; + a = r->a; + lput(n); + t += 4; + for(i = 0; i < n; i++){ + ra = *a-la; + if(*a < la) + diag("bad relocation order"); + if(ra < 256) + c = 0; + else if(ra < 65536) + c = 1; + else + c = 2; + cput((c<<6)|*m++); + t++; + if(c == 0){ + cput(ra); + t++; + } + else if(c == 1){ + wput(ra); + t += 2; + } + else{ + lput(ra); + t += 4; + } + la = *a++; + } + + cflush(); + seek(cout, off, 0); + lput(t); + + if(debug['v']){ + Bprint(&bso, "import table entries = %d\n", imports); + Bprint(&bso, "export table entries = %d\n", exports); + } +} diff --git a/utils/5l/thumb.c b/utils/tl/thumb.c index f16175ea..f16175ea 100644 --- a/utils/5l/thumb.c +++ b/utils/tl/thumb.c diff --git a/utils/va/a.h b/utils/va/a.h index 92199a08..fb6c8cb5 100644 --- a/utils/va/a.h +++ b/utils/va/a.h @@ -29,7 +29,7 @@ struct Sym { Sym* link; char* macro; - long value; + vlong value; ushort type; char *name; char sym; @@ -61,7 +61,7 @@ EXTERN struct struct Gen { Sym* sym; - long offset; + vlong offset; short type; short reg; short name; @@ -74,7 +74,7 @@ struct Hist Hist* link; char* name; long line; - long offset; + vlong offset; }; #define H ((Hist*)0) diff --git a/utils/va/a.y b/utils/va/a.y index cbc07fd7..fa7a9341 100644 --- a/utils/va/a.y +++ b/utils/va/a.y @@ -4,7 +4,7 @@ %union { Sym *sym; - long lval; + vlong lval; double dval; char sval[8]; Gen gen; diff --git a/utils/va/lex.c b/utils/va/lex.c index 83b3fb9e..df03aea8 100644 --- a/utils/va/lex.c +++ b/utils/va/lex.c @@ -462,7 +462,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } } diff --git a/utils/va/note b/utils/va/note deleted file mode 100644 index f68e464f..00000000 --- a/utils/va/note +++ /dev/null @@ -1,51 +0,0 @@ -gen address - -$con - type = D_CONST - offset = con - -$name+con(P) - type = D_CONST - offset = con - name = P - -$"xxx" - type = D_SCONST - -$1.0 - type = D_FCONST - -con - type = D_OREG - offset = con - -name+con(P) - type = D_OREG - offset = con - name = P - -con(R1) - type = D_OREG - offset = con - reg = 1 - -name+con(P)(R1) - type = D_OREG - offset = con - name = P - reg = 1 - -R1 - type = D_REG - reg = 1 - -MOVB[U] - LB[U], SB -MOVH[U] - LH[U], SB -MOVW[LR] - LW[LR], SW[LR] -MOVW - LW, SW, LUI, M[FT]HI, M[FT]LO -BREAK is synonym for CACHE. -operands make the difference. diff --git a/utils/vc/gc.h b/utils/vc/gc.h index 29fc0bc5..ad34f1d2 100644 --- a/utils/vc/gc.h +++ b/utils/vc/gc.h @@ -55,7 +55,7 @@ struct Prog struct Case { Case* link; - long val; + vlong val; long label; char def; char isv; @@ -64,7 +64,7 @@ struct Case struct C1 { - long val; + vlong val; long label; }; @@ -256,7 +256,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void swit2(C1*, int, long, Node*, Node*); @@ -267,7 +267,6 @@ long outstring(char*, long); int mulcon(Node*, Node*); Multab* mulcon0(long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); @@ -287,7 +286,7 @@ int Bconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); Bits mkvar(Adr*, int); diff --git a/utils/vc/list.c b/utils/vc/list.c index f89b17ca..b96130f4 100644 --- a/utils/vc/list.c +++ b/utils/vc/list.c @@ -70,7 +70,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/vc/peep.c b/utils/vc/peep.c index 5f635571..849d3c15 100644 --- a/utils/vc/peep.c +++ b/utils/vc/peep.c @@ -403,6 +403,7 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f) * 4 if set and used * 0 otherwise (not touched) */ +int copyu(Prog *p, Adr *v, Adr *s) { @@ -569,7 +570,6 @@ copyu(Prog *p, Adr *v, Adr *s) return 3; return 0; } - /* not reached */ } int diff --git a/utils/vc/reg.c b/utils/vc/reg.c index bde52df0..f9d2a72c 100644 --- a/utils/vc/reg.c +++ b/utils/vc/reg.c @@ -18,7 +18,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; diff --git a/utils/vc/swt.c b/utils/vc/swt.c index cdc58e1b..65f90301 100644 --- a/utils/vc/swt.c +++ b/utils/vc/swt.c @@ -19,8 +19,8 @@ swit2(C1 *q, int nc, long def, Node *n, Node *tn) if(nc < 5) { for(i=0; i<nc; i++) { - if(debug['W']) - print("case = %.8lux\n", q->val); + if(debug['K']) + print("case = %.8llux\n", q->val); gmove(nodconst(q->val), tn); gopcode(OEQ, n, tn, Z); patch(p, q->label); @@ -32,8 +32,8 @@ swit2(C1 *q, int nc, long def, Node *n, Node *tn) } i = nc / 2; r = q+i; - if(debug['W']) - print("case > %.8lux\n", r->val); + if(debug['K']) + print("case > %.8llux\n", r->val); gmove(nodconst(r->val), tn); gopcode(OLT, tn, n, Z); sp = p; @@ -41,8 +41,8 @@ swit2(C1 *q, int nc, long def, Node *n, Node *tn) patch(p, r->label); swit2(q, i, def, n, tn); - if(debug['W']) - print("case < %.8lux\n", r->val); + if(debug['K']) + print("case < %.8llux\n", r->val); patch(sp, pc); swit2(r+1, nc-i-1, def, n, tn); } @@ -234,23 +234,6 @@ loop: } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0)); - p->from.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { @@ -596,8 +579,8 @@ align(long i, Type *t, int op) long maxround(long max, long v) { - v += SZ_LONG-1; + v = round(v, SZ_LONG); if(v > max) - max = round(v, SZ_LONG); + return v; return max; } diff --git a/utils/vl/Nt.c b/utils/vl/Nt.c deleted file mode 100644 index 73c6f795..00000000 --- a/utils/vl/Nt.c +++ /dev/null @@ -1,77 +0,0 @@ -#include <windows.h> -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(uint n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(uint m, uint n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, uint n) -{ - void *new; - - new = malloc(n); - if(new && p) - memmove(new, p, n); - return new; -} - -#define Chunk (1*1024*1024) - -void* -mysbrk(ulong size) -{ - void *v; - static int chunk; - static uchar *brk; - - if(chunk < size) { - chunk = Chunk; - if(chunk < size) - chunk = Chunk + size; - brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(brk == 0) - return (void*)-1; - } - v = brk; - chunk -= size; - brk += size; - return v; -} - -double -cputime(void) -{ - return ((double)0); -} diff --git a/utils/vl/Plan9.c b/utils/vl/Plan9.c deleted file mode 100644 index f4cf23f4..00000000 --- a/utils/vl/Plan9.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "l.h" - -/* - * fake malloc - */ -void* -malloc(ulong n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(ulong m, ulong n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, ulong n) -{ - USED(p); - USED(n); - fprint(2, "realloc called\n"); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return sbrk(size); -} - -void -setmalloctag(void*, ulong) -{ -} diff --git a/utils/vl/Posix.c b/utils/vl/Posix.c deleted file mode 100644 index 7c3a661f..00000000 --- a/utils/vl/Posix.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "l.h" -#include <sys/types.h> -#include <sys/times.h> -#undef getwd -#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */ - -/* - * fake malloc - */ -void* -malloc(size_t n) -{ - void *p; - - while(n & 7) - n++; - while(nhunk < n) - gethunk(); - p = hunk; - nhunk -= n; - hunk += n; - return p; -} - -void -free(void *p) -{ - USED(p); -} - -void* -calloc(size_t m, size_t n) -{ - void *p; - - n *= m; - p = malloc(n); - memset(p, 0, n); - return p; -} - -void* -realloc(void *p, size_t n) -{ - fprint(2, "realloc called\n", p, n); - abort(); - return 0; -} - -void* -mysbrk(ulong size) -{ - return (void*)sbrk(size); -} - -double -cputime(void) -{ - - struct tms tmbuf; - double ret_val; - - /* - * times() only fials if &tmbuf is invalid. - */ - (void)times(&tmbuf); - /* - * Return the total time (in system clock ticks) - * spent in user code and system - * calls by both the calling process and its children. - */ - ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + - tmbuf.tms_cutime + tmbuf.tms_cstime); - /* - * Convert to seconds. - */ - ret_val *= sysconf(_SC_CLK_TCK); - return ret_val; - -} diff --git a/utils/vl/asm.c b/utils/vl/asm.c index 1e7039f1..527b8de5 100644 --- a/utils/vl/asm.c +++ b/utils/vl/asm.c @@ -84,6 +84,12 @@ long BADOFFSET = -1; } void +cput(long l) +{ + CPUT(l); +} + +void objput(long l) /* emit long in byte order appropriate to object machine */ { LPUT(l); @@ -96,11 +102,55 @@ objhput(short s) } void +wput(long l) +{ + + cbp[0] = l>>8; + cbp[1] = l; + cbp += 2; + cbc -= 2; + if(cbc <= 0) + cflush(); +} + +void +wputl(long l) +{ + + cbp[0] = l; + cbp[1] = l>>8; + cbp += 2; + cbc -= 2; + if(cbc <= 0) + cflush(); +} + +void lput(long l) /* emit long in big-endian byte order */ { LBEPUT(l); } +void +lputl(long l) /* emit long in big-endian byte order */ +{ + LLEPUT(l); +} + +void +llput(vlong v) +{ + lput(v>>32); + lput(v); +} + +void +llputl(vlong v) +{ + lputl(v); + lputl(v>>32); +} + long entryvalue(void) { @@ -391,64 +441,7 @@ asmb(void) lput(0x80L); /* flags */ break; case 5: - /* first part of ELF is byte-wide parts, thus no byte-order issues */ - strnput("\177ELF", 4); /* e_ident */ - CPUT(1); /* class = 32 bit */ - CPUT(little? 1: 2); /* data: 1 = LSB, 2 = MSB */ - CPUT(1); /* version = 1 */ - strnput("", 9); /* reserved for expansion */ - /* entire remainder of ELF file is in target byte order */ - - /* file header part of ELF header */ - objhput(2); /* type = EXEC */ - objhput(8); /* machine = MIPS */ - objput(1L); /* version = CURRENT */ - objput(entryvalue()); /* entry vaddr */ - objput(52L); /* offset to first phdr */ - objput(0L); /* offset to first shdr */ - objput(0L); /* flags (no MIPS flags defined) */ - objhput(52); /* Ehdr size */ - objhput(32); /* Phdr size */ - objhput(3); /* # of Phdrs */ - objhput(0); /* Shdr size */ - objhput(0); /* # of Shdrs */ - objhput(0); /* Shdr string size */ - - /* "Program headers" - one per chunk of file to load */ - - /* - * include ELF headers in text -- 8l doesn't, - * but in theory it aids demand loading. - */ - objput(1L); /* text: type = PT_LOAD */ - objput(0L); /* file offset */ - objput(INITTEXT-HEADR); /* vaddr */ - objput(INITTEXT-HEADR); /* paddr */ - objput(HEADR+textsize); /* file size */ - objput(HEADR+textsize); /* memory size */ - objput(0x05L); /* protections = RX */ - objput(0x1000L); /* page-align text off's & vaddrs */ - - objput(1L); /* data: type = PT_LOAD */ - objput(HEADR+textsize); /* file offset */ - objput(INITDAT); /* vaddr */ - objput(INITDAT); /* paddr */ - objput(datsize); /* file size */ - objput(datsize+bsssize); /* memory size */ - objput(0x06L); /* protections = RW */ - if(INITDAT % 4096 == 0 && (HEADR + textsize) % 4096 == 0) - objput(0x1000L); /* page-align data off's & vaddrs */ - else - objput(0L); /* do not claim alignment */ - - objput(0L); /* P9 symbols: type = PT_NULL */ - objput(HEADR+textsize+datsize); /* file offset */ - objput(0L); - objput(0L); - objput(symsize); /* symbol table size */ - objput(lcsize); /* line number size */ - objput(0x04L); /* protections = R */ - objput(0L); /* do not claim alignment */ + elf32(MIPS, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil); break; case 6: break; @@ -616,12 +609,12 @@ asmlc(void) if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { if(p->as == ATEXT) curtext = p; - if(debug['L']) + if(debug['V']) Bprint(&bso, "%6lux %P\n", p->pc, p); continue; } - if(debug['L']) + if(debug['V']) Bprint(&bso, "\t\t%6ld", lcsize); v = (p->pc - oldpc) / MINLC; while(v) { @@ -629,7 +622,7 @@ asmlc(void) if(v < 127) s = v; CPUT(s+128); /* 129-255 +pc */ - if(debug['L']) + if(debug['V']) Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); v -= s; lcsize++; @@ -643,7 +636,7 @@ asmlc(void) CPUT(s>>16); CPUT(s>>8); CPUT(s); - if(debug['L']) { + if(debug['V']) { if(s > 0) Bprint(&bso, " lc+%ld(%d,%ld)\n", s, 0, s); @@ -658,14 +651,14 @@ asmlc(void) } if(s > 0) { CPUT(0+s); /* 1-64 +lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); Bprint(&bso, "%6lux %P\n", p->pc, p); } } else { CPUT(64-s); /* 65-128 -lc */ - if(debug['L']) { + if(debug['V']) { Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); Bprint(&bso, "%6lux %P\n", p->pc, p); @@ -678,7 +671,7 @@ asmlc(void) CPUT(s); lcsize++; } - if(debug['v'] || debug['L']) + if(debug['v'] || debug['V']) Bprint(&bso, "lcsize = %ld\n", lcsize); Bflush(&bso); } diff --git a/utils/vl/compat.c b/utils/vl/compat.c index 5e676913..fa93a42a 100644 --- a/utils/vl/compat.c +++ b/utils/vl/compat.c @@ -4,7 +4,7 @@ * fake malloc */ void* -malloc(long n) +malloc(ulong n) { void *p; @@ -25,7 +25,7 @@ free(void *p) } void* -calloc(long m, long n) +calloc(ulong m, ulong n) { void *p; @@ -36,9 +36,9 @@ calloc(long m, long n) } void* -realloc(void *p, long n) +realloc(void*, ulong) { - fprint(2, "realloc called\n", p, n); + fprint(2, "realloc called\n"); abort(); return 0; } @@ -48,3 +48,18 @@ mysbrk(ulong size) { return sbrk(size); } + +void +setmalloctag(void *v, ulong pc) +{ + USED(v, pc); +} + +int +fileexists(char *s) +{ + uchar dirbuf[400]; + + /* it's fine if stat result doesn't fit in dirbuf, since even then the file exists */ + return stat(s, dirbuf, sizeof(dirbuf)) >= 0; +} diff --git a/utils/vl/l.h b/utils/vl/l.h index 75243ad8..c8f9b868 100644 --- a/utils/vl/l.h +++ b/utils/vl/l.h @@ -1,11 +1,14 @@ #include <lib9.h> #include <bio.h> #include "../vc/v.out.h" +#include "../8l/elf.h" #ifndef EXTERN #define EXTERN extern #endif +#define LIBNAMELEN 300 + typedef struct Adr Adr; typedef struct Sym Sym; typedef struct Autom Auto; @@ -186,6 +189,7 @@ EXTERN int HEADTYPE; /* type of header */ EXTERN long INITDAT; /* data location */ EXTERN long INITRND; /* data round above text location */ EXTERN long INITTEXT; /* text location */ +EXTERN long INITTEXTP; /* text location (physical) */ EXTERN char* INITENTRY; /* entry point */ EXTERN long autosize; EXTERN Biobuf bso; @@ -266,6 +270,7 @@ int Pconv(Fmt*); int Sconv(Fmt*); int aclass(Adr*); void addhist(long, int); +void addlibpath(char*); void addnop(Prog*); void append(Prog*, Prog*); void asmb(void); @@ -278,6 +283,7 @@ void buildop(void); void buildrep(int, int); void cflush(void); int cmp(int, int); +void cput(long); int compound(Prog*); double cputime(void); void datblk(long, long, int); @@ -288,7 +294,9 @@ void doprof2(void); long entryvalue(void); void errorexit(void); void exchange(Prog*); +int fileexists(char*); int find1(long, int); +char* findlib(char*); void follow(void); void gethunk(void); void histtoauto(void); @@ -299,7 +307,10 @@ void ldobj(int, long, char*); void loadlib(void); void listinit(void); Sym* lookup(char*, int); +void llput(vlong); +void llputl(vlong); void lput(long); +void lputl(long); void bput(long); void mkfwd(void); void* mysbrk(ulong); @@ -308,7 +319,7 @@ void nocache(Prog*); void noops(void); void nuxiinit(void); void objfile(char*); -int ocmp(const void*, const void*); +int ocmp(void*, void*); long opirr(int); Optab* oplook(Prog*); long oprrr(int); @@ -325,6 +336,8 @@ void sched(Prog*, Prog*); void span(void); void strnput(char*, int); void undef(void); +void wput(long); +void wputl(long); void xdefine(char*, int, long); void xfol(Prog*); void xfol(Prog*); diff --git a/utils/vl/list.c b/utils/vl/list.c index 9261bc8e..c5033a5b 100644 --- a/utils/vl/list.c +++ b/utils/vl/list.c @@ -56,7 +56,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/vl/mkfile b/utils/vl/mkfile index b84163a6..8e18fced 100644 --- a/utils/vl/mkfile +++ b/utils/vl/mkfile @@ -13,6 +13,7 @@ OFILES=\ span.$O\ enam.$O\ $TARGMODEL.$O\ + elf.$O\ HFILES=\ l.h\ @@ -25,7 +26,12 @@ BIN=$ROOT/$OBJDIR/bin <$ROOT/mkfiles/mkone-$SHELLTYPE -CFLAGS= $CFLAGS -I../include +CFLAGS= $CFLAGS -I../include -I. enam.$O: ../vc/enam.c $CC $CFLAGS ../vc/enam.c +elf.$O: ../ld/elf.c + $CC $CFLAGS ../ld/elf.c + +$TARGMODEL.$O: ../ld/$TARGMODEL.c + $CC $CFLAGS ../ld/$TARGMODEL.c diff --git a/utils/vl/obj.c b/utils/vl/obj.c index 8289c588..e80695df 100644 --- a/utils/vl/obj.c +++ b/utils/vl/obj.c @@ -11,6 +11,10 @@ char symname[] = SYMDEF; char thechar = 'v'; char *thestring = "mips"; +char** libdir; +int nlibdir = 0; +static int maxlibdir = 0; + /* * -H0 -T0x40004C -D0x10000000 is abbrev unix * -H1 -T0x80020000 -R4 is bootp() format for 3k @@ -24,10 +28,18 @@ char *thestring = "mips"; int little; void +usage(void) +{ + diag("usage: %s [-options] objects", argv0); + errorexit(); +} + +void main(int argc, char *argv[]) { int c; char *a; + char name[LIBNAMELEN]; Binit(&bso, 1, OWRITE); cout = -1; @@ -37,6 +49,7 @@ main(int argc, char *argv[]) curtext = P; HEADTYPE = -1; INITTEXT = -1; + INITTEXTP = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; @@ -55,7 +68,7 @@ main(int argc, char *argv[]) if(a) INITENTRY = a; break; - case 'L': /* for little-endian mips */ + case 'm': /* for little-endian mips */ thechar = '0'; thestring = "spim"; little = 1; @@ -65,6 +78,11 @@ main(int argc, char *argv[]) if(a) INITTEXT = atolwhex(a); break; + case 'P': + a = ARGF(); + if(a) + INITTEXTP = atolwhex(a); + break; case 'D': a = ARGF(); if(a) @@ -81,16 +99,27 @@ main(int argc, char *argv[]) HEADTYPE = atolwhex(a); /* do something about setting INITTEXT */ break; + case 'L': + addlibpath(EARGF(usage())); + break; } ARGEND USED(argc); - if(*argv == 0) { - diag("usage: %cl [-options] objects", thechar); - errorexit(); - } + if(*argv == 0) + usage(); if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; + a = getenv("ccroot"); + if(a != nil && *a != '\0') { + if(!fileexists(a)) { + diag("nonexistent $ccroot: %s", a); + errorexit(); + } + }else + a = ""; + snprint(name, sizeof(name), "%s/%s/lib", a, thestring); + addlibpath(name); if(HEADTYPE == -1) { if(debug['U']) HEADTYPE = 0; @@ -150,7 +179,7 @@ main(int argc, char *argv[]) INITRND = 0; break; case 5: /* sgi unix elf executable */ - HEADR = rnd(52L+3*32L, 16); + HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16); if(INITTEXT == -1) INITTEXT = 0x00400000L+HEADR; if(INITDAT == -1) @@ -168,6 +197,8 @@ main(int argc, char *argv[]) INITRND = 4096; break; } + if (INITTEXTP == -1) + INITTEXTP = INITTEXT; if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", INITDAT, INITRND); @@ -195,7 +226,7 @@ main(int argc, char *argv[]) } cout = create(outfile, 1, 0775); if(cout < 0) { - diag("%s: cannot create", outfile); + diag("cannot create %s: %r", outfile); errorexit(); } nuxiinit(); @@ -212,7 +243,7 @@ main(int argc, char *argv[]) INITENTRY = "_mainp"; if(!debug['l']) lookup(INITENTRY, 0)->type = SXREF; - } else + } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9')) lookup(INITENTRY, 0)->type = SXREF; while(*argv) @@ -249,6 +280,42 @@ out: } void +addlibpath(char *arg) +{ + char **p; + + if(nlibdir >= maxlibdir) { + if(maxlibdir == 0) + maxlibdir = 8; + else + maxlibdir *= 2; + p = malloc(maxlibdir*sizeof(*p)); + if(p == nil) { + diag("out of memory"); + errorexit(); + } + memmove(p, libdir, nlibdir*sizeof(*p)); + free(libdir); + libdir = p; + } + libdir[nlibdir++] = strdup(arg); +} + +char* +findlib(char *file) +{ + int i; + char name[LIBNAMELEN]; + + for(i = 0; i < nlibdir; i++) { + snprint(name, sizeof(name), "%s/%s", libdir[i], file); + if(fileexists(name)) + return libdir[i]; + } + return nil; +} + +void loadlib(void) { int i; @@ -367,7 +434,8 @@ objfile(char *file) l |= (e[3] & 0xff) << 16; l |= (e[4] & 0xff) << 24; seek(f, l, 0); - l = read(f, &arhdr, SAR_HDR); + /* need readn to read the dumps (at least) */ + l = readn(f, &arhdr, SAR_HDR); if(l != SAR_HDR) goto bad; if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) @@ -394,7 +462,7 @@ int zaddr(uchar *p, Adr *a, Sym *h[]) { int i, c; - long l; + int l; Sym *s; Auto *u; @@ -498,25 +566,24 @@ zaddr(uchar *p, Adr *a, Sym *h[]) void addlib(char *obj) { - char name[1024], comp[256], *p; - int i; + char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name; + int i, search; if(histfrogp <= 0) return; + name = fn1; + search = 0; if(histfrog[0]->name[1] == '/') { sprint(name, ""); i = 1; - } else - if(histfrog[0]->name[1] == '.') { + } else if(histfrog[0]->name[1] == '.') { sprint(name, "."); i = 0; } else { - if(debug['9']) - sprint(name, "/%s/lib", thestring); - else - sprint(name, "/usr/%clib", thechar); + sprint(name, ""); i = 0; + search = 1; } for(; i<histfrogp; i++) { @@ -539,13 +606,25 @@ addlib(char *obj) memmove(p+strlen(thestring), p+2, strlen(p+2)+1); memmove(p, thestring, strlen(thestring)); } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { + if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) { diag("library component too long"); return; } - strcat(name, "/"); - strcat(name, comp); + if(i > 0 || !search) + strcat(fn1, "/"); + strcat(fn1, comp); } + + cleanname(name); + + if(search){ + p = findlib(name); + if(p != nil){ + snprint(fn2, sizeof(fn2), "%s/%s", p, name); + name = fn2; + } + } + for(i=0; i<libraryp; i++) if(strcmp(name, library[i]) == 0) return; @@ -1017,8 +1096,7 @@ lookup(char *symb, int v) for(p=symb; c = *p; p++) h = h+h+h + c; l = (p - symb) + 1; - if(h < 0) - h = ~h; + h &= 0xffffff; h %= NHASH; for(s = hash[h]; s != S; s = s->link) if(s->version == v) @@ -1332,6 +1410,7 @@ nuxiinit(void) Bflush(&bso); } +int find1(long l, int c) { char *p; diff --git a/utils/vl/span.c b/utils/vl/span.c index 488c93d3..b28643d2 100644 --- a/utils/vl/span.c +++ b/utils/vl/span.c @@ -456,7 +456,7 @@ cmp(int a, int b) } int -ocmp(const void *a1, const void *a2) +ocmp(void *a1, void *a2) { Optab *p1, *p2; int n; |
