1 /*
  2  * Copyright (c) 1997, 2026, 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/multnode.hpp"
 29 #include "opto/node.hpp"
 30 #include "opto/opcodes.hpp"
 31 #include "opto/type.hpp"
 32 
 33 // Portions of code courtesy of Clifford Click
 34 
 35 class PhaseTransform;
 36 class Matcher;
 37 
 38 //------------------------------MulNode----------------------------------------
 39 // Classic MULTIPLY functionality.  This covers all the usual 'multiply'
 40 // behaviors for an algebraic ring.  Multiply-integer, multiply-float,
 41 // multiply-double, and binary-and are all inherited from this class.  The
 42 // various identity values are supplied by virtual functions.
 43 class MulNode : public Node {
 44   virtual uint hash() const;
 45 public:
 46   MulNode(Node *in1, Node *in2): Node(nullptr,in1,in2) {
 47     init_class_id(Class_Mul);
 48   }
 49 
 50   // Handle algebraic identities here.  If we have an identity, return the Node
 51   // we are equivalent to.  We look for "add of zero" as an identity.
 52   virtual Node* Identity(PhaseGVN* phase);
 53 
 54   // We also canonicalize the Node, moving constants to the right input,
 55   // and flatten expressions (so that 1+x+2 becomes x+3).
 56   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 57 
 58   // Compute a new Type for this node.  Basically we just do the pre-check,
 59   // then call the virtual add() to set the type.
 60   virtual const Type* Value(PhaseGVN* phase) const;
 61 
 62   // Supplied function returns the product of the inputs.
 63   // This also type-checks the inputs for sanity.  Guaranteed never to
 64   // be passed a TOP or BOTTOM type, these are filtered out by a pre-check.
 65   // This call recognizes the multiplicative zero type.
 66   virtual const Type *mul_ring( const Type *, const Type * ) const = 0;
 67 
 68   // Supplied function to return the multiplicative identity type
 69   virtual const Type *mul_id() const = 0;
 70 
 71   // Supplied function to return the additive identity type
 72   virtual const Type *add_id() const = 0;
 73 
 74   // Supplied function to return the additive opcode
 75   virtual int add_opcode() const = 0;
 76 
 77   // Supplied function to return the multiplicative opcode
 78   virtual int mul_opcode() const = 0;
 79 
 80   // Supplied function to return the additive opcode
 81   virtual int max_opcode() const = 0;
 82 
 83   // Supplied function to return the multiplicative opcode
 84   virtual int min_opcode() const = 0;
 85 
 86   static MulNode* make(Node* in1, Node* in2, BasicType bt);
 87   static MulNode* make_and(Node* in1, Node* in2, BasicType bt);
 88 
 89 protected:
 90   Node* AndIL_sum_and_mask(PhaseGVN* phase, BasicType bt);
 91 };
 92 
 93 //------------------------------MulINode---------------------------------------
 94 // Multiply 2 integers
 95 class MulINode : public MulNode {
 96 public:
 97   MulINode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
 98   virtual int Opcode() const;
 99   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
100   virtual const Type *mul_ring( const Type *, const Type * ) const;
101   static bool does_overflow(const TypeInt* type_left, const TypeInt* type_right);
102   const Type *mul_id() const { return TypeInt::ONE; }
103   const Type *add_id() const { return TypeInt::ZERO; }
104   int add_opcode() const { return Op_AddI; }
105   int mul_opcode() const { return Op_MulI; }
106   int max_opcode() const { return Op_MaxI; }
107   int min_opcode() const { return Op_MinI; }
108   const Type *bottom_type() const { return TypeInt::INT; }
109   virtual uint ideal_reg() const { return Op_RegI; }
110 };
111 
112 //------------------------------MulLNode---------------------------------------
113 // Multiply 2 longs
114 class MulLNode : public MulNode {
115 public:
116   MulLNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
117   virtual int Opcode() const;
118   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
119   virtual const Type *mul_ring( const Type *, const Type * ) const;
120   const Type *mul_id() const { return TypeLong::ONE; }
121   const Type *add_id() const { return TypeLong::ZERO; }
122   int add_opcode() const { return Op_AddL; }
123   int mul_opcode() const { return Op_MulL; }
124   int max_opcode() const { return Op_MaxL; }
125   int min_opcode() const { return Op_MinL; }
126   const Type *bottom_type() const { return TypeLong::LONG; }
127   virtual uint ideal_reg() const { return Op_RegL; }
128 };
129 
130 
131 //------------------------------MulFNode---------------------------------------
132 // Multiply 2 floats
133 class MulFNode : public MulNode {
134 public:
135   MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
136   virtual int Opcode() const;
137   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
138   virtual const Type *mul_ring( const Type *, const Type * ) const;
139   const Type *mul_id() const { return TypeF::ONE; }
140   const Type *add_id() const { return TypeF::ZERO; }
141   int add_opcode() const { return Op_AddF; }
142   int mul_opcode() const { return Op_MulF; }
143   int max_opcode() const { return Op_MaxF; }
144   int min_opcode() const { return Op_MinF; }
145   const Type *bottom_type() const { return Type::FLOAT; }
146   virtual uint ideal_reg() const { return Op_RegF; }
147 };
148 
149 //------------------------------MulHFNode---------------------------------------
150 // Multiply 2 half floats
151 class MulHFNode : public MulNode {
152 public:
153   MulHFNode(Node* in1, Node* in2) : MulNode(in1, in2) {}
154   virtual int Opcode() const;
155   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
156   virtual const Type* mul_ring(const Type*, const Type*) const;
157   const Type* mul_id() const { return TypeH::ONE; }
158   const Type* add_id() const { return TypeH::ZERO; }
159   int add_opcode() const { return Op_AddHF; }
160   int mul_opcode() const { return Op_MulHF; }
161   int max_opcode() const { return Op_MaxHF; }
162   int min_opcode() const { return Op_MinHF; }
163   const Type* bottom_type() const { return Type::HALF_FLOAT; }
164   virtual uint ideal_reg() const { return Op_RegF; }
165 };
166 
167 //------------------------------MulDNode---------------------------------------
168 // Multiply 2 doubles
169 class MulDNode : public MulNode {
170 public:
171   MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
172   virtual int Opcode() const;
173   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
174   virtual const Type *mul_ring( const Type *, const Type * ) const;
175   const Type *mul_id() const { return TypeD::ONE; }
176   const Type *add_id() const { return TypeD::ZERO; }
177   int add_opcode() const { return Op_AddD; }
178   int mul_opcode() const { return Op_MulD; }
179   int max_opcode() const { return Op_MaxD; }
180   int min_opcode() const { return Op_MinD; }
181   const Type *bottom_type() const { return Type::DOUBLE; }
182   virtual uint ideal_reg() const { return Op_RegD; }
183 };
184 
185 //-------------------------------MulHiLNode------------------------------------
186 const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
187 
188 // Upper 64 bits of a 64 bit by 64 bit multiply
189 class MulHiLNode : public Node {
190 public:
191   MulHiLNode( Node *in1, Node *in2 ) : Node(nullptr,in1,in2) {}
192   virtual int Opcode() const;
193   virtual const Type* Value(PhaseGVN* phase) const;
194   const Type *bottom_type() const { return TypeLong::LONG; }
195   virtual uint ideal_reg() const { return Op_RegL; }
196   friend const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
197 };
198 
199 // Upper 64 bits of a 64 bit by 64 bit unsigned multiply
200 class UMulHiLNode : public Node {
201 public:
202   UMulHiLNode( Node *in1, Node *in2 ) : Node(nullptr,in1,in2) {}
203   virtual int Opcode() const;
204   virtual const Type* Value(PhaseGVN* phase) const;
205   const Type *bottom_type() const { return TypeLong::LONG; }
206   virtual uint ideal_reg() const { return Op_RegL; }
207   friend const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
208 };
209 
210 //------------------------------MulHiLoLNode-----------------------------------
211 // Lower and upper 64-bit results of a signed 64x64->128 multiply.
212 class MulHiLoLNode : public BinaryMultiNode {
213 protected:
214   MulHiLoLNode(Node* ctrl, Node* in1, Node* in2) : BinaryMultiNode(ctrl, in1, in2) {}
215 
216 public:
217   virtual int Opcode() const;
218   virtual const Type* bottom_type() const { return TypeTuple::LONG_PAIR; }
219 
220   virtual Node* match(const ProjNode* proj, const Matcher* m, const RegMask* mask);
221 
222   static MulHiLoLNode* make(Node* mul_hi);
223 };
224 
225 //------------------------------UMulHiLoLNode----------------------------------
226 // Lower and upper 64-bit results of an unsigned 64x64->128 multiply.
227 class UMulHiLoLNode : public MulHiLoLNode {
228 public:
229   UMulHiLoLNode(Node* ctrl, Node* in1, Node* in2) : MulHiLoLNode(ctrl, in1, in2) {}
230   virtual int Opcode() const;
231 
232   static UMulHiLoLNode* make(Node* umul_hi);
233 };
234 
235 //------------------------------AndINode---------------------------------------
236 // Logically AND 2 integers.  Included with the MUL nodes because it inherits
237 // all the behavior of multiplication on a ring.
238 class AndINode : public MulINode {
239 public:
240   AndINode( Node *in1, Node *in2 ) : MulINode(in1,in2) {}
241   virtual int Opcode() const;
242   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
243   virtual Node* Identity(PhaseGVN* phase);
244   virtual const Type* Value(PhaseGVN* phase) const;
245   virtual const Type *mul_ring( const Type *, const Type * ) const;
246   const Type *mul_id() const { return TypeInt::MINUS_1; }
247   const Type *add_id() const { return TypeInt::ZERO; }
248   int add_opcode() const { return Op_OrI; }
249   int mul_opcode() const { return Op_AndI; }
250   int max_opcode() const { return Op_MaxI; }
251   int min_opcode() const { return Op_MinI; }
252   virtual uint ideal_reg() const { return Op_RegI; }
253 };
254 
255 //------------------------------AndINode---------------------------------------
256 // Logically AND 2 longs.  Included with the MUL nodes because it inherits
257 // all the behavior of multiplication on a ring.
258 class AndLNode : public MulLNode {
259 public:
260   AndLNode( Node *in1, Node *in2 ) : MulLNode(in1,in2) {}
261   virtual int Opcode() const;
262   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
263   virtual Node* Identity(PhaseGVN* phase);
264   virtual const Type* Value(PhaseGVN* phase) const;
265   virtual const Type *mul_ring( const Type *, const Type * ) const;
266   const Type *mul_id() const { return TypeLong::MINUS_1; }
267   const Type *add_id() const { return TypeLong::ZERO; }
268   int add_opcode() const { return Op_OrL; }
269   int mul_opcode() const { return Op_AndL; }
270   int max_opcode() const { return Op_MaxL; }
271   int min_opcode() const { return Op_MinL; }
272   virtual uint ideal_reg() const { return Op_RegL; }
273 };
274 
275 template <typename TypeClass>
276 Node* make_and(Node* a, Node* b);
277 
278 template <>
279 inline Node* make_and<TypeLong>(Node* a, Node* b) {
280   return new AndLNode(a, b);
281 }
282 
283 template <>
284 inline Node* make_and<TypeInt>(Node* a, Node* b) {
285   return new AndINode(a, b);
286 }
287 
288 class LShiftNode : public Node {
289 public:
290   LShiftNode(Node* in1, Node* in2) : Node(nullptr,in1,in2) {
291     init_class_id(Class_LShift);
292   }
293 
294   const Type* ValueIL(PhaseGVN* phase, BasicType bt) const;
295   Node* IdentityIL(PhaseGVN* phase, BasicType bt);
296   Node* IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt);
297 
298   static LShiftNode* make(Node* in1, Node* in2, BasicType bt);
299 };
300 
301 //------------------------------LShiftINode------------------------------------
302 // Logical shift left
303 class LShiftINode : public LShiftNode {
304 public:
305   LShiftINode(Node* in1, Node* in2) : LShiftNode(in1,in2) {}
306   virtual int Opcode() const;
307   virtual Node* Identity(PhaseGVN* phase);
308   virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
309   virtual const Type* Value(PhaseGVN* phase) const;
310   const Type* bottom_type() const { return TypeInt::INT; }
311   virtual uint ideal_reg() const { return Op_RegI; }
312 };
313 
314 //------------------------------LShiftLNode------------------------------------
315 // Logical shift left
316 class LShiftLNode : public LShiftNode {
317 public:
318   LShiftLNode(Node *in1, Node *in2) : LShiftNode(in1,in2) {}
319   virtual int Opcode() const;
320   virtual Node* Identity(PhaseGVN* phase);
321   virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
322   virtual const Type* Value(PhaseGVN* phase) const;
323   const Type* bottom_type() const { return TypeLong::LONG; }
324   virtual uint ideal_reg() const { return Op_RegL; }
325 };
326 
327 
328 //------------------------ RotateLeftNode ----------------------------------
329 class RotateLeftNode : public TypeNode {
330   public:
331   RotateLeftNode(Node* in1, Node* in2, const Type* type) : TypeNode(type, 3) {
332     init_req(1, in1);
333     init_req(2, in2);
334   }
335   virtual int Opcode() const;
336   virtual Node* Identity(PhaseGVN* phase);
337   virtual const Type* Value(PhaseGVN* phase) const;
338   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
339 };
340 
341 //----------------------- RotateRightNode ----------------------------------
342 class RotateRightNode : public TypeNode {
343   public:
344   RotateRightNode(Node* in1, Node* in2, const Type* type) : TypeNode(type, 3) {
345     init_req(1, in1);
346     init_req(2, in2);
347   }
348   virtual int Opcode() const;
349   virtual Node* Identity(PhaseGVN* phase);
350   virtual const Type* Value(PhaseGVN* phase) const;
351 };
352 
353 
354 class RShiftNode : public Node {
355  public:
356   RShiftNode(Node* in1, Node* in2) : Node(nullptr, in1, in2) {}
357   Node* IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt);
358   Node* IdentityIL(PhaseGVN* phase, BasicType bt);
359   const Type* ValueIL(PhaseGVN* phase, BasicType bt) const;
360   static RShiftNode* make(Node* in1, Node* in2, BasicType bt);
361 };
362 
363 //------------------------------RShiftINode------------------------------------
364 // Signed shift right
365 class RShiftINode : public RShiftNode {
366 public:
367   RShiftINode(Node* in1, Node* in2) : RShiftNode(in1, in2) {}
368   virtual int Opcode() const;
369   virtual Node* Identity(PhaseGVN* phase);
370 
371   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
372   virtual const Type* Value(PhaseGVN* phase) const;
373 
374   const Type* bottom_type() const { return TypeInt::INT; }
375   virtual uint ideal_reg() const { return Op_RegI; }
376 };
377 
378 //------------------------------RShiftLNode------------------------------------
379 // Signed shift right
380 class RShiftLNode : public RShiftNode {
381 public:
382   RShiftLNode(Node* in1, Node* in2) : RShiftNode(in1,in2) {}
383   virtual int Opcode() const;
384   virtual Node* Identity(PhaseGVN* phase);
385   virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
386 
387   virtual const Type* Value(PhaseGVN* phase) const;
388   const Type* bottom_type() const { return TypeLong::LONG; }
389   virtual uint ideal_reg() const { return Op_RegL; }
390 };
391 
392 class URShiftNode : public Node {
393 public:
394   URShiftNode(Node* in1, Node* in2) : Node(nullptr, in1, in2) {}
395   static URShiftNode* make(Node* in1, Node* in2, BasicType bt);
396 };
397 
398 //------------------------------URShiftBNode-----------------------------------
399 // Logical shift right
400 class URShiftBNode : public URShiftNode {
401 public:
402   URShiftBNode(Node* in1, Node* in2) : URShiftNode(in1,in2) {
403     ShouldNotReachHere(); // only vector variant is used
404   }
405   virtual int Opcode() const;
406 };
407 
408 //------------------------------URShiftSNode-----------------------------------
409 // Logical shift right
410 class URShiftSNode : public URShiftNode {
411 public:
412   URShiftSNode(Node* in1, Node* in2) : URShiftNode(in1,in2) {
413     ShouldNotReachHere(); // only vector variant is used
414   }
415   virtual int Opcode() const;
416 };
417 
418 //------------------------------URShiftINode-----------------------------------
419 // Logical shift right
420 class URShiftINode : public URShiftNode {
421 public:
422   URShiftINode(Node* in1, Node* in2) : URShiftNode(in1,in2) {}
423   virtual int Opcode() const;
424   virtual Node* Identity(PhaseGVN* phase);
425   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
426   virtual const Type* Value(PhaseGVN* phase) const;
427   const Type* bottom_type() const { return TypeInt::INT; }
428   virtual uint ideal_reg() const { return Op_RegI; }
429 };
430 
431 //------------------------------URShiftLNode-----------------------------------
432 // Logical shift right
433 class URShiftLNode : public URShiftNode {
434 public:
435   URShiftLNode(Node* in1, Node* in2) : URShiftNode(in1,in2) {}
436   virtual int Opcode() const;
437   virtual Node* Identity(PhaseGVN* phase);
438   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
439   virtual const Type* Value(PhaseGVN* phase) const;
440   const Type* bottom_type() const { return TypeLong::LONG; }
441   virtual uint ideal_reg() const { return Op_RegL; }
442 };
443 
444 template <typename TypeClass>
445 Node* make_urshift(Node* a, Node* b);
446 
447 template <>
448 inline Node* make_urshift<TypeLong>(Node* a, Node* b) {
449   return new URShiftLNode(a, b);
450 }
451 
452 template <>
453 inline Node* make_urshift<TypeInt>(Node* a, Node* b) {
454   return new URShiftINode(a, b);
455 }
456 
457 //------------------------------FmaNode--------------------------------------
458 // fused-multiply-add
459 class FmaNode : public Node {
460 public:
461   FmaNode(Node* in1, Node* in2, Node* in3) : Node(nullptr, in1, in2, in3) {
462     assert(UseFMA, "Needs FMA instructions support.");
463   }
464   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
465 };
466 
467 //------------------------------FmaDNode--------------------------------------
468 // fused-multiply-add double
469 class FmaDNode : public FmaNode {
470 public:
471   FmaDNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {}
472   virtual int Opcode() const;
473   const Type* bottom_type() const { return Type::DOUBLE; }
474   virtual uint ideal_reg() const { return Op_RegD; }
475   virtual const Type* Value(PhaseGVN* phase) const;
476 };
477 
478 //------------------------------FmaFNode--------------------------------------
479 // fused-multiply-add float
480 class FmaFNode : public FmaNode {
481 public:
482   FmaFNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {}
483   virtual int Opcode() const;
484   const Type* bottom_type() const { return Type::FLOAT; }
485   virtual uint ideal_reg() const { return Op_RegF; }
486   virtual const Type* Value(PhaseGVN* phase) const;
487 };
488 
489 //------------------------------FmaHFNode-------------------------------------
490 // fused-multiply-add half-precision float
491 class FmaHFNode : public FmaNode {
492 public:
493   FmaHFNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {}
494   virtual int Opcode() const;
495   const Type* bottom_type() const { return Type::HALF_FLOAT; }
496   virtual uint ideal_reg() const { return Op_RegF; }
497   virtual const Type* Value(PhaseGVN* phase) const;
498 };
499 
500 //------------------------------MulAddS2INode----------------------------------
501 // Multiply shorts into integers and add them.
502 // Semantics: I_OUT = S1 * S2 + S3 * S4
503 class MulAddS2INode : public Node {
504   virtual uint hash() const;
505 public:
506   MulAddS2INode(Node* in1, Node *in2, Node *in3, Node* in4) : Node(nullptr, in1, in2, in3, in4) {}
507   virtual int Opcode() const;
508   const Type *bottom_type() const { return TypeInt::INT; }
509   virtual uint ideal_reg() const { return Op_RegI; }
510 };
511 
512 #endif // SHARE_OPTO_MULNODE_HPP