1/*
2 * Copyright (c) 1997, 2014, 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.
43class DivINode : public Node {
44public:
45  DivINode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {}
46  virtual int Opcode() const;
47  virtual Node* Identity(PhaseGVN* phase);
48  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
49  virtual const Type* Value(PhaseGVN* phase) const;
50  virtual const Type *bottom_type() const { return TypeInt::INT; }
51  virtual uint ideal_reg() const { return Op_RegI; }
52};
53
54//------------------------------DivLNode---------------------------------------
55// Long division
56class DivLNode : public Node {
57public:
58  DivLNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {}
59  virtual int Opcode() const;
60  virtual Node* Identity(PhaseGVN* phase);
61  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
62  virtual const Type* Value(PhaseGVN* phase) const;
63  virtual const Type *bottom_type() const { return TypeLong::LONG; }
64  virtual uint ideal_reg() const { return Op_RegL; }
65};
66
67//------------------------------DivFNode---------------------------------------
68// Float division
69class DivFNode : public Node {
70public:
71  DivFNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor) {}
72  virtual int Opcode() const;
73  virtual Node* Identity(PhaseGVN* phase);
74  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
75  virtual const Type* Value(PhaseGVN* phase) const;
76  virtual const Type *bottom_type() const { return Type::FLOAT; }
77  virtual uint ideal_reg() const { return Op_RegF; }
78};
79
80//------------------------------DivDNode---------------------------------------
81// Double division
82class DivDNode : public Node {
83public:
84  DivDNode( Node *c, Node *dividend, Node *divisor ) : Node(c,dividend, divisor) {}
85  virtual int Opcode() const;
86  virtual Node* Identity(PhaseGVN* phase);
87  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
88  virtual const Type* Value(PhaseGVN* phase) const;
89  virtual const Type *bottom_type() const { return Type::DOUBLE; }
90  virtual uint ideal_reg() const { return Op_RegD; }
91};
92
93//------------------------------ModINode---------------------------------------
94// Integer modulus
95class ModINode : public Node {
96public:
97  ModINode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}
98  virtual int Opcode() const;
99  virtual const Type* Value(PhaseGVN* phase) const;
100  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
101  virtual const Type *bottom_type() const { return TypeInt::INT; }
102  virtual uint ideal_reg() const { return Op_RegI; }
103};
104
105//------------------------------ModLNode---------------------------------------
106// Long modulus
107class ModLNode : public Node {
108public:
109  ModLNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}
110  virtual int Opcode() const;
111  virtual const Type* Value(PhaseGVN* phase) const;
112  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
113  virtual const Type *bottom_type() const { return TypeLong::LONG; }
114  virtual uint ideal_reg() const { return Op_RegL; }
115};
116
117//------------------------------ModFNode---------------------------------------
118// Float Modulus
119class ModFNode : public Node {
120public:
121  ModFNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}
122  virtual int Opcode() const;
123  virtual const Type* Value(PhaseGVN* phase) const;
124  virtual const Type *bottom_type() const { return Type::FLOAT; }
125  virtual uint ideal_reg() const { return Op_RegF; }
126};
127
128//------------------------------ModDNode---------------------------------------
129// Double Modulus
130class ModDNode : public Node {
131public:
132  ModDNode( Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {}
133  virtual int Opcode() const;
134  virtual const Type* Value(PhaseGVN* phase) const;
135  virtual const Type *bottom_type() const { return Type::DOUBLE; }
136  virtual uint ideal_reg() const { return Op_RegD; }
137};
138
139//------------------------------DivModNode---------------------------------------
140// Division with remainder result.
141class DivModNode : public MultiNode {
142protected:
143  DivModNode( Node *c, Node *dividend, Node *divisor );
144public:
145  enum {
146    div_proj_num =  0,      // quotient
147    mod_proj_num =  1       // remainder
148  };
149  virtual int Opcode() const;
150  virtual Node* Identity(PhaseGVN* phase) { return this; }
151  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { return NULL; }
152  virtual const Type* Value(PhaseGVN* phase)  const { return bottom_type(); }
153  virtual uint hash() const { return Node::hash(); }
154  virtual bool is_CFG() const  { return false; }
155  virtual uint ideal_reg() const { return NotAMachineReg; }
156
157  ProjNode* div_proj() { return proj_out(div_proj_num); }
158  ProjNode* mod_proj() { return proj_out(mod_proj_num); }
159};
160
161//------------------------------DivModINode---------------------------------------
162// Integer division with remainder result.
163class DivModINode : public DivModNode {
164public:
165  DivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
166  virtual int Opcode() const;
167  virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; }
168  virtual Node *match( const ProjNode *proj, const Matcher *m );
169
170  // Make a divmod and associated projections from a div or mod.
171  static DivModINode* make(Node* div_or_mod);
172};
173
174//------------------------------DivModLNode---------------------------------------
175// Long division with remainder result.
176class DivModLNode : public DivModNode {
177public:
178  DivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
179  virtual int Opcode() const;
180  virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; }
181  virtual Node *match( const ProjNode *proj, const Matcher *m );
182
183  // Make a divmod and associated projections from a div or mod.
184  static DivModLNode* make(Node* div_or_mod);
185};
186
187#endif // SHARE_VM_OPTO_DIVNODE_HPP
188