From 0b3093f0a5a71749c44835a9e3703853238d8d4d Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Tue, 10 Jun 2008 21:29:57 -0700 Subject: [PATCH] debugging to get fmt to run SVN=122046 --- src/cmd/6g/gen.c | 21 +++-- src/cmd/gc/go.h | 5 +- src/cmd/gc/sys.go | 8 ++ src/cmd/gc/sysimport.c | 91 +++++++++++-------- src/cmd/gc/walk.c | 199 +++++++++++++++++++++++++++++++---------- src/runtime/runtime.c | 154 +++++++++++++++++++++++++++++++ 6 files changed, 386 insertions(+), 92 deletions(-) diff --git a/src/cmd/6g/gen.c b/src/cmd/6g/gen.c index 01ef519b83..1a0385dc12 100644 --- a/src/cmd/6g/gen.c +++ b/src/cmd/6g/gen.c @@ -692,19 +692,26 @@ cgen_asop(Node *nl, Node *nr, int op) fatal("cgen_asop both sides call"); } - a = optoas(op, nl->type); - if(nr->ullman > nl->ullman) { - fatal("gcgen_asopen"); - } +// BOTCH make special case for DIVQ - regalloc(&n1, nl->type, N); + a = optoas(op, nl->type); if(nl->addable) { - cgen(nr, &n1); - gins(a, &n1, nl); + regalloc(&n2, nr->type, N); + cgen(nr, &n2); + regalloc(&n1, nl->type, N); + cgen(nl, &n1); + gins(a, &n2, &n1); + gmove(&n1, nl); regfree(&n1); + regfree(&n2); return; } + if(nr->ullman > nl->ullman) { + fatal("gcgen_asopen"); + } + + regalloc(&n1, nl->type, N); igen(nl, &n2, N); cgen(nr, &n1); gins(a, &n1, &n2); diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 1598a8e69e..1f501db5a1 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -529,8 +529,11 @@ Node* nodpanic(long); Node* newcompat(Node*); Node* stringop(Node*); Node* convas(Node*); -Node* reorder(Node*); void arrayconv(Type*, Node*); +Node* reorder1(Node*); +Node* reorder2(Node*); +Node* reorder3(Node*); +Node* reorder4(Node*); /* * const.c diff --git a/src/cmd/gc/sys.go b/src/cmd/gc/sys.go index 19b5c2e86a..89da8919fb 100644 --- a/src/cmd/gc/sys.go +++ b/src/cmd/gc/sys.go @@ -23,6 +23,10 @@ func intstring(int64) string; func byteastring(*byte, int32) string; func mkiface(*byte, *byte, *struct{}) interface{}; +func frexp(float64) (int32, float64); // break fp into exp,fract +func ldexp(int32, float64) float64; // make fp from exp,fract +func modf(float64) (float64, float64); // break fp into double.double + export mal breakpoint @@ -41,4 +45,8 @@ export intstring byteastring mkiface + + frexp + ldexp + modf ; diff --git a/src/cmd/gc/sysimport.c b/src/cmd/gc/sysimport.c index f3a0fb6456..776d5a76bb 100644 --- a/src/cmd/gc/sysimport.c +++ b/src/cmd/gc/sysimport.c @@ -2,10 +2,10 @@ char* sysimport = "type sys._e002 {}\n" "type sys.uint8 2\n" "type sys._e003 *sys.uint8\n" - "type sys._o116 {_e114 sys._e003}\n" + "type sys._o137 {_e135 sys._e003}\n" "type sys.uint32 6\n" - "type sys._i118 {_e115 sys.uint32}\n" - "type sys._e001 (sys._e002 sys._o116 sys._i118)\n" + "type sys._i139 {_e136 sys.uint32}\n" + "type sys._e001 (sys._e002 sys._o137 sys._i139)\n" "var !sys.mal sys._e001\n" "type sys._e005 {}\n" "type sys._e006 {}\n" @@ -15,80 +15,95 @@ char* sysimport = "type sys._e009 {}\n" "type sys._e010 {}\n" "type sys.int32 5\n" - "type sys._i124 {_e123 sys.int32}\n" - "type sys._e008 (sys._e009 sys._e010 sys._i124)\n" + "type sys._i145 {_e144 sys.int32}\n" + "type sys._e008 (sys._e009 sys._e010 sys._i145)\n" "var !sys.panicl sys._e008\n" "type sys._e012 {}\n" "type sys._e013 {}\n" "type sys.bool 12\n" - "type sys._i129 {_e128 sys.bool}\n" - "type sys._e011 (sys._e012 sys._e013 sys._i129)\n" + "type sys._i150 {_e149 sys.bool}\n" + "type sys._e011 (sys._e012 sys._e013 sys._i150)\n" "var !sys.printbool sys._e011\n" "type sys._e015 {}\n" "type sys._e016 {}\n" "type sys.float64 10\n" - "type sys._i134 {_e133 sys.float64}\n" - "type sys._e014 (sys._e015 sys._e016 sys._i134)\n" + "type sys._i155 {_e154 sys.float64}\n" + "type sys._e014 (sys._e015 sys._e016 sys._i155)\n" "var !sys.printfloat sys._e014\n" "type sys._e018 {}\n" "type sys._e019 {}\n" "type sys.int64 7\n" - "type sys._i139 {_e138 sys.int64}\n" - "type sys._e017 (sys._e018 sys._e019 sys._i139)\n" + "type sys._i160 {_e159 sys.int64}\n" + "type sys._e017 (sys._e018 sys._e019 sys._i160)\n" "var !sys.printint sys._e017\n" "type sys._e021 {}\n" "type sys._e022 {}\n" "type sys._e023 25\n" "type sys.string *sys._e023\n" - "type sys._i144 {_e143 sys.string}\n" - "type sys._e020 (sys._e021 sys._e022 sys._i144)\n" + "type sys._i165 {_e164 sys.string}\n" + "type sys._e020 (sys._e021 sys._e022 sys._i165)\n" "var !sys.printstring sys._e020\n" "type sys._e025 {}\n" "type sys._e026 {}\n" "type sys._e027 *sys.uint8\n" - "type sys._i149 {_e148 sys._e027}\n" - "type sys._e024 (sys._e025 sys._e026 sys._i149)\n" + "type sys._i170 {_e169 sys._e027}\n" + "type sys._e024 (sys._e025 sys._e026 sys._i170)\n" "var !sys.printpointer sys._e024\n" "type sys._e029 {}\n" - "type sys._o156 {_e153 sys.string}\n" - "type sys._i158 {_e154 sys.string _e155 sys.string}\n" - "type sys._e028 (sys._e029 sys._o156 sys._i158)\n" + "type sys._o177 {_e174 sys.string}\n" + "type sys._i179 {_e175 sys.string _e176 sys.string}\n" + "type sys._e028 (sys._e029 sys._o177 sys._i179)\n" "var !sys.catstring sys._e028\n" "type sys._e031 {}\n" - "type sys._o166 {_e163 sys.int32}\n" - "type sys._i168 {_e164 sys.string _e165 sys.string}\n" - "type sys._e030 (sys._e031 sys._o166 sys._i168)\n" + "type sys._o187 {_e184 sys.int32}\n" + "type sys._i189 {_e185 sys.string _e186 sys.string}\n" + "type sys._e030 (sys._e031 sys._o187 sys._i189)\n" "var !sys.cmpstring sys._e030\n" "type sys._e033 {}\n" - "type sys._o177 {_e173 sys.string}\n" - "type sys._i179 {_e174 sys.string _e175 sys.int32 _e176 sys.int32}\n" - "type sys._e032 (sys._e033 sys._o177 sys._i179)\n" + "type sys._o198 {_e194 sys.string}\n" + "type sys._i200 {_e195 sys.string _e196 sys.int32 _e197 sys.int32}\n" + "type sys._e032 (sys._e033 sys._o198 sys._i200)\n" "var !sys.slicestring sys._e032\n" "type sys._e035 {}\n" - "type sys._o188 {_e185 sys.uint8}\n" - "type sys._i190 {_e186 sys.string _e187 sys.int32}\n" - "type sys._e034 (sys._e035 sys._o188 sys._i190)\n" + "type sys._o209 {_e206 sys.uint8}\n" + "type sys._i211 {_e207 sys.string _e208 sys.int32}\n" + "type sys._e034 (sys._e035 sys._o209 sys._i211)\n" "var !sys.indexstring sys._e034\n" "type sys._e037 {}\n" - "type sys._o197 {_e195 sys.string}\n" - "type sys._i199 {_e196 sys.int64}\n" - "type sys._e036 (sys._e037 sys._o197 sys._i199)\n" + "type sys._o218 {_e216 sys.string}\n" + "type sys._i220 {_e217 sys.int64}\n" + "type sys._e036 (sys._e037 sys._o218 sys._i220)\n" "var !sys.intstring sys._e036\n" "type sys._e039 {}\n" - "type sys._o206 {_e203 sys.string}\n" + "type sys._o227 {_e224 sys.string}\n" "type sys._e040 *sys.uint8\n" - "type sys._i208 {_e204 sys._e040 _e205 sys.int32}\n" - "type sys._e038 (sys._e039 sys._o206 sys._i208)\n" + "type sys._i229 {_e225 sys._e040 _e226 sys.int32}\n" + "type sys._e038 (sys._e039 sys._o227 sys._i229)\n" "var !sys.byteastring sys._e038\n" "type sys._e042 {}\n" "type sys._e043 <>\n" - "type sys._o217 {_e213 sys._e043}\n" + "type sys._o238 {_e234 sys._e043}\n" "type sys._e044 *sys.uint8\n" "type sys._e045 *sys.uint8\n" - "type sys._s224 {}\n" - "type sys._e046 *sys._s224\n" - "type sys._i219 {_e214 sys._e044 _e215 sys._e045 _e216 sys._e046}\n" - "type sys._e041 (sys._e042 sys._o217 sys._i219)\n" + "type sys._s245 {}\n" + "type sys._e046 *sys._s245\n" + "type sys._i240 {_e235 sys._e044 _e236 sys._e045 _e237 sys._e046}\n" + "type sys._e041 (sys._e042 sys._o238 sys._i240)\n" "var !sys.mkiface sys._e041\n" + "type sys._e048 {}\n" + "type sys._o251 {_e248 sys.int32 _e249 sys.float64}\n" + "type sys._i253 {_e250 sys.float64}\n" + "type sys._e047 (sys._e048 sys._o251 sys._i253)\n" + "var !sys.frexp sys._e047\n" + "type sys._e050 {}\n" + "type sys._o260 {_e257 sys.float64}\n" + "type sys._i262 {_e258 sys.int32 _e259 sys.float64}\n" + "type sys._e049 (sys._e050 sys._o260 sys._i262)\n" + "var !sys.ldexp sys._e049\n" + "type sys._e052 {}\n" + "type sys._o270 {_e267 sys.float64 _e268 sys.float64}\n" + "type sys._i272 {_e269 sys.float64}\n" + "type sys._e051 (sys._e052 sys._o270 sys._i272)\n" + "var !sys.modf sys._e051\n" "))\n" ; diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 1aeca1adeb..948b0a8973 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -161,9 +161,6 @@ loop: n->type = *getoutarg(t); if(t->outtuple == 1) n->type = n->type->type->type; - else - if(!top) - yyerror("function call must be single valued (%d)", t->outtuple); walktype(n->right, 0); @@ -173,12 +170,12 @@ loop: case OCALLINTER: l = ascompatte(n->op, getinarg(t), &n->right, 0); - n->right = reorder(l); + n->right = reorder1(l); break; case OCALL: l = ascompatte(n->op, getinarg(t), &n->right, 0); - n->right = reorder(l); + n->right = reorder1(l); break; case OCALLMETH: @@ -187,7 +184,7 @@ loop: r = ascompatte(n->op, getthis(t), &n->left->left, 0); if(l != N) r = nod(OLIST, r, l); - n->right = reorder(r); + n->right = reorder1(r); break; } goto ret; @@ -204,12 +201,12 @@ loop: goto ret; if(r->op == OCALL && l->op == OLIST) { - // botch callmulti - need to do more walktype(l, 0); walktype(r, 0); l = ascompatet(n->op, &n->left, &r->type, 0); - if(l != N && l->op == OAS) - *n = *reorder(l); + if(l != N) { + *n = *nod(OLIST, r, reorder2(l)); + } goto ret; } @@ -217,7 +214,7 @@ loop: walktype(r, 0); l = ascompatee(n->op, &n->left, &n->right); if(l != N) - *n = *reorder(l); + *n = *reorder3(l); goto ret; case OBREAK: @@ -296,7 +293,7 @@ loop: walktype(n->left, 0); l = ascompatte(n->op, getoutarg(curfn->type), &n->left, 1); if(l != N) - n->left = reorder(l); + n->left = reorder4(l); goto ret; case ONOT: @@ -561,6 +558,7 @@ loop: nottop: fatal("walktype: not top %O", n->op); + goto ret; badt: if(n->right == N) { @@ -701,13 +699,6 @@ lookdot(Node *n, Type *t, int d) Type *f, *r, *c; Sym *s; -//dowidth(t); -//print("\nlookdot %T\n", t); -//for(f=t->type; f!=T; f=f->down) { -//print(" %3ld", f->width); -//print(" %S\n", f->sym); -//} - r = T; s = n->sym; if(d > 0) @@ -822,17 +813,17 @@ walkdot(Node *n) } -/* - * check assign expression list to - * a expression list. called in - * expr-list = expr-list - */ Node* ascompatee(int op, Node **nl, Node **nr) { Node *l, *r, *nn, *a; Iter savel, saver; + /* + * check assign expression list to + * a expression list. called in + * expr-list = expr-list + */ l = listfirst(&savel, nl); r = listfirst(&saver, nr); nn = N; @@ -842,7 +833,7 @@ loop: if(l == N || r == N) { if(l != r) yyerror("error in shape across assignment"); - return nn; + return rev(nn); } convlit(r, l->type); @@ -856,18 +847,13 @@ loop: if(nn == N) nn = a; else - nn = nod(OLIST, nn, a); + nn = nod(OLIST, a, nn); l = listnext(&savel); r = listnext(&saver); goto loop; } -/* - * check assign type list to - * a expression list. called in - * expr-list = func() - */ Node* ascompatet(int op, Node **nl, Type **nr, int fp) { @@ -875,6 +861,11 @@ ascompatet(int op, Node **nl, Type **nr, int fp) Type *r; Iter savel, saver; + /* + * check assign type list to + * a expression list. called in + * expr-list = func() + */ l = listfirst(&savel, nl); r = structfirst(&saver, nr); nn = N; @@ -883,7 +874,7 @@ loop: if(l == N || r == T) { if(l != N || r != T) yyerror("error in shape across assignment"); - return nn; + return rev(nn); } if(!ascompat(l->type, r->type)) { @@ -896,7 +887,7 @@ loop: if(nn == N) nn = a; else - nn = nod(OLIST, nn, a); + nn = nod(OLIST, a, nn); l = listnext(&savel); r = structnext(&saver); @@ -904,12 +895,6 @@ loop: goto loop; } -/* - * check assign expression list to - * a type list. called in - * return expr-list - * func(expr-list) - */ Node* ascompatte(int op, Type **nl, Node **nr, int fp) { @@ -917,6 +902,12 @@ ascompatte(int op, Type **nl, Node **nr, int fp) Node *r, *nn, *a; Iter savel, saver; + /* + * check assign expression list to + * a type list. called in + * return expr-list + * func(expr-list) + */ l = structfirst(&savel, nl); r = listfirst(&saver, nr); nn = N; @@ -925,7 +916,7 @@ loop: if(l == T || r == N) { if(l != T || r != N) yyerror("error in shape across assignment"); - return nn; + return rev(nn); } convlit(r, l->type); @@ -939,7 +930,7 @@ loop: if(nn == N) nn = a; else - nn = nod(OLIST, nn, a); + nn = nod(OLIST, a, nn); l = structnext(&savel); r = listnext(&saver); @@ -1277,12 +1268,6 @@ ret: return n; } -Node* -reorder(Node *n) -{ - return n; -} - void arrayconv(Type *t, Node *n) { @@ -1310,3 +1295,125 @@ loop: l = listnext(&save); goto loop; } + +Node* +reorder1(Node *n) +{ + Iter save; + Node *l, *r, *f; + int c, t; + + /* + * from ascompat[te] + * evaluating actual function arguments. + * f(a,b) + * if there is exactly one function expr, + * then it is done first. otherwise must + * make temp variables + */ + + l = listfirst(&save, &n); + c = 0; // function calls + t = 0; // total parameters + +loop1: + if(l == N) { + if(c == 0 || t == 1) + return n; + if(c > 1) { + yyerror("reorder1: too many funcation calls evaluating parameters"); + return n; + } + goto pass2; + } + if(l->op == OLIST) + fatal("reorder1 OLIST"); + + t++; + if(l->ullman >= UINF) + c++; + l = listnext(&save); + goto loop1; + +pass2: + l = listfirst(&save, &n); + f = N; // isolated function call + r = N; // rest of them + +loop2: + if(l == N) { + if(r == N || f == N) + fatal("reorder1 not nil 1"); + r = nod(OLIST, f, r); + return rev(r); + } + if(l->ullman >= UINF) { + if(f != N) + fatal("reorder1 not nil 2"); + f = l; + } else + if(r == N) + r = l; + else + r = nod(OLIST, l, r); + + l = listnext(&save); + goto loop2; +} + +Node* +reorder2(Node *n) +{ + Iter save; + Node *l; + int c; + + /* + * from ascompat[et] + * a,b = f() + * return of a multi. + * there can be no function calls at all, + * or they will over-write the return values. + */ + + l = listfirst(&save, &n); + c = 0; + +loop1: + if(l == N) { + if(c > 0) + yyerror("reorder2: too many funcation calls evaluating parameters"); + return n; + } + if(l->op == OLIST) + fatal("reorder2 OLIST"); + + if(l->ullman >= UINF) + c++; + l = listnext(&save); + goto loop1; +} + +Node* +reorder3(Node *n) +{ + /* + * from ascompat[ee] + * a,b = c,d + * simultaneous assignment. there can be + * later use of an earlier lvalue. + */ + return n; +} + +Node* +reorder4(Node *n) +{ + /* + * from ascompat[te] + * return c,d + * return expression assigned to output + * parameters. there may be no problems. + */ + return n; +} diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index c99333ba7b..b4c4a6ce30 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -563,6 +563,160 @@ sys_ifacei2s(Sigs *ss, Map *m, void *s) } } +enum +{ + NANEXP = 2047<<20, + NANMASK = 2047<<20, + NANSIGN = 1<<31, +}; + +static uint64 uvnan = 0x7FF0000000000001; +static uint64 uvinf = 0x7FF0000000000000; +static uint64 uvneginf = 0xFFF0000000000000; + +static int32 +isInf(float64 d, int32 sign) +{ + uint64 x; + + x = *(uint64*)&d; + if(sign == 0) { + if(x == uvinf || x == uvneginf) + return 1; + return 0; + } + if(sign > 0) { + if(x == uvinf) + return 1; + return 0; + } + if(x == uvneginf) + return 1; + return 0; +} + +static float64 +NaN(void) +{ + return *(float64*)&uvnan; +} + +static int32 +isNaN(float64 d) +{ + uint64 x; + + x = *(uint64*)&d; + return ((uint32)x>>32)==0x7FF00000 && !isInf(d, 0); +} + +static float64 +Inf(int32 sign) +{ + if(sign < 0) + return *(float64*)&uvinf; + else + return *(float64*)&uvneginf; +} + +enum +{ + MASK = 0x7ffL, + SHIFT = 64-11-1, + BIAS = 1022L, +}; + +static float64 +frexp(float64 d, int32 *ep) +{ + uint64 x; + + if(d == 0) { + *ep = 0; + return 0; + } + x = *(uint64*)&d; + *ep = (int32)((x >> SHIFT) & MASK) - BIAS; + x &= ~((uint64)MASK << SHIFT); + x |= (uint64)BIAS << SHIFT; + return *(float64*)&x; +} + +static float64 +ldexp(float64 d, int32 e) +{ + uint64 x; + + if(d == 0) + return 0; + x = *(uint64*)&d; + e += (int32)(x >> SHIFT) & MASK; + if(e <= 0) + return 0; /* underflow */ + if(e >= MASK){ /* overflow */ + if(d < 0) + return Inf(-1); + return Inf(1); + } + x &= ~((uint64)MASK << SHIFT); + x |= (uint64)e << SHIFT; + return *(float64*)&x; +} + +static float64 +modf(float64 d, float64 *ip) +{ + float64 dd; + uint64 x; + int32 e; + + if(d < 1) { + if(d < 0) { + d = modf(-d, ip); + *ip = -*ip; + return -d; + } + *ip = 0; + return d; + } + + x = *(uint64*)&d; + e = (int32)((x >> SHIFT) & MASK) - BIAS; + + /* + * Keep the top 11+e bits; clear the rest. + */ + if(e <= 64-11) + x &= ~((uint64)1 << (64-11-e))-1; + dd = *(float64*)&x; + *ip = dd; + return d - dd; +} + +// func frexp(float64) (int32, float64); // break fp into exp,fract +void +sys_frexp(float64 din, int32 iou, float64 dou) +{ + dou = frexp(din, &iou); + FLUSH(&dou); +} + +//func ldexp(int32, float64) float64; // make fp from exp,fract +void +sys_ldexp(float64 din, int32 ein, float64 dou) +{ + dou = ldexp(din, ein); + FLUSH(&dou); +} + +//func modf(float64) (float64, float64); // break fp into double+double +float64 +sys_modf(float64 din, float64 dou1, float64 dou2) +{ + dou1 = modf(din, &dou2); + FLUSH(&dou2); +} + void check(void) { -- 2.48.1