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:
 40   PartialSubtypeCheckNode(Node* c, Node* sub, Node* super) : Node(c,sub,super) {}
 41   virtual int Opcode() const;
 42   virtual const Type* bottom_type() const { return TypeRawPtr::BOTTOM; }
 43   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:
 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 
 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 
 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 
 77   virtual bool depends_only_on_test() const { return false; }
 78   virtual const TypePtr* adr_type() const { return TypeAryPtr::BYTES; }
 79   virtual uint match_edge(uint idx) const;
 80   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;
 83   ArgEncoding encoding() const { return _encoding; }
 84 };
 85 
 86 //------------------------------StrComp-------------------------------------
 87 class StrCompNode: public StrIntrinsicNode {
 88  public:
 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;
 93   virtual const Type* bottom_type() const { return TypeInt::INT; }
 94 };
 95 
 96 //------------------------------StrEquals-------------------------------------
 97 class StrEqualsNode: public StrIntrinsicNode {
 98  public:
 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;
103   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
104 };
105 
106 //------------------------------StrIndexOf-------------------------------------
107 class StrIndexOfNode: public StrIntrinsicNode {
108  public:
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;
113   virtual const Type* bottom_type() const { return TypeInt::INT; }
114 };
115 
116 //------------------------------StrIndexOfChar-------------------------------------
117 class StrIndexOfCharNode: public StrIntrinsicNode {
118  public:
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;
123   virtual const Type* bottom_type() const { return TypeInt::INT; }
124 };
125 
126 //--------------------------StrCompressedCopy-------------------------------
127 class StrCompressedCopyNode: public StrIntrinsicNode {
128  public:
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;
133   virtual const Type* bottom_type() const { return TypeInt::INT; }
134   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:
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;
145   virtual const Type* bottom_type() const { return Type::MEMORY; }
146   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:
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;
157   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
158 };
159 
160 //------------------------------HasNegatives---------------------------------
161 class HasNegativesNode: public StrIntrinsicNode {
162  public:
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;
166   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
167 };
168 
169 //------------------------------EncodeISOArray--------------------------------
170 // encode char[] to byte[] in ISO_8859_1 or ASCII
171 class EncodeISOArrayNode: public Node {
172   bool ascii;
173  public:
174   EncodeISOArrayNode(Node* control, Node* arymem, Node* s1, Node* s2, Node* c, bool ascii)
175     : Node(control, arymem, s1, s2, c), ascii(ascii) {}
176 
177   bool is_ascii() { return ascii; }
178   virtual int Opcode() const;
179   virtual bool depends_only_on_test() const { return false; }
180   virtual const Type* bottom_type() const { return TypeInt::INT; }
181   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
182   virtual uint match_edge(uint idx) const;
183   virtual uint ideal_reg() const { return Op_RegI; }
184   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
185   virtual const Type* Value(PhaseGVN* phase) const;
186 };
187 
188 //-------------------------------DigitNode----------------------------------------
189 class DigitNode : public Node {
190 public:
191   DigitNode(Node* control, Node *in1) : Node(control, in1) {}
192   virtual int Opcode() const;
193   const Type* bottom_type() const { return TypeInt::BOOL; }
194   virtual uint ideal_reg() const { return Op_RegI; }
195 };
196 
197 //------------------------------LowerCaseNode------------------------------------
198 class LowerCaseNode : public Node {
199 public:
200   LowerCaseNode(Node* control, Node *in1) : Node(control, in1) {}
201   virtual int Opcode() const;
202   const Type* bottom_type() const { return TypeInt::BOOL; }
203   virtual uint ideal_reg() const { return Op_RegI; }
204 };
205 
206 //------------------------------UpperCaseNode------------------------------------
207 class UpperCaseNode : public Node {
208 public:
209   UpperCaseNode(Node* control, Node *in1) : Node(control, in1) {}
210   virtual int Opcode() const;
211   const Type* bottom_type() const { return TypeInt::BOOL; }
212   virtual uint ideal_reg() const { return Op_RegI; }
213 };
214 
215 //------------------------------WhitespaceCode-----------------------------------
216 class WhitespaceNode : public Node {
217 public:
218   WhitespaceNode(Node* control, Node *in1) : Node(control, in1) {}
219   virtual int Opcode() const;
220   const Type* bottom_type() const { return TypeInt::BOOL; }
221   virtual uint ideal_reg() const { return Op_RegI; }
222 };
223 
224 //------------------------------CopySign-----------------------------------------
225 class CopySignDNode : public Node {
226  protected:
227   CopySignDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
228  public:
229   static CopySignDNode* make(PhaseGVN& gvn, Node* in1, Node* in2);
230   virtual int Opcode() const;
231   const Type* bottom_type() const { return TypeLong::DOUBLE; }
232   virtual uint ideal_reg() const { return Op_RegD; }
233 };
234 
235 class CopySignFNode : public Node {
236  public:
237   CopySignFNode(Node* in1, Node* in2) : Node(0, in1, in2) {}
238   virtual int Opcode() const;
239   const Type* bottom_type() const { return TypeLong::FLOAT; }
240   virtual uint ideal_reg() const { return Op_RegF; }
241 };
242 
243 //------------------------------Signum-------------------------------------------
244 class SignumDNode : public Node {
245  protected:
246   SignumDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
247  public:
248   static SignumDNode* make(PhaseGVN& gvn, Node* in);
249   virtual int Opcode() const;
250   virtual const Type* bottom_type() const { return Type::DOUBLE; }
251   virtual uint ideal_reg() const { return Op_RegD; }
252 };
253 
254 class SignumFNode : public Node {
255  protected:
256   SignumFNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
257  public:
258   static SignumFNode* make(PhaseGVN& gvn, Node* in);
259   virtual int Opcode() const;
260   virtual const Type* bottom_type() const { return Type::FLOAT; }
261   virtual uint ideal_reg() const { return Op_RegF; }
262 };
263 
264 #endif // SHARE_OPTO_INTRINSICNODE_HPP