github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/cmd/cc/funct.c (about) 1 // Inferno utils/cc/funct.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/cc/funct.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 #include <u.h> 32 #include "cc.h" 33 34 typedef struct Ftab Ftab; 35 struct Ftab 36 { 37 char op; 38 char* name; 39 char typ; 40 }; 41 typedef struct Gtab Gtab; 42 struct Gtab 43 { 44 char etype; 45 char* name; 46 }; 47 48 Ftab ftabinit[OEND]; 49 Gtab gtabinit[NALLTYPES]; 50 51 int 52 isfunct(Node *n) 53 { 54 Type *t, *t1; 55 Funct *f; 56 Node *l; 57 Sym *s; 58 int o; 59 60 o = n->op; 61 if(n->left == Z) 62 goto no; 63 t = n->left->type; 64 if(t == T) 65 goto no; 66 f = t->funct; 67 68 switch(o) { 69 case OAS: // put cast on rhs 70 case OASI: 71 case OASADD: 72 case OASAND: 73 case OASASHL: 74 case OASASHR: 75 case OASDIV: 76 case OASLDIV: 77 case OASLMOD: 78 case OASLMUL: 79 case OASLSHR: 80 case OASMOD: 81 case OASMUL: 82 case OASOR: 83 case OASSUB: 84 case OASXOR: 85 if(n->right == Z) 86 goto no; 87 t1 = n->right->type; 88 if(t1 == T) 89 goto no; 90 if(t1->funct == f) 91 break; 92 93 l = new(OXXX, Z, Z); 94 *l = *n->right; 95 96 n->right->left = l; 97 n->right->right = Z; 98 n->right->type = t; 99 n->right->op = OCAST; 100 101 if(!isfunct(n->right)) 102 prtree(n, "isfunc !"); 103 break; 104 105 case OCAST: // t f(T) or T f(t) 106 t1 = n->type; 107 if(t1 == T) 108 goto no; 109 if(f != nil) { 110 s = f->castfr[t1->etype]; 111 if(s == S) 112 goto no; 113 n->right = n->left; 114 goto build; 115 } 116 f = t1->funct; 117 if(f != nil) { 118 s = f->castto[t->etype]; 119 if(s == S) 120 goto no; 121 n->right = n->left; 122 goto build; 123 } 124 goto no; 125 } 126 127 if(f == nil) 128 goto no; 129 s = f->sym[o]; 130 if(s == S) 131 goto no; 132 133 /* 134 * the answer is yes, 135 * now we rewrite the node 136 * and give diagnostics 137 */ 138 switch(o) { 139 default: 140 diag(n, "isfunct op missing %O\n", o); 141 goto bad; 142 143 case OADD: // T f(T, T) 144 case OAND: 145 case OASHL: 146 case OASHR: 147 case ODIV: 148 case OLDIV: 149 case OLMOD: 150 case OLMUL: 151 case OLSHR: 152 case OMOD: 153 case OMUL: 154 case OOR: 155 case OSUB: 156 case OXOR: 157 158 case OEQ: // int f(T, T) 159 case OGE: 160 case OGT: 161 case OHI: 162 case OHS: 163 case OLE: 164 case OLO: 165 case OLS: 166 case OLT: 167 case ONE: 168 if(n->right == Z) 169 goto bad; 170 t1 = n->right->type; 171 if(t1 == T) 172 goto bad; 173 if(t1->funct != f) 174 goto bad; 175 n->right = new(OLIST, n->left, n->right); 176 break; 177 178 case OAS: // structure copies done by the compiler 179 case OASI: 180 goto no; 181 182 case OASADD: // T f(T*, T) 183 case OASAND: 184 case OASASHL: 185 case OASASHR: 186 case OASDIV: 187 case OASLDIV: 188 case OASLMOD: 189 case OASLMUL: 190 case OASLSHR: 191 case OASMOD: 192 case OASMUL: 193 case OASOR: 194 case OASSUB: 195 case OASXOR: 196 if(n->right == Z) 197 goto bad; 198 t1 = n->right->type; 199 if(t1 == T) 200 goto bad; 201 if(t1->funct != f) 202 goto bad; 203 n->right = new(OLIST, new(OADDR, n->left, Z), n->right); 204 break; 205 206 case OPOS: // T f(T) 207 case ONEG: 208 case ONOT: 209 case OCOM: 210 n->right = n->left; 211 break; 212 213 214 } 215 216 build: 217 l = new(ONAME, Z, Z); 218 l->sym = s; 219 l->type = s->type; 220 l->etype = s->type->etype; 221 l->xoffset = s->offset; 222 l->class = s->class; 223 tcomo(l, 0); 224 225 n->op = OFUNC; 226 n->left = l; 227 n->type = l->type->link; 228 if(tcompat(n, T, l->type, tfunct)) 229 goto bad; 230 if(tcoma(n->left, n->right, l->type->down, 1)) 231 goto bad; 232 return 1; 233 234 no: 235 return 0; 236 237 bad: 238 diag(n, "can't rewrite typestr for op %O\n", o); 239 prtree(n, "isfunct"); 240 n->type = T; 241 return 1; 242 } 243 244 void 245 dclfunct(Type *t, Sym *s) 246 { 247 Funct *f; 248 Node *n; 249 Type *f1, *f2, *f3, *f4; 250 int o, i, c; 251 char str[100]; 252 253 if(t->funct) 254 return; 255 256 // recognize generated tag of dorm _%d_ 257 if(t->tag == S) 258 goto bad; 259 for(i=0; c = t->tag->name[i]; i++) { 260 if(c == '_') { 261 if(i == 0 || t->tag->name[i+1] == 0) 262 continue; 263 break; 264 } 265 if(c < '0' || c > '9') 266 break; 267 } 268 if(c == 0) 269 goto bad; 270 271 f = alloc(sizeof(*f)); 272 for(o=0; o<nelem(f->sym); o++) 273 f->sym[o] = S; 274 275 t->funct = f; 276 277 f1 = typ(TFUNC, t); 278 f1->down = copytyp(t); 279 f1->down->down = t; 280 281 f2 = typ(TFUNC, types[TINT]); 282 f2->down = copytyp(t); 283 f2->down->down = t; 284 285 f3 = typ(TFUNC, t); 286 f3->down = typ(TIND, t); 287 f3->down->down = t; 288 289 f4 = typ(TFUNC, t); 290 f4->down = t; 291 292 for(i=0;; i++) { 293 o = ftabinit[i].op; 294 if(o == OXXX) 295 break; 296 sprint(str, "%s_%s_", t->tag->name, ftabinit[i].name); 297 n = new(ONAME, Z, Z); 298 n->sym = slookup(str); 299 f->sym[o] = n->sym; 300 switch(ftabinit[i].typ) { 301 default: 302 diag(Z, "dclfunct op missing %d\n", ftabinit[i].typ); 303 break; 304 305 case 1: // T f(T,T) + 306 dodecl(xdecl, CEXTERN, f1, n); 307 break; 308 309 case 2: // int f(T,T) == 310 dodecl(xdecl, CEXTERN, f2, n); 311 break; 312 313 case 3: // void f(T*,T) += 314 dodecl(xdecl, CEXTERN, f3, n); 315 break; 316 317 case 4: // T f(T) ~ 318 dodecl(xdecl, CEXTERN, f4, n); 319 break; 320 } 321 } 322 for(i=0;; i++) { 323 o = gtabinit[i].etype; 324 if(o == TXXX) 325 break; 326 327 /* 328 * OCAST types T1 _T2_T1_(T2) 329 */ 330 sprint(str, "_%s%s_", gtabinit[i].name, t->tag->name); 331 n = new(ONAME, Z, Z); 332 n->sym = slookup(str); 333 f->castto[o] = n->sym; 334 335 f1 = typ(TFUNC, t); 336 f1->down = types[o]; 337 dodecl(xdecl, CEXTERN, f1, n); 338 339 sprint(str, "%s_%s_", t->tag->name, gtabinit[i].name); 340 n = new(ONAME, Z, Z); 341 n->sym = slookup(str); 342 f->castfr[o] = n->sym; 343 344 f1 = typ(TFUNC, types[o]); 345 f1->down = t; 346 dodecl(xdecl, CEXTERN, f1, n); 347 } 348 return; 349 bad: 350 diag(Z, "dclfunct bad %T %s\n", t, s->name); 351 } 352 353 Gtab gtabinit[NALLTYPES] = 354 { 355 TCHAR, "c", 356 TUCHAR, "uc", 357 TSHORT, "h", 358 TUSHORT, "uh", 359 TINT, "i", 360 TUINT, "ui", 361 TLONG, "l", 362 TULONG, "ul", 363 TVLONG, "v", 364 TUVLONG, "uv", 365 TFLOAT, "f", 366 TDOUBLE, "d", 367 TXXX 368 }; 369 370 Ftab ftabinit[OEND] = 371 { 372 OADD, "add", 1, 373 OAND, "and", 1, 374 OASHL, "ashl", 1, 375 OASHR, "ashr", 1, 376 ODIV, "div", 1, 377 OLDIV, "ldiv", 1, 378 OLMOD, "lmod", 1, 379 OLMUL, "lmul", 1, 380 OLSHR, "lshr", 1, 381 OMOD, "mod", 1, 382 OMUL, "mul", 1, 383 OOR, "or", 1, 384 OSUB, "sub", 1, 385 OXOR, "xor", 1, 386 387 OEQ, "eq", 2, 388 OGE, "ge", 2, 389 OGT, "gt", 2, 390 OHI, "hi", 2, 391 OHS, "hs", 2, 392 OLE, "le", 2, 393 OLO, "lo", 2, 394 OLS, "ls", 2, 395 OLT, "lt", 2, 396 ONE, "ne", 2, 397 398 OASADD, "asadd", 3, 399 OASAND, "asand", 3, 400 OASASHL, "asashl", 3, 401 OASASHR, "asashr", 3, 402 OASDIV, "asdiv", 3, 403 OASLDIV, "asldiv", 3, 404 OASLMOD, "aslmod", 3, 405 OASLMUL, "aslmul", 3, 406 OASLSHR, "aslshr", 3, 407 OASMOD, "asmod", 3, 408 OASMUL, "asmul", 3, 409 OASOR, "asor", 3, 410 OASSUB, "assub", 3, 411 OASXOR, "asxor", 3, 412 413 OPOS, "pos", 4, 414 ONEG, "neg", 4, 415 OCOM, "com", 4, 416 ONOT, "not", 4, 417 418 // OPOSTDEC, 419 // OPOSTINC, 420 // OPREDEC, 421 // OPREINC, 422 423 OXXX, 424 }; 425 426 // Node* nodtestv; 427 428 // Node* nodvpp; 429 // Node* nodppv; 430 // Node* nodvmm; 431 // Node* nodmmv;