0
|
1 /*
|
|
2 * Copyright 1997-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 // Portions of code courtesy of Clifford Click
|
|
26
|
|
27 // Optimization - Graph Style
|
|
28
|
|
29
|
|
30 //------------------------------DivINode---------------------------------------
|
|
31 // Integer division
|
|
32 // Note: this is division as defined by JVMS, i.e., MinInt/-1 == MinInt.
|
|
33 // On processors which don't naturally support this special case (e.g., x86),
|
|
34 // the matcher or runtime system must take care of this.
|
|
35 class DivINode : public Node {
|
|
36 public:
|
|
37 DivINode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {}
|
|
38 virtual int Opcode() const;
|
|
39 virtual Node *Identity( PhaseTransform *phase );
|
|
40 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
|
41 virtual const Type *Value( PhaseTransform *phase ) const;
|
|
42 virtual const Type *bottom_type() const { return TypeInt::INT; }
|
|
43 virtual uint ideal_reg() const { return Op_RegI; }
|
|
44 };
|
|
45
|
|
46 //------------------------------DivLNode---------------------------------------
|
|
47 // Long division
|
|
48 class DivLNode : public Node {
|
|
49 public:
|
|
50 DivLNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {}
|
|
51 virtual int Opcode() const;
|
|
52 virtual Node *Identity( PhaseTransform *phase );
|
|
53 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
|
54 virtual const Type *Value( PhaseTransform *phase ) const;
|
|
55 virtual const Type *bottom_type() const { return TypeLong::LONG; }
|
|
56 virtual uint ideal_reg() const { return Op_RegL; }
|
|
57 };
|
|
58
|
|
59 //------------------------------DivFNode---------------------------------------
|
|
60 // Float division
|
|
61 class DivFNode : public Node {
|
|
62 public:
|
|
63 DivFNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor) {}
|
|
64 virtual int Opcode() const;
|
|
65 virtual Node *Identity( PhaseTransform *phase );
|
|
66 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
|
67 virtual const Type *Value( PhaseTransform *phase ) const;
|
|
68 virtual const Type *bottom_type() const { return Type::FLOAT; }
|
|
69 virtual uint ideal_reg() const { return Op_RegF; }
|
|
70 };
|
|
71
|
|
72 //------------------------------DivDNode---------------------------------------
|
|
73 // Double division
|
|
74 class DivDNode : public Node {
|
|
75 public:
|
|
76 DivDNode( Node *c, Node *dividend, Node *divisor ) : Node(c,dividend, divisor) {}
|
|
77 virtual int Opcode() const;
|
|
78 virtual Node *Identity( PhaseTransform *phase );
|
|
79 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
|
80 virtual const Type *Value( PhaseTransform *phase ) const;
|
|
81 virtual const Type *bottom_type() const { return Type::DOUBLE; }
|
|
82 virtual uint ideal_reg() const { return Op_RegD; }
|
|
83 };
|
|
84
|
|
85 //------------------------------ModINode---------------------------------------
|
|
86 // Integer modulus
|
|
87 class ModINode : public Node {
|
|
88 public:
|
|
89 ModINode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}
|
|
90 virtual int Opcode() const;
|
|
91 virtual const Type *Value( PhaseTransform *phase ) const;
|
|
92 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
|
93 virtual const Type *bottom_type() const { return TypeInt::INT; }
|
|
94 virtual uint ideal_reg() const { return Op_RegI; }
|
|
95 };
|
|
96
|
|
97 //------------------------------ModLNode---------------------------------------
|
|
98 // Long modulus
|
|
99 class ModLNode : public Node {
|
|
100 public:
|
|
101 ModLNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}
|
|
102 virtual int Opcode() const;
|
|
103 virtual const Type *Value( PhaseTransform *phase ) const;
|
|
104 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
|
105 virtual const Type *bottom_type() const { return TypeLong::LONG; }
|
|
106 virtual uint ideal_reg() const { return Op_RegL; }
|
|
107 };
|
|
108
|
|
109 //------------------------------ModFNode---------------------------------------
|
|
110 // Float Modulus
|
|
111 class ModFNode : public Node {
|
|
112 public:
|
|
113 ModFNode( 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 const Type *bottom_type() const { return Type::FLOAT; }
|
|
117 virtual uint ideal_reg() const { return Op_RegF; }
|
|
118 };
|
|
119
|
|
120 //------------------------------ModDNode---------------------------------------
|
|
121 // Double Modulus
|
|
122 class ModDNode : public Node {
|
|
123 public:
|
|
124 ModDNode( Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {}
|
|
125 virtual int Opcode() const;
|
|
126 virtual const Type *Value( PhaseTransform *phase ) const;
|
|
127 virtual const Type *bottom_type() const { return Type::DOUBLE; }
|
|
128 virtual uint ideal_reg() const { return Op_RegD; }
|
|
129 };
|
|
130
|
|
131 //------------------------------DivModNode---------------------------------------
|
|
132 // Division with remainder result.
|
|
133 class DivModNode : public MultiNode {
|
|
134 protected:
|
|
135 DivModNode( Node *c, Node *dividend, Node *divisor );
|
|
136 public:
|
|
137 enum {
|
|
138 div_proj_num = 0, // quotient
|
|
139 mod_proj_num = 1 // remainder
|
|
140 };
|
|
141 virtual int Opcode() const;
|
|
142 virtual Node *Identity( PhaseTransform *phase ) { return this; }
|
|
143 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { return NULL; }
|
|
144 virtual const Type *Value( PhaseTransform *phase ) const { return bottom_type(); }
|
|
145 virtual uint hash() const { return Node::hash(); }
|
|
146 virtual bool is_CFG() const { return false; }
|
|
147 virtual uint ideal_reg() const { return NotAMachineReg; }
|
|
148
|
|
149 ProjNode* div_proj() { return proj_out(div_proj_num); }
|
|
150 ProjNode* mod_proj() { return proj_out(mod_proj_num); }
|
|
151 };
|
|
152
|
|
153 //------------------------------DivModINode---------------------------------------
|
|
154 // Integer division with remainder result.
|
|
155 class DivModINode : public DivModNode {
|
|
156 public:
|
|
157 DivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
|
|
158 virtual int Opcode() const;
|
|
159 virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; }
|
|
160 virtual Node *match( const ProjNode *proj, const Matcher *m );
|
|
161
|
|
162 // Make a divmod and associated projections from a div or mod.
|
|
163 static DivModINode* make(Compile* C, Node* div_or_mod);
|
|
164 };
|
|
165
|
|
166 //------------------------------DivModLNode---------------------------------------
|
|
167 // Long division with remainder result.
|
|
168 class DivModLNode : public DivModNode {
|
|
169 public:
|
|
170 DivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}
|
|
171 virtual int Opcode() const;
|
|
172 virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; }
|
|
173 virtual Node *match( const ProjNode *proj, const Matcher *m );
|
|
174
|
|
175 // Make a divmod and associated projections from a div or mod.
|
|
176 static DivModLNode* make(Compile* C, Node* div_or_mod);
|
|
177 };
|