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