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: }

Defined functions

immconstant defined in line 358; used 2 times
insout defined in line 15; used 2 times
putins defined in line 112; used 5 times

Defined variables

sccsid defined in line 8; never used

Defined macros

IMMFLT defined in line 355; never used
IMMINT defined in line 356; never used
Last modified: 1985-04-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1459
Valid CSS Valid XHTML 1.0 Strict