|
|
1.1 ! root 1: static char *ID_gencode="@(#) gencode.c: 1.22 5/8/84"; ! 2: #include <stdio.h> ! 3: #include "systems.h" ! 4: #include "symbols.h" ! 5: #include "instab.h" ! 6: #include "parse.h" ! 7: #include "gendefs.h" ! 8: #include "expand.h" ! 9: #include "expand2.h" ! 10: ! 11: long ! 12: swap_b2(), ! 13: swap_b4(); ! 14: extern upsymins ! 15: *lookup(); ! 16: extern short ! 17: opt; /* no optimize flag */ ! 18: extern unsigned short ! 19: line; /* current line number */ ! 20: ! 21: addrgen(insptr,addr,expand,opnum) ! 22: register instr ! 23: *insptr; ! 24: register addrmode ! 25: *addr; ! 26: short expand, opnum; ! 27: { ! 28: long val; ! 29: register short reg; ! 30: ! 31: /* check if USER specified an expand byte */ ! 32: /* check if USER specified an operand specifier */ ! 33: if (insptr->tag & IS25) { ! 34: if (addr->newtype != NOTYPE) ! 35: yyerror("Expand byte invalid in IS25 instruction"); ! 36: if (addr->expspec != NULLSPEC) ! 37: yyerror("Operand specifier invalid in IS25 instruction"); ! 38: } else ! 39: expand = addr->newtype; ! 40: if (expand != NOTYPE) ! 41: generate(8,NOACTION,(long)((CEXPAND<<4)|expand),NULLSYM); ! 42: ! 43: switch(addr->admode) { ! 44: ! 45: case REGDFMD: /* register deferred mode */ ! 46: reg = addr->adreg; ! 47: if (reg != PCREG) { ! 48: generate(8,NOACTION,(long)((CREGDFMD<<4)|reg),NULLSYM); ! 49: } else { ! 50: yyerror("Register deferred mode illegal with register 15 (%pc)."); ! 51: } ! 52: return; ! 53: ! 54: case DSPMD: /* displacement mode */ ! 55: val = addr->adexpr.expval; ! 56: reg = addr->adreg; ! 57: if ((addr->adexpr.symptr == NULLSYM) ! 58: && (addr->expspec == NULLSPEC) ! 59: && opt) { ! 60: /* No operand specifier, and optimization allowed, and ! 61: symbol ptr is null */ ! 62: if ((val == 0) && (reg != PCREG)) { ! 63: /* register deferred mode */ ! 64: /* not legal for register 15 or PC */ ! 65: generate(8,NOACTION,(long)((CREGDFMD<<4)|reg), ! 66: NULLSYM); ! 67: return; ! 68: } /* register deferred mode */ ! 69: ! 70: if ((reg == APREG) && (0 <= val && val <= 14)) { ! 71: /* AP displacement mode */ ! 72: generate(8,NOACTION,(CAPDSPMD<<4)|val,NULLSYM); ! 73: return; ! 74: } /* AP displacement mode */ ! 75: ! 76: if ((reg == FPREG) && (0 <= val && val <= 14)) { ! 77: /* FP displacement mode */ ! 78: generate(8,NOACTION,(CFPDSPMD<<4)|val,NULLSYM); ! 79: return; ! 80: } /* FP displacement mode */ ! 81: ! 82: if (-(1<<7) <= val && val < 1<<7) { ! 83: /* byte displacement mode */ ! 84: generate(8,NOACTION,(long)((CBDSPMD<<4)|reg), ! 85: NULLSYM); ! 86: generate(8,NOACTION,val,NULLSYM); ! 87: return; ! 88: } /* byte displacement mode */ ! 89: if (-(1L<<15) <= val && val < 1L<<15) { ! 90: /* halfword displacement mode */ ! 91: generate(8,NOACTION,(long)((CHDSPMD<<4)|reg), ! 92: NULLSYM); ! 93: generate(16,NOACTION,swap_b2(val),NULLSYM); ! 94: return; ! 95: } /* halfword displacement mode */ ! 96: /* Otherwise use word displacement mode */ ! 97: generate(8,NOACTION,(long)((CDSPMD<<4)|reg),NULLSYM); ! 98: generate(32,NOACTION,swap_b4(val),NULLSYM); ! 99: return; ! 100: } /* addr->adexpr.symptr == NULLSYM */ ! 101: ! 102: if ( (addr->adexpr.symptr != NULLSYM) ! 103: || ((!opt) && (addr->expspec == NULLSPEC))) { ! 104: /* don't know displacement; ! 105: must use word displacement mode */ ! 106: generate(8,NOACTION,(long)((CDSPMD<<4)|reg),NULLSYM); ! 107: generate(32,RELDIR32,val,addr->adexpr.symptr); ! 108: return; ! 109: } ! 110: ! 111: /* At this point the user must be specifying the operand ! 112: expression size through the use of an operand specifier. ! 113: Generate the correct operand. */ ! 114: ! 115: switch ( addr->expspec ) { ! 116: ! 117: case BYTESPEC: ! 118: if ( (unsigned) val >= (1<<8)) { ! 119: yyerror("Expression larger than byte."); ! 120: } else { ! 121: /* byte displacement mode */ ! 122: generate(8,NOACTION,(long)((CBDSPMD<<4)|reg), ! 123: NULLSYM); ! 124: generate(8,NOACTION,val,NULLSYM); ! 125: } ! 126: return; ! 127: ! 128: case HALFSPEC: ! 129: if ( (unsigned) val >= (1<<16)) { ! 130: yyerror("Expression larger than halfword."); ! 131: } else { ! 132: /* halfword displacement mode */ ! 133: generate(8,NOACTION,(long)((CHDSPMD<<4)|reg), ! 134: NULLSYM); ! 135: generate(16,NOACTION,swap_b2(val),NULLSYM); ! 136: } ! 137: return; ! 138: ! 139: case WORDSPEC: ! 140: generate(8,NOACTION,(long)((CDSPMD<<4)|reg),NULLSYM); ! 141: generate(32,NOACTION,swap_b4(val),NULLSYM); ! 142: return; ! 143: ! 144: case SHORTSPEC: ! 145: if (0 > val || val > 14) { ! 146: yyerror("Expression outside short offset range."); ! 147: return; ! 148: } ! 149: if (reg == APREG) { ! 150: /* AP displacement mode */ ! 151: generate(8,NOACTION,(CAPDSPMD<<4)|val,NULLSYM); ! 152: return; ! 153: } /* AP short offset */ ! 154: ! 155: if (reg == FPREG) { ! 156: /* FP displacement mode */ ! 157: generate(8,NOACTION,(CFPDSPMD<<4)|val,NULLSYM); ! 158: return; ! 159: } /* FP displacement mode */ ! 160: ! 161: yyerror("Illegal register for short offset address mode."); ! 162: return; ! 163: ! 164: default: ! 165: yyerror("Illegal operand specifier for displacement address mode."); ! 166: return; ! 167: ! 168: } /* switch */ ! 169: ! 170: case DSPDFMD: /* displacement deferred mode */ ! 171: val = addr->adexpr.expval; ! 172: reg = addr->adreg; ! 173: if ( (addr->adexpr.symptr == NULLSYM) ! 174: && (addr->expspec == NULLSPEC) ! 175: && opt) { ! 176: if (-(1<<7) <= val && val < 1<<7) { ! 177: /* byte displacement deferred mode */ ! 178: generate(8,NOACTION,(long)((CBDSPDFMD<<4)|reg), ! 179: NULLSYM); ! 180: generate(8,NOACTION,val,NULLSYM); ! 181: return; ! 182: } /* byte displacement deferred mode */ ! 183: if (-(1L<<15) <= val && val < 1L<<15) { ! 184: /* halfword displacement deferred mode */ ! 185: generate(8,NOACTION,(long)((CHDSPDFMD<<4)|reg), ! 186: NULLSYM); ! 187: generate(16,NOACTION,swap_b2(val),NULLSYM); ! 188: return; ! 189: } /* halfword displacement deferred mode */ ! 190: /* Otherwise use word displacement deferred mode */ ! 191: generate(8,NOACTION,(long)((CDSPDFMD<<4)|reg),NULLSYM); ! 192: generate(32,NOACTION,swap_b4(val),NULLSYM); ! 193: return; ! 194: } /* addr->adexpr.symptr == NULLSYM */ ! 195: ! 196: if ( (addr->adexpr.symptr != NULLSYM) ! 197: || ((!opt) && (addr->expspec == NULLSPEC))) { ! 198: ! 199: /* don't know displacement; ! 200: must use word displacement deferred mode */ ! 201: generate(8,NOACTION,(long)((CDSPDFMD<<4)|reg),NULLSYM); ! 202: generate(32,RELDIR32,val,addr->adexpr.symptr); ! 203: return; ! 204: } ! 205: ! 206: /* At this point the user must be specifying the operand ! 207: expression size through the use of an operand specifier. ! 208: Generate the correct operand. */ ! 209: ! 210: switch ( addr->expspec ) { ! 211: ! 212: case BYTESPEC: ! 213: if ( (unsigned) val >= (1<<8)) { ! 214: yyerror("Expression larger than byte."); ! 215: } else { ! 216: /* byte displacement deferred mode */ ! 217: generate(8,NOACTION,(long)((CBDSPDFMD<<4)|reg), ! 218: NULLSYM); ! 219: generate(8,NOACTION,val,NULLSYM); ! 220: } ! 221: return; ! 222: ! 223: case HALFSPEC: ! 224: if ( (unsigned) val >= (1<<16)) { ! 225: yyerror("Expression larger than halfword."); ! 226: } else { ! 227: /* halfword displacement deferred mode */ ! 228: generate(8,NOACTION,(long)((CHDSPDFMD<<4)|reg), ! 229: NULLSYM); ! 230: generate(16,NOACTION,swap_b2(val),NULLSYM); ! 231: } ! 232: return; ! 233: ! 234: case WORDSPEC: ! 235: generate(8,NOACTION,(long)((CDSPDFMD<<4)|reg),NULLSYM); ! 236: generate(32,NOACTION,swap_b4(val),NULLSYM); ! 237: return; ! 238: ! 239: default: ! 240: yyerror("Illegal operand specifier for displacement deferred address mode."); ! 241: return; ! 242: ! 243: } /* switch */ ! 244: ! 245: case EXADMD: /* external address mode */ ! 246: case ABSMD: /* absolute address mode */ ! 247: generate(8,NOACTION,(long)(CABSMD),NULLSYM); ! 248: generate(32,RELDIR32,addr->adexpr.expval,addr->adexpr.symptr); ! 249: return; ! 250: ! 251: case EXADDFMD: /* external address deferred mode (PC relative deferred) */ ! 252: case ABSDFMD: /* absolute address deferred mode */ ! 253: generate(8,NOACTION,(long)(CABSDFMD),NULLSYM); ! 254: generate(32,RELDIR32,addr->adexpr.expval,addr->adexpr.symptr); ! 255: return; ! 256: ! 257: case IMMD: /* immediate mode */ ! 258: val = addr->adexpr.expval; ! 259: if ( (addr->adexpr.symptr == NULLSYM) ! 260: && (addr->expspec == NULLSPEC) ! 261: && opt) { ! 262: if ( val < 0 ) { ! 263: if ( (insptr->tag & IS25) && ! 264: (insptr->name[0] == 'u') ) ! 265: { ! 266: generate(8,NOACTION,(long)CIMMD,NULLSYM); ! 267: generate(32,NOACTION,swap_b4(val),NULLSYM); ! 268: return; ! 269: } ! 270: } ! 271: ! 272: if (-(1<<4) <= val && val < 1<<6) { ! 273: generate(8,NOACTION,val,NULLSYM); ! 274: return; ! 275: } ! 276: ! 277: if (-(1<<7) <= val && val < 1<<7) { ! 278: /* byte immediate mode */ ! 279: generate(8,NOACTION,(long)CBIMMD,NULLSYM); ! 280: generate(8,NOACTION,val,NULLSYM); ! 281: return; ! 282: } /* byte immediate mode */ ! 283: if (-(1L<<15) <= val && val < 1L<<15) { ! 284: /* halfword immediate mode */ ! 285: generate(8,NOACTION,(long)CHIMMD,NULLSYM); ! 286: generate(16,NOACTION,swap_b2(val),NULLSYM); ! 287: return; ! 288: } /* halfword immediate mode */ ! 289: /* Otherwise use fullword immediate mode */ ! 290: generate(8,NOACTION,(long)CIMMD,NULLSYM); ! 291: generate(32,NOACTION,swap_b4(val),NULLSYM); ! 292: return; ! 293: } /* addr->adexpr.symptr == NULLSYM */ ! 294: ! 295: if ( (addr->adexpr.symptr != NULLSYM) ! 296: || ((!opt) && (addr->expspec == NULLSPEC))) { ! 297: ! 298: /* don't know value; ! 299: must use fullword immediate mode */ ! 300: generate(8,NOACTION,(long)CIMMD,NULLSYM); ! 301: generate(32,RELDIR32,val,addr->adexpr.symptr); ! 302: return; ! 303: } ! 304: ! 305: /* At this point the user must be specifying the operand ! 306: expression size through the use of an operand specifier. ! 307: Generate the correct operand. */ ! 308: ! 309: switch ( addr->expspec ) { ! 310: ! 311: case BYTESPEC: ! 312: if ( (unsigned) val >= (1<<8)) { ! 313: yyerror("Expression larger than byte."); ! 314: } else { ! 315: /* byte immediate mode */ ! 316: generate(8,NOACTION,(long)CBIMMD,NULLSYM); ! 317: generate(8,NOACTION,val,NULLSYM); ! 318: } ! 319: return; ! 320: ! 321: case HALFSPEC: ! 322: if ( (unsigned) val >= (1<<16)) { ! 323: yyerror("Expression larger than halfword."); ! 324: } else { ! 325: /* halfword immediate mode */ ! 326: generate(8,NOACTION,(long)CHIMMD,NULLSYM); ! 327: generate(16,NOACTION,swap_b2(val),NULLSYM); ! 328: } ! 329: return; ! 330: ! 331: case WORDSPEC: ! 332: /* fullword immediate mode */ ! 333: generate(8,NOACTION,(long)CIMMD,NULLSYM); ! 334: generate(32,NOACTION,swap_b4(val),NULLSYM); ! 335: return; ! 336: ! 337: case LITERALSPEC: ! 338: if (-(1<<4) <= val && val < 1<<6) { ! 339: generate(8,NOACTION,val,NULLSYM); ! 340: } else { ! 341: yyerror("Expression larger than literal."); ! 342: } ! 343: return; ! 344: ! 345: default: ! 346: yyerror("Illegal operand specifier for immediate address mode."); ! 347: return; ! 348: ! 349: } /* switch */ ! 350: ! 351: #if FLOAT ! 352: case FPIMMD: /* fp immediate, same as IMMD but w/o optimization */ ! 353: if ((val=optype(insptr->tag,opnum)) == 3) /* 64 bit (double) */ ! 354: generate(8,NOACTION,(long)CDIMMD,NULLSYM); ! 355: else /* 32 bit (single) */ ! 356: generate(8,NOACTION,(long)CIMMD,NULLSYM); ! 357: generate(32,NOACTION,swap_b4(addr->adexpr.expval),addr->adexpr.symptr); ! 358: if (val == 3) /* generate second 32 bits */ ! 359: generate(32,NOACTION,swap_b4(addr->adexpr.fdexpval2),addr->adexpr.symptr); ! 360: break; ! 361: #endif ! 362: ! 363: case REGMD: /* register mode */ ! 364: reg = addr->adreg; ! 365: if ( reg == PCREG ) { ! 366: yyerror("Register mode illegal with register 15 (%pc)."); ! 367: } else { ! 368: generate(8,NOACTION,(long)((CREGMD<<4)|reg),NULLSYM); ! 369: } ! 370: return; ! 371: ! 372: default: ! 373: yyerror("Assembler error: invalid addressing mode"); ! 374: return; ! 375: } /* switch */ ! 376: } /* addrgen */ ! 377: ! 378: long ! 379: swap_b2(val) ! 380: long val; ! 381: { ! 382: long b1, b2; ! 383: ! 384: b1 = (val >> 8) & 0x00FFL; /* 2nd low goes to low */ ! 385: b2 = (val << 8) & 0xFF00L; /* low goes to high */ ! 386: return (b2|b1); ! 387: } /* swap_b2 */ ! 388: ! 389: long ! 390: swap_b4(val) ! 391: long val; ! 392: { ! 393: long b1, b2, b3, b4; ! 394: ! 395: b1 = (val >> 24) & 0x000000FFL; /* high goes to low */ ! 396: b2 = (val >> 8) & 0x0000FF00L; /* 2nd high goes to 2nd low */ ! 397: b3 = (val << 8) & 0x00FF0000L; /* 2nd low goes to 2nd high */ ! 398: b4 = (val << 24) & 0xFF000000L; /* low goes to high */ ! 399: return (b1|b2|b3|b4); ! 400: } /* swap_b4 */ ! 401: ! 402: optype(instype,opnum) ! 403: BYTE instype; ! 404: short opnum; ! 405: { ! 406: /* ! 407: * figure out operand type according to instruction type and operand number ! 408: * return: 0=byte 1=half 2=word 3=double ! 409: */ ! 410: ! 411: switch (instype & (~IS25)) { ! 412: ! 413: case INSTRB: ! 414: return 0; ! 415: ! 416: case INSTRH: ! 417: return 1; ! 418: ! 419: case INSTRW: ! 420: return 2; ! 421: ! 422: #if FLOAT ! 423: case INSTRD: ! 424: return 3; ! 425: #endif ! 426: ! 427: case INSTRBH: ! 428: return (opnum==1) ? 0 : 1; ! 429: ! 430: case INSTRBW: ! 431: return (opnum==1) ? 0 : 2; ! 432: ! 433: case INSTRHW: ! 434: return (opnum==1) ? 1 : 2; ! 435: ! 436: case INSTRWH: ! 437: return (opnum==1) ? 2 : 1; ! 438: ! 439: case INSTRWB: ! 440: return (opnum==1) ? 2 : 0; ! 441: ! 442: case INSTRHB: ! 443: return (opnum==1) ? 1 : 0; ! 444: ! 445: default: /* should not happen, but just in case */ ! 446: return 2; /* treat as word operand */ ! 447: } ! 448: } /* optype */ ! 449: ! 450: convgen(insptr,addr1,addr2) ! 451: instr *insptr; ! 452: register addrmode ! 453: *addr1, ! 454: *addr2; ! 455: { ! 456: /* ! 457: * ! 458: * movb[bh|bw|hw] and movt[wb|hb|wh] instructions; ! 459: * ! 460: * All are encoded as expand mode mappings except ! 461: * for movtXY with a register destination. ! 462: * These are encoded as follows: ! 463: * ! 464: * movthb X,%ry -> andh3 &0xFF,X,%ry ! 465: * movtwb X,%ry -> andw3 &0xFF,X,%ry ! 466: * movtwh X,%ry -> movw X,%ry ; movh %ry,%ry ! 467: * ! 468: */ ! 469: ! 470: static addrmode maskop = {NOTYPE,IMMD,0x01,{ABS,NULLSYM,0xFFL}}; ! 471: register short expand; ! 472: instr *newins; /* set up dummy operands for movtwb */ ! 473: char *maskinst = "andw3"; ! 474: ! 475: /* check for movtXY with a register dest. */ ! 476: if (addr2->admode == REGMD) ! 477: switch (insptr->tag & (~IS25)) { ! 478: case INSTRHB: ! 479: /* change instruction for movthb */ ! 480: maskinst = "andh3"; ! 481: /* fall through to ... */ ! 482: case INSTRWB: ! 483: newins = (*lookup(maskinst,N_INSTALL,MNEMON)).itp; ! 484: generate(8,NOACTION,newins->opcode,NULLSYM); ! 485: addrgen(newins,&maskop,NOTYPE,1); /* mask operand */ ! 486: addrgen(insptr,addr1,NOTYPE,2); ! 487: addrgen(insptr,addr2,UBYTE,3); ! 488: return; ! 489: case INSTRWH: ! 490: generate(8,NOACTION,insptr->opcode,NULLSYM); /* movw */ ! 491: addrgen(insptr,addr1,NOTYPE,1); ! 492: addrgen(insptr,addr2,NOTYPE,2); ! 493: generate(0,NEWSTMT,(long)line,NULLSYM); ! 494: newins = (*lookup("movh",N_INSTALL,MNEMON)).itp; ! 495: generate(8,NOACTION,newins->opcode,NULLSYM); ! 496: addrgen(insptr,addr2,NOTYPE,1); ! 497: addrgen(insptr,addr2,NOTYPE,2); ! 498: return; ! 499: } /* switch */ ! 500: ! 501: generate(insptr->nbits,NOACTION,insptr->opcode,NULLSYM); ! 502: addrgen(insptr,addr1,NOTYPE,1); ! 503: switch (optype(insptr->tag,2)) { ! 504: case 0: /* byte */ ! 505: expand = SBYTE; ! 506: break; ! 507: case 1: /* half */ ! 508: expand = SHALF; ! 509: break; ! 510: case 2: /* word */ ! 511: expand = SWORD; ! 512: break; ! 513: } /* switch */ ! 514: ! 515: addrgen(insptr,addr2,expand,2); ! 516: } /* convgen */ ! 517: ! 518: testgen(insptr, addr1) ! 519: register instr *insptr; ! 520: register addrmode *addr1; ! 521: { ! 522: /* ! 523: * NOP2 NOP3 ! 524: * ! 525: * This routine will generate the filler bytes ! 526: * for the above two nops. ! 527: */ ! 528: ! 529: int val; ! 530: ! 531: if ( addr1->newtype != NOTYPE ) { ! 532: yyerror("Expand byte illegal with NOP2 or NOP3 instructions."); ! 533: return; ! 534: } ! 535: ! 536: if ( addr1->expspec != NULLSPEC ) { ! 537: yyerror("Operand specifier illegal with NOP2 or NOP3 instructions."); ! 538: return; ! 539: } ! 540: ! 541: generate( insptr->nbits, NOACTION, insptr->opcode, NULLSYM); ! 542: val = addr1->adexpr.expval; ! 543: ! 544: if ( insptr->tag == INSTRB ) { ! 545: if ((unsigned) val >= (1L << 8)) { ! 546: yyerror("Optional immediate for NOP2 larger than byte."); ! 547: } else { ! 548: generate( 8, NOACTION, val, NULLSYM); ! 549: } ! 550: } else { ! 551: if ((unsigned) val >= (1L << 16)) { ! 552: yyerror("Optional immediate for NOP3 larger than halfword."); ! 553: } else { ! 554: generate(16, NOACTION, val, NULLSYM); ! 555: } ! 556: } ! 557: } /* testgen */ ! 558: ! 559: opt21gen(insptr,addr1,addr2,constant) ! 560: instr *insptr; ! 561: register addrmode ! 562: *addr1, ! 563: *addr2; ! 564: short constant; ! 565: { ! 566: /* ! 567: * This function attempts to optimize certain dyadic instructions ! 568: * into monadics when the first operand is a particular ! 569: * immediate constant. ! 570: * ! 571: * The possible optimizations are: ! 572: * ! 573: * Dyadic Constant Monadic ! 574: * ! 575: * mov[bhw] 0 CLR[BHW] ! 576: * add[bhw]2 1 INC[BHW] ! 577: * sub[bhw]2 1 DEC[BHW] ! 578: * cmp[bhw] 0 TST[BHW] ! 579: * ! 580: * ! 581: * In all cases the dyadic opcode is stored in the low byte ! 582: * of the opcode field of the instruction table (pointed to by insptr) ! 583: * and the monadic opcode is stored in the 2nd low byte ! 584: * ! 585: */ ! 586: ! 587: if (addr1->admode==IMMD && addr1->adexpr.exptype==ABS && ! 588: addr1->adexpr.expval==(long)constant && ! 589: (insptr->tag & IS25) && opt) ! 590: { ! 591: /* generate monadic opcode */ ! 592: generate(8,NOACTION,(insptr->opcode >> 8),NULLSYM); ! 593: addrgen(insptr,addr2,NOTYPE,2); ! 594: } ! 595: else { ! 596: /* just do normal dyadic instruction */ ! 597: /* mask off 2nd low byte, but don't really have to */ ! 598: generate(8,NOACTION,insptr->opcode & 0xFFL,NULLSYM); ! 599: addrgen(insptr,addr1,NOTYPE,1); ! 600: addrgen(insptr,addr2,NOTYPE,2); ! 601: } /* else */ ! 602: } /* opt21gen */ ! 603: ! 604: jmpopgen(insptr,opnd1) ! 605: instr *insptr; ! 606: addrmode *opnd1; ! 607: { ! 608: instr *newins; ! 609: long opcd, newopcd; ! 610: BYTE nbits; ! 611: unsigned short action; ! 612: short jmptype; ! 613: ! 614: opcd = insptr->opcode; ! 615: ! 616: switch (insptr->tag) { ! 617: case INSTRB: /* byte displacement */ ! 618: nbits = 8; ! 619: if (opnd1->admode != EXADMD) ! 620: yyerror("Invalid operand"); ! 621: action = RELPC8; ! 622: break; ! 623: case INSTRH: /* halfword displacement */ ! 624: if (opnd1->admode != EXADMD) ! 625: yyerror("Invalid operand"); ! 626: nbits = 16; ! 627: action = RELPC16; ! 628: break; ! 629: case IS25|INSTRW: /* IS25, word displacement */ ! 630: if (opnd1->admode != EXADMD) { ! 631: /* can't generate PC relative */ ! 632: if ((newopcd = opcd >> 8) != 0) { ! 633: /* generate complementary branch */ ! 634: generate(8,NOACTION,newopcd,NULLSYM); ! 635: generate(8,FNDBRLEN,0L,NULLSYM); ! 636: } /* (newopcd = opcd >> 8) != 0 */ ! 637: newins = (*lookup("JMP",N_INSTALL,MNEMON)).itp; ! 638: generate(8,NOACTION,newins->opcode,NULLSYM); ! 639: addrgen(insptr,opnd1,NOTYPE,1); ! 640: return; ! 641: } /* opnd1->admode != EXADMD */ ! 642: jmptype = (opcd >> 8) != 0; ! 643: /* 1 means conditional; 0 unconditional */ ! 644: if (opt) switch(shortsdi(opnd1->adexpr.symptr, ! 645: opnd1->adexpr.expval, ! 646: jmptype ? CBRB : UBRB)) ! 647: { ! 648: case S_SDI: /* definitely 8-bit short */ ! 649: generate(8,NOACTION,opcd & 0xFFL,NULLSYM); ! 650: generate(8,RELPC8,opnd1->adexpr.expval, ! 651: opnd1->adexpr.symptr); ! 652: return; ! 653: case U_SDI: /* don't know; generate short and flag */ ! 654: generate(8,BRNOPT,opcd,NULLSYM); ! 655: generate(8,RELPC8,opnd1->adexpr.expval, ! 656: opnd1->adexpr.symptr); ! 657: return; ! 658: /* case L_SDI: fall through */ ! 659: } /* if (opt) switch (...) */ ! 660: ! 661: /* try 16-bit branch offset */ ! 662: switch(shortsdi(opnd1->adexpr.symptr, ! 663: opnd1->adexpr.expval, ! 664: jmptype ? CBRH : UBRH)) ! 665: { ! 666: case S_SDI: /* definitely 16-bit short */ ! 667: generate(8,NOACTION,(opcd & 0xFFL) - 1L, ! 668: NULLSYM); ! 669: generate(16,RELPC16,opnd1->adexpr.expval, ! 670: opnd1->adexpr.symptr); ! 671: return; ! 672: case U_SDI: /* unknown; generate 16-bit short (interm.) and flag */ ! 673: /* convert opcode(s) from short to intermed. */ ! 674: if ((opcd >> 8) != 0) ! 675: /* subtract 1 from both opcodes */ ! 676: opcd -= 0x0101L; ! 677: else ! 678: /* subtract 1 from opcode */ ! 679: --opcd; ! 680: generate(8,BRNOPT,opcd,NULLSYM); ! 681: generate(16,RELPC16,opnd1->adexpr.expval, ! 682: opnd1->adexpr.symptr); ! 683: return; ! 684: case L_SDI: ! 685: /* test for unconditional jump */ ! 686: if ((newopcd = opcd >> 8) != 0) { ! 687: /* generate complementary branch */ ! 688: generate(8,NOACTION,newopcd,NULLSYM); ! 689: generate(8,FNDBRLEN,0L,NULLSYM); ! 690: generate(0,NEWSTMT,(long)line,NULLSYM); ! 691: } ! 692: newins = (*lookup("JMP",N_INSTALL,MNEMON)).itp; ! 693: generate(8,NOACTION,newins->opcode,NULLSYM); ! 694: addrgen(insptr,opnd1,NOTYPE,1); ! 695: return; ! 696: } /* switch */ ! 697: case INSTRW: /* word displacement */ ! 698: generate(8,NOACTION,opcd,NULLSYM); ! 699: addrgen(insptr,opnd1,NOTYPE,1); ! 700: return; ! 701: default: ! 702: aerror("assembler error; invalid operator type"); ! 703: } /* switch */ ! 704: ! 705: generate(8,NOACTION,opcd & 0xFFL,NULLSYM); /* not necessary to mask */ ! 706: generate(nbits,action,opnd1->adexpr.expval,opnd1->adexpr.symptr); ! 707: } /* jmpopgen */ ! 708: ! 709: jsbopgen(insptr,opnd1) ! 710: instr *insptr; ! 711: addrmode *opnd1; ! 712: { ! 713: long opcd; ! 714: ! 715: opcd = insptr->opcode; ! 716: ! 717: if (opnd1->admode != EXADMD) { ! 718: /* can't generate PC relative */ ! 719: generate(8,NOACTION,opcd >> 8,NULLSYM); ! 720: addrgen(insptr,opnd1,NOTYPE,1); ! 721: } ! 722: else { ! 723: if (opt) switch(shortsdi(opnd1->adexpr.symptr, ! 724: opnd1->adexpr.expval,BSBB)) ! 725: { ! 726: case S_SDI: /* definitely 8-bit short */ ! 727: generate(8,NOACTION,opcd & 0xFFL,NULLSYM); ! 728: generate(8,RELPC8,opnd1->adexpr.expval, ! 729: opnd1->adexpr.symptr); ! 730: return; ! 731: case U_SDI: /* don't know; generate short and flag */ ! 732: generate(8,BSBNOPT,opcd,NULLSYM); ! 733: generate(8,RELPC8,opnd1->adexpr.expval, ! 734: opnd1->adexpr.symptr); ! 735: return; ! 736: /* case L_SDI: fall through */ ! 737: } /* if (opt) switch (...) */ ! 738: ! 739: /* try 16-bit branch offset */ ! 740: switch(shortsdi(opnd1->adexpr.symptr, ! 741: opnd1->adexpr.expval,BSBH)) ! 742: { ! 743: case S_SDI: /* definitely 16-bit short */ ! 744: generate(8,NOACTION,(opcd & 0xFFL) - 1L,NULLSYM); ! 745: generate(16,RELPC16,opnd1->adexpr.expval, ! 746: opnd1->adexpr.symptr); ! 747: return; ! 748: case U_SDI: /* don't know; generate 16-bit short and flag */ ! 749: /* convert opcode from short to intermed. */ ! 750: --opcd; ! 751: generate(8,BSBNOPT,opcd,NULLSYM); ! 752: generate(16,RELPC16,opnd1->adexpr.expval, ! 753: opnd1->adexpr.symptr); ! 754: generate(8,NOACTION,opcd >> 8,NULLSYM); ! 755: addrgen(insptr,opnd1,NOTYPE,1); ! 756: return; ! 757: case L_SDI: ! 758: generate(8,NOACTION,opcd,NULLSYM); ! 759: addrgen(insptr,opnd1,NOTYPE,2); ! 760: return; ! 761: } /* switch */ ! 762: } /* else */ ! 763: } /* jsbopgen */ ! 764: ! 765: callgen(insptr,imm,dest) ! 766: instr *insptr; ! 767: addrmode *imm, *dest; ! 768: { ! 769: /* ! 770: * ! 771: * call imm,dest ! 772: * ! 773: * is encoded as ! 774: * ! 775: * CALL -(4*imm)(%sp),dest ! 776: * ! 777: */ ! 778: ! 779: static addrmode dispsp = {NOTYPE,DSPMD,SPREG,{ABS,NULLSYM,1L}}; ! 780: int span; ! 781: ! 782: dispsp.adexpr.expval = - (4L * imm->adexpr.expval ); ! 783: generate(8,NOACTION,insptr->opcode,NULLSYM); /* CALL opcode */ ! 784: addrgen(insptr,&dispsp,NOTYPE,1); ! 785: ! 786: #ifndef CALLPCREL ! 787: addrgen(insptr,dest,NOTYPE,2); ! 788: #else ! 789: if (dest->admode != EXADMD) { ! 790: /* can't generate PC relative */ ! 791: addrgen(insptr,dest,NOTYPE,2); ! 792: } else { ! 793: if (opt) { ! 794: if (sdi(dest->adexpr.symptr, dest->adexpr.expval, ! 795: PCBRELCALL) == S_SDI) { ! 796: span = shortsdi(dest->adexpr.symptr, ! 797: dest->adexpr.expval,PCBRELCALL); ! 798: if ( span == S_SDI) { ! 799: /* byte displacement from PC */ ! 800: generate(8,NOACTION,0xCFL,NULLSYM); ! 801: generate(8,RELPC8,dest->adexpr.expval, ! 802: dest->adexpr.symptr); ! 803: } else { ! 804: yyerror("Assembler error with short span dependent procedure call."); ! 805: } ! 806: return; ! 807: } ! 808: } ! 809: ! 810: /* if (opt) switch(shortsdi(dest->adexpr.symptr, ! 811: /* dest->adexpr.expval,PCBRELCALL)) ! 812: /* { ! 813: /* case S_SDI: /* definitely 8-bit short */ ! 814: /* /* byte displacement from PC */ ! 815: /* generate(8,NOACTION,0xCFL,NULLSYM); ! 816: /* generate(8,RELPC8,dest->adexpr.expval, ! 817: /* dest->adexpr.symptr); ! 818: /* return; ! 819: /* case U_SDI: /* don't know; generate short and flag */ ! 820: /* /* byte displacement from PC */ ! 821: /* generate(8,CALLNOPT,0xCFL,NULLSYM); ! 822: /* generate(8,RELPC8,dest->adexpr.expval, ! 823: /* dest->adexpr.symptr); ! 824: /* return; ! 825: /* /* case L_SDI: fall through */ ! 826: /* } /* if (opt) switch (...) */ ! 827: ! 828: /* try 16-bit branch offset */ ! 829: switch(shortsdi(dest->adexpr.symptr, ! 830: dest->adexpr.expval,PCHRELCALL)) ! 831: { ! 832: case S_SDI: /* definitely 16-bit short */ ! 833: /* halfword relative from PC */ ! 834: generate(8,NOACTION,0xAFL,NULLSYM); ! 835: generate(16,RELPC16,dest->adexpr.expval, ! 836: dest->adexpr.symptr); ! 837: return; ! 838: case U_SDI: /* don't know; generate 16-bit short and flag */ ! 839: /* halfword relative from PC */ ! 840: generate(8,CALLNOPT,0xAFL,NULLSYM); ! 841: generate(16,RELPC16,dest->adexpr.expval, ! 842: dest->adexpr.symptr); ! 843: return; ! 844: case L_SDI: ! 845: /* CALL opcode */ ! 846: addrgen(insptr,dest,NOTYPE,2); ! 847: return; ! 848: } /* switch */ ! 849: } /* else */ ! 850: #endif ! 851: } /* callgen */ ! 852: ! 853: loop1gen(insptr,index,incr,limit,dest) ! 854: instr *insptr; ! 855: addrmode *index, *incr, *limit, *dest; ! 856: { ! 857: /* ! 858: * ! 859: * acX index,incr,limit,dest ! 860: * where X can be [jl|jlu|jle|jleu] ! 861: * ! 862: * is encoded as ! 863: * ! 864: * addw2 incr,index ! 865: * cmpw index,limit ! 866: * X dest ! 867: * ! 868: */ ! 869: ! 870: instr *newins; ! 871: ! 872: /* addw2 */ ! 873: newins = (*lookup("addw2",N_INSTALL,MNEMON)).itp; ! 874: opt21gen(newins,incr,index,1); /* optimized "add" */ ! 875: pcintcheck(newins,index); ! 876: ! 877: /* cmpw */ ! 878: generate(0,NEWSTMT,(long)line,NULLSYM); ! 879: newins = (*lookup("cmpw",N_INSTALL,MNEMON)).itp; ! 880: #if 0 ! 881: /* generate optimized "cmpw" and interchange operands */ ! 882: opt21gen(newins,limit,index,0); ! 883: #endif ! 884: /* DONT generate optimized "cmpw" because of Interrupt ! 885: * After TSTW Chip Bug. ! 886: */ ! 887: generate(8,NOACTION,newins->opcode & 0xFFL,NULLSYM); ! 888: addrgen(newins,limit,NOTYPE,1); ! 889: addrgen(newins,index,NOTYPE,2); ! 890: ! 891: /* jump instr. */ ! 892: generate(0,NEWSTMT,(long)line,NULLSYM); ! 893: newins = (*lookup((insptr->name)+2,N_INSTALL,MNEMON)).itp; ! 894: jmpopgen(newins,dest); ! 895: } /* loop1gen */ ! 896: ! 897: loop2gen(insptr,index,incr,dest) ! 898: instr *insptr; ! 899: addrmode *index, *incr, *dest; ! 900: { ! 901: /* ! 902: * ! 903: * atjnz[bhw] index,incr,dest ! 904: * ! 905: * is encoded as ! 906: * ! 907: * addw2 incr,index ! 908: * TST[BHW] *index ! 909: * jnz dest ! 910: * ! 911: */ ! 912: ! 913: instr *newins; ! 914: ! 915: /* addw2 */ ! 916: newins = (*lookup("addw2",N_INSTALL,MNEMON)).itp; ! 917: opt21gen(newins,incr,index,1); /* optimized "add" */ ! 918: ! 919: /* TST[BHW] */ ! 920: generate(0,NEWSTMT,(long)line,NULLSYM); ! 921: generate(8,NOACTION,insptr->opcode,NULLSYM); /* TST opcode */ ! 922: ! 923: /* ! 924: * To generate TST *index, ! 925: * must add a level of indirection to "index" ! 926: * ! 927: */ ! 928: ! 929: switch(index->admode) { ! 930: ! 931: case DSPMD: ! 932: case EXADMD: ! 933: case ABSMD: ! 934: ++(index->admode); /* adds a level of indirection */ ! 935: break; ! 936: case REGMD: ! 937: index->admode = DSPMD; ! 938: index->adexpr.exptype = ABS; ! 939: index->adexpr.expval = 0L; ! 940: index->adexpr.symptr = NULLSYM; ! 941: break; ! 942: default: ! 943: yyerror("Invalid `index' operand of `atjnz'"); ! 944: break; ! 945: } /* switch */ ! 946: ! 947: addrgen(insptr,index,NOTYPE,1); ! 948: ! 949: /* jnz */ ! 950: generate(0,NEWSTMT,(long)line,NULLSYM); ! 951: newins = (*lookup("jnz",N_INSTALL,MNEMON)).itp; ! 952: jmpopgen(newins,dest); ! 953: } /* loop2gen */ ! 954: ! 955: blockgen(insptr) ! 956: instr *insptr; ! 957: { ! 958: /* ! 959: * ! 960: * movbl[bh] ! 961: * is encoded as ! 962: * ! 963: * TSTW %r2 ! 964: * BRB +12 (for half) or +14 (for byte) ! 965: * mov[bh] (%r0),(%r1) ! 966: * NOP ! 967: * addw2 &2,%r0 (for half) or INCW %r0 (for byte) ! 968: * addw2 &2,%r1 (for half) or INCW %r1 (for byte) ! 969: * DECW %r2 ! 970: * BNEB -12 (for half) or -10 (for byte) ! 971: * ! 972: */ ! 973: ! 974: instr *newins; ! 975: short byte; ! 976: ! 977: if( (insptr->tag & SHFT_MSK) == INSTRB) ! 978: byte = YES; ! 979: else ! 980: byte = NO; ! 981: ! 982: /* TSTW */ ! 983: newins = (*lookup("TSTW",N_INSTALL,MNEMON)).itp; ! 984: generate(8,NOACTION,newins->opcode,NULLSYM); /* TSTW opcode */ ! 985: generate(8,NOACTION,(long)(CREGMD<<4|0x02),NULLSYM); /* %r2 */ ! 986: ! 987: /* BRB */ ! 988: generate(0,NEWSTMT,(long)line,NULLSYM); ! 989: newins = (*lookup("BRB",N_INSTALL,MNEMON)).itp; ! 990: generate(8,NOACTION,newins->opcode,NULLSYM); /* unc. branch */ ! 991: if (byte == YES) ! 992: generate(8,NOACTION,12L,NULLSYM); ! 993: else ! 994: generate(8,NOACTION,14L,NULLSYM); ! 995: ! 996: /* mov[bh] */ ! 997: generate(0,NEWSTMT,(long)line,NULLSYM); ! 998: generate(8,NOACTION,insptr->opcode,NULLSYM); /* mov[bh] */ ! 999: generate(8,NOACTION,(long)(CREGDFMD<<4|0x00),NULLSYM); /* (%r0) */ ! 1000: generate(8,NOACTION,(long)(CREGDFMD<<4|0x01),NULLSYM); /* (%r1) */ ! 1001: ! 1002: /* ! 1003: * A NOP must ne inserted here because a write to memory ! 1004: * was just generated. ! 1005: */ ! 1006: generate(0,NEWSTMT,(long)line,NULLSYM); ! 1007: newins = (*lookup("NOP",N_INSTALL,MNEMON)).itp; ! 1008: generate(newins->nbits, NOACTION, newins->opcode, NULLSYM); ! 1009: ! 1010: generate(0,NEWSTMT,(long)line,NULLSYM); ! 1011: if (byte == YES) { ! 1012: /* INCW - increment register 0 */ ! 1013: /* INCW - increment register 1 */ ! 1014: ! 1015: newins = (*lookup("INCW",N_INSTALL,MNEMON)).itp; ! 1016: generate(8,NOACTION,newins->opcode,NULLSYM); /* INCW */ ! 1017: generate(8,NOACTION,(long)(CREGMD<<4|0x00),NULLSYM); /* %r0 */ ! 1018: generate(0,NEWSTMT,(long)line,NULLSYM); ! 1019: generate(8,NOACTION,newins->opcode,NULLSYM); /* INCW */ ! 1020: generate(8,NOACTION,(long)(CREGMD<<4|0x01),NULLSYM); /* %r1 */ ! 1021: } ! 1022: else { ! 1023: ! 1024: /* addw2 - increment register 0 */ ! 1025: /* addw2 - increment register 1 */ ! 1026: newins = (*lookup("addw2",N_INSTALL,MNEMON)).itp; ! 1027: generate(8,NOACTION,newins->opcode,NULLSYM); /* addw2 */ ! 1028: generate(8,NOACTION,2L,NULLSYM); ! 1029: generate(8,NOACTION,(long)(CREGMD<<4|0x00),NULLSYM); /* %r0 */ ! 1030: generate(0,NEWSTMT,(long)line,NULLSYM); ! 1031: generate(8,NOACTION,newins->opcode,NULLSYM); /* addw2 */ ! 1032: generate(8,NOACTION,2L,NULLSYM); ! 1033: generate(8,NOACTION,(long)(CREGMD<<4|0x01),NULLSYM); /* %r1 */ ! 1034: } ! 1035: ! 1036: /* DECW */ ! 1037: generate(0,NEWSTMT,(long)line,NULLSYM); ! 1038: newins = (*lookup("DECW",N_INSTALL,MNEMON)).itp; ! 1039: generate(8,NOACTION,newins->opcode,NULLSYM); /* DECW */ ! 1040: generate(8,NOACTION,(long)(CREGMD<<4|0x02),NULLSYM); /* %r2 */ ! 1041: ! 1042: /* BNEB */ ! 1043: generate(0,NEWSTMT,(long)line,NULLSYM); ! 1044: newins = (*lookup("BNEB",N_INSTALL,MNEMON)).itp; ! 1045: generate(8,NOACTION,newins->opcode,NULLSYM); /* BNEB opcode */ ! 1046: if (byte == YES) ! 1047: generate(8,NOACTION,-10L,NULLSYM); ! 1048: else ! 1049: generate(8,NOACTION,-12L,NULLSYM); ! 1050: } /* blockgen */ ! 1051: ! 1052: pushopgen(insptr,opnd1) ! 1053: instr *insptr; ! 1054: addrmode *opnd1; ! 1055: { ! 1056: /* ! 1057: * ! 1058: * push[zb][bh] opnd1 ! 1059: * ! 1060: * is encoded as ! 1061: * ! 1062: * addw2 &4,%sp ! 1063: * followed by one of the following: ! 1064: * ! 1065: * if opnd1 does not use %sp ! 1066: * mov[bh] {X}opnd1,{sword}-4(%sp) ! 1067: * ! 1068: * if opnd1=%sp ! 1069: * subw3 &4,{X}%sp,{sword}-4(%sp) ! 1070: * ! 1071: * if opnd1=expr(%sp) ! 1072: * mov[bh] {X}expr-4(%sp),{sword}-4(%sp) ! 1073: * ! 1074: * if opnd1=*expr(%sp) ! 1075: * mov[bh] {X}*expr-4(%sp),{sword}-4(%sp) ! 1076: * ! 1077: * where X = signed for push.b ! 1078: * unsigned for push.h ! 1079: */ ! 1080: ! 1081: static addrmode dispsp = {NOTYPE,DSPMD,SPREG,{ABS,NULLSYM,-4L}}; ! 1082: static addrmode immdop = {NOTYPE,IMMD,0x04,{ABS,NULLSYM,4L}}; ! 1083: instr *newins; ! 1084: short expand; ! 1085: ! 1086: /* addw2 */ ! 1087: newins = (*lookup("addw2",N_INSTALL,MNEMON)).itp; ! 1088: generate(8,NOACTION,newins->opcode,NULLSYM); ! 1089: addrgen(insptr,&immdop,NOTYPE,1); ! 1090: generate(8,NOACTION,(long)((CREGMD<<4)|SPREG),NULLSYM); /* operand %sp */ ! 1091: ! 1092: /* decide on which second instruction to generate */ ! 1093: switch (opnd1->admode) { ! 1094: case REGMD: ! 1095: if (opnd1->adreg == SPREG) { /* if opnd1 is %sp then */ ! 1096: /* generate subw3 instr */ ! 1097: newins = (*lookup("subw3",N_INSTALL,MNEMON)).itp; ! 1098: generate(8,NOACTION,newins->opcode,NULLSYM); ! 1099: addrgen(insptr,&immdop,NOTYPE,1); ! 1100: generate(8,NOACTION,(long)((CREGMD<<4)|SPREG),NULLSYM); /* oprnd %sp */ ! 1101: addrgen(insptr,&dispsp,SWORD,3); /* oprnd {sword}-4(%sp) */ ! 1102: pcintcheck(insptr,&dispsp); ! 1103: return; ! 1104: } else ! 1105: break; ! 1106: case REGDFMD: ! 1107: case DSPMD: ! 1108: case DSPDFMD: ! 1109: /* if register is %sp, subtract 4 from displacement */ ! 1110: if (opnd1->adreg == SPREG) ! 1111: opnd1->adexpr.expval -= 4; ! 1112: break; ! 1113: } /* switch */ ! 1114: ! 1115: /* mov[bh] opcode */ ! 1116: generate(8,NOACTION,insptr->opcode,NULLSYM); ! 1117: switch (insptr->tag & (~IS25)) { ! 1118: case INSTRBW: ! 1119: expand = SBYTE; ! 1120: break; ! 1121: case INSTRHW: ! 1122: expand = UHALF; ! 1123: break; ! 1124: default: ! 1125: expand = NOTYPE; ! 1126: } /* switch */ ! 1127: ! 1128: addrgen(insptr,opnd1,expand,1); ! 1129: addrgen(insptr,&dispsp,SWORD,2); ! 1130: pcintcheck(insptr,&dispsp); ! 1131: } /* pushopgen */ ! 1132: ! 1133: shftopgen(insptr,opnd1,opnd2,opnd3) ! 1134: instr *insptr; ! 1135: addrmode *opnd1, *opnd2, *opnd3; ! 1136: { ! 1137: short expand1, expand2; ! 1138: long opcd, opcd2; ! 1139: ! 1140: opcd = insptr->opcode; ! 1141: if ((insptr->tag & IS25) && ! 1142: (opnd1->admode != REGMD) && (opnd1->admode != IMMD)) ! 1143: { ! 1144: expand2 = SWORD; ! 1145: /* ! 1146: * The opcode field contains 2 8-bit opcodes. ! 1147: * The lower opcode corresponds to the shift ! 1148: * word opcode. The higher opcode corresponds ! 1149: * either to a shift word or a shift byte opcode. ! 1150: * Since the shift length (opnd1) is a byte operand ! 1151: * in IS25, the shift byte opcode will be used if ! 1152: * there is one on the MAC32. If there is no shift ! 1153: * byte instruction, then the shift word will be used ! 1154: * with an expand byte of signed-byte specified. ! 1155: * Thus, test to see if the 2 opcodes are the same. ! 1156: * If so, then the expand byte must be used. ! 1157: */ ! 1158: opcd2 = opcd & 0x000000FFL; /* lower 8 bits */ ! 1159: if ((opcd >>= 8) == opcd2) ! 1160: expand1 = SBYTE; ! 1161: else ! 1162: expand1 = NOTYPE; ! 1163: } ! 1164: else ! 1165: expand1 = expand2 = NOTYPE; ! 1166: ! 1167: generate(8,NOACTION,opcd,NULLSYM); ! 1168: addrgen(insptr,opnd1,expand1,1); ! 1169: addrgen(insptr,opnd2,expand2,2); ! 1170: addrgen(insptr,opnd3,NOTYPE,3); ! 1171: } /* shftopgen */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.