1 #include "lib9.h" 2 #include "isa.h" 3 #include "interp.h" 4 #include "raise.h" 5 6 #define T(r) *((void**)(R.r)) 7 8 #define SRR(op,c,r1,r2) gen((op)|((c)<<6)|((r1)<<16)|((r2)<<11)) 9 #define RRR(op,r1,r2,r3) gen((op)|((r1)<<16)|((r2)<<21)|((r3)<<11)) 10 #define FRRR(op,r1,r2,r3) gen((op)|((r1)<<16)|((r2)<<11)|((r3)<<6)) 11 #define FI(op,c) gen((op)|((c)&0xffff)) 12 #define IRR(op,c,r1,r2) gen((op)|((c)&0xffff)|((r1)<<21)|((r2)<<16)) 13 #define BRRI(op,r1,r2,c) gen((op)|((r1)<<21)|((r2)<<16)|((c)&0xffff)) 14 #define BRI(op,r,c) gen((op)|((r)<<21)|((c)&0xffff)) 15 #define JR(op,r) gen((op)|((r)<<21)) 16 #define J(op,c) gen((op)|(((ulong)(c)>>2)&0x3FFFFFFUL)) 17 18 #ifndef HIOFFSET 19 #define HIOFFSET 0 /* big endian */ 20 #endif 21 22 enum 23 { 24 Rzero = 0, 25 26 Ro1 = 8, 27 Ro2 = 9, 28 Ro3 = 10, 29 Ri = 11, 30 Rj = 12, 31 32 Rmp = 13, 33 Rfp = 14, 34 Rreg = 15, 35 36 Rpic = 25, 37 Rlink = 31, 38 39 Rf1 = 4, 40 Rf2 = 6, 41 42 Olw = 0x23<<26, 43 Olbu = 0x24<<26, 44 Olhu = 0x25<<26, 45 Osw = 0x2b<<26, 46 Osb = 0x28<<26, 47 Oaddui = 0x09<<26, 48 Olui = 0x0f<<26, 49 Oori = 0x0d<<26, 50 Odiv = (0x00<<26) | 0x1a, 51 Omul = (0x00<<26) | 0x18, 52 Omfhi = (0x00<<26) | 0x10, 53 Omflo = (0x00<<26) | 0x12, 54 Osubu = (0x00<<26) | 0x23, 55 Oaddu = (0x00<<26) | 0x21, 56 Oand = (0x00<<26) | 0x24, 57 Oor = (0x00<<26) | 0x25, 58 Oxor = (0x00<<26) | 0x26, 59 Odelay = (0x00<<26) | 0x27, 60 Osll = (0x00<<26) | 0x00, 61 Osrl = (0x00<<26) | 0x02, 62 Osra = (0x00<<26) | 0x03, 63 Osllv = (0x00<<26) | 0x04, 64 Osrlv = (0x00<<26) | 0x06, 65 Osrav = (0x00<<26) | 0x07, 66 Oslt = (0x00<<26) | 0x2a, 67 Osltu = (0x00<<26) | 0x2b, 68 Obeq = 0x04<<26, 69 Obne = 0x05<<26, 70 Obltz = (0x01<<26) | (0x0<<16), 71 Obgtz = (0x07<<26) | (0x0<<16), 72 Oblez = (0x06<<26) | (0x0<<16), 73 Obgez = (0x01<<26) | (0x1<<16), 74 Ojr = (0x00<<26) | 0x08, 75 Ojalr = (0x00<<26) | 0x09 | (Rlink<<11), 76 Oj = (0x02<<26), 77 Ojal = (0x03<<26), 78 Olea = Oaddui, // pseudo op 79 80 Olf = 0x31<<26, 81 Osf = 0x39<<26, 82 Oaddf = (0x11<<26) | (17<<21) | 0, 83 Osubf = (0x11<<26) | (17<<21) | 1, 84 Omulf = (0x11<<26) | (17<<21) | 2, 85 Odivf = (0x11<<26) | (17<<21) | 3, 86 Onegf = (0x11<<26) | (17<<21) | 7, 87 88 Ocvtwf = (0x11<<26) | (20<<21) | 33, 89 Ocvtfw = (0x11<<26) | (17<<21) | 36, 90 91 Ofeq = (0x11<<26) | (17<<21) | (3<<4) | 2, 92 Oflt = (0x11<<26) | (17<<21) | (3<<4) | 12, 93 94 Obrf = (0x11<<26) | (0x100<<16), 95 Obrt = (0x11<<26) | (0x101<<16), 96 97 SRCOP = (1<<0), 98 DSTOP = (1<<1), 99 WRTPC = (1<<2), 100 TCHECK = (1<<3), 101 NEWPC = (1<<4), 102 DBRAN = (1<<5), 103 THREOP = (1<<6), 104 105 ANDAND = 1, 106 OROR, 107 EQAND, 108 109 XOR, 110 IOR, 111 AND, 112 ADD, 113 SUB, 114 115 OMASK = (1<<4) - 1, 116 REV1 = 1<<4, 117 REV2 = 1<<5, 118 119 Bhi = HIOFFSET, 120 Blo = Bhi ^ 4, 121 122 MacRET = 0, 123 MacFRP, 124 MacINDX, 125 MacCASE, 126 MacLENA, 127 MacFRAM, 128 MacMOVM, 129 MacCOLR, 130 MacMCAL, 131 MacMFRA, 132 MacEND, 133 NMACRO 134 }; 135 136 extern char Tmodule[]; 137 void (*comvec)(void); 138 extern void das(ulong*); 139 static ulong* code; 140 static ulong* base; 141 static ulong* patch; 142 static int pass; 143 static int regdelay; 144 static Module* mod; 145 static ulong* tinit; 146 static ulong* litpool; 147 static int nlit; 148 static ulong macro[NMACRO]; 149 static void rdestroy(void); 150 static void macret(void); 151 static void macfrp(void); 152 static void macindx(void); 153 static void maccase(void); 154 static void maclena(void); 155 static void macfram(void); 156 static void macmovm(void); 157 static void maccvtfw(void); 158 static void maccolr(void); 159 static void macend(void); 160 static void macmcal(void); 161 static void macmfra(void); 162 163 struct 164 { 165 int o; 166 void (*f)(void); 167 } macinit[] = 168 { 169 MacFRP, macfrp, /* decrement and free pointer */ 170 MacRET, macret, /* return instruction */ 171 MacCASE, maccase, /* case instruction */ 172 MacCOLR, maccolr, /* increment and color pointer */ 173 MacFRAM, macfram, /* frame instruction */ 174 MacMCAL, macmcal, /* mcall bottom half */ 175 MacMFRA, macmfra, /* punt mframe because t->initialize==0 */ 176 MacMOVM, macmovm, 177 MacLENA, maclena, 178 MacINDX, macindx, 179 MacEND, macend, 180 0 181 }; 182 183 static void 184 rdestroy(void) 185 { 186 destroy(R.s); 187 } 188 189 static void 190 rmcall(void) 191 { 192 Prog *p; 193 Frame *f; 194 195 f = (Frame*)R.FP; 196 if(f == H) 197 error(exModule); 198 199 f->mr = nil; 200 ((void(*)(Frame*))R.dt)(f); 201 R.SP = (uchar*)f; 202 R.FP = f->fp; 203 if(f->t == nil) 204 unextend(f); 205 else 206 freeptrs(f, f->t); 207 p = currun(); 208 if(p->kill != nil) 209 error(p->kill); 210 } 211 212 static void 213 rmfram(void) 214 { 215 Type *t; 216 Frame *f; 217 uchar *nsp; 218 219 t = (Type*)R.s; 220 nsp = R.SP + t->size; 221 if(nsp >= R.TS) { 222 R.s = t; 223 extend(); 224 T(d) = R.s; 225 return; 226 } 227 f = (Frame*)R.SP; 228 R.SP = nsp; 229 f->t = t; 230 f->mr = nil; 231 initmem(t, f); 232 T(d) = f; 233 } 234 235 void 236 urk(char *s) 237 { 238 print("urk: %s\n", s); 239 exits(0); 240 } 241 242 void 243 gen(ulong o) 244 { 245 *code++ = o; 246 } 247 248 void 249 delay(void) 250 { 251 gen(Odelay); 252 } 253 254 int 255 bigc(long c) 256 { 257 c >>= 15; 258 if(c == 0 || c == -1) 259 return 0; 260 return 1; 261 } 262 263 void 264 ldbigc(ulong c, int reg) 265 { 266 IRR(Olui, c>>16,Rzero,reg); 267 IRR(Oori, c,reg,reg); 268 } 269 270 void 271 ldc(ulong c, int reg) 272 { 273 274 if(bigc(c)) 275 ldbigc(c, reg); 276 else 277 IRR(Oaddui, c,Rzero, reg); 278 } 279 280 void 281 xchg(void) 282 { 283 ulong t; 284 285 t = code[-1]; 286 code[-1] = code[-2]; 287 code[-2] = t; 288 } 289 290 void 291 opx(int mode, Adr *a, int op, int reg, int del) 292 { 293 ulong c; 294 int r, rx; 295 296 switch(mode) { 297 case AFP: 298 c = a->ind; 299 if(bigc(c)) 300 urk("bigc op1b 1"); 301 if(regdelay == Rfp) 302 delay(); 303 IRR(op, c,Rfp, reg); 304 break; 305 case AMP: 306 c = a->ind; 307 if(bigc(c)) 308 urk("bigc op1b 2"); 309 if(regdelay == Rmp) 310 delay(); 311 IRR(op, c,Rmp, reg); 312 break; 313 case AIMM: 314 if(op == Olea) { 315 if(a->imm != 0) { 316 ldc(a->imm, reg); 317 IRR(Osw, O(REG,st),Rreg, reg); 318 } else 319 IRR(Osw, O(REG,st),Rreg, Rzero); 320 IRR(Oaddui, O(REG,st),Rreg, reg); 321 } else 322 ldc(a->imm, reg); 323 return; 324 case AIND|AFP: 325 r = Rfp; 326 goto offset; 327 case AIND|AMP: 328 r = Rmp; 329 offset: 330 if(regdelay == r) 331 delay(); 332 c = a->i.s; 333 rx = Ri; 334 if(op == Olea || op == Olw) 335 rx = reg; 336 IRR(Olw, a->i.f,r, rx); 337 if(c != 0 || op != Oaddui) { 338 delay(); 339 IRR(op, c,rx, reg); 340 } 341 break; 342 } 343 if(op != Olea && del) 344 delay(); 345 regdelay = 0; 346 } 347 348 void 349 op1(Inst *i, int op, int reg, int del) 350 { 351 opx(USRC(i->add), &i->s, op, reg, del); 352 } 353 354 void 355 op3(Inst *i, int op, int reg, int del) 356 { 357 opx(UDST(i->add), &i->d, op, reg, del); 358 } 359 360 void 361 op2(Inst *i, int op, int reg, int del) 362 { 363 switch(i->add & ARM) { 364 case AXNON: 365 op3(i, op, reg, del); 366 return; 367 case AXIMM: 368 if(op == Olea) { 369 if((short)i->reg != 0) { 370 ldc((short)i->reg, reg); 371 IRR(Osw, O(REG,t),Rreg, reg); 372 } else 373 IRR(Osw, O(REG,t),Rreg, Rzero); 374 IRR(Oaddui, O(REG,t),Rreg, reg); 375 } else 376 ldc((short)i->reg, reg); 377 return; 378 case AXINF: 379 IRR(op, i->reg,Rfp, reg); 380 break; 381 case AXINM: 382 IRR(op, i->reg,Rmp, reg); 383 break; 384 } 385 if(op != Olea && del) 386 delay(); 387 } 388 389 ulong 390 branch(Inst *i) 391 { 392 ulong rel; 393 394 if(base == 0) 395 return 0; 396 rel = patch[(Inst*)i->d.imm - mod->prog]; 397 rel += (base - code) - 1; 398 return rel & 0xffff; 399 } 400 401 static void 402 literal(ulong imm, int roff) 403 { 404 nlit++; 405 406 ldbigc((ulong)litpool, Ro1); 407 IRR(Osw, roff, Rreg, Ro1); 408 409 if(pass == 0) 410 return; 411 412 *litpool = imm; 413 litpool++; 414 } 415 416 void 417 punt(Inst *i, int m, void (*fn)(void)) 418 { 419 ulong *cp, pc; 420 421 if(m & SRCOP) { 422 op1(i, Olea, Ro1, 1); 423 IRR(Osw, O(REG,s),Rreg, Ro1); 424 } 425 if(m & DSTOP) { 426 op3(i, Olea, Ro3, 1); 427 IRR(Osw, O(REG,d),Rreg, Ro3); 428 } 429 if(m & WRTPC) { 430 pc = patch[i-mod->prog+1]; 431 ldbigc((ulong)(base+pc), Ro1); 432 IRR(Osw, O(REG,PC),Rreg, Ro1); 433 } 434 if(m & DBRAN) { 435 pc = patch[(Inst*)i->d.imm-mod->prog]; 436 literal((ulong)(base+pc), O(REG, d)); 437 } 438 439 if((i->add&ARM) == AXNON) { 440 if(m & THREOP) { 441 delay(); 442 IRR(Olw, O(REG,d),Rreg, Ro2); 443 delay(); 444 IRR(Osw, O(REG,m),Rreg, Ro2); 445 } 446 } else { 447 op2(i, Olea, Ro2, 1); 448 IRR(Osw, O(REG,m),Rreg, Ro2); 449 } 450 451 ldc((ulong)fn, Rpic); 452 JR(Ojalr, Rpic); 453 IRR(Osw, O(REG,FP),Rreg, Rfp); 454 455 ldc((ulong)&R, Rreg); 456 IRR(Olw, O(REG,FP),Rreg, Rfp); 457 IRR(Olw, O(REG,MP),Rreg, Rmp); 458 regdelay = Rmp; 459 460 if(m & TCHECK) { 461 IRR(Olw, O(REG,t),Rreg, Ro1); 462 xchg(); 463 cp = code; 464 BRRI(Obeq,Ro1,Rzero,0); 465 IRR(Olw, O(REG,xpc),Rreg, Ro2); 466 delay(); 467 JR(Ojr, Ro2); 468 delay(); 469 *cp |= (code - cp) - 1; 470 regdelay = 0; 471 } 472 473 if(m & NEWPC) { 474 IRR(Olw, O(REG,PC),Rreg, Ro1); 475 if(m & TCHECK) 476 delay(); 477 else 478 xchg(); 479 JR(Ojr, Ro1); 480 delay(); 481 regdelay = 0; 482 } 483 } 484 485 static void 486 comgoto(Inst *i) 487 { 488 WORD *t, *e; 489 490 op1(i, Olw, Ro2, 0); 491 op3(i, Olea, Ro3, 0); 492 SRR(Osll, 2, Ro2, Ro2); 493 RRR(Oaddu, Ro2, Ro3, Ro3); 494 IRR(Olw, 0,Ro3, Ro1); 495 delay(); 496 JR(Ojr, Ro1); 497 delay(); 498 499 if(pass == 0) 500 return; 501 502 t = (WORD*)(mod->origmp+i->d.ind); 503 e = t + t[-1]; 504 t[-1] = 0; 505 while(t < e) { 506 t[0] = (ulong)(base + patch[t[0]]); 507 t++; 508 } 509 } 510 511 static void 512 comcase(Inst *i, int w) 513 { 514 int l; 515 WORD *t, *e; 516 517 if(w != 0) { 518 op1(i, Olw, Ro1, 0); // v 519 op3(i, Olea, Ro3, 0); // table 520 J(Oj, base+macro[MacCASE]); 521 xchg(); 522 } 523 524 t = (WORD*)(mod->origmp+i->d.ind+4); 525 l = t[-1]; 526 527 /* have to take care not to relocate the same table twice - 528 * the limbo compiler can duplicate a case instruction 529 * during its folding phase 530 */ 531 532 if(pass == 0) { 533 if(l >= 0) 534 t[-1] = -l-1; /* Mark it not done */ 535 return; 536 } 537 if(l >= 0) /* Check pass 2 done */ 538 return; 539 t[-1] = -l-1; /* Set real count */ 540 e = t + t[-1]*3; 541 while(t < e) { 542 t[2] = (ulong)(base + patch[t[2]]); 543 t += 3; 544 } 545 t[0] = (ulong)(base + patch[t[0]]); 546 } 547 548 static void 549 comcasel(Inst *i) 550 { 551 int l; 552 WORD *t, *e; 553 554 t = (WORD*)(mod->origmp+i->d.ind+8); 555 l = t[-2]; 556 if(pass == 0) { 557 if(l >= 0) 558 t[-2] = -l-1; /* Mark it not done */ 559 return; 560 } 561 if(l >= 0) /* Check pass 2 done */ 562 return; 563 t[-2] = -l-1; /* Set real count */ 564 e = t + t[-2]*6; 565 while(t < e) { 566 t[4] = (ulong)base + patch[t[4]]; 567 t += 6; 568 } 569 t[0] = (ulong)base + patch[t[0]]; 570 } 571 572 static void 573 commframe(Inst *i) 574 { 575 Modlink *ml; 576 ulong *cp1, *cp2; 577 578 op1(i, Olw, Ro1, 0); 579 ldc((ulong)H, Ri); 580 cp1 = code; 581 BRRI(Obeq, Ro1,Ri, 0); 582 delay(); 583 584 ml = nil; 585 IRR(Olw, (ulong)&ml->links[i->reg].frame,Ro1, Ri); 586 delay(); 587 IRR(Olw, O(Type,initialize),Ri, Ro2); 588 delay(); 589 cp2 = code; 590 BRRI(Obne, Ro2,Rzero, 0); 591 delay(); 592 593 op3(i, Olea, Rj, 0); 594 595 *cp1 |= (code - cp1) - 1; 596 ldbigc((ulong)(base+patch[i-mod->prog+1]), Rlink); 597 J(Oj, base+macro[MacMFRA]); 598 xchg(); 599 600 *cp2 |= (code - cp2) - 1; 601 J(Ojal, base+macro[MacFRAM]); 602 delay(); 603 op3(i, Osw, Ro1, 0); 604 } 605 606 static void 607 commcall(Inst *i) 608 { 609 Modlink *ml; 610 611 op1(i, Olw, Ro1, 0); // f in Ro1 612 IRR(Olw, O(REG,M),Rreg, Ro3); 613 IRR(Osw, O(Frame,fp),Ro1, Rfp); // f->fp = R.FP 614 IRR(Osw, O(Frame,mr),Ro1, Ro3); // f->mr = R.M 615 op3(i, Olw, Ri, 1); 616 ml = nil; 617 IRR(Olw, (ulong)&ml->links[i->reg].u.pc,Ri, Rj);// ml->entry in Rj 618 J(Ojal, base+macro[MacMCAL]); 619 xchg(); 620 } 621 622 static void 623 cbral(Inst *i, int op, int mode) 624 { 625 ulong *cp; 626 627 cp = 0; 628 op1(i, Olea, Ri, 0); 629 op2(i, Olea, Rj, 0); 630 IRR(Olw, Bhi,Ri, Ro1); 631 IRR(Olw, Bhi,Rj, Ro2); 632 IRR(Olw, Blo,Ri, Ri); 633 634 switch(mode & OMASK) { 635 case ANDAND: 636 cp = code; 637 BRRI(Obne, Ro2,Ro1, 0); 638 goto b1; 639 640 case OROR: 641 BRRI(Obne, Ro2,Ro1, branch(i)); 642 b1: 643 IRR(Olw, Blo,Rj, Rj); 644 delay(); 645 BRRI(op, Rj,Ri, branch(i)); 646 break; 647 648 case EQAND: 649 if(mode & REV1) 650 RRR(Oslt, Ro2,Ro1, Ro3); 651 else 652 RRR(Oslt, Ro1,Ro2, Ro3); 653 BRI(Obne, Ro3, branch(i)); 654 IRR(Olw, Blo,Rj, Rj); 655 cp = code; 656 BRRI(Obne, Ro2,Ro1, 0); 657 if(mode & REV2) 658 RRR(Osltu, Rj,Ri, Ro3); 659 else 660 RRR(Osltu, Ri,Rj, Ro3); 661 BRI(op, Ro3, branch(i)); 662 break; 663 } 664 delay(); 665 if(cp) 666 *cp |= (code - cp) - 1; 667 } 668 669 static void 670 op12(Inst *i, int b1flag, int b2flag) 671 { 672 int o1, o2; 673 674 o1 = Olw; 675 if(b1flag) 676 o1 = Olbu; 677 o2 = Olw; 678 if(b2flag) 679 o2 = Olbu; 680 if((i->add & ARM) == AXIMM) { 681 op1(i, o1, Ro1, 0); 682 op2(i, o2, Ro2, 1); 683 } else { 684 op2(i, o2, Ro2, 0); 685 op1(i, o1, Ro1, 1); 686 } 687 } 688 689 static void 690 op13(Inst *i, int o1, int o2) 691 { 692 op1(i, o1, Ro1, 1); 693 op3(i, o2, Ro1, 0); 694 } 695 696 static void 697 shrl(Inst *i) 698 { 699 int c; 700 701 if(USRC(i->add) != AIMM) { 702 punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); 703 return; 704 } 705 c = i->s.imm; 706 op2(i, Olea, Ro3, 1); 707 IRR(Olw, Bhi,Ro3, Ro1); 708 if(c >= 32) { 709 if((i->add&ARM) != AXNON) 710 op3(i, Olea, Ro3, 0); 711 else 712 delay(); 713 SRR(Osra, 31, Ro1, Ro2); 714 IRR(Osw, Bhi,Ro3, Ro2); 715 if(c >= 64) { 716 IRR(Osw, Blo,Ro3, Ro2); 717 return; 718 } 719 if(c > 32) 720 SRR(Osra, c-32, Ro1, Ro1); 721 IRR(Osw, Blo,Ro3, Ro1); 722 return; 723 } 724 IRR(Olw, Blo,Ro3, Ro2); 725 if((i->add&ARM) != AXNON) 726 op3(i, Olea, Ro3, !c); 727 if(c != 0) { 728 SRR(Osll, 32-c, Ro1, Ri); 729 SRR(Osra, c, Ro1, Ro1); 730 SRR(Osrl, c, Ro2, Ro2); 731 RRR(Oor, Ri, Ro2, Ro2); 732 } 733 IRR(Osw, Blo,Ro3, Ro2); 734 IRR(Osw, Bhi,Ro3, Ro1); 735 } 736 737 static void 738 shll(Inst *i) 739 { 740 int c; 741 742 if(USRC(i->add) != AIMM) { 743 punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); 744 return; 745 } 746 c = i->s.imm; 747 if(c >= 64) { 748 op3(i, Olea, Ro3, 1); 749 IRR(Osw, Bhi,Ro3, Rzero); 750 IRR(Osw, Blo,Ro3, Rzero); 751 return; 752 } 753 op2(i, Olea, Ro3, 1); 754 if(c >= 32) { 755 IRR(Olw, Blo,Ro3, Ro1); 756 if((i->add&ARM) != AXNON) 757 op3(i, Olea, Ro3, 1); 758 IRR(Osw, Blo,Ro3, Rzero); 759 if(c > 32) 760 SRR(Osll, c-32, Ro1, Ro1); 761 IRR(Osw, Bhi,Ro3, Ro1); 762 return; 763 } 764 IRR(Olw, Blo,Ro3, Ro2); 765 IRR(Olw, Bhi,Ro3, Ro1); 766 if((i->add&ARM) != AXNON) 767 op3(i, Olea, Ro3, !c); 768 if(c != 0) { 769 SRR(Osrl, 32-c, Ro2, Ri); 770 SRR(Osll, c, Ro2, Ro2); 771 SRR(Osll, c, Ro1, Ro1); 772 RRR(Oor, Ri, Ro1, Ro1); 773 } 774 IRR(Osw, Blo,Ro3, Ro2); 775 IRR(Osw, Bhi,Ro3, Ro1); 776 } 777 778 static void 779 compdbg(void) 780 { 781 print("%s:%d@%.8ux\n", R.M->m->name, R.t, R.st); 782 } 783 784 static void 785 comp(Inst *i) 786 { 787 int o, q, b; 788 ulong *cp, *cp1; 789 char buf[64]; 790 791 if(0) { 792 Inst xx; 793 xx.add = AXIMM|SRC(AIMM); 794 xx.s.imm = (ulong)code; 795 xx.reg = i-mod->prog; 796 punt(&xx, SRCOP, compdbg); 797 } 798 799 switch(i->op) { 800 default: 801 snprint(buf, sizeof buf, "%s compile, no '%D'", mod->name, i); 802 error(buf); 803 break; 804 case IMCALL: 805 if((i->add&ARM) == AXIMM) 806 commcall(i); 807 else 808 punt(i, SRCOP|DSTOP|THREOP|WRTPC|NEWPC, optab[i->op]); 809 break; 810 case ISEND: 811 case IRECV: 812 case IALT: 813 punt(i, SRCOP|DSTOP|TCHECK|WRTPC, optab[i->op]); 814 break; 815 case ISPAWN: 816 punt(i, SRCOP|DBRAN, optab[i->op]); 817 break; 818 case IBNEC: 819 case IBEQC: 820 case IBLTC: 821 case IBLEC: 822 case IBGTC: 823 case IBGEC: 824 punt(i, SRCOP|DBRAN|NEWPC|WRTPC, optab[i->op]); 825 break; 826 case ICASEC: 827 comcase(i, 0); 828 punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); 829 break; 830 case ICASEL: 831 comcasel(i); 832 punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); 833 break; 834 case IADDC: 835 case IMULL: 836 case IDIVL: 837 case IMODL: 838 case ILSRL: 839 case IMNEWZ: 840 punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); 841 break; 842 case IMFRAME: 843 if((i->add&ARM) == AXIMM) 844 commframe(i); 845 else 846 punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); 847 break; 848 case ILOAD: 849 case INEWA: 850 case INEWAZ: 851 case INEW: 852 case INEWZ: 853 case ISLICEA: 854 case ISLICELA: 855 case ICONSB: 856 case ICONSW: 857 case ICONSL: 858 case ICONSF: 859 case ICONSM: 860 case ICONSMP: 861 case ICONSP: 862 case IMOVMP: 863 case IHEADL: 864 case IHEADMP: 865 case IINDC: 866 case ILENC: 867 case IINSC: 868 case ICVTAC: 869 case ICVTCW: 870 case ICVTWC: 871 case ICVTCL: 872 case ICVTLC: 873 case ICVTFC: 874 case ICVTCF: 875 case ICVTFL: 876 case ICVTLF: 877 case ICVTFR: 878 case ICVTRF: 879 case IMSPAWN: 880 case ICVTCA: 881 case ISLICEC: 882 case INBALT: 883 punt(i, SRCOP|DSTOP, optab[i->op]); 884 break; 885 case INEWCM: 886 case INEWCMP: 887 punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); 888 break; 889 case INEWCB: 890 case INEWCW: 891 case INEWCF: 892 case INEWCP: 893 case INEWCL: 894 punt(i, DSTOP|THREOP, optab[i->op]); 895 break; 896 case IEXIT: 897 punt(i, 0, optab[i->op]); 898 break; 899 case ICVTWB: 900 op13(i, Olw, Osb); 901 break; 902 case ICVTBW: 903 op13(i, Olbu, Osw); 904 break; 905 case ICVTWS: 906 op13(i, Olw, Osb); 907 break; 908 case ICVTSW: 909 op13(i, Olhu, Osw); 910 break; 911 case IMOVB: 912 op13(i, Olbu, Osb); 913 break; 914 case IMOVW: 915 if(USRC(i->add) == AIMM && i->s.imm == 0) { 916 op3(i, Osw, Rzero, 0); 917 break; 918 } 919 op13(i, Olw, Osw); 920 break; 921 case ICVTLW: 922 op1(i, Olea, Ro1, 1); 923 IRR(Olw, Blo,Ro1, Ro1); 924 delay(); 925 op3(i, Osw, Ro1, 0); 926 break; 927 case ICVTWL: 928 op1(i, Olw, Ro1, 0); 929 op3(i, Olea, Ro2, 0); 930 SRR(Osra, 31, Ro1, Ro3); 931 IRR(Osw, Blo,Ro2, Ro1); 932 IRR(Osw, Bhi,Ro2, Ro3); 933 break; 934 case IHEADM: 935 op1(i, Olw, Ro1, 1); 936 IRR(Oaddui, OA(List,data),Ro1, Ro1); 937 goto m1; 938 case IMOVM: 939 op1(i, Olea, Ro1, 0); 940 m1: 941 op2(i, Olw, Ro2, 0); 942 op3(i, Olea, Ro3, 0); 943 J(Ojal, base+macro[MacMOVM]); 944 xchg(); 945 break; 946 case IRET: 947 J(Oj, base+macro[MacRET]); 948 delay(); 949 break; 950 case IFRAME: 951 if(UXSRC(i->add) != SRC(AIMM)) { 952 punt(i, SRCOP|DSTOP, optab[i->op]); 953 break; 954 } 955 ldc((ulong)mod->type[i->s.imm], Ri); 956 J(Ojal, base+macro[MacFRAM]); 957 xchg(); 958 op3(i, Osw, Ro1, 0); 959 tinit[i->s.imm] = 1; 960 break; 961 case ILEA: 962 op13(i, Olea, Osw); 963 break; 964 case IHEADW: 965 op1(i, Olw, Ro1, 1); 966 IRR(Olw, OA(List,data),Ro1, Ro1); 967 delay(); 968 op3(i, Osw, Ro1, 0); 969 break; 970 case IHEADF: 971 op1(i, Olw, Ro1, 1); 972 IRR(Olw, OA(List,data),Ro1, Ro2); 973 IRR(Olw, OA(List,data)+4,Ro1, Ro3); 974 op3(i, Olea, Ro1, 1); 975 IRR(Osw, 0,Ro1, Ro2); 976 IRR(Osw, 4,Ro1, Ro3); 977 break; 978 case IHEADB: 979 op1(i, Olw, Ro1, 1); 980 IRR(Olbu , OA(List,data),Ro1, Ro1); 981 delay(); 982 op3(i, Osb, Ro1, 0); 983 break; 984 case ITAIL: 985 op1(i, Olw, Ro1, 1); 986 IRR(Olw, O(List,tail),Ro1, Ro1); 987 goto movp; 988 case IMOVP: 989 op1(i, Olw, Ro1, 0); 990 goto movp; 991 case IHEADP: 992 op1(i, Olw, Ro1, 1); 993 IRR(Olw, OA(List,data),Ro1, Ro1); 994 movp: 995 ldc((ulong)H, Ro2); 996 cp = code; 997 BRRI(Obeq,Ro1,Ro2,0); 998 ldbigc((ulong)&mutator, Ri); 999 J(Ojal, base+macro[MacCOLR]); 1000 xchg(); 1001 *cp |= (code - cp) - 1; 1002 op3(i, Olea, Ro3, 1); 1003 IRR(Olw, 0,Ro3, Ri); 1004 J(Ojal, base+macro[MacFRP]); 1005 IRR(Osw, 0,Ro3, Ro1); 1006 break; 1007 case ILENA: 1008 op1(i, Olw, Ri, 0); 1009 J(Ojal, base+macro[MacLENA]); 1010 xchg(); 1011 op3(i, Osw, Ro1, 0); 1012 break; 1013 case ILENL: 1014 op1(i, Olw, Ro1, 0); 1015 ldc((ulong)H, Ro2); 1016 cp = code; 1017 BRRI(Obeq, Ro1,Ro2, 0); 1018 ldc(0, Ro3); 1019 1020 cp1 = code; 1021 IRR(Olw, O(List,tail),Ro1, Ro1); 1022 IRR(Oaddui, 1,Ro3, Ro3); 1023 BRRI(Obne, Ro1,Ro2, (cp1-code)-1); 1024 delay(); 1025 1026 *cp |= (code - cp) - 1; 1027 op3(i, Osw, Ro3, 0); 1028 break; 1029 case IMOVL: 1030 case IMOVF: 1031 op1(i, Olea, Ro1, 1); 1032 IRR(Olw, 0,Ro1, Ro2); 1033 IRR(Olw, 4,Ro1, Ro3); 1034 op3(i, Olea, Ro1, 1); 1035 IRR(Osw, 0,Ro1, Ro2); 1036 IRR(Osw, 4,Ro1, Ro3); 1037 break; 1038 case ICVTFW: 1039 op1(i, Olea, Ro1, 1); 1040 IRR(Olf, Bhi,Ro1, Rf2+1); 1041 IRR(Olf, Blo,Ro1, Rf2); 1042 delay(); 1043 FRRR(Ocvtfw, 0, Rf2, Rf2); 1044 op3(i, Olea, Ro2, 1); 1045 IRR(Osf, 0,Ro2, Rf2); 1046 break; 1047 case ICVTWF: 1048 op1(i, Olea, Ro1, 1); 1049 IRR(Olf, 0,Ro1, Rf2); 1050 delay(); 1051 FRRR(Ocvtwf, 0, Rf2, Rf2); 1052 op3(i, Olea, Ro2, 1); 1053 IRR(Osf, Bhi,Ro2, Rf2+1); 1054 IRR(Osf, Blo,Ro2, Rf2); 1055 break; 1056 case INEGF: 1057 op1(i, Olea, Ro1, 1); 1058 IRR(Olf, Bhi,Ro1, Rf1+1); 1059 IRR(Olf, Blo,Ro1, Rf1); 1060 op3(i, Olea, Ro2, 1); 1061 FRRR(Onegf, 0, Rf1,Rf2); 1062 IRR(Osf, Bhi,Ro2, Rf2+1); 1063 IRR(Osf, Blo,Ro2, Rf2); 1064 break; 1065 case IXORL: 1066 case IORL: 1067 case IANDL: 1068 case IADDL: 1069 case ISUBL: 1070 op1(i, Olea, Ro1, 0); 1071 op2(i, Olea, Ro3, 0); 1072 1073 IRR(Olw, Blo,Ro1, Rj); /* ls */ 1074 IRR(Olw, Blo,Ro3, Ro2); 1075 IRR(Olw, Bhi,Ro1, Ri); /* ms */ 1076 IRR(Olw, Bhi,Ro3, Ro1); 1077 1078 switch(i->op) { 1079 case IXORL: 1080 o = Oxor; 1081 goto l1; 1082 case IORL: 1083 o = Oor; 1084 goto l1; 1085 case IANDL: 1086 o = Oand; 1087 l1: 1088 RRR(o, Ri,Ro1, Ro1); 1089 RRR(o, Rj,Ro2, Ro2); 1090 break; 1091 case IADDL: 1092 RRR(Oaddu, Ri,Ro1, Ro1); 1093 RRR(Oaddu, Rj,Ro2, Ro2); 1094 RRR(Osltu, Rj,Ro2, Ri); 1095 RRR(Oaddu, Ri,Ro1, Ro1); 1096 break; 1097 case ISUBL: 1098 RRR(Osubu, Ri,Ro1, Ro1); 1099 RRR(Osltu, Rj,Ro2, Ri); 1100 RRR(Osubu, Rj,Ro2, Ro2); 1101 RRR(Osubu, Ri,Ro1, Ro1); 1102 break; 1103 } 1104 if((i->add&ARM) != AXNON) 1105 op3(i, Olea, Ro3, 1); 1106 IRR(Osw, Bhi,Ro3, Ro1); 1107 IRR(Osw, Blo,Ro3, Ro2); 1108 break; 1109 case ISHLL: 1110 shll(i); 1111 break; 1112 case ISHRL: 1113 shrl(i); 1114 break; 1115 case IADDF: 1116 case ISUBF: 1117 case IMULF: 1118 case IDIVF: 1119 case IBEQF: 1120 case IBGEF: 1121 case IBGTF: 1122 case IBLEF: 1123 case IBLTF: 1124 case IBNEF: 1125 op1(i, Olea, Ro1, 0); 1126 op2(i, Olea, Ro2, 0); 1127 IRR(Olf, Bhi,Ro1, Rf1+1); 1128 IRR(Olf, Blo,Ro1, Rf1); 1129 IRR(Olf, Bhi,Ro2, Rf2+1); 1130 IRR(Olf, Blo,Ro2, Rf2); 1131 switch(i->op) { 1132 case IADDF: o = Oaddf; goto f1; 1133 case ISUBF: o = Osubf; goto f1; 1134 case IMULF: o = Omulf; goto f1; 1135 case IDIVF: o = Odivf; goto f1; 1136 case IBEQF: o = Ofeq; q = Obrt; goto f2; 1137 case IBGEF: o = Oflt; q = Obrf; goto f3; 1138 case IBGTF: o = Oflt; q = Obrt; goto f2; 1139 case IBLEF: o = Oflt; q = Obrf; goto f2; 1140 case IBLTF: o = Oflt; q = Obrt; goto f3; 1141 case IBNEF: o = Ofeq; q = Obrf; goto f2; 1142 f1: 1143 op3(i, Olea, Ro1, 0); 1144 FRRR(o, Rf1,Rf2, Rf2); 1145 IRR(Osf, Bhi,Ro1, Rf2+1); 1146 IRR(Osf, Blo,Ro1, Rf2); 1147 break; 1148 f2: 1149 delay(); 1150 FRRR(o, Rf1,Rf2, 0); 1151 goto f4; 1152 f3: 1153 delay(); 1154 FRRR(o, Rf2,Rf1, 0); 1155 goto f4; 1156 f4: 1157 delay(); 1158 FI(q, branch(i)); 1159 delay(); 1160 break; 1161 } 1162 break; 1163 1164 case IBLTB: 1165 case IBLEB: 1166 case IBGTB: 1167 case IBGEB: 1168 case IBEQB: 1169 case IBNEB: 1170 b = 1; 1171 goto s1; 1172 case IBLTW: 1173 case IBLEW: 1174 case IBGTW: 1175 case IBGEW: 1176 case IBEQW: 1177 case IBNEW: 1178 b = 0; 1179 s1: 1180 op12(i, b, b); 1181 switch(i->op) { 1182 case IBLTB: 1183 case IBLTW: o = Obne; goto b1; 1184 case IBGEB: 1185 case IBGEW: o = Obeq; goto b1; 1186 case IBGTB: 1187 case IBGTW: o = Obne; goto b2; 1188 case IBLEB: 1189 case IBLEW: o = Obeq; goto b2; 1190 case IBEQB: 1191 case IBEQW: o = Obeq; goto b3; 1192 case IBNEB: 1193 case IBNEW: o = Obne; goto b3; 1194 b1: RRR(Oslt, Ro2,Ro1, Ro3); 1195 BRI(o,Ro3, branch(i)); 1196 break; 1197 b2: RRR(Oslt, Ro1,Ro2, Ro3); 1198 BRI(o,Ro3, branch(i)); 1199 break; 1200 b3: BRRI(o, Ro2,Ro1, branch(i)); 1201 break; 1202 } 1203 delay(); 1204 break; 1205 1206 case IBEQL: 1207 cbral(i, Obeq, ANDAND); 1208 break; 1209 case IBNEL: 1210 cbral(i, Obne, OROR); 1211 break; 1212 case IBLEL: 1213 cbral(i, Obeq, EQAND|REV1); 1214 break; 1215 case IBGTL: 1216 cbral(i, Obne, EQAND); 1217 break; 1218 case IBLTL: 1219 cbral(i, Obne, EQAND|REV1|REV2); 1220 break; 1221 case IBGEL: 1222 cbral(i, Obeq, EQAND|REV2); 1223 break; 1224 1225 case ISUBB: 1226 case IADDB: 1227 case IANDB: 1228 case IORB: 1229 case IXORB: 1230 case IMODB: 1231 case IDIVB: 1232 case IMULB: 1233 b = 1; 1234 op12(i, b, b); 1235 goto s2; 1236 case ISHLB: 1237 case ISHRB: 1238 b = 1; 1239 op12(i, 0, b); 1240 goto s2; 1241 case ISUBW: 1242 case IADDW: 1243 case IANDW: 1244 case IORW: 1245 case IXORW: 1246 case ISHLW: 1247 case ISHRW: 1248 case IMODW: 1249 case IDIVW: 1250 case IMULW: 1251 b = 0; 1252 op12(i, b, b); 1253 s2: 1254 switch(i->op) { 1255 case IADDB: 1256 case IADDW: o = Oaddu; goto c1; 1257 case ISUBB: 1258 case ISUBW: o = Osubu; goto c1; 1259 case IANDB: 1260 case IANDW: o = Oand; goto c1; 1261 case IORB: 1262 case IORW: o = Oor; goto c1; 1263 case IXORB: 1264 case IXORW: o = Oxor; goto c1; 1265 c1: 1266 RRR(o, Ro1,Ro2, Ro3); 1267 break; 1268 case ISHLB: 1269 case ISHLW: o = Osllv; goto c2; 1270 case ILSRW: o = Osrlv; goto c2; 1271 case ISHRB: 1272 case ISHRW: o = Osrav; goto c2; 1273 c2: 1274 RRR(o, Ro2,Ro1, Ro3); 1275 break; 1276 case IMULB: 1277 case IMULW: q = Omul; o = Omflo; goto c3; 1278 case IDIVB: 1279 case IDIVW: q = Odiv; o = Omflo; goto c3; 1280 case IMODB: 1281 case IMODW: q = Odiv; o = Omfhi; goto c3; 1282 c3: 1283 RRR(q, Ro1,Ro2, Rzero); 1284 RRR(o, Rzero,Rzero, Ro3); 1285 break; 1286 } 1287 op3(i, b? Osb: Osw, Ro3, 0); 1288 break; 1289 case ICALL: 1290 op1(i, Olw, Ro1, 0); 1291 ldbigc((ulong)(base+patch[i-mod->prog+1]), Ro2); 1292 IRR(Osw, O(Frame,lr),Ro1, Ro2); 1293 IRR(Osw, O(Frame,fp),Ro1, Rfp); 1294 J(Oj, base+patch[(Inst*)i->d.imm - mod->prog]); 1295 RRR(Oaddu, Ro1,Rzero, Rfp); 1296 break; 1297 case IJMP: 1298 J(Oj, base+patch[(Inst*)i->d.imm - mod->prog]); 1299 delay(); 1300 break; 1301 case IGOTO: 1302 comgoto(i); 1303 break; 1304 case IINDX: 1305 op1(i, Olw, Ro1, 0); /* Ro1 = a */ 1306 op3(i, Olw, Ro3, 0); /* Ro2 = i */ 1307 J(Ojal, base+macro[MacINDX]); 1308 xchg(); 1309 op2(i, Osw, Ro2, 0); 1310 break; 1311 case IINDB: 1312 case IINDF: 1313 case IINDW: 1314 case IINDL: 1315 op1(i, Olw, Ro1, 0); /* Ro1 = a */ 1316 op3(i, Olw, Ro3, 0); /* Ro3 = i */ 1317 IRR(Olw, O(Array,data),Ro1, Ro1); /* Ro1 = a->data */ 1318 switch(i->op) { 1319 case IINDL: 1320 case IINDF: 1321 SRR(Osll, 3, Ro3, Ro3); /* Ro3 = i*8 */ 1322 break; 1323 case IINDW: 1324 SRR(Osll, 2, Ro3, Ro3); /* Ro3 = i*4 */ 1325 break; 1326 case IINDB: 1327 delay(); 1328 break; 1329 } 1330 RRR(Oaddu, Ro1,Ro3, Ro2); /* Ro2 = i*size + data */ 1331 op2(i, Osw, Ro2, 0); 1332 break; 1333 case ICASE: 1334 comcase(i, 1); 1335 break; 1336 case IRAISE: 1337 punt(i, SRCOP|WRTPC|NEWPC, optab[i->op]); 1338 break; 1339 case IMULX: 1340 case IDIVX: 1341 case ICVTXX: 1342 case IMULX0: 1343 case IDIVX0: 1344 case ICVTXX0: 1345 case IMULX1: 1346 case IDIVX1: 1347 case ICVTXX1: 1348 case ICVTFX: 1349 case ICVTXF: 1350 case IEXPW: 1351 case IEXPL: 1352 case IEXPF: 1353 punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); 1354 break; 1355 case ISELF: 1356 punt(i, DSTOP, optab[i->op]); 1357 break; 1358 } 1359 } 1360 1361 static void 1362 preamble(void) 1363 { 1364 ldc((ulong)&R, Rreg); 1365 IRR(Olw, O(REG,PC),Rreg, Ri); 1366 IRR(Olw, O(REG,FP),Rreg, Rfp); 1367 IRR(Olw, O(REG,MP),Rreg, Rmp); 1368 IRR(Osw, O(REG,xpc),Rreg, Rlink); 1369 JR(Ojr, Ri); 1370 delay(); 1371 } 1372 1373 static void 1374 macfrp(void) 1375 { 1376 ulong *cp1, *cp2; 1377 1378 ldc((ulong)H, Ro1); 1379 cp1 = code; 1380 BRRI(Obeq, Ri,Ro1, 0); // arg == $H 1381 delay(); 1382 1383 IRR(Olw, O(Heap,ref)-sizeof(Heap),Ri, Ro2); 1384 ldc((ulong)1, Ro1); 1385 cp2 = code; 1386 BRRI(Obeq, Ro1,Ro2, 0); // ref(arg) == $1 1387 IRR(Oaddui, -1,Ro2, Ro2); // ref(arg)-- 1388 JR(Ojr, Rlink); 1389 IRR(Osw, O(Heap,ref)-sizeof(Heap),Ri, Ro2); 1390 1391 *cp2 |= (code - cp2) - 1; 1392 IRR(Osw, O(REG,st),Rreg, Rlink); 1393 IRR(Osw, O(REG,FP),Rreg, Rfp); 1394 1395 ldc((ulong)rdestroy, Rpic); 1396 JR(Ojalr, Rpic); // CALL destroy 1397 IRR(Osw, O(REG,s),Rreg, Ri); 1398 1399 ldc((ulong)&R, Rreg); 1400 IRR(Olw, O(REG,st),Rreg, Rlink); 1401 IRR(Olw, O(REG,FP),Rreg, Rfp); 1402 IRR(Olw, O(REG,MP),Rreg, Rmp); 1403 1404 *cp1 |= (code - cp1) - 1; 1405 JR(Ojr, Rlink); 1406 delay(); 1407 } 1408 1409 static void 1410 macret(void) 1411 { 1412 ulong *cp1, *cp2, *cp3, *cp4, *cp5, *cp6; 1413 Inst i; 1414 1415 // NOTE this needs to be scheduled 1416 1417 IRR(Olw, O(Frame,t),Rfp, Ro1); 1418 delay(); 1419 cp1 = code; 1420 BRRI(Obeq, Ro1,Rzero, 0); // t(Rfp) == 0 1421 delay(); 1422 1423 IRR(Olw, O(Type,destroy),Ro1, Rpic); 1424 delay(); 1425 cp2 = code; 1426 BRRI(Obeq, Rpic,Rzero, 0); // destroy(t(fp)) == 0 1427 delay(); 1428 1429 IRR(Olw, O(Frame,fp),Rfp, Ro2); 1430 delay(); 1431 cp3 = code; 1432 BRRI(Obeq, Ro2,Rzero, 0); // fp(Rfp) == 0 1433 delay(); 1434 1435 IRR(Olw, O(Frame,mr),Rfp, Ro3); 1436 delay(); 1437 cp4 = code; 1438 BRRI(Obeq, Ro3,Rzero, 0); // mr(Rfp) == 0 1439 delay(); 1440 1441 IRR(Olw, O(REG,M),Rreg, Ro2); 1442 delay(); 1443 IRR(Olw, O(Heap,ref)-sizeof(Heap),Ro2, Ro3); 1444 delay(); 1445 IRR(Oaddui, -1,Ro3, Ro3); 1446 cp5 = code; 1447 BRRI(Obeq, Ro3,Rzero, 0); // --ref(arg) == 0 1448 delay(); 1449 IRR(Osw, O(Heap,ref)-sizeof(Heap),Ro2, Ro3); 1450 1451 IRR(Olw, O(Frame,mr),Rfp, Ro1); 1452 delay(); 1453 IRR(Osw, O(REG,M),Rreg, Ro1); 1454 IRR(Olw, O(Modlink,compiled),Ro1, Ro2); // check for uncompiled module 1455 IRR(Olw, O(Modlink,MP),Ro1, Rmp); 1456 cp6 = code; 1457 BRRI(Obeq, Ro2,Rzero, 0); 1458 IRR(Osw, O(REG,MP),Rreg, Rmp); 1459 1460 *cp4 |= (code - cp4) - 1; 1461 JR(Ojalr, Rpic); // call destroy(t(fp)) 1462 delay(); 1463 IRR(Osw, O(REG,SP),Rreg, Rfp); 1464 IRR(Olw, O(Frame,lr),Rfp, Ro1); 1465 IRR(Olw, O(Frame,fp),Rfp, Rfp); 1466 IRR(Osw, O(REG,FP),Rreg, Rfp); 1467 JR(Ojr, Ro1); // goto lr(Rfp) 1468 delay(); 1469 1470 *cp6 |= (code - cp6) - 1; // returning to uncompiled module 1471 JR(Ojalr, Rpic); // call destroy(t(fp)) 1472 delay(); 1473 IRR(Osw, O(REG,SP),Rreg, Rfp); 1474 IRR(Olw, O(Frame,lr),Rfp, Ro1); 1475 IRR(Olw, O(Frame,fp),Rfp, Rfp); 1476 IRR(Osw, O(REG,FP),Rreg, Rfp); 1477 IRR(Olw, O(REG,xpc),Rreg, Ro2); 1478 JR(Ojr, Ro2); // return to uncompiled code 1479 IRR(Osw, O(REG,PC),Rreg, Ro1); 1480 1481 *cp1 |= (code - cp1) - 1; 1482 *cp2 |= (code - cp2) - 1; 1483 *cp3 |= (code - cp3) - 1; 1484 *cp5 |= (code - cp5) - 1; 1485 i.add = AXNON; 1486 punt(&i, TCHECK|NEWPC, optab[IRET]); 1487 } 1488 1489 static void 1490 macindx(void) 1491 { 1492 1493 IRR(Olw, O(Array,t),Ro1, Ro2); 1494 IRR(Olw, O(Array,data),Ro1, Ro1); // Ro1 = data 1495 IRR(Olw, O(Type,size),Ro2, Ro2); // Ro2 = size 1496 delay(); 1497 1498 RRR(Omul, Ro3,Ro2,Rzero); // Ro2 = i*size 1499 RRR(Omflo, Rzero,Rzero,Ro2); 1500 JR(Ojr, Rlink); 1501 RRR(Oaddu, Ro1,Ro2,Ro2); // Ro2 = i*size + data 1502 } 1503 1504 static void 1505 maccase(void) 1506 { 1507 ulong *cp1, *cp2, *cp3; 1508 1509 /* 1510 * Ro1 = value (input arg), t 1511 * Ro2 = count, n 1512 * Ro3 = table pointer (input arg) 1513 * Ri = n/2, n2 1514 * Rj = pivot element t+n/2*3, l 1515 */ 1516 1517 IRR(Olw, 0,Ro3, Ro2); // count 1518 IRR(Oaddui, 0,Ro3, Rlink); // initial table pointer 1519 1520 cp1 = code; // loop: 1521 BRI(Oblez,Ro2, 0); // n <= 0? goto out 1522 SRR(Osra, 1, Ro2, Ri); // n2 = n>>1 1523 SRR(Osll, 1, Ri, Rj); 1524 RRR(Oaddu, Rj, Ri, Rj); 1525 SRR(Osll, 2, Rj, Rj); 1526 RRR(Oaddu, Ro3, Rj, Rj); // l = t + n2*3; 1527 IRR(Olw, 4,Rj, Rpic); 1528 delay(); 1529 RRR(Oslt, Rpic, Ro1, Rpic); 1530 cp2 = code; 1531 BRI(Obne, Rpic, 0); // v < l[1]? goto low 1532 delay(); 1533 1534 IRR(Olw, 8,Rj, Rpic); 1535 delay(); 1536 RRR(Oslt, Rpic, Ro1, Rpic); 1537 cp3 = code; 1538 BRI(Obeq, Rpic, 0); // v >= l[2]? goto high 1539 delay(); 1540 1541 IRR(Olw, 12,Rj, Ro3); // found 1542 delay(); 1543 JR(Ojr, Ro3); 1544 delay(); 1545 1546 *cp2 |= (code - cp2) - 1; // low: 1547 BRRI(Obeq, Rzero,Rzero, (cp1-code)-1); 1548 IRR(Oaddui, 0, Ri, Ro2); // n = n2 1549 1550 *cp3 |= (code - cp3) - 1; // high: 1551 IRR(Oaddui, 12, Rj, Ro3); // t = l+3; 1552 IRR(Oaddui, 1, Ri, Rpic); 1553 BRRI(Obeq, Rzero,Rzero, (cp1-code)-1); 1554 RRR(Osubu, Rpic, Ro2, Ro2); // n -= n2 + 1 1555 1556 *cp1 |= (code - cp1) - 1; // out: 1557 IRR(Olw, 0,Rlink, Ro2); // initial n 1558 delay(); 1559 SRR(Osll, 1, Ro2, Ro3); 1560 RRR(Oaddu, Ro3, Ro2, Ro2); 1561 SRR(Osll, 2, Ro2, Ro2); 1562 RRR(Oaddu, Ro2, Rlink, Rlink); 1563 IRR(Olw, 4,Rlink, Ro3); // (initital t)[n*3+1] 1564 delay(); 1565 JR(Ojr, Ro3); 1566 delay(); 1567 } 1568 1569 static void 1570 maclena(void) 1571 { 1572 ulong *cp; 1573 1574 ldc((ulong)H, Ro1); 1575 cp = code; 1576 BRRI(Obeq, Ri,Ro1, 0); 1577 delay(); 1578 IRR(Olw, O(Array,len),Ri, Ro1); 1579 JR(Ojr, Rlink); 1580 delay(); 1581 *cp |= (code - cp) - 1; 1582 JR(Ojr, Rlink); 1583 ldc(0, Ro1); 1584 } 1585 1586 static void 1587 macmcal(void) 1588 { 1589 ulong *cp1, *cp2; 1590 1591 IRR(Olw, O(Modlink,prog),Ri, Ro2); 1592 IRR(Osw, O(Frame,lr),Ro1, Rlink); // f->lr = return 1593 cp1 = code; 1594 BRRI(Obne, Ro2, Rzero, 0); // CMPL ml->m->prog != 0 1595 IRR(Oaddui, 0,Ro1, Rfp); // R.FP = f 1596 1597 IRR(Osw, O(REG,st),Rreg, Rlink); 1598 ldc((ulong)rmcall, Rpic); 1599 IRR(Osw, O(REG,FP),Rreg, Ro1); 1600 IRR(Osw, O(REG,dt),Rreg, Rj); 1601 JR(Ojalr, Rpic); // CALL rmcall 1602 xchg(); 1603 ldc((ulong)&R, Rreg); 1604 IRR(Olw, O(REG,st),Rreg, Rlink); 1605 IRR(Olw, O(REG,FP),Rreg, Rfp); 1606 IRR(Olw, O(REG,MP),Rreg, Rmp); 1607 JR(Ojr, Rlink); 1608 delay(); 1609 1610 *cp1 |= (code - cp1) - 1; 1611 IRR(Olw, O(Heap,ref)-sizeof(Heap),Ri, Ro2); 1612 IRR(Osw, O(REG,M),Rreg, Ri); 1613 IRR(Oaddui, 1,Ro2, Ro2); 1614 IRR(Olw, O(Modlink,MP),Ri, Rmp); 1615 IRR(Olw, O(Modlink,compiled),Ri, Ro1); 1616 IRR(Osw, O(Heap,ref)-sizeof(Heap),Ri, Ro2); 1617 cp2 = code; 1618 BRRI(Obeq, Ro1,Rzero, 0); 1619 IRR(Osw, O(REG,MP),Rreg, Rmp); 1620 1621 JR(Ojr, Rj); 1622 delay(); 1623 1624 *cp2 |= (code - cp2) - 1; 1625 IRR(Osw, O(REG,FP),Rreg, Rfp); // call to uncompiled code 1626 IRR(Olw, O(REG,xpc),Rreg, Ro1); 1627 JR(Ojr, Ro1); 1628 IRR(Osw, O(REG,PC),Rreg, Rj); 1629 } 1630 1631 static void 1632 macmfra(void) 1633 { 1634 ldc((ulong)rmfram, Rpic); 1635 IRR(Osw, O(REG,st),Rreg, Rlink); 1636 IRR(Osw, O(REG,FP),Rreg, Rfp); 1637 IRR(Osw, O(REG,s),Rreg, Ri); 1638 IRR(Osw, O(REG,d),Rreg, Rj); 1639 JR(Ojalr, Rpic); // CALL rmfram 1640 xchg(); 1641 ldc((ulong)&R, Rreg); 1642 IRR(Olw, O(REG,st),Rreg, Rlink); 1643 IRR(Olw, O(REG,FP),Rreg, Rfp); 1644 IRR(Olw, O(REG,MP),Rreg, Rmp); 1645 JR(Ojr, Rlink); 1646 delay(); 1647 } 1648 1649 static void 1650 macfram(void) 1651 { 1652 ulong *cp; 1653 1654 /* 1655 * Ri has t 1656 */ 1657 IRR(Olw, O(Type,initialize),Ri, Rj); 1658 IRR(Olw, O(Type,size),Ri, Ro3); // MOVL $t->size, Ro3 1659 IRR(Olw, O(REG,SP),Rreg, Ro2); // MOVL R.SP, Ro2 1660 IRR(Olw, O(REG,TS),Rreg, Ro1); // MOVL R.TS, Ro1 1661 RRR(Oaddu,Ro3,Ro2, Ro2); // ADDL $t->size, Ro2 1662 RRR(Osltu, Ro1,Ro2, Ro3); // CMP Ro1,Ro2,Ro3 1663 cp = code; 1664 BRI(Obne,Ro3,0); // BLT Ro3,** 1665 delay(); 1666 1667 IRR(Osw, O(REG,s),Rreg, Ri); // MOVL t, R.s 1668 IRR(Osw, O(REG,st),Rreg, Rlink); // MOVL Rlink, R.st 1669 ldc((ulong)extend, Rpic); 1670 JR(Ojalr, Rpic); // CALL extend 1671 IRR(Osw, O(REG,FP),Rreg, Rfp); // MOVL RFP, R.FP 1672 ldc((ulong)&R, Rreg); 1673 IRR(Olw, O(REG,st),Rreg, Rlink); // reload registers 1674 IRR(Olw, O(REG,FP),Rreg, Rfp); 1675 IRR(Olw, O(REG,MP),Rreg, Rmp); 1676 IRR(Olw, O(REG,s),Rreg, Ro1); // return arg 1677 JR(Ojr, Rlink); 1678 delay(); 1679 1680 *cp |= (code - cp) - 1; 1681 IRR(Olw, O(REG,SP),Rreg, Ro1); 1682 IRR(Osw, O(REG,SP),Rreg, Ro2); 1683 IRR(Osw, O(Frame,mr),Ro1, Rzero); 1684 JR(Ojr, Rj); // return from tinit to main program 1685 IRR(Osw, O(Frame,t),Ro1, Ri); 1686 } 1687 1688 static void 1689 macmovm(void) 1690 { 1691 ulong *cp1, *cp2; 1692 1693 /* 1694 * from = Ro1 1695 * to = Ro3 1696 * count = Ro2 1697 */ 1698 1699 cp1 = code; 1700 BRRI(Obeq, Ro2, Rzero, 0); 1701 delay(); 1702 1703 cp2 = code; 1704 IRR(Olbu, 0,Ro1, Ri); 1705 IRR(Oaddui, -1,Ro2, Ro2); 1706 IRR(Osb, 0,Ro3, Ri); 1707 IRR(Oaddui, 1,Ro1, Ro1); 1708 BRRI(Obne, Ro2, Rzero, (cp2-code)-1); 1709 IRR(Oaddui, 1,Ro3, Ro3); 1710 1711 *cp1 |= (code - cp1) - 1; 1712 JR(Ojr, Rlink); 1713 delay(); 1714 } 1715 1716 static void 1717 maccolr(void) 1718 { 1719 ulong *cp; 1720 1721 IRR(Olw, 0,Ri, Ri); 1722 IRR(Olw, O(Heap,color)-sizeof(Heap),Ro1, Ro3); 1723 1724 IRR(Olw, O(Heap,ref)-sizeof(Heap),Ro1, Ro2); 1725 1726 cp = code; 1727 BRRI(Obeq, Ri, Ro3, 0); 1728 IRR(Oaddui, 1,Ro2, Ro2); 1729 1730 ldc(propagator, Ro3); 1731 IRR(Osw, O(Heap,color)-sizeof(Heap),Ro1, Ro3); 1732 ldc((ulong)&nprop, Ro3); 1733 IRR(Osw, 0,Ro3, Ro1); 1734 1735 *cp |= (code - cp) - 1; 1736 JR(Ojr, Rlink); 1737 IRR(Osw, O(Heap,ref)-sizeof(Heap),Ro1, Ro2); 1738 } 1739 1740 static void 1741 macend(void) 1742 { 1743 } 1744 1745 void 1746 comd(Type *t) 1747 { 1748 int i, j, m, c; 1749 1750 IRR(Osw, O(REG,dt),Rreg, Rlink); 1751 for(i = 0; i < t->np; i++) { 1752 c = t->map[i]; 1753 j = i<<5; 1754 for(m = 0x80; m != 0; m >>= 1) { 1755 if(c & m) { 1756 J(Ojal, base+macro[MacFRP]); 1757 IRR(Olw, j,Rfp, Ri); 1758 } 1759 j += sizeof(WORD*); 1760 } 1761 } 1762 IRR(Olw, O(REG,dt),Rreg, Rlink); 1763 delay(); 1764 JR(Ojr, Rlink); 1765 delay(); 1766 } 1767 1768 void 1769 comi(Type *t) 1770 { 1771 int i, j, m, c; 1772 1773 ldc((ulong)H, Ri); 1774 for(i = 0; i < t->np; i++) { 1775 c = t->map[i]; 1776 j = i<<5; 1777 for(m = 0x80; m != 0; m >>= 1) { 1778 if(c & m) 1779 IRR(Osw, j,Ro1, Ri); 1780 j += sizeof(WORD*); 1781 } 1782 } 1783 JR(Ojr, Rlink); 1784 xchg(); 1785 } 1786 1787 void 1788 typecom(Type *t) 1789 { 1790 int n; 1791 ulong *tmp, *start; 1792 1793 if(t == nil || t->initialize != 0) 1794 return; 1795 1796 tmp = mallocz(4096, 0); 1797 if(tmp == nil) 1798 return; 1799 code = tmp; 1800 comi(t); 1801 n = code - tmp; 1802 code = tmp; 1803 comd(t); 1804 n += code - tmp; 1805 free(tmp); 1806 1807 n *= sizeof(*code); 1808 code = mallocz(n, 0); 1809 if(code == nil) 1810 return; 1811 1812 start = code; 1813 t->initialize = code; 1814 comi(t); 1815 t->destroy = code; 1816 comd(t); 1817 1818 segflush(start, n); 1819 1820 if(cflag > 1) 1821 print("typ= %.8p %4d i %.8p d %.8p asm=%d\n", 1822 t, t->size, t->initialize, t->destroy, n); 1823 } 1824 1825 static void 1826 patchex(Module *m, ulong *p) 1827 { 1828 Handler *h; 1829 Except *e; 1830 1831 if((h = m->htab) == nil) 1832 return; 1833 for( ; h->etab != nil; h++){ 1834 h->pc1 = p[h->pc1]; 1835 h->pc2 = p[h->pc2]; 1836 for(e = h->etab; e->s != nil; e++) 1837 e->pc = p[e->pc]; 1838 if(e->pc != -1) 1839 e->pc = p[e->pc]; 1840 } 1841 } 1842 1843 int 1844 compile(Module *m, int size, Modlink *ml) 1845 { 1846 Link *l; 1847 Modl *e; 1848 int i, n; 1849 ulong *s, tmp[512]; 1850 1851 patch = mallocz(size*sizeof(*patch), 0); 1852 tinit = malloc(m->ntype*sizeof(*tinit)); 1853 base = 0; 1854 1855 if(!comvec) { 1856 i = 10; /* length of comvec */ 1857 code = malloc(i*sizeof(*code)); 1858 s = code; 1859 preamble(); 1860 if(code >= (ulong*)(s + i)) 1861 urk("preamble"); 1862 comvec = (void*)s; 1863 segflush(s, i*sizeof(*s)); 1864 if(cflag > 1) { 1865 print("comvec\n"); 1866 while(s < code) 1867 das(s++); 1868 }/**/ 1869 } 1870 1871 mod = m; 1872 n = 0; 1873 regdelay = 0; 1874 pass = 0; 1875 nlit = 0; 1876 1877 for(i = 0; i < size; i++) { 1878 code = tmp; 1879 comp(&m->prog[i]); 1880 if(code >= &tmp[nelem(tmp)]) { 1881 print("%3d %D\n", i, &m->prog[i]); 1882 urk("tmp ovflo"); 1883 } 1884 patch[i] = n; 1885 n += code - tmp; 1886 } 1887 1888 for(i=0; macinit[i].f; i++) { 1889 code = tmp; 1890 (*macinit[i].f)(); 1891 macro[macinit[i].o] = n; 1892 n += code - tmp; 1893 } 1894 1895 base = malloc((n+nlit)*sizeof(*base)); 1896 if(cflag > 1) 1897 print("dis=%5d %5d mips=%5d asm=%.8p lit=%d: %s\n", 1898 size, size*sizeof(Inst), n, base, nlit, m->name); 1899 1900 pass++; 1901 code = base; 1902 litpool = base+n; 1903 n = 0; 1904 nlit = 0; 1905 regdelay = 0; 1906 1907 for(i = 0; i < size; i++) { 1908 s = code; 1909 comp(&m->prog[i]); 1910 if(patch[i] != n) { 1911 print("%3d %D\n", i, &m->prog[i]); 1912 urk(exCphase); 1913 } 1914 n += code - s; 1915 if(cflag > 1) { 1916 print("%3d %D\n", i, &m->prog[i]); 1917 while(s < code) 1918 das(s++); 1919 }/**/ 1920 } 1921 1922 for(i=0; macinit[i].f; i++) { 1923 if(macro[macinit[i].o] != n) { 1924 print("macinit %d\n", macinit[i].o); 1925 urk(exCphase); 1926 } 1927 s = code; 1928 (*macinit[i].f)(); 1929 n += code - s; 1930 if(cflag > 1) { 1931 print("macinit %d\n", macinit[i].o); 1932 while(s < code) 1933 das(s++); 1934 }/**/ 1935 } 1936 1937 for(l = m->ext; l->name; l++) { 1938 l->u.pc = (Inst*)(base+patch[l->u.pc-m->prog]); 1939 typecom(l->frame); 1940 } 1941 if(ml != nil) { 1942 e = &ml->links[0]; 1943 for(i = 0; i < ml->nlinks; i++) { 1944 e->u.pc = (Inst*)(base+patch[e->u.pc-m->prog]); 1945 typecom(e->frame); 1946 e++; 1947 } 1948 } 1949 for(i = 0; i < m->ntype; i++) { 1950 if(tinit[i] != 0) 1951 typecom(m->type[i]); 1952 } 1953 patchex(m, patch); 1954 m->entry = (Inst*)(base+patch[mod->entry-mod->prog]); 1955 free(patch); 1956 free(tinit); 1957 free(m->prog); 1958 m->prog = (Inst*)base; 1959 m->compiled = 1; 1960 segflush(base, n*sizeof(*base)); 1961 return 1; 1962 } 1963