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   TupleNode* make_tuple_of_input_state_and_constant_result(PhaseIterGVN* phase, const Type* con) const;
179 
180 protected:
181   virtual Node* dividend() const = 0;
182   virtual Node* divisor() const = 0;
183   virtual const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const = 0;
184 
185 public:
186   ModFloatingNode(Compile* C, const TypeFunc* tf, address addr, const char* name);
187   Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
188 };
189 
190 // Float Modulus
191 class ModFNode : public ModFloatingNode {
192 private:
193   Node* dividend() const override { return in(TypeFunc::Parms + 0); }
194   Node* divisor() const override { return in(TypeFunc::Parms + 1); }
195   const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
196 
197 public:
198   ModFNode(Compile* C, Node* a, Node* b);
199   int Opcode() const override;
200   uint ideal_reg() const override { return Op_RegF; }
201   uint size_of() const override { return sizeof(*this); }
202 };
203 
204 // Double Modulus
205 class ModDNode : public ModFloatingNode {
206 private:
207   Node* dividend() const override { return in(TypeFunc::Parms + 0); }
208   Node* divisor() const override { return in(TypeFunc::Parms + 2); }
209   const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
210 
211 public:
212   ModDNode(Compile* C, Node* a, Node* b);
213   int Opcode() const override;
214   uint ideal_reg() const override { return Op_RegD; }
215   uint size_of() const override { return sizeof(*this); }
216 };
217 
218 //------------------------------UModINode---------------------------------------
219 // Unsigned integer modulus
220 class UModINode : public DivModIntegerNode {
221 public:
222   UModINode(Node* c, Node* in1, Node* in2) : DivModIntegerNode(c, in1, in2) {}
223   virtual int Opcode() const;
224   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
225   virtual const Type *bottom_type() const { return TypeInt::INT; }
226   virtual uint ideal_reg() const { return Op_RegI; }
227   virtual const Type* Value(PhaseGVN* phase) const;
228 };
229 
230 //------------------------------UModLNode---------------------------------------
231 // Unsigned long modulus
232 class UModLNode : public DivModIntegerNode {
233 public:
234   UModLNode(Node* c, Node* in1, Node* in2) : DivModIntegerNode(c, in1, in2) {}
235   virtual int Opcode() const;
236   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
237   virtual const Type *bottom_type() const { return TypeLong::LONG; }
238   virtual uint ideal_reg() const { return Op_RegL; }
239   virtual const Type* Value(PhaseGVN* phase) const;
240 };
241 
242 //------------------------------DivModNode---------------------------------------
243 // Division with remainder result.
244 class DivModNode : public MultiNode {
245 protected:
246   DivModNode( Node *c, Node *dividend, Node *divisor );
247 public:
248   enum {
249     div_proj_num =  0,      // quotient
250     mod_proj_num =  1       // remainder
251   };
252   virtual int Opcode() const;
253   virtual Node* Identity(PhaseGVN* phase) { return this; }
254   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { return nullptr; }
255   virtual const Type* Value(PhaseGVN* phase)  const { return bottom_type(); }
256   virtual uint hash() const { return Node::hash(); }
257   virtual bool is_CFG() const  { return false; }
258   virtual uint ideal_reg() const { return NotAMachineReg; }
259 
260   static DivModNode* make(Node* div_or_mod, BasicType bt, bool is_unsigned);
261 
262   ProjNode* div_proj() { return proj_out_or_null(div_proj_num); }
263   ProjNode* mod_proj() { return proj_out_or_null(mod_proj_num); }
264 
265 private:
266   virtual bool depends_only_on_test() const { return false; }
267 };
268 
269 //------------------------------DivModINode---------------------------------------
270 // Integer division with remainder result.
271 class DivModINode : public DivModNode {
272 public:
273   DivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
274   virtual int Opcode() const;
275   virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; }
276   virtual Node *match(const ProjNode *proj, const Matcher *m, const RegMask* mask);
277 
278   // Make a divmod and associated projections from a div or mod.
279   static DivModINode* make(Node* div_or_mod);
280 };
281 
282 //------------------------------DivModLNode---------------------------------------
283 // Long division with remainder result.
284 class DivModLNode : public DivModNode {
285 public:
286   DivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
287   virtual int Opcode() const;
288   virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; }
289   virtual Node *match(const ProjNode *proj, const Matcher *m, const RegMask* mask);
290 
291   // Make a divmod and associated projections from a div or mod.
292   static DivModLNode* make(Node* div_or_mod);
293 };
294 
295 
296 //------------------------------UDivModINode---------------------------------------
297 // Unsigend integer division with remainder result.
298 class UDivModINode : public DivModNode {
299 public:
300   UDivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
301   virtual int Opcode() const;
302   virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; }
303   virtual Node* match(const ProjNode* proj, const Matcher* m, const RegMask* mask);
304 
305   // Make a divmod and associated projections from a div or mod.
306   static UDivModINode* make(Node* div_or_mod);
307 };
308 
309 //------------------------------UDivModLNode---------------------------------------
310 // Unsigned long division with remainder result.
311 class UDivModLNode : public DivModNode {
312 public:
313   UDivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
314   virtual int Opcode() const;
315   virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; }
316   virtual Node* match(const ProjNode* proj, const Matcher* m, const RegMask* mask);
317 
318   // Make a divmod and associated projections from a div or mod.
319   static UDivModLNode* make(Node* div_or_mod);
320 };
321 
322 #endif // SHARE_OPTO_DIVNODE_HPP