1 /* 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_OPTO_MULNODE_HPP 26 #define SHARE_VM_OPTO_MULNODE_HPP 27 28 #include "opto/node.hpp" 29 #include "opto/opcodes.hpp" 30 #include "opto/type.hpp" 31 32 // Portions of code courtesy of Clifford Click 33 34 class PhaseTransform; 35 36 //------------------------------MulNode---------------------------------------- 37 // Classic MULTIPLY functionality. This covers all the usual 'multiply' 38 // behaviors for an algebraic ring. Multiply-integer, multiply-float, 39 // multiply-double, and binary-and are all inherited from this class. The 40 // various identity values are supplied by virtual functions. 41 class MulNode : public Node { 42 virtual uint hash() const; 43 public: 44 MulNode( Node *in1, Node *in2 ): Node(0,in1,in2) {} 45 46 // Handle algebraic identities here. If we have an identity, return the Node 47 // we are equivalent to. We look for "add of zero" as an identity. 48 virtual Node *Identity( PhaseTransform *phase ); 49 50 // We also canonicalize the Node, moving constants to the right input, 51 // and flatten expressions (so that 1+x+2 becomes x+3). 52 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 53 54 // Compute a new Type for this node. Basically we just do the pre-check, 55 // then call the virtual add() to set the type. 56 virtual const Type *Value( PhaseTransform *phase ) const; 57 58 // Supplied function returns the product of the inputs. 59 // This also type-checks the inputs for sanity. Guaranteed never to 60 // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. 61 // This call recognizes the multiplicative zero type. 62 virtual const Type *mul_ring( const Type *, const Type * ) const = 0; 63 64 // Supplied function to return the multiplicative identity type 65 virtual const Type *mul_id() const = 0; 66 67 // Supplied function to return the additive identity type 68 virtual const Type *add_id() const = 0; 69 70 // Supplied function to return the additive opcode 71 virtual int add_opcode() const = 0; 72 73 // Supplied function to return the multiplicative opcode 74 virtual int mul_opcode() const = 0; 75 76 }; 77 78 //------------------------------MulINode--------------------------------------- 79 // Multiply 2 integers 80 class MulINode : public MulNode { 81 public: 82 MulINode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 83 virtual int Opcode() const; 84 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 85 virtual const Type *mul_ring( const Type *, const Type * ) const; 86 const Type *mul_id() const { return TypeInt::ONE; } 87 const Type *add_id() const { return TypeInt::ZERO; } 88 int add_opcode() const { return Op_AddI; } 89 int mul_opcode() const { return Op_MulI; } 90 const Type *bottom_type() const { return TypeInt::INT; } 91 virtual uint ideal_reg() const { return Op_RegI; } 92 }; 93 94 //------------------------------MulLNode--------------------------------------- 95 // Multiply 2 longs 96 class MulLNode : public MulNode { 97 public: 98 MulLNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 99 virtual int Opcode() const; 100 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 101 virtual const Type *mul_ring( const Type *, const Type * ) const; 102 const Type *mul_id() const { return TypeLong::ONE; } 103 const Type *add_id() const { return TypeLong::ZERO; } 104 int add_opcode() const { return Op_AddL; } 105 int mul_opcode() const { return Op_MulL; } 106 const Type *bottom_type() const { return TypeLong::LONG; } 107 virtual uint ideal_reg() const { return Op_RegL; } 108 }; 109 110 111 //------------------------------MulFNode--------------------------------------- 112 // Multiply 2 floats 113 class MulFNode : public MulNode { 114 public: 115 MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 116 virtual int Opcode() const; 117 virtual const Type *mul_ring( const Type *, const Type * ) const; 118 const Type *mul_id() const { return TypeF::ONE; } 119 const Type *add_id() const { return TypeF::ZERO; } 120 int add_opcode() const { return Op_AddF; } 121 int mul_opcode() const { return Op_MulF; } 122 const Type *bottom_type() const { return Type::FLOAT; } 123 virtual uint ideal_reg() const { return Op_RegF; } 124 }; 125 126 //------------------------------MulDNode--------------------------------------- 127 // Multiply 2 doubles 128 class MulDNode : public MulNode { 129 public: 130 MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 131 virtual int Opcode() const; 132 virtual const Type *mul_ring( const Type *, const Type * ) const; 133 const Type *mul_id() const { return TypeD::ONE; } 134 const Type *add_id() const { return TypeD::ZERO; } 135 int add_opcode() const { return Op_AddD; } 136 int mul_opcode() const { return Op_MulD; } 137 const Type *bottom_type() const { return Type::DOUBLE; } 138 virtual uint ideal_reg() const { return Op_RegD; } 139 }; 140 141 //-------------------------------MulHiLNode------------------------------------ 142 // Upper 64 bits of a 64 bit by 64 bit multiply 143 class MulHiLNode : public Node { 144 public: 145 MulHiLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 146 virtual int Opcode() const; 147 virtual const Type *Value( PhaseTransform *phase ) const; 148 const Type *bottom_type() const { return TypeLong::LONG; } 149 virtual uint ideal_reg() const { return Op_RegL; } 150 }; 151 152 //------------------------------AndINode--------------------------------------- 153 // Logically AND 2 integers. Included with the MUL nodes because it inherits 154 // all the behavior of multiplication on a ring. 155 class AndINode : public MulINode { 156 public: 157 AndINode( Node *in1, Node *in2 ) : MulINode(in1,in2) {} 158 virtual int Opcode() const; 159 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 160 virtual Node *Identity( PhaseTransform *phase ); 161 virtual const Type *mul_ring( const Type *, const Type * ) const; 162 const Type *mul_id() const { return TypeInt::MINUS_1; } 163 const Type *add_id() const { return TypeInt::ZERO; } 164 int add_opcode() const { return Op_OrI; } 165 int mul_opcode() const { return Op_AndI; } 166 virtual uint ideal_reg() const { return Op_RegI; } 167 }; 168 169 //------------------------------AndINode--------------------------------------- 170 // Logically AND 2 longs. Included with the MUL nodes because it inherits 171 // all the behavior of multiplication on a ring. 172 class AndLNode : public MulLNode { 173 public: 174 AndLNode( Node *in1, Node *in2 ) : MulLNode(in1,in2) {} 175 virtual int Opcode() const; 176 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 177 virtual Node *Identity( PhaseTransform *phase ); 178 virtual const Type *mul_ring( const Type *, const Type * ) const; 179 const Type *mul_id() const { return TypeLong::MINUS_1; } 180 const Type *add_id() const { return TypeLong::ZERO; } 181 int add_opcode() const { return Op_OrL; } 182 int mul_opcode() const { return Op_AndL; } 183 virtual uint ideal_reg() const { return Op_RegL; } 184 }; 185 186 //------------------------------LShiftINode------------------------------------ 187 // Logical shift left 188 class LShiftINode : public Node { 189 public: 190 LShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 191 virtual int Opcode() const; 192 virtual Node *Identity( PhaseTransform *phase ); 193 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 194 virtual const Type *Value( PhaseTransform *phase ) const; 195 const Type *bottom_type() const { return TypeInt::INT; } 196 virtual uint ideal_reg() const { return Op_RegI; } 197 }; 198 199 //------------------------------LShiftLNode------------------------------------ 200 // Logical shift left 201 class LShiftLNode : public Node { 202 public: 203 LShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 204 virtual int Opcode() const; 205 virtual Node *Identity( PhaseTransform *phase ); 206 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 207 virtual const Type *Value( PhaseTransform *phase ) const; 208 const Type *bottom_type() const { return TypeLong::LONG; } 209 virtual uint ideal_reg() const { return Op_RegL; } 210 }; 211 212 //------------------------------RShiftINode------------------------------------ 213 // Signed shift right 214 class RShiftINode : public Node { 215 public: 216 RShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 217 virtual int Opcode() const; 218 virtual Node *Identity( PhaseTransform *phase ); 219 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 220 virtual const Type *Value( PhaseTransform *phase ) const; 221 const Type *bottom_type() const { return TypeInt::INT; } 222 virtual uint ideal_reg() const { return Op_RegI; } 223 }; 224 225 //------------------------------RShiftLNode------------------------------------ 226 // Signed shift right 227 class RShiftLNode : public Node { 228 public: 229 RShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 230 virtual int Opcode() const; 231 virtual Node *Identity( PhaseTransform *phase ); 232 virtual const Type *Value( PhaseTransform *phase ) const; 233 const Type *bottom_type() const { return TypeLong::LONG; } 234 virtual uint ideal_reg() const { return Op_RegL; } 235 }; 236 237 238 //------------------------------URShiftINode----------------------------------- 239 // Logical shift right 240 class URShiftINode : public Node { 241 public: 242 URShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 243 virtual int Opcode() const; 244 virtual Node *Identity( PhaseTransform *phase ); 245 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 246 virtual const Type *Value( PhaseTransform *phase ) const; 247 const Type *bottom_type() const { return TypeInt::INT; } 248 virtual uint ideal_reg() const { return Op_RegI; } 249 }; 250 251 //------------------------------URShiftLNode----------------------------------- 252 // Logical shift right 253 class URShiftLNode : public Node { 254 public: 255 URShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 256 virtual int Opcode() const; 257 virtual Node *Identity( PhaseTransform *phase ); 258 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 259 virtual const Type *Value( PhaseTransform *phase ) const; 260 const Type *bottom_type() const { return TypeLong::LONG; } 261 virtual uint ideal_reg() const { return Op_RegL; } 262 }; 263 264 #endif // SHARE_VM_OPTO_MULNODE_HPP