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 }