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