|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California ! 3: */ ! 4: #ifndef lint ! 5: static char sccsid[] = "@(#)ascode.c 4.11 6/30/83"; ! 6: #endif not lint ! 7: ! 8: #include <stdio.h> ! 9: #include "as.h" ! 10: #include "assyms.h" ! 11: ! 12: insout(opcode, ap, nact) ! 13: u_char opcode; ! 14: struct arg *ap; ! 15: int nact; ! 16: { ! 17: int jxxflg; ! 18: reg struct instab *ip; /* the instruction */ ! 19: reg struct arg *ap_walk; /* actual param walk */ ! 20: reg int i; ! 21: reg int ap_type; /* actual param type */ ! 22: reg int ap_type_mask; /* masked actual param */ ! 23: reg int argtype; ! 24: ! 25: jxxflg = nact; ! 26: if (nact < 0) ! 27: nact = -nact; ! 28: if (passno == 1) { ! 29: ip = ITABFETCH(opcode & 0xFF); ! 30: if (nact < ip->i_nargs) ! 31: yyerror("Too few arguments"); ! 32: if (nact > ip->i_nargs) { ! 33: yyerror("Too many arguments"); ! 34: nact = ip->i_nargs; ! 35: } ! 36: /* ! 37: * Check argument compatability with instruction template ! 38: */ ! 39: for (ap_walk = ap, i = 1; i <= nact; ap_walk++, i++){ ! 40: ap_type = ap_walk->a_atype; ! 41: ap_type_mask = ap_type & AMASK; ! 42: /* ! 43: * The switch value is >> by TYPLG so that the switch ! 44: * code is dense, not implemented as a sequence ! 45: * of branches but implemented as a casel. ! 46: * In addition, cases ACCI and ACCR are added to force ! 47: * dense switch code. ! 48: * switch on the type of fp ! 49: */ ! 50: argtype = fetcharg(ip, i-1); ! 51: switch( (argtype & ACCESSMASK) >> TYPLG){ ! 52: case ACCI >> TYPLG: ! 53: break; ! 54: case ACCR >> TYPLG: ! 55: if ((argtype == A_RQ) && ! 56: (ap_type_mask == AREG) && ! 57: (ap_walk->a_areg1 & 0x01)) { ! 58: yyerror("arg %d, register must be even",i); ! 59: return; ! 60: } ! 61: if (ap_type_mask == ADECR) ! 62: { ! 63: yyerror("arg %d, a source arg cant be auto decrement",i); ! 64: return; ! 65: } ! 66: if (argtype == A_RD) ! 67: { ! 68: if (ap_type_mask == AIMM) ! 69: if ( !(ap_type&ASTAR)) ! 70: { ! 71: yyerror("arg %d, cant be immediate data",i); ! 72: return; ! 73: } ! 74: if ((argtype == A_RD) && ! 75: ((ap_type_mask == AINCR) || ! 76: (ap_type_mask == ADECR))) ! 77: { ! 78: yyerror("arg %d, cant be auto increment/decrement",i); ! 79: return; ! 80: } ! 81: if ((argtype == A_RD) && ! 82: (ap_type_mask == AREG) && ! 83: (ap_walk->a_areg1 & 0x01)) { ! 84: yyerror("arg %d, register must be even",i); ! 85: return; ! 86: } ! 87: } ! 88: break; ! 89: case ACCB >> TYPLG: ! 90: if ( ap_type_mask != AEXP) ! 91: { ! 92: yyerror("arg %d, branch displacement must be an expression",i); ! 93: return; ! 94: } ! 95: break; ! 96: case ACCA >> TYPLG: ! 97: switch(ap_type_mask){ ! 98: case AREG: yyerror("arg %d, addressing a register",i); ! 99: return; ! 100: case AIMM: if ( !(ap_type & ASTAR) ){ ! 101: yyerror("arg %d, addressing an immediate operand",i); ! 102: return; ! 103: } ! 104: } ! 105: break; ! 106: case ACCM >> TYPLG: ! 107: case ACCW >> TYPLG: ! 108: if ((argtype == A_WQ) && ! 109: (ap_type_mask == AREG) && ! 110: (ap_walk->a_areg1 & 0x01)) { ! 111: yyerror("arg %d, register must be even",i); ! 112: return; ! 113: } ! 114: switch(ap_type_mask){ ! 115: case AIMM: if (!(ap_type&ASTAR)) { ! 116: yyerror("arg %d, modifying a constant",i); ! 117: return; ! 118: } ! 119: case AINCR: ! 120: yyerror("arg %d, a destination arg cant be auto increment",i); ! 121: return; ! 122: } ! 123: break; ! 124: } /* end of the switch on fp_type */ ! 125: if (ap_type & AINDX) { ! 126: if (ap_walk->a_areg2==0xF) { ! 127: yyerror("arg %d, PC used as index",i); ! 128: return; ! 129: } ! 130: if (ap_walk->a_areg2==0xE) { ! 131: yyerror("arg %d, SP used as index",i); ! 132: return; ! 133: } ! 134: switch(ap_type_mask){ ! 135: case AREG: yyerror("arg %d, indexing the register file",i); ! 136: return; ! 137: case AIMM: yyerror("arg %d, indexing a constant",i); ! 138: return; ! 139: case ADECR: ! 140: case AINCR: if (ap_walk->a_areg1==ap_walk->a_areg2) { ! 141: yyerror("arg %d, indexing with modified register",i); ! 142: return; ! 143: } ! 144: break; ! 145: } /* end of switch on ap_type_mask */ ! 146: } /* end of AINDX */ ! 147: } ! 148: } /* both passes here */ ! 149: if (jxxflg < 0) ! 150: ijxout(opcode, ap, nact); ! 151: else ! 152: putins(opcode, ap, nact); ! 153: } ! 154: ! 155: extern int d124; ! 156: ! 157: putins(opcode, ap, n) ! 158: u_char opcode; ! 159: register struct arg *ap; ! 160: int n; /* Must be positive */ ! 161: { ! 162: reg struct exp *xp; ! 163: reg int argtype; ! 164: int i; ! 165: int reloc_how; ! 166: ! 167: #ifdef DEBUG ! 168: fflush(stdout); ! 169: #endif ! 170: if (passno == 2) ! 171: goto PASS2; ! 172: ! 173: dotp->e_xvalue += n+1; /* at least one byte per arg */ ! 174: ! 175: for (i=0; i<n; i++,ap++) { /* some args take more than 1 byte */ ! 176: argtype = ap->a_atype; ! 177: if (argtype & AINDX) ! 178: dotp->e_xvalue++; ! 179: /* ! 180: * This switch has been fixed by enumerating the no action ! 181: * alternatives (those that have 1 one byte of code) ! 182: * so that a casel instruction is emitted. ! 183: */ ! 184: switch (argtype&~(AINDX|ASTAR)) { ! 185: case AREG: ! 186: case ABASE: ! 187: case ADECR: ! 188: case AINCR: ! 189: break; ! 190: case AEXP: ! 191: argtype = fetcharg(ITABFETCH(opcode), i); ! 192: if (argtype == A_BB) ! 193: break; ! 194: if (argtype == A_BW){ ! 195: dotp->e_xvalue++; ! 196: break; ! 197: } ! 198: /* ! 199: * Reduces to PC relative ! 200: */ ! 201: dotp->e_xvalue += ap->a_dispsize; ! 202: break; ! 203: ! 204: case ADISP: ! 205: xp=ap->a_xp; ! 206: if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){ ! 207: dotp->e_xvalue += ap->a_dispsize; ! 208: break; ! 209: } ! 210: if (xp->e_xvalue==0 && !(argtype&ASTAR)) ! 211: break; ! 212: dotp->e_xvalue ++; ! 213: if (ISBYTE(xp->e_xvalue)) ! 214: break; ! 215: dotp->e_xvalue ++; ! 216: if (ISWORD(xp->e_xvalue)) ! 217: break; ! 218: dotp->e_xvalue += 2; ! 219: break; ! 220: ! 221: case AIMM: ! 222: if (ap->a_atype&ASTAR) { ! 223: argtype=TYPL; ! 224: } else { ! 225: argtype = fetcharg(ITABFETCH(opcode), i); ! 226: if (argtype&ACCA) ! 227: argtype = TYPL; ! 228: else ! 229: argtype &= TYPMASK; ! 230: xp = ap->a_xp; ! 231: if ( ((xp->e_xtype&XTYPE)==XABS) ! 232: && (!(xp->e_xtype&XFORW)) ! 233: && (argtype != TYPD) ! 234: && (argtype != TYPF)) ! 235: { ! 236: if ((xp->e_xvalue>=0) ! 237: && (xp->e_xvalue<=63)) ! 238: break; ! 239: if (ISBYTE(xp->e_xvalue)) ! 240: argtype = TYPB; ! 241: else ! 242: if (ISWORD(xp->e_xvalue)) ! 243: argtype = TYPW; ! 244: else ! 245: argtype = TYPL; ! 246: } ! 247: else ! 248: argtype = TYPL; ! 249: } ! 250: switch (argtype) { ! 251: case TYPD: ! 252: case TYPF: ! 253: if (!(slitflt(xp))) ! 254: return; ! 255: case TYPQ: ! 256: case TYPL: ! 257: case TYPW: ! 258: case TYPB: ! 259: dotp->e_xvalue += ty_nbyte[argtype]; ! 260: break; ! 261: } /*end of the switch on argtype*/ ! 262: } /*end of the switch on the type*/ ! 263: } /*end of looping for all arguments*/ ! 264: return; ! 265: ! 266: PASS2: ! 267: /* ! 268: * Output the opcode ! 269: */ ! 270: Outb(opcode); ! 271: if ((passno == 2) && liston) ! 272: { ! 273: byte_out (opcode); ! 274: *layoutpos++ = ' '; ! 275: } ! 276: ! 277: for (i=0; i<n; i++,ap++) {/* now for the arguments */ ! 278: argtype=ap->a_atype; ! 279: xp=ap->a_xp; ! 280: reloc_how = TYPNONE; ! 281: if (argtype&AINDX) { ! 282: { Outb(0x40 | ap->a_areg2); ! 283: if ((passno == 2) && liston) ! 284: byte_out (0x40 | ap->a_areg2); } ! 285: argtype &= ~AINDX; ! 286: } ! 287: if (argtype&ASTAR) { ! 288: ap->a_areg1 |= 0x10; ! 289: argtype &= ~ASTAR; ! 290: } ! 291: switch (argtype) { ! 292: case AREG: /* %r */ ! 293: ap->a_areg1 |= 0x50; ! 294: break; ! 295: case ABASE: /* (%r) */ ! 296: ap->a_areg1 |= 0x60; ! 297: break; ! 298: case ADECR: /* -(%r) */ ! 299: ap->a_areg1 |= 0x70; ! 300: break; ! 301: case AINCR: /* (%r)+ */ ! 302: ap->a_areg1 |= 0x80; ! 303: break; ! 304: case AEXP: /* expr */ ! 305: argtype = fetcharg(ITABFETCH(opcode), i); ! 306: if (argtype == A_BB) { ! 307: ap->a_areg1 = argtype = ! 308: xp->e_xvalue - (dotp->e_xvalue + 1); ! 309: if (xp->e_xtype & XXTRN) ! 310: yywarning("%s: destination label is external", ! 311: FETCHNAME(ITABFETCH(opcode))); ! 312: if (!ISBYTE(argtype) && !jxxxJUMP) ! 313: yyerror("%s: Branch too far(%db): try -J flag", ! 314: FETCHNAME(ITABFETCH(opcode)), ! 315: argtype); ! 316: break; ! 317: } ! 318: if (argtype == A_BW) { ! 319: ap->a_areg1 = argtype = xp->e_xvalue ! 320: -= dotp->e_xvalue + 2; ! 321: if (xp->e_xtype & XXTRN) ! 322: yywarning("%s: destination label is external", ! 323: FETCHNAME(ITABFETCH(opcode))); ! 324: xp->e_xtype = XABS; ! 325: if (!ISWORD(argtype) && !jxxxJUMP) ! 326: yyerror("%s: Branch too far(%db): try -J flag", ! 327: FETCHNAME(ITABFETCH(opcode)), ! 328: argtype); ! 329: reloc_how = TYPB; ! 330: ap->a_areg1 = argtype>>8; ! 331: xp->e_xvalue = argtype; ! 332: break; ! 333: } ! 334: /* reduces to expr(pc) mode */ ! 335: ap->a_areg1 |= (0xAF + mod124[ap->a_dispsize]); ! 336: reloc_how = type_124[ap->a_dispsize] + RELOC_PCREL; ! 337: break; ! 338: ! 339: case ADISP: /* expr(%r) */ ! 340: ap->a_areg1 |= 0xA0; ! 341: if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){ ! 342: ap->a_areg1 += mod124[ap->a_dispsize]; ! 343: reloc_how = type_124[ap->a_dispsize]; ! 344: break; ! 345: } ! 346: if (xp->e_xvalue==0 && !(ap->a_areg1&0x10)) { ! 347: ap->a_areg1 ^= 0xC0; ! 348: break; ! 349: } ! 350: reloc_how = TYPB; ! 351: if (ISBYTE(xp->e_xvalue)) ! 352: break; ! 353: ap->a_areg1 += 0x20; ! 354: reloc_how = TYPW; ! 355: if (ISWORD(xp->e_xvalue)) ! 356: break; ! 357: ap->a_areg1 += 0x20; ! 358: reloc_how = TYPL; ! 359: break; ! 360: ! 361: case AIMM: /* $expr */ ! 362: if (ap->a_atype&ASTAR) { ! 363: argtype=TYPL; ! 364: ap->a_areg1 |= 0x8F; ! 365: } else { ! 366: argtype = fetcharg(ITABFETCH(opcode), i); ! 367: if (argtype&ACCA) ! 368: argtype = TYPL; ! 369: else ! 370: argtype &= TYPMASK; ! 371: if ( ( (xp->e_xtype&XTYPE) == XABS) ! 372: && !(xp->e_xtype&XFORW) ! 373: && (argtype != TYPF) ! 374: && (argtype != TYPD) ! 375: ) ! 376: { ! 377: if ((xp->e_xvalue <= 63) ! 378: && (xp->e_xvalue >= 0)) ! 379: { ! 380: ap->a_areg1 = xp->e_xvalue; ! 381: break; ! 382: } ! 383: else ! 384: if (ISBYTE (xp->e_xvalue)) ! 385: { ! 386: ap->a_areg1 = 0x88; ! 387: argtype = TYPB; ! 388: } ! 389: else ! 390: if (ISWORD (xp->e_xvalue)) ! 391: { ! 392: ap->a_areg1 = 0x89; ! 393: argtype = TYPW; ! 394: } ! 395: else ! 396: { ! 397: ap->a_areg1 = 0x8F; ! 398: argtype = TYPL; ! 399: } ! 400: } ! 401: else ! 402: { ! 403: ap->a_areg1 = 0x8F; ! 404: argtype = TYPL; ! 405: } ! 406: } ! 407: reloc_how = argtype; ! 408: if (reloc_how == TYPD || reloc_how == TYPF){ ! 409: if ( ((xp->e_xtype&XTYPE)==XABS) ! 410: && (!(xp->e_xtype&XFORW)) ! 411: && (slitflt(xp)) ! 412: ){ ! 413: reloc_how = TYPNONE; ! 414: ap->a_areg1=extlitflt(xp); ! 415: } ! 416: } ! 417: break; ! 418: ! 419: } /*end of the switch on argtype*/ ! 420: /* ! 421: * use the first byte to describe the argument ! 422: */ ! 423: Outb(ap->a_areg1); ! 424: if ((passno == 2) && liston) ! 425: byte_out (ap->a_areg1); ! 426: if (reloc_how != TYPNONE) ! 427: outrel(xp, reloc_how); ! 428: if ((passno == 2) && liston) ! 429: *layoutpos++ = ' '; ! 430: } /*end of the for to pick up all arguments*/ ! 431: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.