1 /* 2 * Copyright (c) 1997, 2012, 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 init_class_id(Class_Mul); 46 } 47 48 // Handle algebraic identities here. If we have an identity, return the Node 49 // we are equivalent to. We look for "add of zero" as an identity. 50 virtual Node* Identity(PhaseGVN* phase); 51 52 // We also canonicalize the Node, moving constants to the right input, 53 // and flatten expressions (so that 1+x+2 becomes x+3). 54 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 55 56 // Compute a new Type for this node. Basically we just do the pre-check, 57 // then call the virtual add() to set the type. 58 virtual const Type* Value(PhaseGVN* phase) const; 59 60 // Supplied function returns the product of the inputs. 61 // This also type-checks the inputs for sanity. Guaranteed never to 62 // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. 63 // This call recognizes the multiplicative zero type. 64 virtual const Type *mul_ring( const Type *, const Type * ) const = 0; 65 66 // Supplied function to return the multiplicative identity type 67 virtual const Type *mul_id() const = 0; 68 69 // Supplied function to return the additive identity type 70 virtual const Type *add_id() const = 0; 71 72 // Supplied function to return the additive opcode 73 virtual int add_opcode() const = 0; 74 75 // Supplied function to return the multiplicative opcode 76 virtual int mul_opcode() const = 0; 77 78 }; 79 80 //------------------------------MulINode--------------------------------------- 81 // Multiply 2 integers 82 class MulINode : public MulNode { 83 public: 84 MulINode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 85 virtual int Opcode() const; 86 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 87 virtual const Type *mul_ring( const Type *, const Type * ) const; 88 const Type *mul_id() const { return TypeInt::ONE; } 89 const Type *add_id() const { return TypeInt::ZERO; } 90 int add_opcode() const { return Op_AddI; } 91 int mul_opcode() const { return Op_MulI; } 92 const Type *bottom_type() const { return TypeInt::INT; } 93 virtual uint ideal_reg() const { return Op_RegI; } 94 }; 95 96 //------------------------------MulLNode--------------------------------------- 97 // Multiply 2 longs 98 class MulLNode : public MulNode { 99 public: 100 MulLNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 101 virtual int Opcode() const; 102 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 103 virtual const Type *mul_ring( const Type *, const Type * ) const; 104 const Type *mul_id() const { return TypeLong::ONE; } 105 const Type *add_id() const { return TypeLong::ZERO; } 106 int add_opcode() const { return Op_AddL; } 107 int mul_opcode() const { return Op_MulL; } 108 const Type *bottom_type() const { return TypeLong::LONG; } 109 virtual uint ideal_reg() const { return Op_RegL; } 110 }; 111 112 113 //------------------------------MulFNode--------------------------------------- 114 // Multiply 2 floats 115 class MulFNode : public MulNode { 116 public: 117 MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 118 virtual int Opcode() const; 119 virtual const Type *mul_ring( const Type *, const Type * ) const; 120 const Type *mul_id() const { return TypeF::ONE; } 121 const Type *add_id() const { return TypeF::ZERO; } 122 int add_opcode() const { return Op_AddF; } 123 int mul_opcode() const { return Op_MulF; } 124 const Type *bottom_type() const { return Type::FLOAT; } 125 virtual uint ideal_reg() const { return Op_RegF; } 126 }; 127 128 //------------------------------MulDNode--------------------------------------- 129 // Multiply 2 doubles 130 class MulDNode : public MulNode { 131 public: 132 MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} 133 virtual int Opcode() const; 134 virtual const Type *mul_ring( const Type *, const Type * ) const; 135 const Type *mul_id() const { return TypeD::ONE; } 136 const Type *add_id() const { return TypeD::ZERO; } 137 int add_opcode() const { return Op_AddD; } 138 int mul_opcode() const { return Op_MulD; } 139 const Type *bottom_type() const { return Type::DOUBLE; } 140 virtual uint ideal_reg() const { return Op_RegD; } 141 }; 142 143 //-------------------------------MulHiLNode------------------------------------ 144 // Upper 64 bits of a 64 bit by 64 bit multiply 145 class MulHiLNode : public Node { 146 public: 147 MulHiLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 148 virtual int Opcode() const; 149 virtual const Type* Value(PhaseGVN* phase) const; 150 const Type *bottom_type() const { return TypeLong::LONG; } 151 virtual uint ideal_reg() const { return Op_RegL; } 152 }; 153 154 //------------------------------AndINode--------------------------------------- 155 // Logically AND 2 integers. Included with the MUL nodes because it inherits 156 // all the behavior of multiplication on a ring. 157 class AndINode : public MulINode { 158 public: 159 AndINode( Node *in1, Node *in2 ) : MulINode(in1,in2) {} 160 virtual int Opcode() const; 161 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 162 virtual Node* Identity(PhaseGVN* phase); 163 virtual const Type *mul_ring( const Type *, const Type * ) const; 164 const Type *mul_id() const { return TypeInt::MINUS_1; } 165 const Type *add_id() const { return TypeInt::ZERO; } 166 int add_opcode() const { return Op_OrI; } 167 int mul_opcode() const { return Op_AndI; } 168 virtual uint ideal_reg() const { return Op_RegI; } 169 }; 170 171 //------------------------------AndINode--------------------------------------- 172 // Logically AND 2 longs. Included with the MUL nodes because it inherits 173 // all the behavior of multiplication on a ring. 174 class AndLNode : public MulLNode { 175 public: 176 AndLNode( Node *in1, Node *in2 ) : MulLNode(in1,in2) {} 177 virtual int Opcode() const; 178 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 179 virtual Node* Identity(PhaseGVN* phase); 180 virtual const Type *mul_ring( const Type *, const Type * ) const; 181 const Type *mul_id() const { return TypeLong::MINUS_1; } 182 const Type *add_id() const { return TypeLong::ZERO; } 183 int add_opcode() const { return Op_OrL; } 184 int mul_opcode() const { return Op_AndL; } 185 virtual uint ideal_reg() const { return Op_RegL; } 186 }; 187 188 //------------------------------LShiftINode------------------------------------ 189 // Logical shift left 190 class LShiftINode : public Node { 191 public: 192 LShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 193 virtual int Opcode() const; 194 virtual Node* Identity(PhaseGVN* phase); 195 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 196 virtual const Type* Value(PhaseGVN* phase) const; 197 const Type *bottom_type() const { return TypeInt::INT; } 198 virtual uint ideal_reg() const { return Op_RegI; } 199 }; 200 201 //------------------------------LShiftLNode------------------------------------ 202 // Logical shift left 203 class LShiftLNode : public Node { 204 public: 205 LShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 206 virtual int Opcode() const; 207 virtual Node* Identity(PhaseGVN* phase); 208 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 209 virtual const Type* Value(PhaseGVN* phase) const; 210 const Type *bottom_type() const { return TypeLong::LONG; } 211 virtual uint ideal_reg() const { return Op_RegL; } 212 }; 213 214 //------------------------------RShiftINode------------------------------------ 215 // Signed shift right 216 class RShiftINode : public Node { 217 public: 218 RShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 219 virtual int Opcode() const; 220 virtual Node* Identity(PhaseGVN* phase); 221 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 222 virtual const Type* Value(PhaseGVN* phase) const; 223 const Type *bottom_type() const { return TypeInt::INT; } 224 virtual uint ideal_reg() const { return Op_RegI; } 225 }; 226 227 //------------------------------RShiftLNode------------------------------------ 228 // Signed shift right 229 class RShiftLNode : public Node { 230 public: 231 RShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 232 virtual int Opcode() const; 233 virtual Node* Identity(PhaseGVN* phase); 234 virtual const Type* Value(PhaseGVN* phase) const; 235 const Type *bottom_type() const { return TypeLong::LONG; } 236 virtual uint ideal_reg() const { return Op_RegL; } 237 }; 238 239 240 //------------------------------URShiftINode----------------------------------- 241 // Logical shift right 242 class URShiftINode : public Node { 243 public: 244 URShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 245 virtual int Opcode() const; 246 virtual Node* Identity(PhaseGVN* phase); 247 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 248 virtual const Type* Value(PhaseGVN* phase) const; 249 const Type *bottom_type() const { return TypeInt::INT; } 250 virtual uint ideal_reg() const { return Op_RegI; } 251 }; 252 253 //------------------------------URShiftLNode----------------------------------- 254 // Logical shift right 255 class URShiftLNode : public Node { 256 public: 257 URShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 258 virtual int Opcode() const; 259 virtual Node* Identity(PhaseGVN* phase); 260 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 261 virtual const Type* Value(PhaseGVN* phase) const; 262 const Type *bottom_type() const { return TypeLong::LONG; } 263 virtual uint ideal_reg() const { return Op_RegL; } 264 }; 265 266 #endif // SHARE_VM_OPTO_MULNODE_HPP