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