1 cananian 1.1.2.1 // UNOP.java, created Wed Jan 13 21:14:57 1999 by cananian 2 cananian 1.1.2.16 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.16 // 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.4 import harpoon.ClassFile.HCodeElement; 7 cananian 1.1.2.21 import harpoon.Temp.TempMap; 8 cananian 1.1.2.3 import harpoon.Util.Util; 9 cananian 1.1.2.3 10 cananian 1.1.2.1 /** 11 cananian 1.1.2.1 * <code>UNOP</code> objects are expressions which stand for result of 12 cananian 1.1.2.1 * applying some unary operator <i>o</i> to a subexpression. 13 cananian 1.1.2.1 * 14 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu>, based on 15 cananian 1.1.2.1 * <i>Modern Compiler Implementation in Java</i> by Andrew Appel. 16 cananian 1.4 * @version $Id: UNOP.java,v 1.4 2002/04/10 03:05:46 cananian Exp $ 17 cananian 1.1.2.3 * @see Uop 18 cananian 1.1.2.1 */ 19 cananian 1.1.2.1 public class UNOP extends OPER { 20 cananian 1.1.2.12 /** Constructor. 21 cananian 1.1.2.12 * @param unop Enumerated operation type, from <code>Uop</code>. 22 cananian 1.1.2.12 */ 23 cananian 1.1.2.4 public UNOP(TreeFactory tf, HCodeElement source, 24 cananian 1.1.2.5 int optype, int unop, Exp operand) { 25 cananian 1.1.2.20 super(tf, source, optype, unop, 1); 26 cananian 1.3.2.1 assert operand!=null; 27 duncan 1.1.2.18 this.setOperand(operand); 28 cananian 1.3.2.1 assert Uop.isValid(unop); 29 cananian 1.3.2.1 assert tf == operand.tf : "This and Operand must have same tree factory"; 30 cananian 1.1.2.23 if (unop==Uop.I2B || unop==Uop.I2C || unop==Uop.I2S) 31 cananian 1.3.2.1 assert optype == Type.INT;/* these are special conversions */ 32 cananian 1.3.2.1 assert operand.type()==optype : "operand and optype don't match"; 33 duncan 1.1.2.18 } 34 duncan 1.1.2.18 35 cananian 1.1.2.20 /** Returns the subexpression to be operated upon. */ 36 cananian 1.1.2.20 public Exp getOperand() { return (Exp) getChild(0); } 37 duncan 1.1.2.18 38 cananian 1.1.2.20 /** Sets the subexpression to be operated upon. */ 39 cananian 1.1.2.20 public void setOperand(Exp operand) { setChild(0, operand); } 40 pnkfelix 1.1.2.10 41 pnkfelix 1.1.2.10 /** Returns an <code>int</code> identifying the TYPE that this 42 pnkfelix 1.1.2.10 unary operation returns. 43 pnkfelix 1.1.2.10 @see harpoon.IR.Tree.Uop 44 pnkfelix 1.1.2.10 */ 45 cananian 1.1.2.5 public int type() { 46 duncan 1.1.2.8 switch (op) { 47 cananian 1.1.2.23 case Uop.I2B: case Uop.I2C: case Uop.I2S: case Uop._2I: 48 cananian 1.1.2.3 return INT; 49 cananian 1.1.2.3 case Uop._2L: 50 cananian 1.1.2.3 return LONG; 51 cananian 1.1.2.3 case Uop._2F: 52 cananian 1.1.2.3 return FLOAT; 53 cananian 1.1.2.3 case Uop._2D: 54 cananian 1.1.2.3 return DOUBLE; 55 cananian 1.1.2.3 default: 56 cananian 1.1.2.5 return optype; 57 cananian 1.1.2.3 } 58 cananian 1.1.2.3 } 59 duncan 1.1.2.8 60 duncan 1.1.2.8 61 duncan 1.1.2.8 public static Object evalValue(TreeFactory tf, int op, 62 duncan 1.1.2.8 int optype, Object left) { 63 duncan 1.1.2.8 switch(op) { 64 duncan 1.1.2.8 case Uop.NEG: 65 duncan 1.1.2.8 switch (optype) { 66 duncan 1.1.2.8 case Type.INT: return _i(-(_i(left))); 67 duncan 1.1.2.8 case Type.LONG: return _l(-(_l(left))); 68 duncan 1.1.2.8 case Type.FLOAT: return _f(-(_f(left))); 69 duncan 1.1.2.8 case Type.DOUBLE: return _d(-(_d(left))); 70 duncan 1.1.2.8 case Type.POINTER: 71 bdemsky 1.1.2.13 return Type.isDoubleWord(tf, optype) ? 72 bdemsky 1.1.2.13 (Object)_i(-(_i(left))) : (Object)_l(-(_l(left))); 73 duncan 1.1.2.8 } 74 duncan 1.1.2.8 case Uop.NOT: 75 duncan 1.1.2.8 switch (optype) { 76 duncan 1.1.2.8 case Type.INT: return _i(~(_i(left))); 77 duncan 1.1.2.8 case Type.LONG: return _l(~(_l(left))); 78 duncan 1.1.2.8 case Type.FLOAT: 79 duncan 1.1.2.8 case Type.DOUBLE: 80 duncan 1.1.2.8 case Type.POINTER: 81 duncan 1.1.2.8 throw new Error("Operation not supported"); 82 duncan 1.1.2.8 } 83 cananian 1.1.2.23 case Uop.I2B: 84 duncan 1.1.2.8 switch (optype) { 85 duncan 1.1.2.9 case Type.INT: return _i((byte)_i(left)); 86 cananian 1.1.2.23 default: 87 duncan 1.1.2.8 throw new Error("Operation not supported"); 88 duncan 1.1.2.8 } 89 cananian 1.1.2.23 case Uop.I2C: 90 duncan 1.1.2.8 switch (optype) { 91 duncan 1.1.2.8 case Type.INT: return _i((char)_i(left)); 92 cananian 1.1.2.23 default: 93 duncan 1.1.2.8 throw new Error("Operation not supported"); 94 duncan 1.1.2.8 } 95 cananian 1.1.2.23 case Uop.I2S: 96 duncan 1.1.2.8 switch (optype) { 97 duncan 1.1.2.8 case Type.INT: return _i((short)_i(left)); 98 cananian 1.1.2.23 default: 99 duncan 1.1.2.8 throw new Error("Operation not supported"); 100 duncan 1.1.2.8 } 101 duncan 1.1.2.8 case Uop._2I: 102 duncan 1.1.2.8 switch (optype) { 103 duncan 1.1.2.8 case Type.INT: return left; 104 duncan 1.1.2.8 case Type.LONG: return _i((int)_l(left)); 105 duncan 1.1.2.8 case Type.FLOAT: return _i((int)_f(left)); 106 duncan 1.1.2.8 case Type.DOUBLE: return _i((int)_d(left)); 107 duncan 1.1.2.8 case Type.POINTER: 108 duncan 1.1.2.8 if (Type.isDoubleWord(tf, optype)) 109 duncan 1.1.2.8 throw new Error("Operation not supported"); 110 duncan 1.1.2.8 else return _i((int)_i(left)); 111 duncan 1.1.2.8 } 112 duncan 1.1.2.8 case Uop._2L: 113 duncan 1.1.2.8 switch (optype) { 114 duncan 1.1.2.8 case Type.INT: return _l((long)_i(left)); 115 duncan 1.1.2.8 case Type.LONG: return left; 116 duncan 1.1.2.8 case Type.FLOAT: return _l((long)_f(left)); 117 duncan 1.1.2.8 case Type.DOUBLE: return _l((long)_d(left)); 118 duncan 1.1.2.8 case Type.POINTER: 119 duncan 1.1.2.8 if (Type.isDoubleWord(tf, optype)) return left; 120 duncan 1.1.2.8 else return _l((long)_i(left)); 121 duncan 1.1.2.8 } 122 duncan 1.1.2.8 case Uop._2F: 123 duncan 1.1.2.8 switch (optype) { 124 duncan 1.1.2.8 case Type.INT: return _f((float)_i(left)); 125 duncan 1.1.2.8 case Type.LONG: return _f((float)_l(left)); 126 duncan 1.1.2.8 case Type.FLOAT: return left; 127 duncan 1.1.2.8 case Type.DOUBLE: return _f((float)_d(left)); 128 duncan 1.1.2.8 case Type.POINTER: 129 duncan 1.1.2.8 if (Type.isDoubleWord(tf, optype)) 130 duncan 1.1.2.8 throw new Error("Operation not supported"); 131 duncan 1.1.2.8 else return _f((float)_i(left)); 132 duncan 1.1.2.8 } 133 duncan 1.1.2.8 case Uop._2D: 134 duncan 1.1.2.8 switch (optype) { 135 duncan 1.1.2.8 case Type.INT: return _d((double)_i(left)); 136 duncan 1.1.2.8 case Type.LONG: return _d((double)_l(left)); 137 duncan 1.1.2.8 case Type.FLOAT: return _d((double)_f(left)); 138 duncan 1.1.2.8 case Type.DOUBLE: return left; 139 duncan 1.1.2.8 case Type.POINTER: 140 duncan 1.1.2.8 if (Type.isDoubleWord(tf, optype)) return left; 141 duncan 1.1.2.8 else return _d((double)_i(left)); 142 duncan 1.1.2.8 } 143 duncan 1.1.2.8 default: 144 duncan 1.1.2.8 throw new Error("Unrecognized Uop"); 145 duncan 1.1.2.8 } 146 duncan 1.1.2.8 } 147 duncan 1.1.2.8 148 duncan 1.1.2.8 // wrapper functions. 149 duncan 1.1.2.9 private static Byte _b(byte b) { return new Byte(b); } 150 duncan 1.1.2.8 private static Integer _i(int i) { return new Integer(i); } 151 duncan 1.1.2.8 private static Long _l(long l) { return new Long(l); } 152 duncan 1.1.2.8 private static Float _f(float f) { return new Float(f); } 153 duncan 1.1.2.8 private static Double _d(double d) { return new Double(d); } 154 duncan 1.1.2.8 155 duncan 1.1.2.8 // unwrapper functions. 156 duncan 1.1.2.9 private static byte _b(Object o) { return ((Byte)o) .byteValue(); } 157 duncan 1.1.2.8 private static int _i(Object o) { return ((Integer)o).intValue(); } 158 duncan 1.1.2.8 private static long _l(Object o) { return ((Long)o) .longValue(); } 159 duncan 1.1.2.8 private static float _f(Object o) { return ((Float)o) .floatValue(); } 160 duncan 1.1.2.8 private static double _d(Object o) { return ((Double)o) .doubleValue(); } 161 cananian 1.1.2.3 162 duncan 1.1.2.11 public int kind() { return TreeKind.UNOP; } 163 duncan 1.1.2.15 164 duncan 1.1.2.15 public Exp build(TreeFactory tf, ExpList kids) { 165 cananian 1.3.2.1 assert kids!=null && kids.tail==null; 166 cananian 1.3.2.1 assert tf == kids.head.tf; 167 cananian 1.1.2.5 return new UNOP(tf, this, optype, op, kids.head); 168 cananian 1.1.2.1 } 169 duncan 1.1.2.2 /** Accept a visitor */ 170 cananian 1.1.2.17 public void accept(TreeVisitor v) { v.visit(this); } 171 duncan 1.1.2.6 172 cananian 1.1.2.21 public Tree rename(TreeFactory tf, TempMap tm, CloneCallback cb) { 173 cananian 1.1.2.22 return cb.callback(this, 174 cananian 1.1.2.22 new UNOP(tf, this, optype, op, 175 cananian 1.1.2.22 (Exp)getOperand().rename(tf, tm, cb)), 176 cananian 1.1.2.22 tm); 177 andyb 1.1.2.7 } 178 andyb 1.1.2.7 179 andyb 1.1.2.7 public String toString() { 180 andyb 1.1.2.7 return "UNOP<" + Type.toString(optype) + ">(" + Uop.toString(op) + 181 cananian 1.1.2.20 ", #" + getOperand().getID() + ")"; 182 duncan 1.1.2.6 } 183 cananian 1.1.2.1 } 184 cananian 1.2