1 /* 2 * Copyright (c) 1997, 2020, 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_OPTO_MULNODE_HPP 26 #define SHARE_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: MulNode(Node * in1,Node * in2)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: MulINode(Node * in1,Node * in2)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; mul_id() const88 const Type *mul_id() const { return TypeInt::ONE; } add_id() const89 const Type *add_id() const { return TypeInt::ZERO; } add_opcode() const90 int add_opcode() const { return Op_AddI; } mul_opcode() const91 int mul_opcode() const { return Op_MulI; } bottom_type() const92 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const93 virtual uint ideal_reg() const { return Op_RegI; } 94 }; 95 96 //------------------------------MulLNode--------------------------------------- 97 // Multiply 2 longs 98 class MulLNode : public MulNode { 99 public: MulLNode(Node * in1,Node * in2)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; mul_id() const104 const Type *mul_id() const { return TypeLong::ONE; } add_id() const105 const Type *add_id() const { return TypeLong::ZERO; } add_opcode() const106 int add_opcode() const { return Op_AddL; } mul_opcode() const107 int mul_opcode() const { return Op_MulL; } bottom_type() const108 const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const109 virtual uint ideal_reg() const { return Op_RegL; } 110 }; 111 112 113 //------------------------------MulFNode--------------------------------------- 114 // Multiply 2 floats 115 class MulFNode : public MulNode { 116 public: MulFNode(Node * in1,Node * in2)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; mul_id() const120 const Type *mul_id() const { return TypeF::ONE; } add_id() const121 const Type *add_id() const { return TypeF::ZERO; } add_opcode() const122 int add_opcode() const { return Op_AddF; } mul_opcode() const123 int mul_opcode() const { return Op_MulF; } bottom_type() const124 const Type *bottom_type() const { return Type::FLOAT; } ideal_reg() const125 virtual uint ideal_reg() const { return Op_RegF; } 126 }; 127 128 //------------------------------MulDNode--------------------------------------- 129 // Multiply 2 doubles 130 class MulDNode : public MulNode { 131 public: MulDNode(Node * in1,Node * in2)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; mul_id() const135 const Type *mul_id() const { return TypeD::ONE; } add_id() const136 const Type *add_id() const { return TypeD::ZERO; } add_opcode() const137 int add_opcode() const { return Op_AddD; } mul_opcode() const138 int mul_opcode() const { return Op_MulD; } bottom_type() const139 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const140 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: MulHiLNode(Node * in1,Node * in2)147 MulHiLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 148 virtual int Opcode() const; 149 virtual const Type* Value(PhaseGVN* phase) const; bottom_type() const150 const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const151 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: AndINode(Node * in1,Node * in2)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; mul_id() const164 const Type *mul_id() const { return TypeInt::MINUS_1; } add_id() const165 const Type *add_id() const { return TypeInt::ZERO; } add_opcode() const166 int add_opcode() const { return Op_OrI; } mul_opcode() const167 int mul_opcode() const { return Op_AndI; } ideal_reg() const168 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: AndLNode(Node * in1,Node * in2)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; mul_id() const181 const Type *mul_id() const { return TypeLong::MINUS_1; } add_id() const182 const Type *add_id() const { return TypeLong::ZERO; } add_opcode() const183 int add_opcode() const { return Op_OrL; } mul_opcode() const184 int mul_opcode() const { return Op_AndL; } ideal_reg() const185 virtual uint ideal_reg() const { return Op_RegL; } 186 }; 187 188 //------------------------------LShiftINode------------------------------------ 189 // Logical shift left 190 class LShiftINode : public Node { 191 public: LShiftINode(Node * in1,Node * in2)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; bottom_type() const197 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const198 virtual uint ideal_reg() const { return Op_RegI; } 199 }; 200 201 //------------------------------LShiftLNode------------------------------------ 202 // Logical shift left 203 class LShiftLNode : public Node { 204 public: LShiftLNode(Node * in1,Node * in2)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; bottom_type() const210 const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const211 virtual uint ideal_reg() const { return Op_RegL; } 212 }; 213 214 215 //------------------------ RotateLeftNode ---------------------------------- 216 class RotateLeftNode : public TypeNode { 217 public: RotateLeftNode(Node * in1,Node * in2,const Type * type)218 RotateLeftNode(Node* in1, Node* in2, const Type* type) : TypeNode(type, 3) { 219 init_req(1, in1); 220 init_req(2, in2); 221 } 222 virtual int Opcode() const; 223 virtual Node* Identity(PhaseGVN* phase); 224 virtual const Type* Value(PhaseGVN* phase) const; 225 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); 226 }; 227 228 //----------------------- RotateRightNode ---------------------------------- 229 class RotateRightNode : public TypeNode { 230 public: RotateRightNode(Node * in1,Node * in2,const Type * type)231 RotateRightNode(Node* in1, Node* in2, const Type* type) : TypeNode(type, 3) { 232 init_req(1, in1); 233 init_req(2, in2); 234 } 235 virtual int Opcode() const; 236 virtual Node* Identity(PhaseGVN* phase); 237 virtual const Type* Value(PhaseGVN* phase) const; 238 }; 239 240 //------------------------------RShiftINode------------------------------------ 241 // Signed shift right 242 class RShiftINode : public Node { 243 public: RShiftINode(Node * in1,Node * in2)244 RShiftINode( 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; bottom_type() const249 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const250 virtual uint ideal_reg() const { return Op_RegI; } 251 }; 252 253 //------------------------------RShiftLNode------------------------------------ 254 // Signed shift right 255 class RShiftLNode : public Node { 256 public: RShiftLNode(Node * in1,Node * in2)257 RShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 258 virtual int Opcode() const; 259 virtual Node* Identity(PhaseGVN* phase); 260 virtual const Type* Value(PhaseGVN* phase) const; bottom_type() const261 const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const262 virtual uint ideal_reg() const { return Op_RegL; } 263 }; 264 265 //------------------------------URShiftBNode----------------------------------- 266 // Logical shift right 267 class URShiftBNode : public Node { 268 public: URShiftBNode(Node * in1,Node * in2)269 URShiftBNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { 270 ShouldNotReachHere(); // only vector variant is used 271 } 272 virtual int Opcode() const; 273 }; 274 275 //------------------------------URShiftSNode----------------------------------- 276 // Logical shift right 277 class URShiftSNode : public Node { 278 public: URShiftSNode(Node * in1,Node * in2)279 URShiftSNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { 280 ShouldNotReachHere(); // only vector variant is used 281 } 282 virtual int Opcode() const; 283 }; 284 285 //------------------------------URShiftINode----------------------------------- 286 // Logical shift right 287 class URShiftINode : public Node { 288 public: URShiftINode(Node * in1,Node * in2)289 URShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 290 virtual int Opcode() const; 291 virtual Node* Identity(PhaseGVN* phase); 292 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 293 virtual const Type* Value(PhaseGVN* phase) const; bottom_type() const294 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const295 virtual uint ideal_reg() const { return Op_RegI; } 296 }; 297 298 //------------------------------URShiftLNode----------------------------------- 299 // Logical shift right 300 class URShiftLNode : public Node { 301 public: URShiftLNode(Node * in1,Node * in2)302 URShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} 303 virtual int Opcode() const; 304 virtual Node* Identity(PhaseGVN* phase); 305 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 306 virtual const Type* Value(PhaseGVN* phase) const; bottom_type() const307 const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const308 virtual uint ideal_reg() const { return Op_RegL; } 309 }; 310 311 //------------------------------FmaDNode-------------------------------------- 312 // fused-multiply-add double 313 class FmaDNode : public Node { 314 public: FmaDNode(Node * c,Node * in1,Node * in2,Node * in3)315 FmaDNode(Node *c, Node *in1, Node *in2, Node *in3) : Node(c, in1, in2, in3) {} 316 virtual int Opcode() const; bottom_type() const317 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const318 virtual uint ideal_reg() const { return Op_RegD; } 319 virtual const Type* Value(PhaseGVN* phase) const; 320 }; 321 322 //------------------------------FmaFNode-------------------------------------- 323 // fused-multiply-add float 324 class FmaFNode : public Node { 325 public: FmaFNode(Node * c,Node * in1,Node * in2,Node * in3)326 FmaFNode(Node *c, Node *in1, Node *in2, Node *in3) : Node(c, in1, in2, in3) {} 327 virtual int Opcode() const; bottom_type() const328 const Type *bottom_type() const { return Type::FLOAT; } ideal_reg() const329 virtual uint ideal_reg() const { return Op_RegF; } 330 virtual const Type* Value(PhaseGVN* phase) const; 331 }; 332 333 //------------------------------MulAddS2INode---------------------------------- 334 // Multiply shorts into integers and add them. 335 // Semantics: I_OUT = S1 * S2 + S3 * S4 336 class MulAddS2INode : public Node { 337 virtual uint hash() const; 338 public: MulAddS2INode(Node * in1,Node * in2,Node * in3,Node * in4)339 MulAddS2INode(Node* in1, Node *in2, Node *in3, Node* in4) : Node(0, in1, in2, in3, in4) {} 340 virtual int Opcode() const; bottom_type() const341 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const342 virtual uint ideal_reg() const { return Op_RegI; } 343 }; 344 345 #endif // SHARE_OPTO_MULNODE_HPP 346