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