|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1984 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 1.3 (Berkeley) 2/24/86"; ! 9: #endif ! 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: /* ! 25: * Instruction stop table. ! 26: * All instructions that implicitly modify any of the temporary ! 27: * registers, change control flow, or implicitly loop must be ! 28: * listed in this table. It is used to find the end of a basic ! 29: * block when scanning backwards through the instruction stream ! 30: * trying to merge the inline expansion. ! 31: */ ! 32: struct inststoptbl inststoptable[] = { ! 33: /* control */ ! 34: { "bbssi" }, { "bcc" }, { "bcs" }, { "beql" }, { "beqlu" }, ! 35: { "bgeq" }, { "bgequ" }, { "bgtr" }, { "bgtru" }, { "bleq" }, ! 36: { "blequ" }, { "blss" }, { "blssu" }, { "bneq" }, { "bnequ" }, ! 37: { "brb" }, { "brw" }, { "bvc" }, { "bvs" }, { "jmp" }, ! 38: /* jump versions of control */ ! 39: { "jbc" }, { "jbs" }, { "jeql" }, { "jeqlu" }, ! 40: { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" }, { "jleq" }, ! 41: { "jlequ" }, { "jlss" }, { "jlssu" }, { "jneq" }, { "jnequ" }, ! 42: { "jcc" }, { "jcs" }, { "jvc" }, { "jvs" }, { "jbr" }, ! 43: /* multiple registers */ ! 44: { "loadr" }, ! 45: /* bit field */ ! 46: { "bbc" }, { "bbs" }, ! 47: /* character string and block move */ ! 48: { "cmps2" }, { "cmps3" }, { "movblk" }, { "movs2" }, { "movs3" }, ! 49: /* procedure call */ ! 50: { "callf" }, { "calls" }, { "ret" }, ! 51: /* loop control */ ! 52: { "aobleq" }, { "aoblss" }, { "casel" }, ! 53: /* privileged and miscellaneous */ ! 54: { "bpt" }, { "halt" }, { "kcall" }, { "ldpctx" }, { "rei" }, ! 55: { "svpctx" }, ! 56: { "" } ! 57: }; ! 58: ! 59: /* ! 60: * Check to see if a line is a candidate for replacement. ! 61: * Return pointer to name to be looked up in pattern table. ! 62: */ ! 63: char * ! 64: doreplaceon(cp) ! 65: char *cp; ! 66: { ! 67: ! 68: if (bcmp(cp, "callf\t", 6)) ! 69: return (0); ! 70: if ((cp = index(cp + 6, ',')) == 0) ! 71: return (0); ! 72: return (++cp); ! 73: } ! 74: ! 75: /* ! 76: * Find out how many arguments the function is being called with. ! 77: * A return value of -1 indicates that the count can't be determined. ! 78: */ ! 79: countargs(cp) ! 80: char *cp; ! 81: { ! 82: int i; ! 83: ! 84: if ((cp = index(cp, '$')) == 0) ! 85: return (-1); ! 86: if (!isdigit(*++cp) || (i = atoi(cp)) == -1) ! 87: return (-1); ! 88: return (i/4 - 1); ! 89: } ! 90: ! 91: /* ! 92: * Find the next argument to the function being expanded. ! 93: */ ! 94: nextarg(argc, argv) ! 95: int argc; ! 96: char *argv[]; ! 97: { ! 98: register char *lastarg = argv[2]; ! 99: ! 100: if (argc == 3 && ! 101: bcmp(argv[0], "mov", 3) == 0 && ! 102: bcmp(argv[1], "(sp)+", 6) == 0 && ! 103: lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 104: return (lastarg[1] - '0'); ! 105: return (-1); ! 106: } ! 107: ! 108: /* ! 109: * Determine whether the current line pushes an argument. ! 110: */ ! 111: ispusharg(argc, argv) ! 112: int argc; ! 113: char *argv[]; ! 114: { ! 115: ! 116: if (argc < 2) ! 117: return (0); ! 118: if (argc == 2 && bcmp(argv[0], "push", 4) == 0) ! 119: return (1); ! 120: if (bcmp(argv[argc - 1], "-(sp)", 6) == 0) ! 121: return (1); ! 122: return (0); ! 123: } ! 124: ! 125: /* ! 126: * Determine which (if any) registers are modified ! 127: * Return register number that is modified, -1 if none are modified. ! 128: */ ! 129: modifies(argc, argv) ! 130: int argc; ! 131: char *argv[]; ! 132: { ! 133: register char *lastarg = argv[argc - 1]; ! 134: ! 135: /* ! 136: * For the tahoe all we care about are r0 to r5 ! 137: */ ! 138: if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 139: return (lastarg[1] - '0'); ! 140: return (-1); ! 141: } ! 142: ! 143: /* ! 144: * Rewrite the instruction in (argc, argv) to store its ! 145: * contents into arg instead of onto the stack. The new ! 146: * instruction is placed in the buffer that is provided. ! 147: */ ! 148: rewrite(instbuf, argc, argv, target) ! 149: char *instbuf; ! 150: int argc; ! 151: char *argv[]; ! 152: int target; ! 153: { ! 154: ! 155: switch (argc) { ! 156: case 0: ! 157: instbuf[0] = '\0'; ! 158: fprintf(stderr, "blank line to rewrite?\n"); ! 159: return; ! 160: case 1: ! 161: sprintf(instbuf, "\t%s\n", argv[0]); ! 162: fprintf(stderr, "rewrite?-> %s", instbuf); ! 163: return; ! 164: case 2: ! 165: if (bcmp(argv[0], "push", 4) == 0) { ! 166: sprintf(instbuf, "\tmov%s\t%s,r%d\n", ! 167: &argv[0][4], argv[1], target); ! 168: return; ! 169: } ! 170: sprintf(instbuf, "\t%s\tr%d\n", argv[0], target); ! 171: return; ! 172: case 3: ! 173: sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target); ! 174: return; ! 175: case 4: ! 176: sprintf(instbuf, "\t%s\t%s,%s,r%d\n", ! 177: argv[0], argv[1], argv[2], target); ! 178: return; ! 179: case 5: ! 180: sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n", ! 181: argv[0], argv[1], argv[2], argv[3], target); ! 182: return; ! 183: default: ! 184: sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); ! 185: argc -= 2, argv += 2; ! 186: while (argc-- > 0) { ! 187: strcat(instbuf, ","); ! 188: strcat(instbuf, *argv++); ! 189: } ! 190: strcat(instbuf, "\n"); ! 191: fprintf(stderr, "rewrite?-> %s", instbuf); ! 192: return; ! 193: } ! 194: } ! 195: ! 196: /* ! 197: * Do any necessary post expansion cleanup. ! 198: */ ! 199: cleanup(numargs) ! 200: int numargs; ! 201: { ! 202: ! 203: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.