1 /*
2  * Copyright (c) 2015, 2019, 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 
31 
32 //----------------------PartialSubtypeCheckNode--------------------------------
33 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
34 // array for an instance of the superklass.  Set a hidden internal cache on a
35 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
36 // not zero for a miss or zero for a hit.
37 class PartialSubtypeCheckNode : public Node {
38  public:
PartialSubtypeCheckNode(Node * c,Node * sub,Node * super)39   PartialSubtypeCheckNode(Node* c, Node* sub, Node* super) : Node(c,sub,super) {}
40   virtual int Opcode() const;
bottom_type() const41   virtual const Type* bottom_type() const { return TypeRawPtr::BOTTOM; }
ideal_reg() const42   virtual uint ideal_reg() const { return Op_RegP; }
43 };
44 
45 //------------------------------StrIntrinsic-------------------------------
46 // Base class for Ideal nodes used in String intrinsic code.
47 class StrIntrinsicNode: public Node {
48  public:
49   // Possible encodings of the two parameters passed to the string intrinsic.
50   // 'L' stands for Latin1 and 'U' stands for UTF16. For example, 'LU' means that
51   // the first string is Latin1 encoded and the second string is UTF16 encoded.
52   typedef enum ArgEncoding { LL, LU, UL, UU, none } ArgEnc;
53 
54  protected:
55   // Encoding of strings. Used to select the right version of the intrinsic.
56   const ArgEncoding _encoding;
57   virtual uint size_of() const;
58 
59  public:
StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)60   StrIntrinsicNode(Node* control, Node* char_array_mem,
61                    Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
62   Node(control, char_array_mem, s1, c1, s2, c2), _encoding(encoding) {
63   }
64 
StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,Node * c,ArgEncoding encoding)65   StrIntrinsicNode(Node* control, Node* char_array_mem,
66                    Node* s1, Node* s2, Node* c, ArgEncoding encoding):
67   Node(control, char_array_mem, s1, s2, c), _encoding(encoding) {
68   }
69 
StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,ArgEncoding encoding)70   StrIntrinsicNode(Node* control, Node* char_array_mem,
71                    Node* s1, Node* s2, ArgEncoding encoding):
72   Node(control, char_array_mem, s1, s2), _encoding(encoding) {
73   }
74 
depends_only_on_test() const75   virtual bool depends_only_on_test() const { return false; }
adr_type() const76   virtual const TypePtr* adr_type() const { return TypeAryPtr::BYTES; }
77   virtual uint match_edge(uint idx) const;
ideal_reg() const78   virtual uint ideal_reg() const { return Op_RegI; }
79   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
80   virtual const Type* Value(PhaseGVN* phase) const;
encoding() const81   ArgEncoding encoding() const { return _encoding; }
82 };
83 
84 //------------------------------StrComp-------------------------------------
85 class StrCompNode: public StrIntrinsicNode {
86  public:
StrCompNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)87   StrCompNode(Node* control, Node* char_array_mem,
88               Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
89   StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
90   virtual int Opcode() const;
bottom_type() const91   virtual const Type* bottom_type() const { return TypeInt::INT; }
92 };
93 
94 //------------------------------StrEquals-------------------------------------
95 class StrEqualsNode: public StrIntrinsicNode {
96  public:
StrEqualsNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,Node * c,ArgEncoding encoding)97   StrEqualsNode(Node* control, Node* char_array_mem,
98                 Node* s1, Node* s2, Node* c, ArgEncoding encoding):
99   StrIntrinsicNode(control, char_array_mem, s1, s2, c, encoding) {};
100   virtual int Opcode() const;
bottom_type() const101   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
102 };
103 
104 //------------------------------StrIndexOf-------------------------------------
105 class StrIndexOfNode: public StrIntrinsicNode {
106  public:
StrIndexOfNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)107   StrIndexOfNode(Node* control, Node* char_array_mem,
108                  Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
109   StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
110   virtual int Opcode() const;
bottom_type() const111   virtual const Type* bottom_type() const { return TypeInt::INT; }
112 };
113 
114 //------------------------------StrIndexOfChar-------------------------------------
115 class StrIndexOfCharNode: public StrIntrinsicNode {
116  public:
StrIndexOfCharNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * c,ArgEncoding encoding)117   StrIndexOfCharNode(Node* control, Node* char_array_mem,
118                      Node* s1, Node* c1, Node* c, ArgEncoding encoding):
119   StrIntrinsicNode(control, char_array_mem, s1, c1, c, encoding) {};
120   virtual int Opcode() const;
bottom_type() const121   virtual const Type* bottom_type() const { return TypeInt::INT; }
122 };
123 
124 //--------------------------StrCompressedCopy-------------------------------
125 class StrCompressedCopyNode: public StrIntrinsicNode {
126  public:
StrCompressedCopyNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)127   StrCompressedCopyNode(Node* control, Node* arymem,
128                         Node* s1, Node* s2, Node* c):
129   StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
130   virtual int Opcode() const;
bottom_type() const131   virtual const Type* bottom_type() const { return TypeInt::INT; }
adr_type() const132   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
133   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
134 };
135 
136 //--------------------------StrInflatedCopy---------------------------------
137 class StrInflatedCopyNode: public StrIntrinsicNode {
138  public:
StrInflatedCopyNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)139   StrInflatedCopyNode(Node* control, Node* arymem,
140                       Node* s1, Node* s2, Node* c):
141   StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
142   virtual int Opcode() const;
bottom_type() const143   virtual const Type* bottom_type() const { return Type::MEMORY; }
adr_type() const144   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
145   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
146 };
147 
148 //------------------------------AryEq---------------------------------------
149 class AryEqNode: public StrIntrinsicNode {
150  public:
AryEqNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,ArgEncoding encoding)151   AryEqNode(Node* control, Node* char_array_mem,
152             Node* s1, Node* s2, ArgEncoding encoding):
153   StrIntrinsicNode(control, char_array_mem, s1, s2, encoding) {};
154   virtual int Opcode() const;
bottom_type() const155   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
156 };
157 
158 //------------------------------HasNegatives---------------------------------
159 class HasNegativesNode: public StrIntrinsicNode {
160  public:
HasNegativesNode(Node * control,Node * char_array_mem,Node * s1,Node * c1)161   HasNegativesNode(Node* control, Node* char_array_mem, Node* s1, Node* c1):
162   StrIntrinsicNode(control, char_array_mem, s1, c1, none) {};
163   virtual int Opcode() const;
bottom_type() const164   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
165 };
166 
167 
168 //------------------------------EncodeISOArray--------------------------------
169 // encode char[] to byte[] in ISO_8859_1
170 class EncodeISOArrayNode: public Node {
171  public:
EncodeISOArrayNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)172   EncodeISOArrayNode(Node* control, Node* arymem, Node* s1, Node* s2, Node* c): Node(control, arymem, s1, s2, c) {};
173   virtual int Opcode() const;
depends_only_on_test() const174   virtual bool depends_only_on_test() const { return false; }
bottom_type() const175   virtual const Type* bottom_type() const { return TypeInt::INT; }
adr_type() const176   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
177   virtual uint match_edge(uint idx) const;
ideal_reg() const178   virtual uint ideal_reg() const { return Op_RegI; }
179   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
180   virtual const Type* Value(PhaseGVN* phase) const;
181 };
182 
183 //-------------------------------DigitNode----------------------------------------
184 class DigitNode : public Node {
185 public:
DigitNode(Node * control,Node * in1)186   DigitNode(Node* control, Node *in1) : Node(control, in1) {}
187   virtual int Opcode() const;
bottom_type() const188   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const189   virtual uint ideal_reg() const { return Op_RegI; }
190 };
191 
192 //------------------------------LowerCaseNode------------------------------------
193 class LowerCaseNode : public Node {
194 public:
LowerCaseNode(Node * control,Node * in1)195   LowerCaseNode(Node* control, Node *in1) : Node(control, in1) {}
196   virtual int Opcode() const;
bottom_type() const197   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const198   virtual uint ideal_reg() const { return Op_RegI; }
199 };
200 
201 //------------------------------UpperCaseNode------------------------------------
202 class UpperCaseNode : public Node {
203 public:
UpperCaseNode(Node * control,Node * in1)204   UpperCaseNode(Node* control, Node *in1) : Node(control, in1) {}
205   virtual int Opcode() const;
bottom_type() const206   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const207   virtual uint ideal_reg() const { return Op_RegI; }
208 };
209 
210 //------------------------------WhitespaceCode-----------------------------------
211 class WhitespaceNode : public Node {
212 public:
WhitespaceNode(Node * control,Node * in1)213   WhitespaceNode(Node* control, Node *in1) : Node(control, in1) {}
214   virtual int Opcode() const;
bottom_type() const215   const Type* bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const216   virtual uint ideal_reg() const { return Op_RegI; }
217 };
218 
219 #endif // SHARE_OPTO_INTRINSICNODE_HPP
220