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