home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 6 / FreshFish_September1994.bin / new / dev / c / hce / hcesource / top / source / data.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  9KB  |  384 lines

  1. /* Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Tony Andrews
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  * Modified by Detlef Wuerkner for AMIGA
  12.  * Changes marked with TETISOFT
  13.  */
  14.  
  15. /*
  16.  * Routines for data flow analysis of a single instruction
  17.  */
  18.  
  19. #include "top.h"
  20.  
  21. /*
  22.  * idata
  23.  *
  24.  * For each instruction, we have some global information, as well
  25.  * as flags indicating what the instruction does with its operands.
  26.  * We need to know if each operand is set and/or referenced. If the
  27.  * instruction has side-effects not directly related to its operands,
  28.  * we need to know that as well, so "special case" code can deal with
  29.  * that as well.
  30.  */
  31. struct    idata    {
  32.  
  33.     char    iflag;        /* flags regarding the entire instruction */
  34. #define        SIDE    0x01    /* inst. has side-effects */
  35. #define        CC    0x02    /* inst. munges condition codes */
  36.  
  37.     char    op1f;        /* flags for the first and second operands */
  38.     char    op2f;
  39. #define        SET    0x01    /* operand is set */
  40. #define        REF    0x02    /* operand is referenced */
  41.  
  42. } idata[] =
  43. {
  44.     { CC,        REF,        REF|SET },    /* OR */
  45.     { CC,        REF,        REF },        /* BTST */
  46.     { 0,        REF,        SET },        /* MOVEP */
  47.     { CC,        REF,        REF|SET },    /* BCHG */
  48.     { CC,        REF,        REF|SET },    /* BCLR */
  49.     { CC,        REF,        REF|SET },    /* BSET */
  50.     { CC,        REF,        REF|SET },    /* AND */
  51.     { CC,        REF,        REF|SET },    /* SUB */
  52.     { CC,        REF,        REF|SET },    /* ADD */
  53.     { CC,        REF,        REF|SET },    /* EOR */
  54.     { CC,        REF,        REF },        /* CMP */
  55.     { CC,        REF,        SET },        /* MOVE */
  56.     { CC,        REF|SET,    0 },        /* NEGX */
  57.     { CC,        REF,        REF },        /* CHK */
  58.     { 0,        REF,        SET },        /* LEA */
  59.     { CC,        SET,        0 },        /* CLR */
  60.     { CC,        REF|SET,    0 },        /* NEG */
  61.     { CC,        REF|SET,    0 },        /* NOT */
  62.     { CC,        REF|SET,    0 },        /* NBCD */
  63.     { CC,        REF|SET,    0 },        /* SWAP */
  64.     { SIDE,        REF,        0 },        /* PEA */
  65.     { CC,        REF|SET,    0 },        /* EXT */
  66.     { SIDE,        REF,        SET },        /* MOVEM */
  67.     { CC,        REF,        0 },        /* TST */
  68.     { CC,        REF|SET,    0 },        /* TAS */
  69.     { 0,        REF,        0 },        /* TRAP */
  70.     { SIDE,        REF|SET,    REF },        /* LINK */
  71.     { SIDE,        REF|SET,    0 },        /* UNLK */
  72.     { 0,        0,        0 },        /* RESET */
  73.     { 0,        0,        0 },        /* NOP */
  74.     { CC,        REF,        0 },        /* STOP */
  75.     { SIDE|CC,    0,        0 },        /* RTE */
  76.     { SIDE,        0,        0 },        /* RTS */
  77.     { 0,        0,        0 },        /* TRAPV */
  78.     { SIDE|CC,    0,        0 },        /* RTR */
  79.     { SIDE,        REF,        0 },        /* JSR */
  80.     { 0,        REF,        0 },        /* JMP */
  81.     { CC,        REF,        REF|SET },    /* ADDQ */
  82.     { 0,        SET,        0 },        /* ST */
  83.     { CC,        REF|SET,    REF },        /* DBT */
  84.     { CC,        REF,        REF|SET },    /* SUBQ */
  85.     { 0,        SET,        0 },        /* SF */
  86.     { CC,        REF|SET,    REF },        /* DBRA (dbf) */
  87.     { 0,        SET,        0 },        /* SHI */
  88.     { CC,        REF|SET,    REF },        /* DBHI */
  89.     { 0,        SET,        0 },        /* SLS */
  90.     { CC,        REF|SET,    REF },        /* DBLS */
  91.     { 0,        SET,        0 },        /* SCC */
  92.     { CC,        REF|SET,    REF },        /* DBCC */
  93.     { 0,        SET,        0 },        /* SCS */
  94.     { CC,        REF|SET,    REF },        /* DBCS */
  95.     { 0,        SET,        0 },        /* SNE */
  96.     { CC,        REF|SET,    REF },        /* DBNE */
  97.     { 0,        SET,        0 },        /* SEQ */
  98.     { CC,        REF|SET,    REF },        /* DBEQ */
  99.     { 0,        SET,        0 },        /* SVC */
  100.     { CC,        REF|SET,    REF },        /* DBVC */
  101.     { 0,        SET,        0 },        /* SVS */
  102.     { CC,        REF|SET,    REF },        /* DBVS */
  103.     { 0,        SET,        0 },        /* SPL */
  104.     { 0,        SET,        0 },        /* SMI */
  105.     { CC,        REF|SET,    REF },        /* DBMI */
  106.     { 0,        SET,        0 },        /* SGE */
  107.     { CC,        REF|SET,    REF },        /* DBGE */
  108.     { 0,        SET,        0 },        /* SLT */
  109.     { CC,        REF|SET,    REF },        /* DBLT */
  110.     { 0,        SET,        0 },        /* SGT */
  111.     { CC,        REF|SET,    REF },        /* DBGT */
  112.     { 0,        SET,        0 },        /* SLE */
  113.     { CC,        REF|SET,    REF },        /* DBLE */
  114.     { 0,        REF,        0 },        /* BRA */
  115.     { SIDE,        REF,        0 },        /* BSR */
  116.     { 0,        REF,        0 },        /* BHI */
  117.     { 0,        REF,        0 },        /* BLS */
  118.     { 0,        REF,        0 },        /* BCC */
  119.     { 0,        REF,        0 },        /* BCS */
  120.     { 0,        REF,        0 },        /* BNE */
  121.     { 0,        REF,        0 },        /* BEQ */
  122.     { 0,        REF,        0 },        /* BVC */
  123.     { 0,        REF,        0 },        /* BVS */
  124.     { 0,        REF,        0 },        /* BPL */
  125.     { 0,        REF,        0 },        /* BMI */
  126.     { 0,        REF,        0 },        /* BGE */
  127.     { 0,        REF,        0 },        /* BLT */
  128.     { 0,        REF,        0 },        /* BGT */
  129.     { 0,        REF,        0 },        /* BLE */
  130.     { CC,        REF,        SET },        /* MOVEQ */
  131.     { CC,        REF,        REF|SET },    /* DIVU */
  132.     { CC,        REF,        REF|SET },    /* SBCD */
  133.     { CC,        REF,        REF|SET },    /* DIVS */
  134.     { CC,        REF,        REF|SET },    /* SUBX */
  135.     { CC,        REF,        REF },        /* CMPM */
  136.     { CC,        REF,        REF|SET },    /* MULU */
  137.     { CC,        REF,        REF|SET },    /* ABCD */
  138.     { 0,        REF|SET,    REF|SET },    /* EXG */
  139.     { CC,        REF,        REF|SET },    /* MULS */
  140.     { CC,        REF,        REF|SET },    /* ADDX */
  141.     { CC,        REF,        REF|SET },    /* ASR */
  142.     { CC,        REF,        REF|SET },    /* LSR */
  143.     { CC,        REF,        REF|SET },    /* ROXR */
  144.     { CC,        REF,        REF|SET },    /* ROR */
  145.     { CC,        REF,        REF|SET },    /* ASL */
  146.     { CC,        REF,        REF|SET },    /* LSL */
  147.     { CC,        REF,        REF|SET },    /* ROXL */
  148.     { CC,        REF,        REF|SET },    /* ROL */
  149.     { 0,        0,        0 },        /* DC */
  150. };
  151.  
  152. /*
  153.  * chkset(op) - check to see if operand 'op' sets a register
  154.  *
  155.  * This given operand is set by an instruction. Depending on the
  156.  * addressing mode used, this may set a register. If so, return
  157.  * an appropriate mask. This only happens with register direct
  158.  * addressing.
  159.  */
  160. int
  161. chkset(op)
  162. register struct    opnd    *op;
  163. {
  164.     switch (M(op->amode)) {
  165.  
  166.     case REG:
  167.         return RM(op->areg);
  168.     case REGI:
  169.         if (op->amode & (INC|DEC))
  170.             return RM(op->areg);
  171.         else
  172.             return 0;
  173.  
  174.     default:
  175.         return 0;
  176.     }
  177. }
  178.  
  179. /*
  180.  * chkref(op) - check to see if operand 'op' references a register
  181.  *
  182.  * Checks for register references in source or destination
  183.  * operands, since they can occur in either.
  184.  */
  185. int
  186. chkref(op, is_src)
  187. register struct    opnd    *op;
  188. register bool    is_src;        /* is the operand a source? */
  189. {
  190.     switch (M(op->amode)) {
  191.  
  192.     case NONE:
  193.     case IMM:
  194.     case ABS:
  195.     case PCD:
  196.         return 0;
  197.  
  198.     case REG:
  199.         if (is_src)
  200.             return RM(op->areg);
  201.         else
  202.             return 0;
  203.  
  204.     case REGI:
  205.     case REGID:
  206.         return RM(op->areg);
  207.  
  208.     case REGIDX:
  209.         return (RM(op->areg) | RM(op->ireg));
  210.  
  211.     case PCDX:
  212.         return RM(op->ireg);
  213.  
  214.     default:
  215.         fprintf(stderr, "illegal mode in chkref() %d\n", M(op->amode));
  216.  
  217. /* CHANGED BY TETISOFT */
  218. /*        exit(1); */
  219.         exit(EXIT_FAILURE);
  220.  
  221.     }
  222. }
  223.  
  224. /*
  225.  * chkside(ip, type) - check for side-effects of 'ip'
  226.  *
  227.  * Return a mask of registers set or referenced (depending on 'type')
  228.  * by the given instruction. For example, "pea" sets and references
  229.  * the stack pointer.
  230.  */
  231. int
  232. chkside(ip, type)
  233. INST    *ip;
  234. int    type;
  235. {
  236.     switch (ip->opcode) {
  237.     case PEA:        /* refs/sets the stack pointer */
  238.         return RM(SP);
  239.  
  240.     case LINK:        /* refs/sets SP */
  241.         return RM(SP);
  242.  
  243.     case UNLK:
  244.         if (type == SET)
  245.             return RM(SP);
  246.         else
  247.             return 0;
  248.  
  249.     case RTE:
  250.     case RTS:
  251.     case RTR:
  252.         if (type == SET)
  253.             return RM(SP);
  254.         else
  255.             return RM(SP)|RM(D0);    /* return value's in D0 */
  256.  
  257.     case JSR:
  258.     case BSR:
  259.         /*
  260.          * We have to account, here, for what the called
  261.          * routine might do. Registers D0-3 and A0-3 may
  262.          * be munged.
  263.          */
  264.         if (type == SET)
  265.  
  266. /* CHANGED BY TETISOFT */
  267. /* For use with cclib.library, which destroys D0-D3, A0-A2 and A6,
  268.  * we have to beware of that.
  269.  *
  270.  * 15-01-91 TetiSoft CClib.library V3.0 seems to keep D3 and A2
  271.  * Status of D2: see inst.h
  272.  * 20-05-91 TetiSoft A2 as register variable
  273.  */
  274. #ifndef    CCLIB
  275.             return    RM(A0)|RM(A1)|RM(A2)|
  276.                 RM(D0)|RM(D1)|RM(D2)|RM(SP);
  277. #else
  278.             return    RM(A0)|RM(A1)|RM(A6)|
  279.                 RM(D0)|RM(D1)|RM(D2)|RM(SP);
  280. #endif
  281.  
  282.         else
  283.             return    RM(SP);
  284.  
  285.  
  286.     case MOVEM:
  287.         /*
  288.          * We should really check for a register mask spec.
  289.          * here and parse it. The simple solution is to assume
  290.          * that all the registers used for register variables
  291.          * are referenced or modified.
  292.          */
  293.         return RM(A3)|RM(A4)|RM(A5)|RM(A7)|
  294.                RM(D3)|RM(D4)|RM(D5)|RM(D6)|RM(D7);
  295.  
  296.     default:
  297.         fprintf(stderr, "chkside() - unknown opcode\n");
  298.  
  299. /* CHANGED BY TETISOFT */
  300. /*        exit(1); */
  301.         exit(EXIT_FAILURE);
  302.  
  303.     }
  304. }
  305.  
  306. /*
  307.  * reg_set(ip) - return mask of regs set by 'ip'
  308.  */
  309. int
  310. reg_set(ip)
  311. register INST    *ip;
  312. {
  313.     int    mask = 0;    /* build up a register mask */
  314.  
  315.     if (idata[ip->opcode].op1f & SET)
  316.         mask |= chkset(&ip->src);
  317.     if (idata[ip->opcode].op1f & REF) {
  318.         if ((ip->src.amode & (INC|DEC)) != 0)
  319.             mask |= RM(ip->src.areg);
  320.     }
  321.  
  322.     if (idata[ip->opcode].op2f & SET)
  323.         mask |= chkset(&ip->dst);
  324.     if (idata[ip->opcode].op2f & REF) {
  325.         if ((ip->dst.amode & (I