|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)sky.c 1.1 86/02/03 Copyr 1984 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1984 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include "as.h" ! 10: #include "c2.h" ! 11: ! 12: #define SP_REG 15 /* Stack pointer: a7 */ ! 13: #define STATUS_WORD -2 /* Offset to sky status word */ ! 14: #define IDLE 6 /* Idle bit in hibyte of status word */ ! 15: ! 16: #define SP_ADD 0x1001 /* Single add: B1 = A2 + A1 */ ! 17: #define SP_ADDREG 0x104c /* Single add: R0 = R0 + A1 */ ! 18: #define SP_ADDB1 0x1003 /* Single add: B1 = R0 + A1 */ ! 19: ! 20: #define SP_SUB 0x1007 /* Single sub: B1 = A1 - A2 */ ! 21: #define SP_SUBREG1 0x104f /* Single sub: R0 = R0 - A1 */ ! 22: #define SP_SUBREG2 0x1050 /* Single sub: R0 = A1 - R0 */ ! 23: ! 24: #define SP_MUL 0x100b /* Single mul: B1 = A2 * A1 */ ! 25: #define SP_MULREG 0x1052 /* Single mul: R0 = R0 * A1 */ ! 26: #define SP_MULB1 0x100d /* Single mul: B1 = R0 * A1 */ ! 27: ! 28: #define SP_DIV 0x1013 /* Single div: B1 = A2 / A1 */ ! 29: #define SP_DIVREG1 0x1055 /* Single div: R0 = R0 / A1 */ ! 30: #define SP_DIVREG2 0x1056 /* Single div: R0 = A1 / R0 */ ! 31: ! 32: #define SP_LOAD 0x1031 /* Single load: R0 = A1 */ ! 33: #define SP_STORE 0x1037 /* Single store: B1 = R0 */ ! 34: ! 35: #define isskyop(op) (findop(op) != NULL) ! 36: ! 37: /* ! 38: * Struct for each sky operator that can be changed. ! 39: * The code generator produces operations that push two operands ! 40: * to the board and fetch one result. The goal here is to use ! 41: * the on board register as an accumulator. Therefore, one ! 42: * operand will come from register R0 and the result will be ! 43: * left in R0. ! 44: * For some operations (add and mul), one operand can come ! 45: * from register R0 and the result can be fetched from the ! 46: * board. Otherwise (sub and div), a SKY operation to fetch ! 47: * the result must be inserted. ! 48: */ ! 49: struct skyop { ! 50: int op; /* Sky board opcode */ ! 51: int arg_op[2]; /* Opcode if arg "n" in R0 */ ! 52: int fetch; /* Opcode to fetch result from board */ ! 53: }; ! 54: ! 55: /* ! 56: * Info about single precision SKY board operators. ! 57: */ ! 58: struct skyop regops[] = { ! 59: { SP_ADD, SP_ADDREG, SP_ADDREG, SP_ADDB1 }, ! 60: { SP_SUB, SP_SUBREG1, SP_SUBREG2, 0 }, ! 61: { SP_MUL, SP_MULREG, SP_MULREG, SP_MULB1 }, ! 62: { SP_DIV, SP_DIVREG1, SP_DIVREG2, 0 }, ! 63: { 0 }, ! 64: }; ! 65: ! 66: /* ! 67: * Struct for a sky board operation ! 68: */ ! 69: struct skylist { ! 70: NODE *skyload; /* Instruction to load opcode */ ! 71: NODE *arg[2]; /* Args passed to the board */ ! 72: NODE *result; /* Result fetched from the board */ ! 73: NODE *oldresult; /* Result fetched from the board */ ! 74: int oldop; /* Original sky operator */ ! 75: int tstloop; /* Is result preceeded by tst loop */ ! 76: struct skylist *next; /* Linked list */ ! 77: }; ! 78: ! 79: struct oper *newoperand(); ! 80: struct skylist *get_sky(); ! 81: struct skylist *bld_skylist(); ! 82: struct skyop *findop(); ! 83: NODE *newinst(); ! 84: NODE *remove(); ! 85: NODE *delete_tst_loop(); ! 86: static struct sym_bkt *skyname; ! 87: static struct oper skybase; ! 88: ! 89: sky() ! 90: { ! 91: NODE *n; ! 92: register v, regno; ! 93: struct oper *op1; ! 94: struct oper *op2; ! 95: int didchange=0; ! 96: int i, inexact; ! 97: struct oper saveop; ! 98: struct skylist *skylist; ! 99: static struct oper reg = { T_REG, 0, 0, NULL, 0, 0, 0 }; ! 100: static struct oper conz = { T_IMMED, 0, 0, NULL, 0, 0, 0 }; ! 101: ! 102: /* initialize constant table to empty. Find __skybase */ ! 103: forgetall(); ! 104: if (skyname==NULL) skyname = lookup("__skybase"); ! 105: skybase.type_o = T_NORMAL; ! 106: skybase.sym_o = skyname; ! 107: skybase.value_o = 0; ! 108: ! 109: for (n = first.forw; n != &first; n = n->forw){ ! 110: if (n->op == OP_LABEL) { ! 111: /* ! 112: * we really should be doing flow analysis here. ! 113: * lacking that, recognize special case SKY code: ! 114: * 1: tstw a1@(-4) ! 115: * bge 1b ! 116: */ ! 117: if (n->nref == 1 && n->luse == n->forw->forw && ! 118: emptymask( n->forw->rset) && n->forw->forw->op == OP_JUMP) { ! 119: n = n->forw; ! 120: continue; ! 121: } ! 122: /* forget everything */ ! 123: forgetall(); ! 124: continue; ! 125: } ! 126: if (n->nref == 0) { ! 127: continue; ! 128: } ! 129: if (n->op != OP_MOVE) { ! 130: continue; ! 131: } ! 132: op1 = n->ref[0]; ! 133: op2 = n->ref[1]; ! 134: skylist = bld_skylist(&n); ! 135: if (skylist != NULL) { ! 136: rewrite_list(skylist); ! 137: free_list(skylist); ! 138: n = n->back; ! 139: } else if (op1->type_o == T_NORMAL && ! 140: op1->value_o == 0 && ! 141: op1->sym_o == skyname && ! 142: op2->type_o==T_REG) { ! 143: /* move to a register */ ! 144: con_to_reg( op2->value_o, op1, n->subop ); ! 145: } ! 146: } ! 147: } ! 148: ! 149: /* ! 150: * Build a list of sky board operations that ! 151: * can use an accumulator between them. Two operations ! 152: * can use an accumulator if the result of the first operation ! 153: * is the first argument to the second operation. ! 154: */ ! 155: struct skylist * ! 156: bld_skylist(np) ! 157: NODE **np; ! 158: { ! 159: struct skylist *hdr; ! 160: struct skylist *sky; ! 161: struct skylist **bpatch; ! 162: NODE *n; ! 163: ! 164: hdr = NULL; ! 165: n = *np; ! 166: if (is_sky_operation(n)) { ! 167: hdr = get_sky(&n); ! 168: if (hdr == NULL) { ! 169: return(NULL); ! 170: } ! 171: sky = hdr; ! 172: if (result_is_reg(sky)) { ! 173: bpatch = &sky->next; ! 174: while (n->op != OP_LABEL && ! 175: n->op != OP_JUMP && ! 176: n->op != OP_CALL) { ! 177: if (result_killed(n, sky)) { ! 178: break; ! 179: } ! 180: if (n == &first) { ! 181: n = first.back; ! 182: break; ! 183: } ! 184: if (is_sky_operation(n)) { ! 185: sky = get_sky(&n); ! 186: if (sky == NULL) { ! 187: return(NULL); ! 188: } ! 189: *bpatch = sky; ! 190: bpatch = &sky->next; ! 191: if (!result_is_reg(sky)) { ! 192: break; ! 193: } ! 194: } else { ! 195: n = n->forw; ! 196: } ! 197: } ! 198: } ! 199: } ! 200: *np = n; ! 201: return(hdr); ! 202: } ! 203: ! 204: /* ! 205: * Disect a sky board operation. ! 206: * Find the opcode, the two arguments and the result that is fetched ! 207: * off of the board. ! 208: * If it is not a sky board operation return NULL. ! 209: */ ! 210: struct skylist * ! 211: get_sky(np) ! 212: NODE **np; ! 213: { ! 214: NODE *n; ! 215: struct skylist *sky; ! 216: int i; ! 217: ! 218: /* ! 219: * Get the instruction to load an opcode into the sky board ! 220: */ ! 221: n = *np; ! 222: sky = (struct skylist *) calloc(sizeof(*sky), 1); ! 223: sky->skyload = n; ! 224: n = n->forw; ! 225: ! 226: /* ! 227: * Get pointers to the instructions that push arguments ! 228: */ ! 229: for (i = 0; i < 2; i++) { ! 230: if (!move_to_sky(n)) { ! 231: return(NULL); ! 232: } ! 233: sky->arg[i] = n; ! 234: n = n->forw; ! 235: } ! 236: ! 237: /* ! 238: * Get the instruction to fetch the result from the board. ! 239: * It may be preceeded by a test loop. ! 240: */ ! 241: if (n->op == OP_LABEL) { ! 242: for (i = 0; i < 3; i++) { ! 243: n = n->forw; ! 244: } ! 245: sky->tstloop = 1; ! 246: } ! 247: if (!move_from_sky(n)) { ! 248: return(NULL); ! 249: } ! 250: sky->result = n; ! 251: ! 252: n = n->forw; ! 253: sky->next = NULL; ! 254: *np = n; ! 255: return(sky); ! 256: } ! 257: ! 258: /* ! 259: * Is this instruction a movl to the sky board? ! 260: */ ! 261: move_to_sky(n) ! 262: NODE *n; ! 263: { ! 264: struct oper *op2; ! 265: int regno; ! 266: int inexact; ! 267: ! 268: if (n->op == OP_MOVE && n->subop == SUBOP_L) { ! 269: regno = reglookup(&skybase, SUBOP_L, &inexact); ! 270: op2 = n->ref[1]; ! 271: if (op2->type_o == T_DEFER && regno == op2->value_o) { ! 272: return(1); ! 273: } ! 274: } ! 275: return(0); ! 276: } ! 277: ! 278: /* ! 279: * Is this instruction a movl from the sky board? ! 280: */ ! 281: move_from_sky(n) ! 282: NODE *n; ! 283: { ! 284: struct oper *op1; ! 285: int regno; ! 286: int inexact; ! 287: ! 288: if (n->op == OP_MOVE && n->subop == SUBOP_L) { ! 289: regno = reglookup(&skybase, SUBOP_L, &inexact); ! 290: op1 = n->ref[0]; ! 291: if (op1->type_o == T_DEFER && regno == op1->value_o) { ! 292: return(1); ! 293: } ! 294: } ! 295: return(0); ! 296: } ! 297: ! 298: /* ! 299: * See if this instruction stores the result of the sky operation ! 300: * into memory or otherwise kills the result. ! 301: */ ! 302: result_killed(n, sky) ! 303: NODE *n; ! 304: struct skylist *sky; ! 305: { ! 306: struct oper *result; ! 307: struct oper *op1; ! 308: struct oper *op2; ! 309: int i; ! 310: ! 311: /* ! 312: * Is this a movl from the register holding the sky result? ! 313: */ ! 314: result = sky->result->ref[1]; ! 315: if (n->op == OP_MOVE && n->subop == SUBOP_L) { ! 316: op1 = n->ref[0]; ! 317: if (op1->type_o == T_REG && op1->value_o == result->value_o) { ! 318: return(1); ! 319: } ! 320: } ! 321: ! 322: /* ! 323: * Is the destination of this instruction the register holding ! 324: * the sky result? ! 325: */ ! 326: op2 = n->ref[1]; ! 327: if (result->type_o == T_REG && ! 328: op2->type_o == T_REG && ! 329: op2->value_o == result->value_o) { ! 330: return(1); ! 331: } ! 332: return(0); ! 333: } ! 334: ! 335: /* ! 336: * Is the result of this sky operation assigned to a register. ! 337: */ ! 338: result_is_reg(sky) ! 339: struct skylist *sky; ! 340: { ! 341: struct oper *result; ! 342: int i; ! 343: ! 344: result = sky->result->ref[1]; ! 345: if (result->type_o == T_REG) { ! 346: return(1); ! 347: } ! 348: return(0); ! 349: } ! 350: ! 351: /* ! 352: * Is this instuction a movw of an opcode to the sky board? ! 353: */ ! 354: is_sky_operation(n) ! 355: NODE *n; ! 356: { ! 357: struct oper *op1; ! 358: struct oper *op2; ! 359: int regno; ! 360: int inexact; ! 361: ! 362: op1 = n->ref[0]; ! 363: op2 = n->ref[1]; ! 364: if (n->op != OP_MOVE || ! 365: op1->type_o != T_IMMED || ! 366: !isskyop(op1->value_o) || ! 367: op2->type_o != T_DISPL) { ! 368: return(0); ! 369: } ! 370: regno = reglookup(&skybase, SUBOP_L, &inexact); ! 371: if (regno != op2->reg_o || ! 372: op2->value_o != -4) { ! 373: return(0); ! 374: } ! 375: return(1); ! 376: } ! 377: ! 378: /* ! 379: * Rewrite a list of sky operations doing optimizations along the way. ! 380: * Look the for the results of one operation being used as an operand ! 381: * of the next operations. Accumulator operations can be used in ! 382: * this case. ! 383: */ ! 384: rewrite_list(sky) ! 385: struct skylist *sky; ! 386: { ! 387: struct skylist *skyp; ! 388: struct skylist *last_changed; ! 389: NODE *result; ! 390: NODE *arg; ! 391: int first; ! 392: int i; ! 393: ! 394: first = 1; ! 395: last_changed = NULL; ! 396: for (skyp = sky; skyp->next != NULL; skyp = skyp->next) { ! 397: result = skyp->result; ! 398: if (result == NULL) { ! 399: continue; ! 400: } ! 401: for (i = 0; i < 2; i++) { ! 402: arg = skyp->next->arg[i]; ! 403: if (sameops(result->ref[0], arg->ref[1]) && ! 404: sameops(result->ref[1], arg->ref[0])) { ! 405: meter.nskyreg++; ! 406: if (first) { ! 407: insert_reg_load(skyp); ! 408: change_to_reg(skyp, 0); ! 409: } ! 410: change_to_reg(skyp->next, i); ! 411: last_changed = skyp->next; ! 412: first = 0; ! 413: break; ! 414: } ! 415: } ! 416: if (i == 2 && last_changed != NULL) { ! 417: fetch_result(last_changed); ! 418: first = 1; ! 419: last_changed = NULL; ! 420: } ! 421: } ! 422: if (!first && last_changed != NULL) { ! 423: fetch_result(last_changed); ! 424: } ! 425: } ! 426: ! 427: /* ! 428: * Change an operation to use the accumulator and also ! 429: * to leave its result in the accumulator. ! 430: * Remove the instructions that fetch the result from the board. ! 431: * Add a tst loop after the operation to wait for the result ! 432: * to solidify. ! 433: */ ! 434: change_to_reg(sky, argn) ! 435: struct skylist *sky; ! 436: int argn; ! 437: { ! 438: NODE *arg; ! 439: NODE *n; ! 440: struct skyop *skyop; ! 441: struct oper *opcode; ! 442: int op; ! 443: int i; ! 444: ! 445: opcode = sky->skyload->ref[0]; ! 446: op = opcode->value_o; ! 447: sky->oldop = op; ! 448: skyop = findop(op); ! 449: if (skyop == NULL) { ! 450: return; ! 451: } ! 452: opcode->value_o = skyop->arg_op[argn]; ! 453: arg = sky->arg[argn]; ! 454: arg = deletenode(arg); ! 455: if (sky->tstloop) { ! 456: n = sky->result; ! 457: for (i = 0; i < 3; i++) { ! 458: n = n->back; ! 459: } ! 460: delete_tst_loop(n); ! 461: sky->tstloop = 0; ! 462: } ! 463: sky->oldresult = remove(sky->result); ! 464: insert_tst_loop(sky->skyload->forw, sky->skyload->ref[1]); ! 465: } ! 466: ! 467: /* ! 468: * Insert a test loop waiting for the SKY idle bit to turn on. ! 469: * Insert the code: ! 470: * 1: btst #6,skybase(-2) ! 471: * beqs 1b ! 472: */ ! 473: insert_tst_loop(node, skybase) ! 474: NODE *node; ! 475: struct oper *skybase; ! 476: { ! 477: NODE *label; ! 478: NODE *btst; ! 479: NODE *beqs; ! 480: struct sym_bkt *sbp; ! 481: char ltoken[20]; ! 482: extern char *ll_format; ! 483: extern int ll_val[]; ! 484: static struct oper btstbit = { T_IMMED, 0, 0, 0, NULL, NULL, 0, IDLE, 0 }; ! 485: static struct oper labelop = { T_NORMAL, 0, 0, 0, NULL, NULL, 0, 0, 0 }; ! 486: ! 487: sprintf(ltoken, ll_format, '1', ++ll_val[1]); ! 488: sbp = lookup(ltoken); ! 489: sbp->attr_s |= S_LABEL | S_DEC | S_DEF; ! 490: sbp->csect_s = C_TEXT; ! 491: ! 492: label = new(); ! 493: label->op = OP_LABEL; ! 494: label->subop = SUBOP_Z; ! 495: label->nref = 1; ! 496: label->name = sbp; ! 497: ! 498: btst = new(); ! 499: btst->op = OP_OTHER; ! 500: btst->subop = SUBOP_B; ! 501: btst->instr = sopcode("btst"); ! 502: btst->nref = 2; ! 503: btst->ref[0] = newoperand(&btstbit); ! 504: btst->ref[1] = newoperand(skybase); ! 505: btst->ref[1]->value_o = STATUS_WORD; ! 506: ! 507: labelop.sym_o = sbp; ! 508: beqs = new(); ! 509: beqs->op = OP_JUMP; ! 510: beqs->subop = JGE; ! 511: beqs->instr = sopcode("beqs"); ! 512: beqs->nref = 0; ! 513: beqs->ref[0] = newoperand(&labelop); ! 514: beqs->luse = label; ! 515: ! 516: label->forw = btst; ! 517: btst->forw = beqs; ! 518: beqs->back = btst; ! 519: btst->back = label; ! 520: insert(label, node); ! 521: } ! 522: ! 523: /* ! 524: * Remove a node from the list ! 525: */ ! 526: NODE * ! 527: remove(p) ! 528: NODE *p; ! 529: { ! 530: p->back->forw = p->forw; ! 531: p->forw->back = p->back; ! 532: p->back = NULL; ! 533: p->forw = NULL; ! 534: return(p); ! 535: } ! 536: ! 537: /* ! 538: * Find an opcode in the opcode table ! 539: */ ! 540: struct skyop * ! 541: findop(op) ! 542: int op; ! 543: { ! 544: struct skyop *sp; ! 545: ! 546: for (sp = regops; sp->op != 0; sp++) { ! 547: if (sp->op == op) { ! 548: return(sp); ! 549: } ! 550: } ! 551: return(NULL); ! 552: } ! 553: ! 554: /* ! 555: * Insert code to load the sky register with a value. ! 556: * Load it with the first operand of the sky operation ! 557: * passed in here. ! 558: */ ! 559: insert_reg_load(sky) ! 560: struct skylist *sky; ! 561: { ! 562: NODE *p; ! 563: NODE *load; ! 564: NODE *arg; ! 565: ! 566: load = sky->skyload; ! 567: p = newinst(load, load->ref[0], load->ref[1]); ! 568: p->ref[0]->value_o = SP_LOAD; ! 569: insert(p, load->back); ! 570: ! 571: arg = sky->arg[0]; ! 572: p = newinst(arg, arg->ref[0], arg->ref[1]); ! 573: insert(p, load->back); ! 574: } ! 575: ! 576: /* ! 577: * Create a new instruction. ! 578: * Copy the old one passed in and then give it the new arguments. ! 579: */ ! 580: NODE * ! 581: newinst(oldinst, arg1, arg2) ! 582: NODE *oldinst; ! 583: struct oper *arg1; ! 584: struct oper *arg2; ! 585: { ! 586: NODE *p; ! 587: ! 588: p = new(); ! 589: *p = *oldinst; ! 590: p->forw = NULL; ! 591: p->back = NULL; ! 592: p->ref[0] = newoperand(arg1); ! 593: p->ref[1] = newoperand(arg2); ! 594: return(p); ! 595: } ! 596: ! 597: /* ! 598: * Change the code to fetch the result from the sky board. ! 599: * If possible change last operation to use R0 as an operand ! 600: * and generate a fetch'able result. ! 601: * Otherwise, insert additional code to fetch the result. ! 602: */ ! 603: fetch_result(sky) ! 604: struct skylist *sky; ! 605: { ! 606: NODE *n; ! 607: NODE *p; ! 608: NODE *load; ! 609: NODE *result; ! 610: struct skyop *skyop; ! 611: int i; ! 612: ! 613: skyop = findop(sky->oldop); ! 614: if (skyop->fetch != 0) { ! 615: n = sky->skyload->forw; ! 616: n = n->forw; ! 617: if (n->op == OP_LABEL) { ! 618: n = delete_tst_loop(n); ! 619: sky->tstloop = 0; ! 620: } ! 621: sky->skyload->ref[0]->value_o = skyop->fetch; ! 622: insert(sky->oldresult, n); ! 623: } else { ! 624: load = sky->skyload; ! 625: n = load->forw; ! 626: for (i = 0; i < 3; i++) { ! 627: n = n->forw; ! 628: } ! 629: p = newinst(load, load->ref[0], load->ref[1]); ! 630: p->ref[0]->value_o = SP_STORE; ! 631: insert(p, n); ! 632: n = n->forw; ! 633: ! 634: result = sky->oldresult; ! 635: p = newinst(result, result->ref[0], result->ref[1]); ! 636: insert(p, n); ! 637: } ! 638: } ! 639: ! 640: /* ! 641: * Delete a test loop. ! 642: * The actual test and branch may differ here. ! 643: */ ! 644: NODE * ! 645: delete_tst_loop(n) ! 646: NODE *n; ! 647: { ! 648: if (n->op != OP_LABEL) { ! 649: fprintf(stderr, "c2: internal error deleting test loop\n"); ! 650: exit(1); ! 651: } ! 652: n = deletenode(n); /* Label */ ! 653: n = n->forw; ! 654: n = deletenode(n); /* test */ ! 655: n = n->forw; ! 656: n = deletenode(n); /* branch */ ! 657: return(n); ! 658: } ! 659: ! 660: /* ! 661: * Free a list of sky structures ! 662: */ ! 663: free_list(sky) ! 664: struct skylist *sky; ! 665: { ! 666: struct skylist *next; ! 667: struct skylist *skyp; ! 668: ! 669: for (skyp = sky; skyp != NULL; skyp = next) { ! 670: next = skyp->next; ! 671: free(skyp); ! 672: } ! 673: } ! 674: ! 675: /* ! 676: * Look for the sequence: ! 677: * ! 678: * movl skybaseR@,X ! 679: * movl skybaseR@,Y ! 680: * movl X,mem1 ! 681: * movl Y,mem2 ! 682: * ! 683: * Change it to ! 684: * ! 685: * movl skybaseR@,mem1 ! 686: * movl skybaseR@,mem2 ! 687: * ! 688: * This sequence occurs when a double precision value is fetched from ! 689: * the SKY board and is stored into memory. ! 690: */ ! 691: skymove(n) ! 692: NODE *n; ! 693: { ! 694: NODE *n1; ! 695: NODE *n2; ! 696: NODE *n3; ! 697: int reg; ! 698: int reg1; ! 699: ! 700: n1 = n->forw; ! 701: n2 = n1->forw; ! 702: n3 = n2->forw; ! 703: if (skytoreg(n) && skytoreg(n1)) { ! 704: reg = n->ref[1]->value_o; ! 705: reg1 = n1->ref[1]->value_o; ! 706: if (regtomem(n2, reg) && regtomem(n3, reg1)) { ! 707: if (!inmask(reg, n3->forw->rlive ) && ! 708: !inmask(reg1, n3->forw->rlive ) ) { ! 709: n->ref[1] = newoperand(n2->ref[1]); ! 710: n1->ref[1] = newoperand(n3->ref[1]); ! 711: deletenode(n2); ! 712: deletenode(n3); ! 713: meter.ndpsky++; ! 714: return(1); ! 715: } ! 716: } ! 717: } ! 718: return(0); ! 719: } ! 720: ! 721: /* ! 722: * Look for the instruction ! 723: * ! 724: * movl skybaseR@,X ! 725: * ! 726: * which fetches a value from the sky board and puts it in a register. ! 727: * skybaseR is a register containing __skybase and X is a register. ! 728: */ ! 729: static ! 730: skytoreg(n) ! 731: NODE *n; ! 732: { ! 733: struct oper *op1; ! 734: struct oper *op2; ! 735: struct oper *con; ! 736: struct sym_bkt *sym; ! 737: int reg; ! 738: extern struct oper *get_regcon(); ! 739: ! 740: if (n->op != OP_MOVE || n->subop != SUBOP_L) { ! 741: return(0); ! 742: } ! 743: op1 = n->ref[0]; ! 744: op2 = n->ref[1]; ! 745: if (op1->type_o != T_DEFER) { ! 746: return(0); ! 747: } ! 748: reg = op1->value_o; ! 749: sym = get_regcon( reg )->sym_o; ! 750: if (skyname == NULL || sym != skyname) { ! 751: return(0); ! 752: } ! 753: if (op2->type_o != T_REG) { ! 754: return(0); ! 755: } ! 756: return(1); ! 757: } ! 758: ! 759: /* ! 760: * Look for the instruction ! 761: * ! 762: * movl X,mem ! 763: * ! 764: * where X is a register. ! 765: */ ! 766: static ! 767: regtomem(n, reg) ! 768: NODE *n; ! 769: int reg; ! 770: { ! 771: struct oper *op1; ! 772: struct oper *op2; ! 773: ! 774: if (n->op != OP_MOVE || n->subop != SUBOP_L) { ! 775: return(0); ! 776: } ! 777: op1 = n->ref[0]; ! 778: op2 = n->ref[1]; ! 779: if (op1->value_o == reg && op2->type_o != T_REG) { ! 780: return(1); ! 781: } ! 782: return(0); ! 783: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.