1 /* 2 * Copyright (c) 1997, 2015, 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_VM_OPTO_DIVNODE_HPP 26 #define SHARE_VM_OPTO_DIVNODE_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 // Optimization - Graph Style 36 37 38 //------------------------------DivINode--------------------------------------- 39 // Integer division 40 // Note: this is division as defined by JVMS, i.e., MinInt/-1 == MinInt. 41 // On processors which don't naturally support this special case (e.g., x86), 42 // the matcher or runtime system must take care of this. 43 class DivINode : public Node { 44 public: 45 DivINode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {} 46 virtual int Opcode() const; 47 virtual Node *Identity( PhaseTransform *phase ); 48 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 49 virtual const Type *Value( PhaseTransform *phase ) const; 50 virtual const Type *bottom_type() const { return TypeInt::INT; } 51 virtual uint ideal_reg() const { return Op_RegI; } 52 53 #ifndef PRODUCT 54 REL_IN_DATA_OUT_1; 55 #endif 56 }; 57 58 //------------------------------DivLNode--------------------------------------- 59 // Long division 60 class DivLNode : public Node { 61 public: 62 DivLNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {} 63 virtual int Opcode() const; 64 virtual Node *Identity( PhaseTransform *phase ); 65 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 66 virtual const Type *Value( PhaseTransform *phase ) const; 67 virtual const Type *bottom_type() const { return TypeLong::LONG; } 68 virtual uint ideal_reg() const { return Op_RegL; } 69 70 #ifndef PRODUCT 71 REL_IN_DATA_OUT_1; 72 #endif 73 }; 74 75 //------------------------------DivFNode--------------------------------------- 76 // Float division 77 class DivFNode : public Node { 78 public: 79 DivFNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor) {} 80 virtual int Opcode() const; 81 virtual Node *Identity( PhaseTransform *phase ); 82 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 83 virtual const Type *Value( PhaseTransform *phase ) const; 84 virtual const Type *bottom_type() const { return Type::FLOAT; } 85 virtual uint ideal_reg() const { return Op_RegF; } 86 87 #ifndef PRODUCT 88 REL_IN_DATA_OUT_1; 89 #endif 90 }; 91 92 //------------------------------DivDNode--------------------------------------- 93 // Double division 94 class DivDNode : public Node { 95 public: 96 DivDNode( Node *c, Node *dividend, Node *divisor ) : Node(c,dividend, divisor) {} 97 virtual int Opcode() const; 98 virtual Node *Identity( PhaseTransform *phase ); 99 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 100 virtual const Type *Value( PhaseTransform *phase ) const; 101 virtual const Type *bottom_type() const { return Type::DOUBLE; } 102 virtual uint ideal_reg() const { return Op_RegD; } 103 104 #ifndef PRODUCT 105 REL_IN_DATA_OUT_1; 106 #endif 107 }; 108 109 //------------------------------ModINode--------------------------------------- 110 // Integer modulus 111 class ModINode : public Node { 112 public: 113 ModINode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {} 114 virtual int Opcode() const; 115 virtual const Type *Value( PhaseTransform *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 #ifndef PRODUCT 121 REL_IN_DATA_OUT_1; 122 #endif 123 }; 124 125 //------------------------------ModLNode--------------------------------------- 126 // Long modulus 127 class ModLNode : public Node { 128 public: 129 ModLNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {} 130 virtual int Opcode() const; 131 virtual const Type *Value( PhaseTransform *phase ) const; 132 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 133 virtual const Type *bottom_type() const { return TypeLong::LONG; } 134 virtual uint ideal_reg() const { return Op_RegL; } 135 136 #ifndef PRODUCT 137 REL_IN_DATA_OUT_1; 138 #endif 139 }; 140 141 //------------------------------ModFNode--------------------------------------- 142 // Float Modulus 143 class ModFNode : public Node { 144 public: 145 ModFNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {} 146 virtual int Opcode() const; 147 virtual const Type *Value( PhaseTransform *phase ) const; 148 virtual const Type *bottom_type() const { return Type::FLOAT; } 149 virtual uint ideal_reg() const { return Op_RegF; } 150 151 #ifndef PRODUCT 152 REL_IN_DATA_OUT_1; 153 #endif 154 }; 155 156 //------------------------------ModDNode--------------------------------------- 157 // Double Modulus 158 class ModDNode : public Node { 159 public: 160 ModDNode( Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {} 161 virtual int Opcode() const; 162 virtual const Type *Value( PhaseTransform *phase ) const; 163 virtual const Type *bottom_type() const { return Type::DOUBLE; } 164 virtual uint ideal_reg() const { return Op_RegD; } 165 166 #ifndef PRODUCT 167 REL_IN_DATA_OUT_1; 168 #endif 169 }; 170 171 //------------------------------DivModNode--------------------------------------- 172 // Division with remainder result. 173 class DivModNode : public MultiNode { 174 protected: 175 DivModNode( Node *c, Node *dividend, Node *divisor ); 176 public: 177 enum { 178 div_proj_num = 0, // quotient 179 mod_proj_num = 1 // remainder 180 }; 181 virtual int Opcode() const; 182 virtual Node *Identity( PhaseTransform *phase ) { return this; } 183 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { return NULL; } 184 virtual const Type *Value( PhaseTransform *phase ) const { return bottom_type(); } 185 virtual uint hash() const { return Node::hash(); } 186 virtual bool is_CFG() const { return false; } 187 virtual uint ideal_reg() const { return NotAMachineReg; } 188 189 ProjNode* div_proj() { return proj_out(div_proj_num); } 190 ProjNode* mod_proj() { return proj_out(mod_proj_num); } 191 192 #ifndef PRODUCT 193 REL_IN_DATA_OUT_1; 194 #endif 195 }; 196 197 //------------------------------DivModINode--------------------------------------- 198 // Integer division with remainder result. 199 class DivModINode : public DivModNode { 200 public: 201 DivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {} 202 virtual int Opcode() const; 203 virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; } 204 virtual Node *match( const ProjNode *proj, const Matcher *m ); 205 206 // Make a divmod and associated projections from a div or mod. 207 static DivModINode* make(Node* div_or_mod); 208 }; 209 210 //------------------------------DivModLNode--------------------------------------- 211 // Long division with remainder result. 212 class DivModLNode : public DivModNode { 213 public: 214 DivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {} 215 virtual int Opcode() const; 216 virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; } 217 virtual Node *match( const ProjNode *proj, const Matcher *m ); 218 219 // Make a divmod and associated projections from a div or mod. 220 static DivModLNode* make(Node* div_or_mod); 221 }; 222 223 #endif // SHARE_VM_OPTO_DIVNODE_HPP