116960Smckusick /* Copyright (c) 1984 Regents of the University of California */ 216960Smckusick 316960Smckusick #ifndef lint 4*17203Smckusick static char sccsid[] = "@(#)machdep.c 1.4 (Berkeley) 09/20/84"; 516960Smckusick #endif not lint 616960Smckusick 716960Smckusick #include <stdio.h> 816960Smckusick #include <ctype.h> 916979Smckusick #include "inline.h" 1016960Smckusick 1116960Smckusick /* 1216979Smckusick * The routines and tables in this file must be rewritten 1316979Smckusick * for each new machine that this program is ported to. 1416960Smckusick */ 1516960Smckusick 16*17203Smckusick #ifdef vax 1716960Smckusick /* 1816979Smckusick * Instruction stop table. 1916979Smckusick * All instructions that implicitly modify any of the temporary 2016979Smckusick * registers, change control flow, or implicitly loop must be 2116979Smckusick * listed in this table. It is used to find the end of a basic 2216979Smckusick * block when scanning backwards through the instruction stream 2316979Smckusick * trying to merge the inline expansion. 2416979Smckusick */ 2516979Smckusick struct inststoptbl inststoptable[] = { 2616979Smckusick { "jbc" }, { "jlbc" }, { "jbs" }, { "jlbs" }, { "jbcc" }, 2716979Smckusick { "jbsc" }, { "jbcs" }, { "jbss" }, { "jbr" }, { "jcc" }, 2816979Smckusick { "jcs" }, { "jvc" }, { "jvs" }, { "jlss" }, { "jlssu" }, 2916979Smckusick { "jleq" }, { "jlequ" }, { "jeql" }, { "jeqlu" }, { "jneq" }, 3016979Smckusick { "jnequ" }, { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" }, 3116979Smckusick { "chmk" }, { "chme" }, { "chms" }, { "chmu" }, { "rei" }, 3216979Smckusick { "ldpctx" }, { "svpctx" }, { "xfc" }, { "bpt" }, 3316979Smckusick { "bugw" }, { "bugl" }, { "halt" }, { "pushr" }, { "popr" }, 3416979Smckusick { "polyf" }, { "polyd" }, { "polyg" }, { "polyh" }, 3516979Smckusick { "bneq" }, { "bnequ" }, { "beql" }, { "beqlu" }, { "bgtr" }, 3616979Smckusick { "bleq" }, { "bgeq" }, { "blss" }, { "bgtru" }, { "blequ" }, 3716979Smckusick { "bvc" }, { "bvs" }, { "bgequ" }, { "bcc" }, { "blssu" }, 3816979Smckusick { "bcs" }, { "brb" }, { "brw" }, { "jmp" }, 3916979Smckusick { "bbs" }, { "bbc" }, { "bbss" }, { "bbcs" }, { "bbsc" }, 4016979Smckusick { "bbcc" }, { "bbssi" }, { "bbcci" }, { "blbs" }, { "blbc" }, 4116979Smckusick { "acbb" }, { "acbw" }, { "acbl" }, { "acbf" }, { "acbd" }, 4216979Smckusick { "acbg" }, { "acbh" }, { "aoblss" }, { "aobleq" }, 4316979Smckusick { "sobgeq" }, { "sobgtr" }, { "caseb" }, { "casew" }, { "casel" }, 4416979Smckusick { "bsbb" }, { "bsbw" }, { "jsb" }, { "rsb" }, 4516979Smckusick { "callg" }, { "calls" }, { "ret" }, 4616979Smckusick { "movc3" }, { "movc5" }, { "movtc" }, { "movtuc" }, 4716979Smckusick { "cmpc3" }, { "cmpc5" }, { "scanc" }, { "spanc" }, 4816979Smckusick { "locc" }, { "skpc" }, { "matchc" }, { "crc" }, 4916979Smckusick { "movp" }, { "cmpp3" }, { "cmpp4" }, { "addp4" }, { "addp6" }, 5016979Smckusick { "subp4" }, { "subp6" }, { "mulp" }, { "divp" }, { "cvtlp" }, 5116979Smckusick { "cvtpl" }, { "cvtpt" }, { "cvttp" }, { "cvtps" }, { "cvtsp" }, 5216979Smckusick { "ashp" }, { "editpc" }, 5316979Smckusick { "escd" }, { "esce" }, { "escf" }, 5416979Smckusick { "" } 5516979Smckusick }; 5616979Smckusick 5716979Smckusick /* 5816960Smckusick * Check to see if a line is a candidate for replacement. 5916960Smckusick * Return pointer to name to be looked up in pattern table. 6016960Smckusick */ 6116960Smckusick char * 6216960Smckusick doreplaceon(cp) 6316960Smckusick char *cp; 6416960Smckusick { 6516960Smckusick 6616960Smckusick if (bcmp(cp, "calls\t$", 7) == 0) 6716960Smckusick return (cp + 7); 6816960Smckusick return (0); 6916960Smckusick } 7016960Smckusick 7116960Smckusick /* 7216960Smckusick * Find the next argument to the function being expanded. 7316960Smckusick */ 7416960Smckusick nextarg(argc, argv) 7516960Smckusick int argc; 7616960Smckusick char *argv[]; 7716960Smckusick { 7816960Smckusick register char *lastarg = argv[2]; 7916960Smckusick 8016960Smckusick if (argc == 3 && 8116960Smckusick bcmp(argv[0], "mov", 3) == 0 && 8216960Smckusick bcmp(argv[1], "(sp)+", 6) == 0 && 8316960Smckusick lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') 8416960Smckusick return (lastarg[1] - '0'); 8516960Smckusick return (-1); 8616960Smckusick } 8716960Smckusick 8816960Smckusick /* 8916960Smckusick * Determine whether the current line pushes an argument. 9016960Smckusick */ 9116960Smckusick ispusharg(argc, argv) 9216960Smckusick int argc; 9316960Smckusick char *argv[]; 9416960Smckusick { 9516960Smckusick 9616960Smckusick if (argc < 2) 9716960Smckusick return (0); 9816960Smckusick if (argc == 2 && bcmp(argv[0], "push", 4) == 0) 9916960Smckusick return (1); 10016960Smckusick if (bcmp(argv[argc - 1], "-(sp)", 6) == 0) 10116960Smckusick return (1); 10216960Smckusick return (0); 10316960Smckusick } 10416960Smckusick 10516960Smckusick /* 10616960Smckusick * Determine which (if any) registers are modified 10716960Smckusick * Return register number that is modified, -1 if none are modified. 10816960Smckusick */ 10916960Smckusick modifies(argc, argv) 11016960Smckusick int argc; 11116960Smckusick char *argv[]; 11216960Smckusick { 11316960Smckusick /* 11416960Smckusick * For the VAX all we care about are r0 to r5 11516960Smckusick */ 11616960Smckusick register char *lastarg = argv[argc - 1]; 11716960Smckusick 11816960Smckusick if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') 11916960Smckusick return (lastarg[1] - '0'); 12016960Smckusick return (-1); 12116960Smckusick } 12216960Smckusick 12316960Smckusick /* 12416960Smckusick * Rewrite the instruction in (argc, argv) to store its 12516960Smckusick * contents into arg instead of onto the stack. The new 12616960Smckusick * instruction is placed in the buffer that is provided. 12716960Smckusick */ 12816960Smckusick rewrite(instbuf, argc, argv, target) 12916960Smckusick char *instbuf; 13016960Smckusick int argc; 13116960Smckusick char *argv[]; 13216960Smckusick int target; 13316960Smckusick { 13416960Smckusick 13516960Smckusick switch (argc) { 13616960Smckusick case 0: 13716960Smckusick instbuf[0] = '\0'; 13816960Smckusick fprintf("blank line to rewrite?\n"); 13916960Smckusick return; 14016960Smckusick case 1: 14116960Smckusick sprintf(instbuf, "\t%s\n", argv[0]); 14216960Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 14316960Smckusick return; 14416960Smckusick case 2: 14516960Smckusick if (bcmp(argv[0], "push", 4) == 0) { 14616960Smckusick sprintf(instbuf, "\tmov%s\t%s,r%d\n", 14716960Smckusick &argv[0][4], argv[1], target); 14816960Smckusick return; 14916960Smckusick } 15016960Smckusick sprintf(instbuf, "\t%s\tr%d\n", argv[0], target); 15116960Smckusick return; 15216960Smckusick case 3: 15316960Smckusick sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target); 15416960Smckusick return; 15516960Smckusick case 4: 15616960Smckusick sprintf(instbuf, "\t%s\t%s,%s,r%d\n", 15716960Smckusick argv[0], argv[1], argv[2], target); 15816960Smckusick return; 15916971Smckusick case 5: 16016971Smckusick sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n", 16116971Smckusick argv[0], argv[1], argv[2], argv[3], target); 16216971Smckusick return; 16316960Smckusick default: 16416960Smckusick sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); 16516960Smckusick argc -= 2, argv += 2; 16616960Smckusick while (argc-- > 0) { 16716960Smckusick strcat(instbuf, ","); 16816960Smckusick strcat(instbuf, *argv++); 16916960Smckusick } 17016960Smckusick strcat(instbuf, "\n"); 17116960Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 17216960Smckusick return; 17316960Smckusick } 17416960Smckusick } 175*17203Smckusick 176*17203Smckusick /* 177*17203Smckusick * Do any necessary post expansion cleanup. 178*17203Smckusick */ 179*17203Smckusick cleanup(numargs) 180*17203Smckusick int numargs; 181*17203Smckusick { 182*17203Smckusick 183*17203Smckusick return; 184*17203Smckusick } 185*17203Smckusick #endif vax 186*17203Smckusick 187*17203Smckusick #ifdef mc68000 188*17203Smckusick /* 189*17203Smckusick * Instruction stop table. 190*17203Smckusick * All instructions that implicitly modify any of the temporary 191*17203Smckusick * registers, change control flow, or implicitly loop must be 192*17203Smckusick * listed in this table. It is used to find the end of a basic 193*17203Smckusick * block when scanning backwards through the instruction stream 194*17203Smckusick * trying to merge the inline expansion. 195*17203Smckusick */ 196*17203Smckusick struct inststoptbl inststoptable[] = { 197*17203Smckusick { "" } 198*17203Smckusick }; 199*17203Smckusick 200*17203Smckusick /* 201*17203Smckusick * Check to see if a line is a candidate for replacement. 202*17203Smckusick * Return pointer to name to be looked up in pattern table. 203*17203Smckusick */ 204*17203Smckusick char * 205*17203Smckusick doreplaceon(cp) 206*17203Smckusick char *cp; 207*17203Smckusick { 208*17203Smckusick 209*17203Smckusick if (bcmp(cp, "jbsr\t", 5) == 0) 210*17203Smckusick return (cp + 5); 211*17203Smckusick return (0); 212*17203Smckusick } 213*17203Smckusick 214*17203Smckusick /* 215*17203Smckusick * Find the next argument to the function being expanded. 216*17203Smckusick */ 217*17203Smckusick nextarg(argc, argv) 218*17203Smckusick int argc; 219*17203Smckusick char *argv[]; 220*17203Smckusick { 221*17203Smckusick register char *lastarg = argv[2]; 222*17203Smckusick 223*17203Smckusick if (argc == 3 && 224*17203Smckusick bcmp(argv[0], "movl", 5) == 0 && 225*17203Smckusick bcmp(argv[1], "sp@+", 5) == 0 && 226*17203Smckusick (lastarg[1] == '0' || lastarg[1] == '1') && 227*17203Smckusick lastarg[2] == '\0') { 228*17203Smckusick if (lastarg[0] == 'd') 229*17203Smckusick return (lastarg[1] - '0'); 230*17203Smckusick return (lastarg[1] - '0' + 8); 231*17203Smckusick } 232*17203Smckusick return (-1); 233*17203Smckusick } 234*17203Smckusick 235*17203Smckusick /* 236*17203Smckusick * Determine whether the current line pushes an argument. 237*17203Smckusick */ 238*17203Smckusick ispusharg(argc, argv) 239*17203Smckusick int argc; 240*17203Smckusick char *argv[]; 241*17203Smckusick { 242*17203Smckusick 243*17203Smckusick if (argc < 2) 244*17203Smckusick return (0); 245*17203Smckusick if (argc == 2 && bcmp(argv[0], "pea", 4) == 0) 246*17203Smckusick return (1); 247*17203Smckusick if (bcmp(argv[argc - 1], "sp@-", 5) == 0) 248*17203Smckusick return (1); 249*17203Smckusick return (0); 250*17203Smckusick } 251*17203Smckusick 252*17203Smckusick /* 253*17203Smckusick * Determine which (if any) registers are modified 254*17203Smckusick * Return register number that is modified, -1 if none are modified. 255*17203Smckusick */ 256*17203Smckusick modifies(argc, argv) 257*17203Smckusick int argc; 258*17203Smckusick char *argv[]; 259*17203Smckusick { 260*17203Smckusick /* 261*17203Smckusick * For the MC68000 all we care about are d0, d1, a0, and a1. 262*17203Smckusick */ 263*17203Smckusick register char *lastarg = argv[argc - 1]; 264*17203Smckusick 265*17203Smckusick if (lastarg[0] == 'd' && isdigit(lastarg[1]) && lastarg[2] == '\0') 266*17203Smckusick return (lastarg[1] - '0'); 267*17203Smckusick if (lastarg[0] == 'a' && isdigit(lastarg[1]) && lastarg[2] == '\0') 268*17203Smckusick return (lastarg[1] - '0' + 8); 269*17203Smckusick return (-1); 270*17203Smckusick } 271*17203Smckusick 272*17203Smckusick /* 273*17203Smckusick * Rewrite the instruction in (argc, argv) to store its 274*17203Smckusick * contents into arg instead of onto the stack. The new 275*17203Smckusick * instruction is placed in the buffer that is provided. 276*17203Smckusick */ 277*17203Smckusick rewrite(instbuf, argc, argv, target) 278*17203Smckusick char *instbuf; 279*17203Smckusick int argc; 280*17203Smckusick char *argv[]; 281*17203Smckusick int target; 282*17203Smckusick { 283*17203Smckusick int regno; 284*17203Smckusick char regtype; 285*17203Smckusick 286*17203Smckusick if (target < 8) { 287*17203Smckusick regtype = 'd'; 288*17203Smckusick regno = target; 289*17203Smckusick } else { 290*17203Smckusick regtype = 'a'; 291*17203Smckusick regno = target - 8; 292*17203Smckusick } 293*17203Smckusick switch (argc) { 294*17203Smckusick case 0: 295*17203Smckusick instbuf[0] = '\0'; 296*17203Smckusick fprintf("blank line to rewrite?\n"); 297*17203Smckusick return; 298*17203Smckusick case 1: 299*17203Smckusick sprintf(instbuf, "\t%s\n", argv[0]); 300*17203Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 301*17203Smckusick return; 302*17203Smckusick case 2: 303*17203Smckusick if (bcmp(argv[0], "pea", 4) == 0) { 304*17203Smckusick if (regtype == 'a') { 305*17203Smckusick sprintf(instbuf, "\tlea\t%s,%c%d\n", 306*17203Smckusick argv[1], regtype, regno); 307*17203Smckusick return; 308*17203Smckusick } 309*17203Smckusick if (argv[1][0] == '_' || isdigit(argv[1][0])) { 310*17203Smckusick sprintf(instbuf, "\tmovl\t#%s,%c%d\n", 311*17203Smckusick argv[1], regtype, regno); 312*17203Smckusick return; 313*17203Smckusick } 314*17203Smckusick sprintf(instbuf, 315*17203Smckusick "\texg\ta0,d%d\n\tlea\t%s,a0\n\texg\ta0,d%d\n", 316*17203Smckusick regno, argv[1], regno); 317*17203Smckusick return; 318*17203Smckusick } 319*17203Smckusick sprintf(instbuf, "\t%s\t%c%d\n", argv[0], regtype, regno); 320*17203Smckusick return; 321*17203Smckusick case 3: 322*17203Smckusick sprintf(instbuf, "\t%s\t%s,%c%d\n", 323*17203Smckusick argv[0], argv[1], regtype, regno); 324*17203Smckusick return; 325*17203Smckusick default: 326*17203Smckusick sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); 327*17203Smckusick argc -= 2, argv += 2; 328*17203Smckusick while (argc-- > 0) { 329*17203Smckusick strcat(instbuf, ","); 330*17203Smckusick strcat(instbuf, *argv++); 331*17203Smckusick } 332*17203Smckusick strcat(instbuf, "\n"); 333*17203Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 334*17203Smckusick return; 335*17203Smckusick } 336*17203Smckusick } 337*17203Smckusick 338*17203Smckusick /* 339*17203Smckusick * Do any necessary post expansion cleanup. 340*17203Smckusick */ 341*17203Smckusick cleanup(numargs) 342*17203Smckusick int numargs; 343*17203Smckusick { 344*17203Smckusick 345*17203Smckusick if (numargs == 0) 346*17203Smckusick return; 347*17203Smckusick /* 348*17203Smckusick * delete instruction to pop arguments. 349*17203Smckusick * TODO: 350*17203Smckusick * CHECK FOR LABEL 351*17203Smckusick * CHECK THAT INSTRUCTION IS A POP 352*17203Smckusick */ 353*17203Smckusick fgets(line[bufhead], MAXLINELEN, stdin); 354*17203Smckusick } 355*17203Smckusick #endif mc68000 356