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