1 cananian 1.1.2.1 // Bop.java, created Thu Feb  4 21:40:35 1999 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1 package harpoon.IR.Tree;
  5 cananian 1.1.2.1 
  6 cananian 1.1.2.1 /**
  7 cananian 1.1.2.1  * <code>Bop</code> is an enumerated type for <code>BINOP</code>s.
  8 cananian 1.1.2.1  * Operations are typed: pointer (A), integer (I), long (L), float (F) or
  9 cananian 1.1.2.1  * double (D).
 10 cananian 1.1.2.2  * <p>
 11 cananian 1.1.2.2  * Basic rationale: Include full set of comparisons so we can optimize
 12 cananian 1.1.2.2  * jump direction for best cache locality, etc.  Include minimal
 13 cananian 1.1.2.2  * arithmetic, because we can pattern match <code>(x+(-y))</code> for SUB
 14 cananian 1.1.2.2  * pretty easily. Include full set of bitwise-operators to make it easier to
 15 cananian 1.1.2.2  * pattern-match on those architectures with insanely complete sets of
 16 cananian 1.1.2.2  * boolean ops (eg, SPARC has AND/OR/NAND/NOR/XOR/XNOR...).
 17 cananian 1.1.2.2  * Allow fully-flexible typing for easy pointer manipulation (ie pointer
 18 cananian 1.1.2.2  * shifts, pointer ANDs, pointer ORs, etc).
 19 cananian 1.1.2.2  * <p>
 20 cananian 1.1.2.2  * Note that SHL/SHR/USHR mask off all but the low 5 or 6 bits of
 21 cananian 1.1.2.2  * their right-hand operand, just as Qop.xSHL/xSHR/xUSHR do.
 22 cananian 1.1.2.2  * Also note that the NOT operation is included in <code>Uop</code>, but
 23 cananian 1.1.2.2  * not in <code>harpoon.IR.Quads.Qop</code>.  Thus you'll have to do
 24 cananian 1.1.2.2  * some pattern matching on <code>(x ^ (-1))</code> to properly generate
 25 cananian 1.1.2.2  * <code>Uop.NOT</code>.
 26 cananian 1.1.2.1  * 
 27 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 28 cananian 1.2      * @version $Id: Bop.java,v 1.2 2002/02/25 21:05:30 cananian Exp $
 29 cananian 1.1.2.1  */
 30 cananian 1.1.2.1 public abstract class Bop  {
 31 cananian 1.1.2.4     // Comparison operations
 32 cananian 1.1.2.4     /** If less-than, then 1 else 0. */
 33 cananian 1.1.2.4     public final static int CMPLT=0;
 34 cananian 1.1.2.4     /** If less-than-or-equal-to, then 1 else 0. */
 35 cananian 1.1.2.4     public final static int CMPLE=1;
 36 cananian 1.1.2.4     /** If equal-to, then 1 else 0. */
 37 cananian 1.1.2.4     public final static int CMPEQ=2;
 38 cananian 1.1.2.7     /** If not-equal-to, then 1 else 0. */
 39 cananian 1.1.2.7     public final static int CMPNE=3;
 40 cananian 1.1.2.4     /** If greater-than-or-equal-to, then 1 else 0. */
 41 cananian 1.1.2.7     public final static int CMPGE=4;
 42 cananian 1.1.2.4     /** If greater-than, then 1 else 0. */
 43 cananian 1.1.2.7     public final static int CMPGT=5;
 44 cananian 1.1.2.4     // General arithmetic
 45 cananian 1.1.2.4     /** Addition. */
 46 cananian 1.1.2.7     public final static int ADD=6;
 47 cananian 1.1.2.4     /** Multiplication. */
 48 cananian 1.1.2.7     public final static int MUL=7;
 49 cananian 1.1.2.4     /** Division. */
 50 cananian 1.1.2.7     public final static int DIV=8;
 51 cananian 1.1.2.4     /** Remainder operation. Note that this is valid for floating-point
 52 cananian 1.1.2.4      *  as well as integer arithmetic; see the JVM definition of
 53 cananian 1.1.2.5      *  <code>frem</code>. Basically, this is remainder after a 
 54 cananian 1.1.2.5      *  truncating division for both integer and floating-point. */
 55 cananian 1.1.2.7     public final static int REM=9;
 56 cananian 1.1.2.4     // integer arithmetic
 57 cananian 1.1.2.4     /** Left bit-wise shift; long/integer only. */
 58 cananian 1.1.2.7     public final static int SHL =10;
 59 cananian 1.1.2.4     /** Right signed bit-wise shift; long/integer only. */
 60 cananian 1.1.2.7     public final static int SHR =11;
 61 cananian 1.1.2.4     /** Right unsigned bit-wise shift; long/integer only. */
 62 cananian 1.1.2.7     public final static int USHR=12;
 63 cananian 1.1.2.4     /** Bit-wise AND; long/integer only. */
 64 cananian 1.1.2.7     public final static int AND =13;
 65 cananian 1.1.2.4     /** Bit-wise OR; long/integer only. */
 66 cananian 1.1.2.7     public final static int OR  =14;
 67 cananian 1.1.2.4     /** Bit-wise XOR; long/integer only. */
 68 cananian 1.1.2.7     public final static int XOR =15;
 69 cananian 1.1.2.1 
 70 cananian 1.1.2.1     /** Determines if the given <code>Bop</code> value is valid. */
 71 cananian 1.1.2.1     public static boolean isValid(int op) {
 72 cananian 1.1.2.1         switch(op) {
 73 cananian 1.1.2.7         case CMPLT: case CMPLE: case CMPEQ: case CMPNE: case CMPGE: case CMPGT:
 74 cananian 1.1.2.1         case ADD: case MUL: case DIV: case REM:
 75 cananian 1.1.2.1         case SHL: case SHR: case USHR: case AND: case OR: case XOR:
 76 cananian 1.1.2.1             return true;
 77 cananian 1.1.2.1         default:
 78 cananian 1.1.2.1             return false;
 79 cananian 1.1.2.1         }
 80 cananian 1.1.2.1     }
 81 cananian 1.1.2.1 
 82 cananian 1.1.2.1     /** Converts the enumerated <code>Bop</code> value to a human-readable
 83 cananian 1.1.2.1      *  string. */
 84 cananian 1.1.2.1     public static String toString(int op) {
 85 cananian 1.1.2.1         switch(op) {
 86 cananian 1.1.2.1         case CMPLT:     return "cmplt";
 87 cananian 1.1.2.1         case CMPLE:     return "cmple";
 88 cananian 1.1.2.1         case CMPEQ:     return "cmpeq";
 89 cananian 1.1.2.7         case CMPNE:     return "cmpne";
 90 cananian 1.1.2.1         case CMPGE:     return "cmpge";
 91 cananian 1.1.2.1         case CMPGT:     return "cmpgt";
 92 cananian 1.1.2.1         case ADD:       return "add";
 93 cananian 1.1.2.1         case MUL:       return "mul";
 94 cananian 1.1.2.1         case DIV:       return "div";
 95 cananian 1.1.2.1         case REM:       return "rem";
 96 cananian 1.1.2.1         case SHL:       return "shl";
 97 cananian 1.1.2.1         case SHR:       return "shr";
 98 cananian 1.1.2.1         case USHR:      return "ushr";
 99 cananian 1.1.2.1         case AND:       return "and";
100 cananian 1.1.2.1         case OR:        return "or";
101 cananian 1.1.2.1         case XOR:       return "xor";
102 cananian 1.1.2.1         default:        throw new RuntimeException("Unknown Bop type: "+op);
103 cananian 1.1.2.1         }
104 cananian 1.1.2.1     }
105 duncan   1.1.2.3 
106 cananian 1.1.2.6     /** Determines if the given <code>Bop</code> operation
107 cananian 1.1.2.6      *  is commutative. */
108 cananian 1.1.2.6     public static final boolean isCommutative(int op) {
109 cananian 1.1.2.6         switch(op) {
110 cananian 1.1.2.7         case CMPEQ: case CMPNE:
111 cananian 1.1.2.7         case ADD: case MUL: case AND: case OR: case XOR:
112 cananian 1.1.2.6             return true;
113 cananian 1.1.2.6         default:
114 cananian 1.1.2.6             return false;
115 cananian 1.1.2.6         }
116 cananian 1.1.2.6     }
117 cananian 1.1.2.6     /** Determines if the given <code>Bop</code> operation
118 cananian 1.1.2.6      *  is associative. */
119 cananian 1.1.2.6     public static final boolean isAssociative(int op) {
120 cananian 1.1.2.6         switch(op) {
121 cananian 1.1.2.6         case ADD: case MUL: case AND: case OR: case XOR:
122 cananian 1.1.2.6             return true;
123 cananian 1.1.2.6         default:
124 cananian 1.1.2.6             return false;
125 cananian 1.1.2.7         }
126 cananian 1.1.2.7     }
127 cananian 1.1.2.7     /** Returns the inverted opposite for a compare <code>Bop</code>.
128 cananian 1.1.2.7      *  That is, for <code>CMPEQ</code> it will return <code>CMPNE</code>;
129 cananian 1.1.2.7      *  for <code>CMPGT</code> it will return <code>CMPLE</code>; etc. */
130 cananian 1.1.2.7     public static final int invert(int op) {
131 cananian 1.1.2.7         switch(op) {
132 cananian 1.1.2.7         case CMPLT: return CMPGE;
133 cananian 1.1.2.7         case CMPLE: return CMPGT;
134 cananian 1.1.2.7         case CMPEQ: return CMPNE;
135 cananian 1.1.2.7         case CMPNE: return CMPEQ;
136 cananian 1.1.2.7         case CMPGE: return CMPLT;
137 cananian 1.1.2.7         case CMPGT: return CMPLE;
138 cananian 1.1.2.7         default:
139 cananian 1.1.2.7             throw new RuntimeException("Not a compare Bop: "+op);
140 cananian 1.1.2.6         }
141 cananian 1.1.2.6     }
142 cananian 1.2     }