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) 02/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 } 204