1 #include "lib9.h" 2 #include "bio.h" 3 #include "isa.h" 4 #include "mathi.h" 5 6 /* internal dis ops */ 7 #define IEXC MAXDIS 8 #define IEXC0 (MAXDIS+1) 9 #define INOOP (MAXDIS+2) 10 11 /* temporary */ 12 #define LDT 1 13 14 #ifndef Extern 15 #define Extern extern 16 #endif 17 18 #define YYMAXDEPTH 200 19 20 typedef struct Addr Addr; 21 typedef struct Case Case; 22 typedef struct Decl Decl; 23 typedef struct Desc Desc; 24 typedef struct Dlist Dlist; 25 typedef struct Except Except; 26 typedef struct File File; 27 typedef struct Fline Fline; 28 typedef struct Inst Inst; 29 typedef struct Label Label; 30 typedef struct Line Line; 31 typedef struct Node Node; 32 typedef struct Ok Ok; 33 typedef struct Src Src; 34 typedef struct Sym Sym; 35 typedef struct Szal Szal; 36 typedef struct Tattr Tattr; 37 typedef struct Teq Teq; 38 typedef struct Tpair Tpair; 39 typedef struct Type Type; 40 typedef struct Typelist Typelist; 41 42 typedef double Real; 43 typedef vlong Long; 44 45 enum 46 { 47 STemp = NREG * IBY2WD, 48 RTemp = STemp+IBY2WD, 49 DTemp = RTemp+IBY2WD, 50 MaxTemp = DTemp+IBY2WD, 51 MaxReg = 1<<16, 52 MaxAlign = IBY2LG, 53 StrSize = 256, 54 NumSize = 32, /* max length of printed */ 55 MaxIncPath = 32, /* max directories in include path */ 56 MaxScope = 64, /* max nested {} */ 57 MaxInclude = 32, /* max nested include "" */ 58 ScopeBuiltin = 0, 59 ScopeNils = 1, 60 ScopeGlobal = 2 61 }; 62 63 /* 64 * return tuple from expression type checking 65 */ 66 struct Ok 67 { 68 int ok; 69 int allok; 70 }; 71 72 /* 73 * return tuple from type sizing 74 */ 75 struct Szal 76 { 77 int size; 78 int align; 79 }; 80 81 /* 82 * return tuple for file/line numbering 83 */ 84 struct Fline 85 { 86 File *file; 87 int line; 88 }; 89 90 struct File 91 { 92 char *name; 93 int abs; /* absolute line of start of the part of file */ 94 int off; /* offset to line in the file */ 95 int in; /* absolute line where included */ 96 char *act; /* name of real file with #line fake file */ 97 int actoff; /* offset from fake line to real line */ 98 int sbl; /* symbol file number */ 99 }; 100 101 struct Line 102 { 103 int line; 104 int pos; /* character within the line */ 105 }; 106 107 struct Src 108 { 109 Line start; 110 Line stop; 111 }; 112 113 enum 114 { 115 Aimm, /* immediate */ 116 Amp, /* global */ 117 Ampind, /* global indirect */ 118 Afp, /* activation frame */ 119 Afpind, /* frame indirect */ 120 Apc, /* branch */ 121 Adesc, /* type descriptor immediate */ 122 Aoff, /* offset in module description table */ 123 Anoff, /* above encoded as -ve */ 124 Aerr, /* error */ 125 Anone, /* no operand */ 126 Aldt, /* linkage descriptor table immediate */ 127 Aend 128 }; 129 130 struct Addr 131 { 132 long reg; 133 long offset; 134 Decl *decl; 135 }; 136 137 struct Inst 138 { 139 Src src; 140 ushort op; 141 long pc; 142 uchar reach; /* could a control path reach this instruction? */ 143 uchar sm; /* operand addressing modes */ 144 uchar mm; 145 uchar dm; 146 Addr s; /* operands */ 147 Addr m; 148 Addr d; 149 Inst *branch; /* branch destination */ 150 Inst *next; 151 int block; /* blocks nested inside */ 152 }; 153 154 struct Case 155 { 156 int nlab; 157 int nsnd; 158 long offset; /* offset in mp */ 159 Label *labs; 160 Node *wild; /* if nothing matches */ 161 Inst *iwild; 162 }; 163 164 struct Label 165 { 166 Node *node; 167 char isptr; /* true if the labelled alt channel is a pointer */ 168 Node *start; /* value in range [start, stop) => code */ 169 Node *stop; 170 Inst *inst; 171 }; 172 173 enum 174 { 175 Dtype, 176 Dfn, 177 Dglobal, 178 Darg, 179 Dlocal, 180 Dconst, 181 Dfield, 182 Dtag, /* pick tags */ 183 Dimport, /* imported identifier */ 184 Dunbound, /* unbound identified */ 185 Dundef, 186 Dwundef, /* undefined, but don't whine */ 187 188 Dend 189 }; 190 191 struct Decl 192 { 193 Src src; /* where declaration */ 194 Sym *sym; 195 uchar store; /* storage class */ 196 uchar nid; /* block grouping for locals */ 197 schar caninline; /* inline function */ 198 uchar das; /* declared with := */ 199 Decl *dot; /* parent adt or module */ 200 Type *ty; 201 int refs; /* number of references */ 202 long offset; 203 int tag; /* union tag */ 204 205 uchar scope; /* in which it was declared */ 206 uchar handler; /* fn has exception handler in body */ 207 Decl *next; /* list in same scope, field or argument list, etc. */ 208 Decl *old; /* declaration of the symbol in enclosing scope */ 209 210 Node *eimport; /* expr from which imported */ 211 Decl *importid; /* identifier imported */ 212 Decl *timport; /* stack of identifiers importing a type */ 213 214 Node *init; /* data initialization */ 215 int tref; /* 1 => is a tmp; >=2 => tmp in use */ 216 char cycle; /* can create a cycle */ 217 char cyc; /* so labelled in source */ 218 char cycerr; /* delivered an error message for cycle? */ 219 char implicit; /* implicit first argument in an adt? */ 220 221 Decl *iface; /* used external declarations in a module */ 222 223 Decl *locals; /* locals for a function */ 224 Decl *link; /* pointer to parent function or function argument or local share or parent type dec */ 225 Inst *pc; /* start of function */ 226 /* Inst *endpc; */ /* limit of function - unused */ 227 228 Desc *desc; /* heap descriptor */ 229 }; 230 231 struct Desc 232 { 233 int id; /* dis type identifier */ 234 uchar used; /* actually used in output? */ 235 uchar *map; /* byte map of pointers */ 236 long size; /* length of the object */ 237 long nmap; /* length of good bytes in map */ 238 Desc *next; 239 }; 240 241 struct Dlist 242 { 243 Decl *d; 244 Dlist *next; 245 }; 246 247 struct Except 248 { 249 Inst *p1; /* first pc covered */ 250 Inst *p2; /* last pc not covered */ 251 Case *c; /* exception case instructions */ 252 Decl *d; /* exception definition if any */ 253 Node *zn; /* list of nodes to zero in handler */ 254 Desc *desc; /* descriptor map for above */ 255 int ne; /* number of exceptions (ie not strings) in case */ 256 Except *next; 257 }; 258 259 struct Sym 260 { 261 ushort token; 262 char *name; 263 int len; 264 int hash; 265 Sym *next; 266 Decl *decl; 267 Decl *unbound; /* place holder for unbound symbols */ 268 }; 269 270 /* 271 * ops for nodes 272 */ 273 enum 274 { 275 Oadd = 1, 276 Oaddas, 277 Oadr, 278 Oadtdecl, 279 Oalt, 280 Oand, 281 Oandand, 282 Oandas, 283 Oarray, 284 Oas, 285 Obreak, 286 Ocall, 287 Ocase, 288 Ocast, 289 Ochan, 290 Ocomma, 291 Ocomp, 292 Ocondecl, 293 Ocons, 294 Oconst, 295 Ocont, 296 Odas, 297 Odec, 298 Odiv, 299 Odivas, 300 Odo, 301 Odot, 302 Oelem, 303 Oeq, 304 Oexcept, 305 Oexdecl, 306 Oexit, 307 Oexp, 308 Oexpas, 309 Oexstmt, 310 Ofielddecl, 311 Ofnptr, 312 Ofor, 313 Ofunc, 314 Ogeq, 315 Ogt, 316 Ohd, 317 Oif, 318 Oimport, 319 Oinc, 320 Oind, 321 Oindex, 322 Oinds, 323 Oindx, 324 Oinv, 325 Ojmp, 326 Olabel, 327 Olen, 328 Oleq, 329 Oload, 330 Olsh, 331 Olshas, 332 Olt, 333 Omdot, 334 Omod, 335 Omodas, 336 Omoddecl, 337 Omul, 338 Omulas, 339 Oname, 340 Oneg, 341 Oneq, 342 Onot, 343 Onothing, 344 Oor, 345 Ooras, 346 Ooror, 347 Opick, 348 Opickdecl, 349 Opredec, 350 Opreinc, 351 Oraise, 352 Orange, 353 Orcv, 354 Oref, 355 Oret, 356 Orsh, 357 Orshas, 358 Oscope, 359 Oself, 360 Oseq, 361 Oslice, 362 Osnd, 363 Ospawn, 364 Osub, 365 Osubas, 366 Otagof, 367 Otl, 368 Otuple, 369 Otype, 370 Otypedecl, 371 Oused, 372 Ovardecl, 373 Ovardecli, 374 Owild, 375 Oxor, 376 Oxoras, 377 378 Oend 379 }; 380 381 /* 382 * moves 383 */ 384 enum 385 { 386 Mas, 387 Mcons, 388 Mhd, 389 Mtl, 390 391 Mend 392 }; 393 394 /* 395 * addressability 396 */ 397 enum 398 { 399 Rreg, /* v(fp) */ 400 Rmreg, /* v(mp) */ 401 Roff, /* $v */ 402 Rnoff, /* $v encoded as -ve */ 403 Rdesc, /* $v */ 404 Rdescp, /* $v */ 405 Rconst, /* $v */ 406 Ralways, /* preceeding are always addressable */ 407 Radr, /* v(v(fp)) */ 408 Rmadr, /* v(v(mp)) */ 409 Rcant, /* following are not quite addressable */ 410 Rpc, /* branch address */ 411 Rmpc, /* cross module branch address */ 412 Rareg, /* $v(fp) */ 413 Ramreg, /* $v(mp) */ 414 Raadr, /* $v(v(fp)) */ 415 Ramadr, /* $v(v(mp)) */ 416 Rldt, /* $v */ 417 418 Rend 419 }; 420 421 #define PARENS 1 422 #define TEMP 2 423 #define FNPTRA 4 /* argument */ 424 #define FNPTR2 8 /* 2nd parameter */ 425 #define FNPTRN 16 /* use -ve offset */ 426 #define FNPTR (FNPTRA|FNPTR2|FNPTRN) 427 428 struct Node 429 { 430 Src src; 431 uchar op; 432 uchar addable; 433 uchar flags; 434 uchar temps; 435 Node *left; 436 Node *right; 437 Type *ty; 438 Decl *decl; 439 Long val; /* for Oconst */ 440 Real rval; /* for Oconst */ 441 }; 442 443 enum 444 { 445 /* 446 * types visible to limbo 447 */ 448 Tnone = 0, 449 Tadt, 450 Tadtpick, /* pick case of an adt */ 451 Tarray, 452 Tbig, /* 64 bit int */ 453 Tbyte, /* 8 bit unsigned int */ 454 Tchan, 455 Treal, 456 Tfn, 457 Tint, /* 32 bit int */ 458 Tlist, 459 Tmodule, 460 Tref, 461 Tstring, 462 Ttuple, 463 Texception, 464 Tfix, 465 Tpoly, 466 467 /* 468 * internal use types 469 */ 470 Tainit, /* array initializers */ 471 Talt, /* alt channels */ 472 Tany, /* type of nil */ 473 Tarrow, /* unresolved ty->id types */ 474 Tcase, /* case labels */ 475 Tcasel, /* case big labels */ 476 Tcasec, /* case string labels */ 477 Tdot, /* unresolved ty.id types */ 478 Terror, 479 Tgoto, /* goto labels */ 480 Tid, /* id with unknown type */ 481 Tiface, /* module interface */ 482 Texcept, /* exception handler tables */ 483 Tinst, /* instantiated adt */ 484 485 Tend 486 }; 487 488 enum 489 { 490 OKbind = 1 << 0, /* type decls are bound */ 491 OKverify = 1 << 1, /* type looks ok */ 492 OKsized = 1 << 2, /* started figuring size */ 493 OKref = 1 << 3, /* recorded use of type */ 494 OKclass = 1 << 4, /* equivalence class found */ 495 OKcyc = 1 << 5, /* checked for cycles */ 496 OKcycsize = 1 << 6, /* checked for cycles and size */ 497 OKmodref = 1 << 7, /* started checking for a module handle */ 498 499 OKmask = 0xff, 500 501 /* 502 * recursive marks 503 */ 504 TReq = 1 << 0, 505 TRcom = 1 << 1, 506 TRcyc = 1 << 2, 507 TRvis = 1 << 3, 508 }; 509 510 /* type flags */ 511 #define FULLARGS 1 /* all hidden args added */ 512 #define INST 2 /* instantiated adt */ 513 #define CYCLIC 4 /* cyclic type */ 514 #define POLY 8 /* polymorphic types inside */ 515 #define NOPOLY 16 /* no polymorphic types inside */ 516 517 struct Type 518 { 519 Src src; 520 uchar kind; 521 uchar varargs; /* if a function, ends with vargs? */ 522 uchar ok; /* set when type is verified */ 523 uchar linkall; /* put all iface fns in external linkage? */ 524 uchar rec; /* in the middle of recursive type */ 525 uchar cons; /* exception constant */ 526 uchar align; /* alignment in bytes */ 527 uchar flags; 528 int sbl; /* slot in .sbl adt table */ 529 long sig; /* signature for dynamic type check */ 530 long size; /* storage required, in bytes */ 531 Decl *decl; 532 Type *tof; 533 Decl *ids; 534 Decl *tags; /* tagged fields in an adt */ 535 Decl *polys; /* polymorphic fields in fn or adt */ 536 Case *cse; /* case or goto labels */ 537 Type *teq; /* temporary equiv class for equiv checking */ 538 Type *tcom; /* temporary equiv class for compat checking */ 539 Teq *eq; /* real equiv class */ 540 Node *val; /* for Tfix, Tfn, Tadt only */ 541 union { 542 Node *eraises; /* for Tfn only */ 543 Typelist *tlist; /* for Tinst only */ 544 Tpair *tmap; /* for Tadt only */ 545 } u; 546 }; 547 548 /* 549 * type equivalence classes 550 */ 551 struct Teq 552 { 553 int id; /* for signing */ 554 Type *ty; /* an instance of the class */ 555 Teq *eq; /* used to link eq sets */ 556 }; 557 558 struct Tattr 559 { 560 char isptr; 561 char refable; 562 char conable; 563 char big; 564 char vis; /* type visible to users */ 565 }; 566 567 enum { 568 Sother, 569 Sloop, 570 Sscope 571 }; 572 573 struct Tpair 574 { 575 Type *t1; 576 Type *t2; 577 Tpair *nxt; 578 }; 579 580 struct Typelist 581 { 582 Type *t; 583 Typelist *nxt; 584 }; 585 586 Extern Decl **adts; 587 Extern Sym *anontupsym; /* name assigned to all anonymouse tuples */ 588 Extern int arrayz; 589 Extern int asmsym; /* generate symbols in assembly language? */ 590 Extern Biobuf *bins[MaxInclude]; 591 Extern int blocks; 592 Extern Biobuf *bout; /* output file */ 593 Extern Biobuf *bsym; /* symbol output file; nil => no sym out */ 594 Extern double canonnan; /* standard nan */ 595 Extern uchar casttab[Tend][Tend]; /* instruction to cast from [1] to [2] */ 596 Extern long constval; 597 Extern Decl *curfn; 598 Extern char debug[256]; 599 Extern Desc *descriptors; /* list of all possible descriptors */ 600 Extern int dontcompile; /* dis header flag */ 601 Extern int dowarn; 602 Extern char *emitcode; /* emit stub routines for system module functions */ 603 Extern int emitdyn; /* emit stub routines as above but for dynamic modules */ 604 Extern int emitstub; /* emit type and call frames for system modules */ 605 Extern char *emittab; /* emit table of runtime functions for this module */ 606 Extern int errors; 607 Extern char escmap[256]; 608 Extern Inst *firstinst; 609 Extern long fixss; /* set extent from command line */ 610 Extern Decl *fndecls; 611 Extern Decl **fns; 612 Extern int gendis; /* generate dis or asm? */ 613 Extern Decl *impdecl; /* id of implementation module or union if many */ 614 Extern Dlist *impdecls; /* id(s) of implementation module(s) */ 615 /* Extern Sym *impmod; */ /* name of implementation module */ 616 Extern Decl *impmods; /* name of implementation module(s) */ 617 Extern Decl *iota; 618 Extern uchar isbyteinst[256]; 619 Extern int isfatal; 620 Extern int isrelop[Oend]; 621 Extern uchar isused[Oend]; 622 Extern Inst *lastinst; 623 Extern int lenadts; 624 Extern int maxerr; 625 Extern int maxlabdep; /* maximum nesting of breakable/continuable statements */ 626 Extern long maxstack; /* max size of a stack frame called */ 627 Extern int mustcompile; /* dis header flag */ 628 Extern int oldcycles; 629 Extern int nadts; 630 Extern int newfnptr; /* ISELF and -ve indices */ 631 Extern int nfns; 632 Extern Decl *nildecl; /* declaration for limbo's nil */ 633 Extern int nlabel; 634 Extern int dontinline; 635 Extern Line noline; 636 Extern Src nosrc; 637 Extern uchar opcommute[Oend]; 638 Extern int opind[Tend]; 639 Extern uchar oprelinvert[Oend]; 640 Extern int optims; 641 Extern char *outfile; 642 Extern Type *precasttab[Tend][Tend]; 643 Extern int scope; 644 Extern Decl *selfdecl; /* declaration for limbo's self */ 645 Extern uchar sideeffect[Oend]; 646 Extern char *signdump; /* dump sig for this fn */ 647 Extern int superwarn; 648 Extern char *symfile; 649 Extern Type *tany; 650 Extern Type *tbig; 651 Extern Type *tbyte; 652 Extern Type *terror; 653 Extern Type *tint; 654 Extern Type *tnone; 655 Extern Type *treal; 656 Extern Node *tree; 657 Extern Type *tstring; 658 Extern Type *texception; 659 Extern Type *tunknown; 660 Extern Type *tfnptr; 661 Extern Type *rtexception; 662 Extern char unescmap[256]; 663 Extern Src unifysrc; 664 Extern Node znode; 665 666 extern int *blockstack; 667 extern int blockdep; 668 extern int nblocks; 669 extern File **files; 670 extern int nfiles; 671 extern uchar chantab[Tend]; 672 extern uchar disoptab[Oend+1][7]; 673 extern char *instname[]; 674 extern char *kindname[Tend]; 675 extern uchar movetab[Mend][Tend]; 676 extern char *opname[]; 677 extern int setisbyteinst[]; 678 extern int setisused[]; 679 extern int setsideeffect[]; 680 extern char *storename[Dend]; 681 extern int storespace[Dend]; 682 extern Tattr tattr[Tend]; 683 684 #include "fns.h" 685 686 #pragma varargck type "D" Decl* 687 #pragma varargck type "I" Inst* 688 #pragma varargck type "K" Decl* 689 #pragma varargck type "k" Decl* 690 #pragma varargck type "L" Line 691 #pragma varargck type "M" Desc* 692 #pragma varargck type "n" Node* 693 #pragma varargck type "O" int 694 #pragma varargck type "O" uint 695 #pragma varargck type "g" double 696 #pragma varargck type "Q" Node* 697 #pragma varargck type "R" Type* 698 #pragma varargck type "T" Type* 699 #pragma varargck type "t" Type* 700 #pragma varargck type "U" Src 701 #pragma varargck type "v" Node* 702 #pragma varargck type "V" Node* 703