1: /*
   2:  * Copyright (c) 1984, 1986 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[] = "@(#)machdep.c	7.1 (Berkeley) 6/5/86";
   9: #endif not lint
  10: 
  11: #include <stdio.h>
  12: #include <ctype.h>
  13: #include "inline.h"
  14: 
  15: extern char *strcpy();
  16: extern char *strcat();
  17: extern char *index();
  18: 
  19: /*
  20:  * The routines and tables in this file must be rewritten
  21:  * for each new machine that this program is ported to.
  22:  */
  23: 
  24: #ifdef vax
  25: /*
  26:  * Instruction stop table.
  27:  * All instructions that implicitly modify any of the temporary
  28:  * registers, change control flow, or implicitly loop must be
  29:  * listed in this table. It is used to find the end of a basic
  30:  * block when scanning backwards through the instruction stream
  31:  * trying to merge the inline expansion.
  32:  */
  33: struct inststoptbl inststoptable[] = {
  34:     { "jbc" }, { "jlbc" }, { "jbs" }, { "jlbs" }, { "jbcc" },
  35:     { "jbsc" }, { "jbcs" }, { "jbss" }, { "jbr" }, { "jcc" },
  36:     { "jcs" }, { "jvc" }, { "jvs" }, { "jlss" }, { "jlssu" },
  37:     { "jleq" }, { "jlequ" }, { "jeql" }, { "jeqlu" }, { "jneq" },
  38:     { "jnequ" }, { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" },
  39:     { "chmk" }, { "chme" }, { "chms" }, { "chmu" }, { "rei" },
  40:     { "ldpctx" }, { "svpctx" }, { "xfc" }, { "bpt" },
  41:     { "bugw" }, { "bugl" }, { "halt" }, { "pushr" }, { "popr" },
  42:     { "polyf" }, { "polyd" }, { "polyg" }, { "polyh" },
  43:     { "bneq" }, { "bnequ" }, { "beql" }, { "beqlu" }, { "bgtr" },
  44:     { "bleq" }, { "bgeq" }, { "blss" }, { "bgtru" }, { "blequ" },
  45:     { "bvc" }, { "bvs" }, { "bgequ" }, { "bcc" }, { "blssu" },
  46:     { "bcs" }, { "brb" }, { "brw" }, { "jmp" },
  47:     { "bbs" }, { "bbc" }, { "bbss" }, { "bbcs" }, { "bbsc" },
  48:     { "bbcc" }, { "bbssi" }, { "bbcci" }, { "blbs" }, { "blbc" },
  49:     { "acbb" }, { "acbw" }, { "acbl" }, { "acbf" }, { "acbd" },
  50:     { "acbg" }, { "acbh" }, { "aoblss" }, { "aobleq" },
  51:     { "sobgeq" }, { "sobgtr" }, { "caseb" }, { "casew" }, { "casel" },
  52:     { "bsbb" }, { "bsbw" }, { "jsb" }, { "rsb" },
  53:     { "callg" }, { "calls" }, { "ret" },
  54:     { "movc3" }, { "movc5" }, { "movtc" }, { "movtuc" },
  55:     { "cmpc3" }, { "cmpc5" }, { "scanc" }, { "spanc" },
  56:     { "locc" }, { "skpc" }, { "matchc" }, { "crc" },
  57:     { "movp" }, { "cmpp3" }, { "cmpp4" }, { "addp4" }, { "addp6" },
  58:     { "subp4" }, { "subp6" }, { "mulp" }, { "divp" }, { "cvtlp" },
  59:     { "cvtpl" }, { "cvtpt" }, { "cvttp" }, { "cvtps" }, { "cvtsp" },
  60:     { "ashp" }, { "editpc" },
  61:     { "escd" }, { "esce" }, { "escf" },
  62:     { "" }
  63: };
  64: 
  65: /*
  66:  * Check to see if a line is a candidate for replacement.
  67:  * Return pointer to name to be looked up in pattern table.
  68:  */
  69: char *
  70: doreplaceon(cp)
  71:     char *cp;
  72: {
  73: 
  74:     if (bcmp(cp, "calls\t", 6) != 0)
  75:         return (0);
  76:     if ((cp = index(cp + 6, ',')) == 0)
  77:         return (0);
  78:     return (++cp);
  79: }
  80: 
  81: /*
  82:  * Find out how many arguments the function is being called with.
  83:  * A return value of -1 indicates that the count can't be determined.
  84:  */
  85: int
  86: countargs(cp)
  87:     char *cp;
  88: {
  89: 
  90:     if ((cp = index(cp, '$')) == 0)
  91:         return (-1);
  92:     if (!isdigit(*++cp))
  93:         return (-1);
  94:     return (atoi(cp));
  95: }
  96: 
  97: /*
  98:  * Find the next argument to the function being expanded.
  99:  */
 100: nextarg(argc, argv)
 101:     int argc;
 102:     char *argv[];
 103: {
 104:     register char *lastarg = argv[2];
 105: 
 106:     if (argc == 3 &&
 107:         bcmp(argv[0], "mov", 3) == 0 &&
 108:         bcmp(argv[1], "(sp)+", 6) == 0 &&
 109:         lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0')
 110:         return (lastarg[1] - '0');
 111:     return (-1);
 112: }
 113: 
 114: /*
 115:  * Determine whether the current line pushes an argument.
 116:  */
 117: ispusharg(argc, argv)
 118:     int argc;
 119:     char *argv[];
 120: {
 121: 
 122:     if (argc < 2)
 123:         return (0);
 124:     if (argc == 2 && bcmp(argv[0], "push", 4) == 0)
 125:         return (1);
 126:     if (bcmp(argv[argc - 1], "-(sp)", 6) == 0)
 127:         return (1);
 128:     return (0);
 129: }
 130: 
 131: /*
 132:  * Determine which (if any) registers are modified
 133:  * Return register number that is modified, -1 if none are modified.
 134:  */
 135: modifies(argc, argv)
 136:     int argc;
 137:     char *argv[];
 138: {
 139:     /*
 140: 	 * For the VAX all we care about are r0 to r5
 141: 	 */
 142:     register char *lastarg = argv[argc - 1];
 143: 
 144:     if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0')
 145:         return (lastarg[1] - '0');
 146:     return (-1);
 147: }
 148: 
 149: /*
 150:  * Rewrite the instruction in (argc, argv) to store its
 151:  * contents into arg instead of onto the stack. The new
 152:  * instruction is placed in the buffer that is provided.
 153:  */
 154: rewrite(instbuf, argc, argv, target)
 155:     char *instbuf;
 156:     int argc;
 157:     char *argv[];
 158:     int target;
 159: {
 160: 
 161:     switch (argc) {
 162:     case 0:
 163:         instbuf[0] = '\0';
 164:         fprintf(stderr, "blank line to rewrite?\n");
 165:         return;
 166:     case 1:
 167:         sprintf(instbuf, "\t%s\n", argv[0]);
 168:         fprintf(stderr, "rewrite?-> %s", instbuf);
 169:         return;
 170:     case 2:
 171:         if (bcmp(argv[0], "push", 4) == 0) {
 172:             sprintf(instbuf, "\tmov%s\t%s,r%d\n",
 173:                 &argv[0][4], argv[1], target);
 174:             return;
 175:         }
 176:         sprintf(instbuf, "\t%s\tr%d\n", argv[0], target);
 177:         return;
 178:     case 3:
 179:         sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target);
 180:         return;
 181:     case 4:
 182:         sprintf(instbuf, "\t%s\t%s,%s,r%d\n",
 183:             argv[0], argv[1], argv[2], target);
 184:         return;
 185:     case 5:
 186:         sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n",
 187:             argv[0], argv[1], argv[2], argv[3], target);
 188:         return;
 189:     default:
 190:         sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]);
 191:         argc -= 2, argv += 2;
 192:         while (argc-- > 0) {
 193:             (void) strcat(instbuf, ",");
 194:             (void) strcat(instbuf, *argv++);
 195:         }
 196:         (void) strcat(instbuf, "\n");
 197:         fprintf(stderr, "rewrite?-> %s", instbuf);
 198:         return;
 199:     }
 200: }
 201: 
 202: /*
 203:  * Do any necessary post expansion cleanup.
 204:  */
 205: /*ARGSUSED*/
 206: cleanup(numargs)
 207:     int numargs;
 208: {
 209: 
 210:     return;
 211: }
 212: #endif vax
 213: 
 214: #ifdef mc68000
 215: /*
 216:  * Instruction stop table.
 217:  * All instructions that implicitly modify any of the temporary
 218:  * registers, change control flow, or implicitly loop must be
 219:  * listed in this table. It is used to find the end of a basic
 220:  * block when scanning backwards through the instruction stream
 221:  * trying to merge the inline expansion.
 222:  */
 223: struct inststoptbl inststoptable[] = {
 224:     { "" }
 225: };
 226: 
 227: /*
 228:  * Check to see if a line is a candidate for replacement.
 229:  * Return pointer to name to be looked up in pattern table.
 230:  */
 231: char *
 232: doreplaceon(cp)
 233:     char *cp;
 234: {
 235: 
 236:     if (bcmp(cp, "jbsr\t", 5) == 0)
 237:         return (cp + 5);
 238:     return (0);
 239: }
 240: 
 241: /*
 242:  * Find out how many arguments the function is being called with.
 243:  * A return value of -1 indicates that the count can't be determined.
 244:  */
 245: /* ARGSUSED */
 246: int
 247: countargs(cp)
 248:     char *cp;
 249: {
 250: 
 251:     /*
 252: 	 * TODO
 253: 	 * Figure out what the count should be.
 254: 	 * Probably have to read the next instruction here
 255: 	 * instead of in cleanup() below.
 256: 	 */
 257:     return (-1);
 258: }
 259: 
 260: /*
 261:  * Find the next argument to the function being expanded.
 262:  */
 263: nextarg(argc, argv)
 264:     int argc;
 265:     char *argv[];
 266: {
 267:     register char *lastarg = argv[2];
 268: 
 269:     if (argc == 3 &&
 270:         bcmp(argv[0], "movl", 5) == 0 &&
 271:         bcmp(argv[1], "sp@+", 5) == 0 &&
 272:         (lastarg[1] == '0' || lastarg[1] == '1') &&
 273:         lastarg[2] == '\0') {
 274:         if (lastarg[0] == 'd')
 275:             return (lastarg[1] - '0');
 276:         return (lastarg[1] - '0' + 8);
 277:     }
 278:     return (-1);
 279: }
 280: 
 281: /*
 282:  * Determine whether the current line pushes an argument.
 283:  */
 284: ispusharg(argc, argv)
 285:     int argc;
 286:     char *argv[];
 287: {
 288: 
 289:     if (argc < 2)
 290:         return (0);
 291:     if (argc == 2 && bcmp(argv[0], "pea", 4) == 0)
 292:         return (1);
 293:     if (bcmp(argv[argc - 1], "sp@-", 5) == 0)
 294:         return (1);
 295:     return (0);
 296: }
 297: 
 298: /*
 299:  * Determine which (if any) registers are modified
 300:  * Return register number that is modified, -1 if none are modified.
 301:  */
 302: modifies(argc, argv)
 303:     int argc;
 304:     char *argv[];
 305: {
 306:     /*
 307: 	 * For the MC68000 all we care about are d0, d1, a0, and a1.
 308: 	 */
 309:     register char *lastarg = argv[argc - 1];
 310: 
 311:     if (lastarg[0] == 'd' && isdigit(lastarg[1]) && lastarg[2] == '\0')
 312:         return (lastarg[1] - '0');
 313:     if (lastarg[0] == 'a' && isdigit(lastarg[1]) && lastarg[2] == '\0')
 314:         return (lastarg[1] - '0' + 8);
 315:     return (-1);
 316: }
 317: 
 318: /*
 319:  * Rewrite the instruction in (argc, argv) to store its
 320:  * contents into arg instead of onto the stack. The new
 321:  * instruction is placed in the buffer that is provided.
 322:  */
 323: rewrite(instbuf, argc, argv, target)
 324:     char *instbuf;
 325:     int argc;
 326:     char *argv[];
 327:     int target;
 328: {
 329:     int regno;
 330:     char regtype;
 331: 
 332:     if (target < 8) {
 333:         regtype = 'd';
 334:         regno = target;
 335:     } else {
 336:         regtype = 'a';
 337:         regno = target - 8;
 338:     }
 339:     switch (argc) {
 340:     case 0:
 341:         instbuf[0] = '\0';
 342:         fprintf(stderr, "blank line to rewrite?\n");
 343:         return;
 344:     case 1:
 345:         sprintf(instbuf, "\t%s\n", argv[0]);
 346:         fprintf(stderr, "rewrite?-> %s", instbuf);
 347:         return;
 348:     case 2:
 349:         if (bcmp(argv[0], "pea", 4) == 0) {
 350:             if (regtype == 'a') {
 351:                 sprintf(instbuf, "\tlea\t%s,%c%d\n",
 352:                     argv[1], regtype, regno);
 353:                 return;
 354:             }
 355:             if (argv[1][0] == '_' || isdigit(argv[1][0])) {
 356:                 sprintf(instbuf, "\tmovl\t#%s,%c%d\n",
 357:                     argv[1], regtype, regno);
 358:                 return;
 359:             }
 360:             sprintf(instbuf,
 361:                 "\texg\ta0,d%d\n\tlea\t%s,a0\n\texg\ta0,d%d\n",
 362:                 regno, argv[1], regno);
 363:             return;
 364:         }
 365:         sprintf(instbuf, "\t%s\t%c%d\n", argv[0], regtype, regno);
 366:         return;
 367:     case 3:
 368:         sprintf(instbuf, "\t%s\t%s,%c%d\n",
 369:             argv[0], argv[1], regtype, regno);
 370:         return;
 371:     default:
 372:         sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]);
 373:         argc -= 2, argv += 2;
 374:         while (argc-- > 0) {
 375:             (void) strcat(instbuf, ",");
 376:             (void) strcat(instbuf, *argv++);
 377:         }
 378:         (void) strcat(instbuf, "\n");
 379:         fprintf(stderr, "rewrite?-> %s", instbuf);
 380:         return;
 381:     }
 382: }
 383: 
 384: /*
 385:  * Do any necessary post expansion cleanup.
 386:  */
 387: cleanup(numargs)
 388:     int numargs;
 389: {
 390:     extern int lineno;
 391: 
 392:     if (numargs == 0)
 393:         return;
 394:     /*
 395: 	 * delete instruction to pop arguments.
 396: 	 * TODO:
 397: 	 *	CHECK FOR LABEL
 398: 	 *	CHECK THAT INSTRUCTION IS A POP
 399: 	 */
 400:     fgets(line[bufhead], MAXLINELEN, stdin);
 401:     lineno++;
 402: }
 403: #endif mc68000

Defined functions

cleanup defined in line 387; never used
countargs defined in line 246; used 1 times
ispusharg defined in line 284; used 1 times
modifies defined in line 302; used 1 times
nextarg defined in line 263; used 1 times
rewrite defined in line 323; used 1 times

Defined variables

inststoptable defined in line 223; used 1 times
sccsid defined in line 8; never used
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1308
Valid CSS Valid XHTML 1.0 Strict