1 #include "cc.h" 2 3 typedef struct Ftab Ftab; 4 struct Ftab 5 { 6 char op; 7 char* name; 8 char typ; 9 }; 10 typedef struct Gtab Gtab; 11 struct Gtab 12 { 13 char etype; 14 char* name; 15 }; 16 17 Ftab ftabinit[OEND]; 18 Gtab gtabinit[NTYPE]; 19 20 int 21 isfunct(Node *n) 22 { 23 Type *t, *t1; 24 Funct *f; 25 Node *l; 26 Sym *s; 27 int o; 28 29 o = n->op; 30 if(n->left == Z) 31 goto no; 32 t = n->left->type; 33 if(t == T) 34 goto no; 35 f = t->funct; 36 37 switch(o) { 38 case OAS: // put cast on rhs 39 case OASI: 40 case OASADD: 41 case OASAND: 42 case OASASHL: 43 case OASASHR: 44 case OASDIV: 45 case OASLDIV: 46 case OASLMOD: 47 case OASLMUL: 48 case OASLSHR: 49 case OASMOD: 50 case OASMUL: 51 case OASOR: 52 case OASSUB: 53 case OASXOR: 54 if(n->right == Z) 55 goto no; 56 t1 = n->right->type; 57 if(t1 == T) 58 goto no; 59 if(t1->funct == f) 60 break; 61 62 l = new(OXXX, Z, Z); 63 *l = *n->right; 64 65 n->right->left = l; 66 n->right->right = Z; 67 n->right->type = t; 68 n->right->op = OCAST; 69 70 if(!isfunct(n->right)) 71 prtree(n, "isfunc !"); 72 break; 73 74 case OCAST: // t f(T) or T f(t) 75 t1 = n->type; 76 if(t1 == T) 77 goto no; 78 if(f != nil) { 79 s = f->castfr[t1->etype]; 80 if(s == S) 81 goto no; 82 n->right = n->left; 83 goto build; 84 } 85 f = t1->funct; 86 if(f != nil) { 87 s = f->castto[t->etype]; 88 if(s == S) 89 goto no; 90 n->right = n->left; 91 goto build; 92 } 93 goto no; 94 } 95 96 if(f == nil) 97 goto no; 98 s = f->sym[o]; 99 if(s == S) 100 goto no; 101 102 /* 103 * the answer is yes, 104 * now we rewrite the node 105 * and give diagnostics 106 */ 107 switch(o) { 108 default: 109 diag(n, "isfunct op missing %O\n", o); 110 goto bad; 111 112 case OADD: // T f(T, T) 113 case OAND: 114 case OASHL: 115 case OASHR: 116 case ODIV: 117 case OLDIV: 118 case OLMOD: 119 case OLMUL: 120 case OLSHR: 121 case OMOD: 122 case OMUL: 123 case OOR: 124 case OSUB: 125 case OXOR: 126 127 case OEQ: // int f(T, T) 128 case OGE: 129 case OGT: 130 case OHI: 131 case OHS: 132 case OLE: 133 case OLO: 134 case OLS: 135 case OLT: 136 case ONE: 137 if(n->right == Z) 138 goto bad; 139 t1 = n->right->type; 140 if(t1 == T) 141 goto bad; 142 if(t1->funct != f) 143 goto bad; 144 n->right = new(OLIST, n->left, n->right); 145 break; 146 147 case OAS: // structure copies done by the compiler 148 case OASI: 149 goto no; 150 151 case OASADD: // T f(T*, T) 152 case OASAND: 153 case OASASHL: 154 case OASASHR: 155 case OASDIV: 156 case OASLDIV: 157 case OASLMOD: 158 case OASLMUL: 159 case OASLSHR: 160 case OASMOD: 161 case OASMUL: 162 case OASOR: 163 case OASSUB: 164 case OASXOR: 165 if(n->right == Z) 166 goto bad; 167 t1 = n->right->type; 168 if(t1 == T) 169 goto bad; 170 if(t1->funct != f) 171 goto bad; 172 n->right = new(OLIST, new(OADDR, n->left, Z), n->right); 173 break; 174 175 case OPOS: // T f(T) 176 case ONEG: 177 case ONOT: 178 case OCOM: 179 n->right = n->left; 180 break; 181 182 183 } 184 185 build: 186 l = new(ONAME, Z, Z); 187 l->sym = s; 188 l->type = s->type; 189 l->etype = s->type->etype; 190 l->xoffset = s->offset; 191 l->class = s->class; 192 tcomo(l, 0); 193 194 n->op = OFUNC; 195 n->left = l; 196 n->type = l->type->link; 197 if(tcompat(n, T, l->type, tfunct)) 198 goto bad; 199 if(tcoma(n->left, n->right, l->type->down, 1)) 200 goto bad; 201 return 1; 202 203 no: 204 return 0; 205 206 bad: 207 diag(n, "cant rewrite typestr for op %O\n", o); 208 prtree(n, "isfunct"); 209 n->type = T; 210 return 1; 211 } 212 213 void 214 dclfunct(Type *t, Sym *s) 215 { 216 Funct *f; 217 Node *n; 218 Type *f1, *f2, *f3, *f4; 219 int o, i, c; 220 char str[100]; 221 222 if(t->funct) 223 return; 224 225 // recognize generated tag of dorm _%d_ 226 if(t->tag == S) 227 goto bad; 228 for(i=0; c = t->tag->name[i]; i++) { 229 if(c == '_') { 230 if(i == 0 || t->tag->name[i+1] == 0) 231 continue; 232 break; 233 } 234 if(c < '0' || c > '9') 235 break; 236 } 237 if(c == 0) 238 goto bad; 239 240 f = alloc(sizeof(*f)); 241 for(o=0; o<nelem(f->sym); o++) 242 f->sym[o] = S; 243 244 t->funct = f; 245 246 f1 = typ(TFUNC, t); 247 f1->down = copytyp(t); 248 f1->down->down = t; 249 250 f2 = typ(TFUNC, types[TINT]); 251 f2->down = copytyp(t); 252 f2->down->down = t; 253 254 f3 = typ(TFUNC, t); 255 f3->down = typ(TIND, t); 256 f3->down->down = t; 257 258 f4 = typ(TFUNC, t); 259 f4->down = t; 260 261 for(i=0;; i++) { 262 o = ftabinit[i].op; 263 if(o == OXXX) 264 break; 265 sprint(str, "%s_%s_", t->tag->name, ftabinit[i].name); 266 n = new(ONAME, Z, Z); 267 n->sym = slookup(str); 268 f->sym[o] = n->sym; 269 switch(ftabinit[i].typ) { 270 default: 271 diag(Z, "dclfunct op missing %d\n", ftabinit[i].typ); 272 break; 273 274 case 1: // T f(T,T) + 275 dodecl(xdecl, CEXTERN, f1, n); 276 break; 277 278 case 2: // int f(T,T) == 279 dodecl(xdecl, CEXTERN, f2, n); 280 break; 281 282 case 3: // void f(T*,T) += 283 dodecl(xdecl, CEXTERN, f3, n); 284 break; 285 286 case 4: // T f(T) ~ 287 dodecl(xdecl, CEXTERN, f4, n); 288 break; 289 } 290 } 291 for(i=0;; i++) { 292 o = gtabinit[i].etype; 293 if(o == TXXX) 294 break; 295 296 /* 297 * OCAST types T1 _T2_T1_(T2) 298 */ 299 sprint(str, "_%s%s_", gtabinit[i].name, t->tag->name); 300 n = new(ONAME, Z, Z); 301 n->sym = slookup(str); 302 f->castto[o] = n->sym; 303 304 f1 = typ(TFUNC, t); 305 f1->down = types[o]; 306 dodecl(xdecl, CEXTERN, f1, n); 307 308 sprint(str, "%s_%s_", t->tag->name, gtabinit[i].name); 309 n = new(ONAME, Z, Z); 310 n->sym = slookup(str); 311 f->castfr[o] = n->sym; 312 313 f1 = typ(TFUNC, types[o]); 314 f1->down = t; 315 dodecl(xdecl, CEXTERN, f1, n); 316 } 317 return; 318 bad: 319 diag(Z, "dclfunct bad %T %s\n", t, s->name); 320 } 321 322 Gtab gtabinit[NTYPE] = 323 { 324 TCHAR, "c", 325 TUCHAR, "uc", 326 TSHORT, "h", 327 TUSHORT, "uh", 328 TINT, "i", 329 TUINT, "ui", 330 TLONG, "l", 331 TULONG, "ul", 332 TVLONG, "v", 333 TUVLONG, "uv", 334 TFLOAT, "f", 335 TDOUBLE, "d", 336 TXXX 337 }; 338 339 Ftab ftabinit[OEND] = 340 { 341 OADD, "add", 1, 342 OAND, "and", 1, 343 OASHL, "ashl", 1, 344 OASHR, "ashr", 1, 345 ODIV, "div", 1, 346 OLDIV, "ldiv", 1, 347 OLMOD, "lmod", 1, 348 OLMUL, "lmul", 1, 349 OLSHR, "lshr", 1, 350 OMOD, "mod", 1, 351 OMUL, "mul", 1, 352 OOR, "or", 1, 353 OSUB, "sub", 1, 354 OXOR, "xor", 1, 355 356 OEQ, "eq", 2, 357 OGE, "ge", 2, 358 OGT, "gt", 2, 359 OHI, "hi", 2, 360 OHS, "hs", 2, 361 OLE, "le", 2, 362 OLO, "lo", 2, 363 OLS, "ls", 2, 364 OLT, "lt", 2, 365 ONE, "ne", 2, 366 367 OASADD, "asadd", 3, 368 OASAND, "asand", 3, 369 OASASHL, "asashl", 3, 370 OASASHR, "asashr", 3, 371 OASDIV, "asdiv", 3, 372 OASLDIV, "asldiv", 3, 373 OASLMOD, "aslmod", 3, 374 OASLMUL, "aslmul", 3, 375 OASLSHR, "aslshr", 3, 376 OASMOD, "asmod", 3, 377 OASMUL, "asmul", 3, 378 OASOR, "asor", 3, 379 OASSUB, "assub", 3, 380 OASXOR, "asxor", 3, 381 382 OPOS, "pos", 4, 383 ONEG, "neg", 4, 384 OCOM, "com", 4, 385 ONOT, "not", 4, 386 387 // OPOSTDEC, 388 // OPOSTINC, 389 // OPREDEC, 390 // OPREINC, 391 392 OXXX, 393 }; 394 395 // Node* nodtestv; 396 397 // Node* nodvpp; 398 // Node* nodppv; 399 // Node* nodvmm; 400 // Node* nodmmv; 401