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_DIVNODE_HPP
 26 #define SHARE_OPTO_DIVNODE_HPP
 27 
 28 #include "opto/callnode.hpp"
 29 #include "opto/multnode.hpp"
 30 #include "opto/node.hpp"
 31 #include "opto/opcodes.hpp"
 32 #include "opto/type.hpp"
 33 
 34 // Portions of code courtesy of Clifford Click
 35 
 36 // Optimization - Graph Style
 37 
 38 class DivModIntegerNode : public Node {
 39 private:
 40   bool _pinned;
 41 
 42 protected:
 43   DivModIntegerNode(Node* c, Node* dividend, Node* divisor) : Node(c, dividend, divisor), _pinned(false) {}
 44 
 45 private:
 46   virtual uint size_of() const override { return sizeof(DivModIntegerNode); }
 47   virtual uint hash() const override { return Node::hash() + _pinned; }
 48   virtual bool cmp(const Node& o) const override { return Node::cmp(o) && _pinned == static_cast<const DivModIntegerNode&>(o)._pinned; }
 49   virtual bool depends_only_on_test_impl() const override { return !_pinned; }
 50   virtual DivModIntegerNode* pin_node_under_control_impl() const override {
 51     DivModIntegerNode* res = static_cast<DivModIntegerNode*>(clone());
 52     res->_pinned = true;
 53     return res;
 54   }
 55 };
 56 
 57 //------------------------------DivINode---------------------------------------
 58 // Integer division
 59 // Note: this is division as defined by JVMS, i.e., MinInt/-1 == MinInt.
 60 // On processors which don't naturally support this special case (e.g., x86),
 61 // the matcher or runtime system must take care of this.
 62 class DivINode : public DivModIntegerNode {
 63 public:
 64   DivINode(Node* c, Node* dividend, Node* divisor) : DivModIntegerNode(c, dividend, divisor) {}
 65   virtual int Opcode() const;
 66   virtual Node* Identity(PhaseGVN* phase);
 67   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 68   virtual const Type* Value(PhaseGVN* phase) const;
 69   virtual const Type *bottom_type() const { return TypeInt::INT; }
 70   virtual uint ideal_reg() const { return Op_RegI; }
 71 };
 72 
 73 //------------------------------DivLNode---------------------------------------
 74 // Long division
 75 class DivLNode : public DivModIntegerNode {
 76 public:
 77   DivLNode(Node* c, Node* dividend, Node* divisor) : DivModIntegerNode(c, dividend, divisor) {}
 78   virtual int Opcode() const;
 79   virtual Node* Identity(PhaseGVN* phase);
 80   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 81   virtual const Type* Value(PhaseGVN* phase) const;
 82   virtual const Type *bottom_type() const { return TypeLong::LONG; }
 83   virtual uint ideal_reg() const { return Op_RegL; }
 84 };
 85 
 86 //------------------------------DivFNode---------------------------------------
 87 // Float division
 88 class DivFNode : public Node {
 89 public:
 90   DivFNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor) {}
 91   virtual int Opcode() const;
 92   virtual Node* Identity(PhaseGVN* phase);
 93   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 94   virtual const Type* Value(PhaseGVN* phase) const;
 95   virtual const Type *bottom_type() const { return Type::FLOAT; }
 96   virtual uint ideal_reg() const { return Op_RegF; }
 97 };
 98 
 99 
100 //------------------------------DivHFNode--------------------------------------
101 // Half float division
102 class DivHFNode : public Node {
103 public:
104   DivHFNode(Node* c, Node* dividend, Node* divisor) : Node(c, dividend, divisor) {}
105   virtual int Opcode() const;
106   virtual Node* Identity(PhaseGVN* phase);
107   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
108   virtual const Type* Value(PhaseGVN* phase) const;
109   virtual const Type* bottom_type() const { return Type::HALF_FLOAT; }
110   virtual uint ideal_reg() const { return Op_RegF; }
111 };
112 
113 //------------------------------DivDNode---------------------------------------
114 // Double division
115 class DivDNode : public Node {
116 public:
117   DivDNode( Node *c, Node *dividend, Node *divisor ) : Node(c,dividend, divisor) {}
118   virtual int Opcode() const;
119   virtual Node* Identity(PhaseGVN* phase);
120   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
121   virtual const Type* Value(PhaseGVN* phase) const;
122   virtual const Type *bottom_type() const { return Type::DOUBLE; }
123   virtual uint ideal_reg() const { return Op_RegD; }
124 };
125 
126 //------------------------------UDivINode---------------------------------------
127 // Unsigned integer division
128 class UDivINode : public DivModIntegerNode {
129 public:
130   UDivINode(Node* c, Node* dividend, Node* divisor) : DivModIntegerNode(c, dividend, divisor) {}
131   virtual int Opcode() const;
132   virtual Node* Identity(PhaseGVN* phase);
133   virtual const Type* Value(PhaseGVN* phase) const;
134   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
135   virtual const Type *bottom_type() const { return TypeInt::INT; }
136   virtual uint ideal_reg() const { return Op_RegI; }
137 };
138 
139 //------------------------------UDivLNode---------------------------------------
140 // Unsigned long division
141 class UDivLNode : public DivModIntegerNode {
142 public:
143   UDivLNode(Node* c, Node* dividend, Node* divisor) : DivModIntegerNode(c, dividend, divisor) {}
144   virtual int Opcode() const;
145   virtual Node* Identity(PhaseGVN* phase);
146   virtual const Type* Value(PhaseGVN* phase) const;
147   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
148   virtual const Type *bottom_type() const { return TypeLong::LONG; }
149   virtual uint ideal_reg() const { return Op_RegL; }
150 };
151 
152 //------------------------------ModINode---------------------------------------
153 // Integer modulus
154 class ModINode : public DivModIntegerNode {
155 public:
156   ModINode(Node* c, Node* in1, Node* in2) : DivModIntegerNode(c, in1, in2) {}
157   virtual int Opcode() const;
158   virtual const Type* Value(PhaseGVN* phase) const;
159   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
160   virtual const Type *bottom_type() const { return TypeInt::INT; }
161   virtual uint ideal_reg() const { return Op_RegI; }
162 };
163 
164 //------------------------------ModLNode---------------------------------------
165 // Long modulus
166 class ModLNode : public DivModIntegerNode {
167 public:
168   ModLNode(Node* c, Node* in1, Node* in2) : DivModIntegerNode(c, in1, in2) {}
169   virtual int Opcode() const;
170   virtual const Type* Value(PhaseGVN* phase) const;
171   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
172   virtual const Type *bottom_type() const { return TypeLong::LONG; }
173   virtual uint ideal_reg() const { return Op_RegL; }
174 };
175 
176 // Base class for float and double modulus
177 class ModFloatingNode : public CallLeafPureNode {
178 protected:
179   virtual Node* dividend() const = 0;
180   virtual Node* divisor() const = 0;
181   virtual const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const = 0;
182 
183 public:
184   ModFloatingNode(Compile* C, const TypeFunc* tf, address addr, const char* name);
185   const Type* Value(PhaseGVN* phase) const override;
186 };
187 
188 // Float Modulus
189 class ModFNode : public ModFloatingNode {
190 private:
191   Node* dividend() const override { return in(TypeFunc::Parms + 0); }
192   Node* divisor() const override { return in(TypeFunc::Parms + 1); }
193   const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
194 
195 public:
196   ModFNode(Compile* C, Node* a, Node* b);
197   int Opcode() const override;
198   uint ideal_reg() const override { return Op_RegF; }
199   uint size_of() const override { return sizeof(*this); }
200 };
201 
202 // Double Modulus
203 class ModDNode : public ModFloatingNode {
204 private:
205   Node* dividend() const override { return in(TypeFunc::Parms + 0); }
206   Node* divisor() const override { return in(TypeFunc::Parms + 2); }
207   const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
208 
209 public:
210   ModDNode(Compile* C, Node* a, Node* b);
211   int Opcode() const override;
212   uint ideal_reg() const override { return Op_RegD; }
213   uint size_of() const override { return sizeof(*this); }
214 };
215 
216 //------------------------------UModINode---------------------------------------
217 // Unsigned integer modulus
218 class UModINode : public DivModIntegerNode {
219 public:
220   UModINode(Node* c, Node* in1, Node* in2) : DivModIntegerNode(c, in1, in2) {}
221   virtual int Opcode() const;
222   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
223   virtual const Type *bottom_type() const { return TypeInt::INT; }
224   virtual uint ideal_reg() const { return Op_RegI; }
225   virtual const Type* Value(PhaseGVN* phase) const;
226 };
227 
228 //------------------------------UModLNode---------------------------------------
229 // Unsigned long modulus
230 class UModLNode : public DivModIntegerNode {
231 public:
232   UModLNode(Node* c, Node* in1, Node* in2) : DivModIntegerNode(c, in1, in2) {}
233   virtual int Opcode() const;
234   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
235   virtual const Type *bottom_type() const { return TypeLong::LONG; }
236   virtual uint ideal_reg() const { return Op_RegL; }
237   virtual const Type* Value(PhaseGVN* phase) const;
238 };
239 
240 //------------------------------DivModNode---------------------------------------
241 // Division with remainder result.
242 class DivModNode : public MultiNode {
243 protected:
244   DivModNode( Node *c, Node *dividend, Node *divisor );
245 public:
246   enum {
247     div_proj_num =  0,      // quotient
248     mod_proj_num =  1       // remainder
249   };
250   virtual int Opcode() const;
251   virtual Node* Identity(PhaseGVN* phase) { return this; }
252   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { return nullptr; }
253   virtual const Type* Value(PhaseGVN* phase)  const { return bottom_type(); }
254   virtual uint hash() const { return Node::hash(); }
255   virtual bool is_CFG() const  { return false; }
256   virtual uint ideal_reg() const { return NotAMachineReg; }
257 
258   static DivModNode* make(Node* div_or_mod, BasicType bt, bool is_unsigned);
259 
260   ProjNode* div_proj() { return proj_out_or_null(div_proj_num); }
261   ProjNode* mod_proj() { return proj_out_or_null(mod_proj_num); }
262 
263 private:
264   virtual bool depends_only_on_test() const { return false; }
265 };
266 
267 //------------------------------DivModINode---------------------------------------
268 // Integer division with remainder result.
269 class DivModINode : public DivModNode {
270 public:
271   DivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
272   virtual int Opcode() const;
273   virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; }
274   virtual Node *match(const ProjNode *proj, const Matcher *m, const RegMask* mask);
275 
276   // Make a divmod and associated projections from a div or mod.
277   static DivModINode* make(Node* div_or_mod);
278 };
279 
280 //------------------------------DivModLNode---------------------------------------
281 // Long division with remainder result.
282 class DivModLNode : public DivModNode {
283 public:
284   DivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
285   virtual int Opcode() const;
286   virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; }
287   virtual Node *match(const ProjNode *proj, const Matcher *m, const RegMask* mask);
288 
289   // Make a divmod and associated projections from a div or mod.
290   static DivModLNode* make(Node* div_or_mod);
291 };
292 
293 
294 //------------------------------UDivModINode---------------------------------------
295 // Unsigend integer division with remainder result.
296 class UDivModINode : public DivModNode {
297 public:
298   UDivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
299   virtual int Opcode() const;
300   virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; }
301   virtual Node* match(const ProjNode* proj, const Matcher* m, const RegMask* mask);
302 
303   // Make a divmod and associated projections from a div or mod.
304   static UDivModINode* make(Node* div_or_mod);
305 };
306 
307 //------------------------------UDivModLNode---------------------------------------
308 // Unsigned long division with remainder result.
309 class UDivModLNode : public DivModNode {
310 public:
311   UDivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
312   virtual int Opcode() const;
313   virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; }
314   virtual Node* match(const ProjNode* proj, const Matcher* m, const RegMask* mask);
315 
316   // Make a divmod and associated projections from a div or mod.
317   static UDivModLNode* make(Node* div_or_mod);
318 };
319 
320 #endif // SHARE_OPTO_DIVNODE_HPP