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