1 /*
2  * Copyright (c) 2015, 2020, 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_INTRINSICNODE_HPP
26 #define SHARE_OPTO_INTRINSICNODE_HPP
27 
28 #include "opto/node.hpp"
29 #include "opto/opcodes.hpp"
30 #include "opto/connode.hpp"
31 
32 
33 //----------------------PartialSubtypeCheckNode--------------------------------
34 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
35 // array for an instance of the superklass.  Set a hidden internal cache on a
36 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
37 // not zero for a miss or zero for a hit.
38 class PartialSubtypeCheckNode : public Node {
39  public:
PartialSubtypeCheckNode(Node * c,Node * sub,Node * super)40   PartialSubtypeCheckNode(Node* c, Node* sub, Node* super) : Node(c,sub,super) {}
41   virtual int Opcode() const;
bottom_type() const42   virtual const Type* bottom_type() const { return TypeRawPtr::BOTTOM; }
ideal_reg() const43   virtual uint ideal_reg() const { return Op_RegP; }
44 };
45 
46 //------------------------------StrIntrinsic-------------------------------
47 // Base class for Ideal nodes used in String intrinsic code.
48 class StrIntrinsicNode: public Node {
49  public:
50   // Possible encodings of the parameters passed to the string intrinsic.
51   // 'L' stands for Latin1 and 'U' stands for UTF16. For example, 'LU' means that
52   // the first string is Latin1 encoded and the second string is UTF16 encoded.
53   // 'L' means that the single string is Latin1 encoded
54   typedef enum ArgEncoding { LL, LU, UL, UU, L, U, none } ArgEnc;
55 
56  protected:
57   // Encoding of strings. Used to select the right version of the intrinsic.
58   const ArgEncoding _encoding;
59   virtual uint size_of() const;
60 
61  public:
StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)62   StrIntrinsicNode(Node* control, Node* char_array_mem,
63                    Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
64   Node(control, char_array_mem, s1, c1, s2, c2), _encoding(encoding) {
65   }
66 
StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,Node * c,ArgEncoding encoding)67   StrIntrinsicNode(Node* control, Node* char_array_mem,
68                    Node* s1, Node* s2, Node* c, ArgEncoding encoding):
69   Node(control, char_array_mem, s1, s2, c), _encoding(encoding) {
70   }
71 
StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,ArgEncoding encoding)72   StrIntrinsicNode(Node* control, Node* char_array_mem,
73                    Node* s1, Node* s2, ArgEncoding encoding):
74   Node(control, char_array_mem, s1, s2), _encoding(encoding) {
75   }
76 
depends_only_on_test() const77   virtual bool depends_only_on_test() const { return false; }
adr_type() const78   virtual const TypePtr* adr_type() const { return TypeAryPtr::BYTES; }
79   virtual uint match_edge(uint idx) const;
ideal_reg() const80   virtual uint ideal_reg() const { return Op_RegI; }
81   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
82   virtual const Type* Value(PhaseGVN* phase) const;
encoding() const83   ArgEncoding encoding() const { return _encoding; }
84 };
85 
86 //------------------------------StrComp-------------------------------------
87 class StrCompNode: public StrIntrinsicNode {
88  public:
StrCompNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)89   StrCompNode(Node* control, Node* char_array_mem,
90               Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
91   StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
92   virtual int Opcode() const;
bottom_type() const93   virtual const Type* bottom_type() const { return TypeInt::INT; }
94 };
95 
96 //------------------------------StrEquals-------------------------------------
97 class StrEqualsNode: public StrIntrinsicNode {
98  public:
StrEqualsNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,Node * c,ArgEncoding encoding)99   StrEqualsNode(Node* control, Node* char_array_mem,
100                 Node* s1, Node* s2, Node* c, ArgEncoding encoding):
101   StrIntrinsicNode(control, char_array_mem, s1, s2, c, encoding) {};
102   virtual int Opcode() const;
bottom_type() const103   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
104 };
105 
106 //------------------------------StrIndexOf-------------------------------------
107 class StrIndexOfNode: public StrIntrinsicNode {
108  public:
StrIndexOfNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)109   StrIndexOfNode(Node* control, Node* char_array_mem,
110                  Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
111   StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
112   virtual int Opcode() const;
bottom_type() const113   virtual const Type* bottom_type() const { return TypeInt::INT; }
114 };
115 
116 //------------------------------StrIndexOfChar-------------------------------------
117 class StrIndexOfCharNode: public StrIntrinsicNode {
118  public:
StrIndexOfCharNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * c,ArgEncoding encoding)119   StrIndexOfCharNode(Node* control, Node* char_array_mem,
120                      Node* s1, Node* c1, Node* c, ArgEncoding encoding):
121   StrIntrinsicNode(control, char_array_mem, s1, c1, c, encoding) {};
122   virtual int Opcode() const;
bottom_type() const123   virtual const Type* bottom_type() const { return TypeInt::INT; }
124 };
125 
126 //--------------------------StrCompressedCopy-------------------------------
127 class StrCompressedCopyNode: public StrIntrinsicNode {
128  public:
StrCompressedCopyNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)129   StrCompressedCopyNode(Node* control, Node* arymem,
130                         Node* s1, Node* s2, Node* c):
131   StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
132   virtual int Opcode() const;
bottom_type() const133   virtual const Type* bottom_type() const { return TypeInt::INT; }
adr_type() const134   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
135   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
136 };
137 
138 //--------------------------StrInflatedCopy---------------------------------
139 class StrInflatedCopyNode: public StrIntrinsicNode {
140  public:
StrInflatedCopyNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)141   StrInflatedCopyNode(Node* control, Node* arymem,
142                       Node* s1, Node* s2, Node* c):
143   StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
144   virtual int Opcode() const;
bottom_type() const145   virtual const Type* bottom_type() const { return Type::MEMORY; }
adr_type() const146   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
147   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
148 };
149 
150 //------------------------------AryEq---------------------------------------
151 class AryEqNode: public StrIntrinsicNode {
152  public:
AryEqNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,ArgEncoding encoding)153   AryEqNode(Node* control, Node* char_array_mem,
154             Node* s1, Node* s2, ArgEncoding encoding):
155   StrIntrinsicNode(control, char_array_mem, s1, s2, encoding) {};
156   virtual int Opcode() const;
bottom_type() const157   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
158 };
159 
160 //------------------------------HasNegatives---------------------------------
161 class HasNegativesNode: public StrIntrinsicNode {
162  public:
HasNegativesNode(Node * control,Node * char_array_mem,Node * s1,Node * c1)163   HasNegativesNode(Node* control, Node* char_array_mem, Node* s1, Node* c1):
164   StrIntrinsicNode(control, char_array_mem, s1, c1, none) {};
165   virtual int Opcode() const;
bottom_type() const166   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
167 };
168 
169 
170 //------------------------------EncodeISOArray--------------------------------
171 // encode char[] to byte[] in ISO_8859_1
172 class EncodeISOArrayNode: public Node {
173  public:
EncodeISOArrayNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)174   EncodeISOArrayNode(Node* control, Node* arymem, Node* s1, Node* s2, Node* c): Node(control, arymem, s1, s2, c) {};
175   virtual int Opcode() const;
depends_only_on_test() const176   virtual bool depends_only_on_test() const { return false; }
bottom_type() const177   virtual const Type* bottom_type() const { return TypeInt::INT; }
adr_type() const178   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
179   virtual uint match_edge(uint idx) const;
ideal_reg() const180   virtual uint ideal_reg() const { return Op_RegI; }
181   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
182   virtual const Type* Value(PhaseGVN* phase) const;
183 };
184 
185 //-------------------------------DigitNode----------------------------------------
186 class DigitNode : public Node {
187 public:
DigitNode(Node * control,Node * in1)188   DigitNode(Node* control, Node *in1) : Node(control, in1) {}
189   virtual int Opcode() const;
bottom_type() const190   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const191   virtual uint ideal_reg() const { return Op_RegI; }
192 };
193 
194 //------------------------------LowerCaseNode------------------------------------
195 class LowerCaseNode : public Node {
196 public:
LowerCaseNode(Node * control,Node * in1)197   LowerCaseNode(Node* control, Node *in1) : Node(control, in1) {}
198   virtual int Opcode() const;
bottom_type() const199   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const200   virtual uint ideal_reg() const { return Op_RegI; }
201 };
202 
203 //------------------------------UpperCaseNode------------------------------------
204 class UpperCaseNode : public Node {
205 public:
UpperCaseNode(Node * control,Node * in1)206   UpperCaseNode(Node* control, Node *in1) : Node(control, in1) {}
207   virtual int Opcode() const;
bottom_type() const208   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const209   virtual uint ideal_reg() const { return Op_RegI; }
210 };
211 
212 //------------------------------WhitespaceCode-----------------------------------
213 class WhitespaceNode : public Node {
214 public:
WhitespaceNode(Node * control,Node * in1)215   WhitespaceNode(Node* control, Node *in1) : Node(control, in1) {}
216   virtual int Opcode() const;
bottom_type() const217   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const218   virtual uint ideal_reg() const { return Op_RegI; }
219 };
220 
221 //------------------------------CopySign-----------------------------------------
222 class CopySignDNode : public Node {
223  protected:
CopySignDNode(Node * in1,Node * in2,Node * in3)224   CopySignDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
225  public:
226   static CopySignDNode* make(PhaseGVN& gvn, Node* in1, Node* in2);
227   virtual int Opcode() const;
bottom_type() const228   const Type* bottom_type() const { return TypeLong::DOUBLE; }
ideal_reg() const229   virtual uint ideal_reg() const { return Op_RegD; }
230 };
231 
232 class CopySignFNode : public Node {
233  public:
CopySignFNode(Node * in1,Node * in2)234   CopySignFNode(Node* in1, Node* in2) : Node(0, in1, in2) {}
235   virtual int Opcode() const;
bottom_type() const236   const Type* bottom_type() const { return TypeLong::FLOAT; }
ideal_reg() const237   virtual uint ideal_reg() const { return Op_RegF; }
238 };
239 
240 //------------------------------Signum-------------------------------------------
241 class SignumDNode : public Node {
242  protected:
SignumDNode(Node * in1,Node * in2,Node * in3)243   SignumDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
244  public:
245   static SignumDNode* make(PhaseGVN& gvn, Node* in);
246   virtual int Opcode() const;
bottom_type() const247   virtual const Type* bottom_type() const { return Type::DOUBLE; }
ideal_reg() const248   virtual uint ideal_reg() const { return Op_RegD; }
249 };
250 
251 class SignumFNode : public Node {
252  protected:
SignumFNode(Node * in1,Node * in2,Node * in3)253   SignumFNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
254  public:
255   static SignumFNode* make(PhaseGVN& gvn, Node* in);
256   virtual int Opcode() const;
bottom_type() const257   virtual const Type* bottom_type() const { return Type::FLOAT; }
ideal_reg() const258   virtual uint ideal_reg() const { return Op_RegF; }
259 };
260 
261 #endif // SHARE_OPTO_INTRINSICNODE_HPP
262