1*23346Smckusick /* 2*23346Smckusick * Copyright (c) 1984 Regents of the University of California. 3*23346Smckusick * All rights reserved. The Berkeley software License Agreement 4*23346Smckusick * specifies the terms and conditions for redistribution. 5*23346Smckusick */ 616960Smckusick 716960Smckusick #ifndef lint 8*23346Smckusick static char sccsid[] = "@(#)machdep.c 1.6 (Berkeley) 06/08/85"; 916960Smckusick #endif not lint 1016960Smckusick 1116960Smckusick #include <stdio.h> 1216960Smckusick #include <ctype.h> 1316979Smckusick #include "inline.h" 1416960Smckusick 1516960Smckusick /* 1616979Smckusick * The routines and tables in this file must be rewritten 1716979Smckusick * for each new machine that this program is ported to. 1816960Smckusick */ 1916960Smckusick 2017203Smckusick #ifdef vax 2116960Smckusick /* 2216979Smckusick * Instruction stop table. 2316979Smckusick * All instructions that implicitly modify any of the temporary 2416979Smckusick * registers, change control flow, or implicitly loop must be 2516979Smckusick * listed in this table. It is used to find the end of a basic 2616979Smckusick * block when scanning backwards through the instruction stream 2716979Smckusick * trying to merge the inline expansion. 2816979Smckusick */ 2916979Smckusick struct inststoptbl inststoptable[] = { 3016979Smckusick { "jbc" }, { "jlbc" }, { "jbs" }, { "jlbs" }, { "jbcc" }, 3116979Smckusick { "jbsc" }, { "jbcs" }, { "jbss" }, { "jbr" }, { "jcc" }, 3216979Smckusick { "jcs" }, { "jvc" }, { "jvs" }, { "jlss" }, { "jlssu" }, 3316979Smckusick { "jleq" }, { "jlequ" }, { "jeql" }, { "jeqlu" }, { "jneq" }, 3416979Smckusick { "jnequ" }, { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" }, 3516979Smckusick { "chmk" }, { "chme" }, { "chms" }, { "chmu" }, { "rei" }, 3616979Smckusick { "ldpctx" }, { "svpctx" }, { "xfc" }, { "bpt" }, 3716979Smckusick { "bugw" }, { "bugl" }, { "halt" }, { "pushr" }, { "popr" }, 3816979Smckusick { "polyf" }, { "polyd" }, { "polyg" }, { "polyh" }, 3916979Smckusick { "bneq" }, { "bnequ" }, { "beql" }, { "beqlu" }, { "bgtr" }, 4016979Smckusick { "bleq" }, { "bgeq" }, { "blss" }, { "bgtru" }, { "blequ" }, 4116979Smckusick { "bvc" }, { "bvs" }, { "bgequ" }, { "bcc" }, { "blssu" }, 4216979Smckusick { "bcs" }, { "brb" }, { "brw" }, { "jmp" }, 4316979Smckusick { "bbs" }, { "bbc" }, { "bbss" }, { "bbcs" }, { "bbsc" }, 4416979Smckusick { "bbcc" }, { "bbssi" }, { "bbcci" }, { "blbs" }, { "blbc" }, 4516979Smckusick { "acbb" }, { "acbw" }, { "acbl" }, { "acbf" }, { "acbd" }, 4616979Smckusick { "acbg" }, { "acbh" }, { "aoblss" }, { "aobleq" }, 4716979Smckusick { "sobgeq" }, { "sobgtr" }, { "caseb" }, { "casew" }, { "casel" }, 4816979Smckusick { "bsbb" }, { "bsbw" }, { "jsb" }, { "rsb" }, 4916979Smckusick { "callg" }, { "calls" }, { "ret" }, 5016979Smckusick { "movc3" }, { "movc5" }, { "movtc" }, { "movtuc" }, 5116979Smckusick { "cmpc3" }, { "cmpc5" }, { "scanc" }, { "spanc" }, 5216979Smckusick { "locc" }, { "skpc" }, { "matchc" }, { "crc" }, 5316979Smckusick { "movp" }, { "cmpp3" }, { "cmpp4" }, { "addp4" }, { "addp6" }, 5416979Smckusick { "subp4" }, { "subp6" }, { "mulp" }, { "divp" }, { "cvtlp" }, 5516979Smckusick { "cvtpl" }, { "cvtpt" }, { "cvttp" }, { "cvtps" }, { "cvtsp" }, 5616979Smckusick { "ashp" }, { "editpc" }, 5716979Smckusick { "escd" }, { "esce" }, { "escf" }, 5816979Smckusick { "" } 5916979Smckusick }; 6016979Smckusick 6116979Smckusick /* 6216960Smckusick * Check to see if a line is a candidate for replacement. 6316960Smckusick * Return pointer to name to be looked up in pattern table. 6416960Smckusick */ 6516960Smckusick char * 6616960Smckusick doreplaceon(cp) 6716960Smckusick char *cp; 6816960Smckusick { 6916960Smckusick 7016960Smckusick if (bcmp(cp, "calls\t$", 7) == 0) 7116960Smckusick return (cp + 7); 7216960Smckusick return (0); 7316960Smckusick } 7416960Smckusick 7516960Smckusick /* 7616960Smckusick * Find the next argument to the function being expanded. 7716960Smckusick */ 7816960Smckusick nextarg(argc, argv) 7916960Smckusick int argc; 8016960Smckusick char *argv[]; 8116960Smckusick { 8216960Smckusick register char *lastarg = argv[2]; 8316960Smckusick 8416960Smckusick if (argc == 3 && 8516960Smckusick bcmp(argv[0], "mov", 3) == 0 && 8616960Smckusick bcmp(argv[1], "(sp)+", 6) == 0 && 8716960Smckusick lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') 8816960Smckusick return (lastarg[1] - '0'); 8916960Smckusick return (-1); 9016960Smckusick } 9116960Smckusick 9216960Smckusick /* 9316960Smckusick * Determine whether the current line pushes an argument. 9416960Smckusick */ 9516960Smckusick ispusharg(argc, argv) 9616960Smckusick int argc; 9716960Smckusick char *argv[]; 9816960Smckusick { 9916960Smckusick 10016960Smckusick if (argc < 2) 10116960Smckusick return (0); 10216960Smckusick if (argc == 2 && bcmp(argv[0], "push", 4) == 0) 10316960Smckusick return (1); 10416960Smckusick if (bcmp(argv[argc - 1], "-(sp)", 6) == 0) 10516960Smckusick return (1); 10616960Smckusick return (0); 10716960Smckusick } 10816960Smckusick 10916960Smckusick /* 11016960Smckusick * Determine which (if any) registers are modified 11116960Smckusick * Return register number that is modified, -1 if none are modified. 11216960Smckusick */ 11316960Smckusick modifies(argc, argv) 11416960Smckusick int argc; 11516960Smckusick char *argv[]; 11616960Smckusick { 11716960Smckusick /* 11816960Smckusick * For the VAX all we care about are r0 to r5 11916960Smckusick */ 12016960Smckusick register char *lastarg = argv[argc - 1]; 12116960Smckusick 12216960Smckusick if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') 12316960Smckusick return (lastarg[1] - '0'); 12416960Smckusick return (-1); 12516960Smckusick } 12616960Smckusick 12716960Smckusick /* 12816960Smckusick * Rewrite the instruction in (argc, argv) to store its 12916960Smckusick * contents into arg instead of onto the stack. The new 13016960Smckusick * instruction is placed in the buffer that is provided. 13116960Smckusick */ 13216960Smckusick rewrite(instbuf, argc, argv, target) 13316960Smckusick char *instbuf; 13416960Smckusick int argc; 13516960Smckusick char *argv[]; 13616960Smckusick int target; 13716960Smckusick { 13816960Smckusick 13916960Smckusick switch (argc) { 14016960Smckusick case 0: 14116960Smckusick instbuf[0] = '\0'; 14221192Smckusick fprintf(stderr, "blank line to rewrite?\n"); 14316960Smckusick return; 14416960Smckusick case 1: 14516960Smckusick sprintf(instbuf, "\t%s\n", argv[0]); 14616960Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 14716960Smckusick return; 14816960Smckusick case 2: 14916960Smckusick if (bcmp(argv[0], "push", 4) == 0) { 15016960Smckusick sprintf(instbuf, "\tmov%s\t%s,r%d\n", 15116960Smckusick &argv[0][4], argv[1], target); 15216960Smckusick return; 15316960Smckusick } 15416960Smckusick sprintf(instbuf, "\t%s\tr%d\n", argv[0], target); 15516960Smckusick return; 15616960Smckusick case 3: 15716960Smckusick sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target); 15816960Smckusick return; 15916960Smckusick case 4: 16016960Smckusick sprintf(instbuf, "\t%s\t%s,%s,r%d\n", 16116960Smckusick argv[0], argv[1], argv[2], target); 16216960Smckusick return; 16316971Smckusick case 5: 16416971Smckusick sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n", 16516971Smckusick argv[0], argv[1], argv[2], argv[3], target); 16616971Smckusick return; 16716960Smckusick default: 16816960Smckusick sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); 16916960Smckusick argc -= 2, argv += 2; 17016960Smckusick while (argc-- > 0) { 17116960Smckusick strcat(instbuf, ","); 17216960Smckusick strcat(instbuf, *argv++); 17316960Smckusick } 17416960Smckusick strcat(instbuf, "\n"); 17516960Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 17616960Smckusick return; 17716960Smckusick } 17816960Smckusick } 17917203Smckusick 18017203Smckusick /* 18117203Smckusick * Do any necessary post expansion cleanup. 18217203Smckusick */ 18317203Smckusick cleanup(numargs) 18417203Smckusick int numargs; 18517203Smckusick { 18617203Smckusick 18717203Smckusick return; 18817203Smckusick } 18917203Smckusick #endif vax 19017203Smckusick 19117203Smckusick #ifdef mc68000 19217203Smckusick /* 19317203Smckusick * Instruction stop table. 19417203Smckusick * All instructions that implicitly modify any of the temporary 19517203Smckusick * registers, change control flow, or implicitly loop must be 19617203Smckusick * listed in this table. It is used to find the end of a basic 19717203Smckusick * block when scanning backwards through the instruction stream 19817203Smckusick * trying to merge the inline expansion. 19917203Smckusick */ 20017203Smckusick struct inststoptbl inststoptable[] = { 20117203Smckusick { "" } 20217203Smckusick }; 20317203Smckusick 20417203Smckusick /* 20517203Smckusick * Check to see if a line is a candidate for replacement. 20617203Smckusick * Return pointer to name to be looked up in pattern table. 20717203Smckusick */ 20817203Smckusick char * 20917203Smckusick doreplaceon(cp) 21017203Smckusick char *cp; 21117203Smckusick { 21217203Smckusick 21317203Smckusick if (bcmp(cp, "jbsr\t", 5) == 0) 21417203Smckusick return (cp + 5); 21517203Smckusick return (0); 21617203Smckusick } 21717203Smckusick 21817203Smckusick /* 21917203Smckusick * Find the next argument to the function being expanded. 22017203Smckusick */ 22117203Smckusick nextarg(argc, argv) 22217203Smckusick int argc; 22317203Smckusick char *argv[]; 22417203Smckusick { 22517203Smckusick register char *lastarg = argv[2]; 22617203Smckusick 22717203Smckusick if (argc == 3 && 22817203Smckusick bcmp(argv[0], "movl", 5) == 0 && 22917203Smckusick bcmp(argv[1], "sp@+", 5) == 0 && 23017203Smckusick (lastarg[1] == '0' || lastarg[1] == '1') && 23117203Smckusick lastarg[2] == '\0') { 23217203Smckusick if (lastarg[0] == 'd') 23317203Smckusick return (lastarg[1] - '0'); 23417203Smckusick return (lastarg[1] - '0' + 8); 23517203Smckusick } 23617203Smckusick return (-1); 23717203Smckusick } 23817203Smckusick 23917203Smckusick /* 24017203Smckusick * Determine whether the current line pushes an argument. 24117203Smckusick */ 24217203Smckusick ispusharg(argc, argv) 24317203Smckusick int argc; 24417203Smckusick char *argv[]; 24517203Smckusick { 24617203Smckusick 24717203Smckusick if (argc < 2) 24817203Smckusick return (0); 24917203Smckusick if (argc == 2 && bcmp(argv[0], "pea", 4) == 0) 25017203Smckusick return (1); 25117203Smckusick if (bcmp(argv[argc - 1], "sp@-", 5) == 0) 25217203Smckusick return (1); 25317203Smckusick return (0); 25417203Smckusick } 25517203Smckusick 25617203Smckusick /* 25717203Smckusick * Determine which (if any) registers are modified 25817203Smckusick * Return register number that is modified, -1 if none are modified. 25917203Smckusick */ 26017203Smckusick modifies(argc, argv) 26117203Smckusick int argc; 26217203Smckusick char *argv[]; 26317203Smckusick { 26417203Smckusick /* 26517203Smckusick * For the MC68000 all we care about are d0, d1, a0, and a1. 26617203Smckusick */ 26717203Smckusick register char *lastarg = argv[argc - 1]; 26817203Smckusick 26917203Smckusick if (lastarg[0] == 'd' && isdigit(lastarg[1]) && lastarg[2] == '\0') 27017203Smckusick return (lastarg[1] - '0'); 27117203Smckusick if (lastarg[0] == 'a' && isdigit(lastarg[1]) && lastarg[2] == '\0') 27217203Smckusick return (lastarg[1] - '0' + 8); 27317203Smckusick return (-1); 27417203Smckusick } 27517203Smckusick 27617203Smckusick /* 27717203Smckusick * Rewrite the instruction in (argc, argv) to store its 27817203Smckusick * contents into arg instead of onto the stack. The new 27917203Smckusick * instruction is placed in the buffer that is provided. 28017203Smckusick */ 28117203Smckusick rewrite(instbuf, argc, argv, target) 28217203Smckusick char *instbuf; 28317203Smckusick int argc; 28417203Smckusick char *argv[]; 28517203Smckusick int target; 28617203Smckusick { 28717203Smckusick int regno; 28817203Smckusick char regtype; 28917203Smckusick 29017203Smckusick if (target < 8) { 29117203Smckusick regtype = 'd'; 29217203Smckusick regno = target; 29317203Smckusick } else { 29417203Smckusick regtype = 'a'; 29517203Smckusick regno = target - 8; 29617203Smckusick } 29717203Smckusick switch (argc) { 29817203Smckusick case 0: 29917203Smckusick instbuf[0] = '\0'; 30021192Smckusick fprintf(stderr, "blank line to rewrite?\n"); 30117203Smckusick return; 30217203Smckusick case 1: 30317203Smckusick sprintf(instbuf, "\t%s\n", argv[0]); 30417203Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 30517203Smckusick return; 30617203Smckusick case 2: 30717203Smckusick if (bcmp(argv[0], "pea", 4) == 0) { 30817203Smckusick if (regtype == 'a') { 30917203Smckusick sprintf(instbuf, "\tlea\t%s,%c%d\n", 31017203Smckusick argv[1], regtype, regno); 31117203Smckusick return; 31217203Smckusick } 31317203Smckusick if (argv[1][0] == '_' || isdigit(argv[1][0])) { 31417203Smckusick sprintf(instbuf, "\tmovl\t#%s,%c%d\n", 31517203Smckusick argv[1], regtype, regno); 31617203Smckusick return; 31717203Smckusick } 31817203Smckusick sprintf(instbuf, 31917203Smckusick "\texg\ta0,d%d\n\tlea\t%s,a0\n\texg\ta0,d%d\n", 32017203Smckusick regno, argv[1], regno); 32117203Smckusick return; 32217203Smckusick } 32317203Smckusick sprintf(instbuf, "\t%s\t%c%d\n", argv[0], regtype, regno); 32417203Smckusick return; 32517203Smckusick case 3: 32617203Smckusick sprintf(instbuf, "\t%s\t%s,%c%d\n", 32717203Smckusick argv[0], argv[1], regtype, regno); 32817203Smckusick return; 32917203Smckusick default: 33017203Smckusick sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); 33117203Smckusick argc -= 2, argv += 2; 33217203Smckusick while (argc-- > 0) { 33317203Smckusick strcat(instbuf, ","); 33417203Smckusick strcat(instbuf, *argv++); 33517203Smckusick } 33617203Smckusick strcat(instbuf, "\n"); 33717203Smckusick fprintf(stderr, "rewrite?-> %s", instbuf); 33817203Smckusick return; 33917203Smckusick } 34017203Smckusick } 34117203Smckusick 34217203Smckusick /* 34317203Smckusick * Do any necessary post expansion cleanup. 34417203Smckusick */ 34517203Smckusick cleanup(numargs) 34617203Smckusick int numargs; 34717203Smckusick { 34817203Smckusick 34917203Smckusick if (numargs == 0) 35017203Smckusick return; 35117203Smckusick /* 35217203Smckusick * delete instruction to pop arguments. 35317203Smckusick * TODO: 35417203Smckusick * CHECK FOR LABEL 35517203Smckusick * CHECK THAT INSTRUCTION IS A POP 35617203Smckusick */ 35717203Smckusick fgets(line[bufhead], MAXLINELEN, stdin); 35817203Smckusick } 35917203Smckusick #endif mc68000 360