1 #include "l.h" 2 3 void 4 span(void) 5 { 6 Prog *p; 7 Sym *setext; 8 Optab *o; 9 int m; 10 long c; 11 12 if(debug['v']) 13 Bprint(&bso, "%5.2f span\n", cputime()); 14 Bflush(&bso); 15 c = INITTEXT; 16 for(p = firstp; p != P; p = p->link) { 17 p->pc = c; 18 o = oplook(p); 19 m = o->size; 20 if(m == 0) { 21 if(p->as == ATEXT) { 22 curtext = p; 23 autosize = p->to.offset + 4; 24 if(p->from.sym != S) 25 p->from.sym->value = c; 26 continue; 27 } 28 if(p->as != ANOP) 29 diag("zero-width instruction\n%P", p); 30 continue; 31 } 32 c += m; 33 } 34 c = rnd(c, 8); 35 36 setext = lookup("etext", 0); 37 if(setext != S) { 38 setext->value = c; 39 textsize = c - INITTEXT; 40 } 41 if(INITRND) 42 INITDAT = rnd(c, INITRND); 43 if(debug['v']) 44 Bprint(&bso, "tsize = %lux\n", textsize); 45 Bflush(&bso); 46 } 47 48 void 49 xdefine(char *p, int t, long v) 50 { 51 Sym *s; 52 53 s = lookup(p, 0); 54 if(s->type == 0 || s->type == SXREF) { 55 s->type = t; 56 s->value = v; 57 } 58 } 59 60 long 61 regoff(Adr *a) 62 { 63 64 instoffset = 0; 65 aclass(a); 66 return instoffset; 67 } 68 69 int 70 aclass(Adr *a) 71 { 72 Sym *s; 73 int t; 74 75 switch(a->type) { 76 case D_NONE: 77 return C_NONE; 78 79 case D_REG: 80 return C_REG; 81 82 case D_FREG: 83 return C_FREG; 84 85 case D_CREG: 86 return C_CREG; 87 88 case D_PREG: 89 if(a->reg == D_FSR) 90 return C_FSR; 91 if(a->reg == D_FPQ) 92 return C_FQ; 93 return C_PREG; 94 95 case D_OREG: 96 switch(a->name) { 97 case D_EXTERN: 98 case D_STATIC: 99 if(a->sym == S) 100 break; 101 t = a->sym->type; 102 if(t == 0 || t == SXREF) { 103 diag("undefined external: %s in %s", 104 a->sym->name, TNAME); 105 a->sym->type = SDATA; 106 } 107 instoffset = a->sym->value + a->offset - BIG; 108 if(instoffset >= -BIG && instoffset < BIG) { 109 if(instoffset & 7) 110 return C_OSEXT; 111 return C_ESEXT; 112 } 113 if(instoffset & 7) 114 return C_OLEXT; 115 return C_ELEXT; 116 case D_AUTO: 117 instoffset = autosize + a->offset; 118 goto dauto; 119 120 case D_PARAM: 121 instoffset = autosize + a->offset + 4L; 122 dauto: 123 if(instoffset >= -BIG && instoffset < BIG) { 124 if(instoffset & 7) 125 return C_OSAUTO; 126 return C_ESAUTO; 127 } 128 if(instoffset & 7) 129 return C_OLAUTO; 130 return C_ELAUTO; 131 case D_NONE: 132 instoffset = a->offset; 133 if(instoffset == 0) 134 return C_ZOREG; 135 if(instoffset >= -BIG && instoffset < BIG) 136 return C_SOREG; 137 return C_LOREG; 138 } 139 return C_GOK; 140 141 case D_ASI: 142 if(a->name == D_NONE) 143 return C_ASI; 144 return C_GOK; 145 146 case D_CONST: 147 switch(a->name) { 148 149 case D_NONE: 150 instoffset = a->offset; 151 consize: 152 if(instoffset == 0) 153 return C_ZCON; 154 if(instoffset >= -0x1000 && instoffset <= 0xfff) 155 return C_SCON; 156 if((instoffset & 0x3ff) == 0) 157 return C_UCON; 158 return C_LCON; 159 160 case D_EXTERN: 161 case D_STATIC: 162 s = a->sym; 163 if(s == S) 164 break; 165 t = s->type; 166 if(t == 0 || t == SXREF) { 167 diag("undefined external: %s in %s", 168 s->name, TNAME); 169 s->type = SDATA; 170 } 171 if(s->type == STEXT || s->type == SLEAF) { 172 instoffset = s->value + a->offset; 173 return C_LCON; 174 } 175 if(s->type == SCONST) { 176 instoffset = s->value + a->offset; 177 goto consize; 178 } 179 instoffset = s->value + a->offset - BIG; 180 if(instoffset >= -BIG && instoffset < BIG && instoffset != 0) 181 return C_SECON; 182 instoffset = s->value + a->offset + INITDAT; 183 /* not sure why this barfs */ 184 return C_LCON; 185 /* 186 if(instoffset == 0) 187 return C_ZCON; 188 if(instoffset >= -0x1000 && instoffset <= 0xfff) 189 return C_SCON; 190 if((instoffset & 0x3ff) == 0) 191 return C_UCON; 192 return C_LCON; 193 */ 194 195 case D_AUTO: 196 instoffset = autosize + a->offset; 197 if(instoffset >= -BIG && instoffset < BIG) 198 return C_SACON; 199 return C_LACON; 200 201 case D_PARAM: 202 instoffset = autosize + a->offset + 4L; 203 if(instoffset >= -BIG && instoffset < BIG) 204 return C_SACON; 205 return C_LACON; 206 } 207 return C_GOK; 208 209 case D_BRANCH: 210 return C_SBRA; 211 } 212 return C_GOK; 213 } 214 215 Optab* 216 oplook(Prog *p) 217 { 218 int a1, a2, a3, r; 219 char *c1, *c3; 220 Optab *o, *e; 221 222 a1 = p->optab; 223 if(a1) 224 return optab+(a1-1); 225 a1 = p->from.class; 226 if(a1 == 0) { 227 a1 = aclass(&p->from) + 1; 228 p->from.class = a1; 229 } 230 a1--; 231 a3 = p->to.class; 232 if(a3 == 0) { 233 a3 = aclass(&p->to) + 1; 234 p->to.class = a3; 235 } 236 a3--; 237 a2 = C_NONE; 238 if(p->reg != NREG) 239 a2 = C_REG; 240 r = p->as; 241 o = oprange[r].start; 242 if(o == 0) 243 o = oprange[r].stop; /* just generate an error */ 244 e = oprange[r].stop; 245 c1 = xcmp[a1]; 246 c3 = xcmp[a3]; 247 for(; o<e; o++) 248 if(o->a2 == a2) 249 if(c1[o->a1]) 250 if(c3[o->a3]) { 251 p->optab = (o-optab)+1; 252 return o; 253 } 254 diag("illegal combination %A %d %d %d", 255 p->as, a1, a2, a3); 256 if(1||!debug['a']) 257 prasm(p); 258 if(o == 0) 259 errorexit(); 260 return o; 261 } 262 263 int 264 cmp(int a, int b) 265 { 266 267 if(a == b) 268 return 1; 269 switch(a) { 270 case C_LCON: 271 if(b == C_ZCON || b == C_SCON || b == C_UCON) 272 return 1; 273 break; 274 case C_UCON: 275 if(b == C_ZCON) 276 return 1; 277 break; 278 case C_SCON: 279 if(b == C_ZCON) 280 return 1; 281 break; 282 case C_LACON: 283 if(b == C_SACON) 284 return 1; 285 break; 286 case C_LBRA: 287 if(b == C_SBRA) 288 return 1; 289 break; 290 case C_ELEXT: 291 if(b == C_ESEXT) 292 return 1; 293 break; 294 case C_LEXT: 295 if(b == C_SEXT || 296 b == C_ESEXT || b == C_OSEXT || 297 b == C_ELEXT || b == C_OLEXT) 298 return 1; 299 break; 300 case C_SEXT: 301 if(b == C_ESEXT || b == C_OSEXT) 302 return 1; 303 break; 304 case C_ELAUTO: 305 if(b == C_ESAUTO) 306 return 1; 307 break; 308 case C_LAUTO: 309 if(b == C_SAUTO || 310 b == C_ESAUTO || b == C_OSAUTO || 311 b == C_ELAUTO || b == C_OLAUTO) 312 return 1; 313 break; 314 case C_SAUTO: 315 if(b == C_ESAUTO || b == C_OSAUTO) 316 return 1; 317 break; 318 case C_REG: 319 if(b == C_ZCON) 320 return 1; 321 break; 322 case C_LOREG: 323 if(b == C_ZOREG || b == C_SOREG) 324 return 1; 325 break; 326 case C_SOREG: 327 if(b == C_ZOREG) 328 return 1; 329 break; 330 331 case C_ANY: 332 return 1; 333 } 334 return 0; 335 } 336 337 int 338 ocmp(const void *a1, const void *a2) 339 { 340 Optab *p1, *p2; 341 int n; 342 343 p1 = (Optab*)a1; 344 p2 = (Optab*)a2; 345 n = p1->as - p2->as; 346 if(n) 347 return n; 348 n = p1->a1 - p2->a1; 349 if(n) 350 return n; 351 n = p1->a2 - p2->a2; 352 if(n) 353 return n; 354 n = p1->a3 - p2->a3; 355 if(n) 356 return n; 357 return 0; 358 } 359 360 void 361 buildop(void) 362 { 363 int i, n, r; 364 365 for(i=0; i<C_NCLASS; i++) 366 for(n=0; n<C_NCLASS; n++) 367 xcmp[i][n] = cmp(n, i); 368 for(n=0; optab[n].as != AXXX; n++) 369 ; 370 qsort(optab, n, sizeof(optab[0]), ocmp); 371 for(i=0; i<n; i++) { 372 r = optab[i].as; 373 oprange[r].start = optab+i; 374 while(optab[i].as == r) 375 i++; 376 oprange[r].stop = optab+i; 377 i--; 378 379 switch(r) 380 { 381 default: 382 diag("unknown op in build: %A", r); 383 errorexit(); 384 case AADD: 385 oprange[AADDX] = oprange[r]; 386 oprange[ASUB] = oprange[r]; 387 oprange[ASUBX] = oprange[r]; 388 oprange[AMUL] = oprange[r]; 389 oprange[AXOR] = oprange[r]; 390 oprange[AXNOR] = oprange[r]; 391 oprange[AAND] = oprange[r]; 392 oprange[AANDN] = oprange[r]; 393 oprange[AOR] = oprange[r]; 394 oprange[AORN] = oprange[r]; 395 oprange[ASLL] = oprange[r]; 396 oprange[ASRL] = oprange[r]; 397 oprange[ASRA] = oprange[r]; 398 oprange[AADDCC] = oprange[r]; 399 oprange[AADDXCC] = oprange[r]; 400 oprange[ATADDCC] = oprange[r]; 401 oprange[ATADDCCTV] = oprange[r]; 402 oprange[ASUBCC] = oprange[r]; 403 oprange[ASUBXCC] = oprange[r]; 404 oprange[ATSUBCC] = oprange[r]; 405 oprange[ATSUBCCTV] = oprange[r]; 406 oprange[AXORCC] = oprange[r]; 407 oprange[AXNORCC] = oprange[r]; 408 oprange[AANDCC] = oprange[r]; 409 oprange[AANDNCC] = oprange[r]; 410 oprange[AORCC] = oprange[r]; 411 oprange[AORNCC] = oprange[r]; 412 oprange[AMULSCC] = oprange[r]; 413 oprange[ASAVE] = oprange[r]; 414 oprange[ARESTORE] = oprange[r]; 415 break; 416 case AMOVB: 417 oprange[AMOVH] = oprange[r]; 418 oprange[AMOVHU] = oprange[r]; 419 oprange[AMOVBU] = oprange[r]; 420 oprange[ASWAP] = oprange[r]; 421 oprange[ATAS] = oprange[r]; 422 break; 423 case ABA: 424 oprange[ABN] = oprange[r]; 425 oprange[AFBA] = oprange[r]; 426 oprange[AFBN] = oprange[r]; 427 break; 428 case ABE: 429 oprange[ABCC] = oprange[r]; 430 oprange[ABCS] = oprange[r]; 431 oprange[ABGE] = oprange[r]; 432 oprange[ABGU] = oprange[r]; 433 oprange[ABG] = oprange[r]; 434 oprange[ABLEU] = oprange[r]; 435 oprange[ABLE] = oprange[r]; 436 oprange[ABL] = oprange[r]; 437 oprange[ABNEG] = oprange[r]; 438 oprange[ABNE] = oprange[r]; 439 oprange[ABPOS] = oprange[r]; 440 oprange[ABVC] = oprange[r]; 441 oprange[ABVS] = oprange[r]; 442 443 oprange[AFBE] = oprange[r]; 444 oprange[AFBG] = oprange[r]; 445 oprange[AFBGE] = oprange[r]; 446 oprange[AFBL] = oprange[r]; 447 oprange[AFBLE] = oprange[r]; 448 oprange[AFBLG] = oprange[r]; 449 oprange[AFBNE] = oprange[r]; 450 oprange[AFBO] = oprange[r]; 451 oprange[AFBU] = oprange[r]; 452 oprange[AFBUE] = oprange[r]; 453 oprange[AFBUG] = oprange[r]; 454 oprange[AFBUGE] = oprange[r]; 455 oprange[AFBUL] = oprange[r]; 456 oprange[AFBULE] = oprange[r]; 457 break; 458 case ATA: 459 oprange[ATCC] = oprange[r]; 460 oprange[ATCS] = oprange[r]; 461 oprange[ATE] = oprange[r]; 462 oprange[ATGE] = oprange[r]; 463 oprange[ATGU] = oprange[r]; 464 oprange[ATG] = oprange[r]; 465 oprange[ATLEU] = oprange[r]; 466 oprange[ATLE] = oprange[r]; 467 oprange[ATL] = oprange[r]; 468 oprange[ATNEG] = oprange[r]; 469 oprange[ATNE] = oprange[r]; 470 oprange[ATN] = oprange[r]; 471 oprange[ATPOS] = oprange[r]; 472 oprange[ATVC] = oprange[r]; 473 oprange[ATVS] = oprange[r]; 474 break; 475 case AFADDD: 476 oprange[AFADDF] = oprange[r]; 477 oprange[AFADDX] = oprange[r]; 478 oprange[AFDIVD] = oprange[r]; 479 oprange[AFDIVF] = oprange[r]; 480 oprange[AFDIVX] = oprange[r]; 481 oprange[AFMULD] = oprange[r]; 482 oprange[AFMULF] = oprange[r]; 483 oprange[AFMULX] = oprange[r]; 484 oprange[AFSUBD] = oprange[r]; 485 oprange[AFSUBF] = oprange[r]; 486 oprange[AFSUBX] = oprange[r]; 487 break; 488 case AFCMPD: 489 oprange[AFCMPF] = oprange[r]; 490 oprange[AFCMPX] = oprange[r]; 491 oprange[AFCMPED] = oprange[r]; 492 oprange[AFCMPEF] = oprange[r]; 493 oprange[AFCMPEX] = oprange[r]; 494 break; 495 case AFABSF: 496 oprange[AFMOVDF] = oprange[r]; 497 oprange[AFMOVDW] = oprange[r]; 498 oprange[AFMOVFD] = oprange[r]; 499 oprange[AFMOVFW] = oprange[r]; 500 oprange[AFMOVWD] = oprange[r]; 501 oprange[AFMOVWF] = oprange[r]; 502 oprange[AFNEGF] = oprange[r]; 503 oprange[AFSQRTD] = oprange[r]; 504 oprange[AFSQRTF] = oprange[r]; 505 break; 506 case AFMOVF: 507 case AFMOVD: 508 case AMOVW: 509 case AMOVD: 510 case AWORD: 511 case ARETT: 512 case AJMPL: 513 case AJMP: 514 case ACMP: 515 case ANOP: 516 case ATEXT: 517 case ADIV: 518 case ADIVL: 519 case AMOD: 520 case AMODL: 521 break; 522 } 523 } 524 } 525