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