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_VM_OPTO_INTRINSICNODE_HPP
  26 #define SHARE_VM_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 two 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   typedef enum ArgEncoding { LL, LU, UL, UU, none } ArgEnc;
  54 
  55  protected:
  56   // Encoding of strings. Used to select the right version of the intrinsic.
  57   const ArgEncoding _encoding;
  58   virtual uint size_of() const;
  59 
  60  public:
  61   StrIntrinsicNode(Node* control, Node* char_array_mem,
  62                    Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
  63   Node(control, char_array_mem, s1, c1, s2, c2), _encoding(encoding) {
  64   }
  65 
  66   StrIntrinsicNode(Node* control, Node* char_array_mem,
  67                    Node* s1, Node* s2, Node* c, ArgEncoding encoding):
  68   Node(control, char_array_mem, s1, s2, c), _encoding(encoding) {
  69   }
  70 
  71   StrIntrinsicNode(Node* control, Node* char_array_mem,
  72                    Node* s1, Node* s2, ArgEncoding encoding):
  73   Node(control, char_array_mem, s1, s2), _encoding(encoding) {
  74   }
  75 
  76   virtual bool depends_only_on_test() const { return false; }
  77   virtual const TypePtr* adr_type() const { return TypeAryPtr::BYTES; }
  78   virtual uint match_edge(uint idx) const;
  79   virtual uint ideal_reg() const { return Op_RegI; }
  80   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
  81   virtual const Type* Value(PhaseGVN* phase) const;
  82   ArgEncoding encoding() const { return _encoding; }
  83 };
  84 
  85 //------------------------------StrComp-------------------------------------
  86 class StrCompNode: public StrIntrinsicNode {
  87  public:
  88   StrCompNode(Node* control, Node* char_array_mem,
  89               Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
  90   StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
  91   virtual int Opcode() const;
  92   virtual const Type* bottom_type() const { return TypeInt::INT; }
  93 };
  94 
  95 //------------------------------StrEquals-------------------------------------
  96 class StrEqualsNode: public StrIntrinsicNode {
  97  public:
  98   StrEqualsNode(Node* control, Node* char_array_mem,
  99                 Node* s1, Node* s2, Node* c, ArgEncoding encoding):
 100   StrIntrinsicNode(control, char_array_mem, s1, s2, c, encoding) {};
 101   virtual int Opcode() const;
 102   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
 103 };
 104 
 105 //------------------------------StrIndexOf-------------------------------------
 106 class StrIndexOfNode: public StrIntrinsicNode {
 107  public:
 108   StrIndexOfNode(Node* control, Node* char_array_mem,
 109                  Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
 110   StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
 111   virtual int Opcode() const;
 112   virtual const Type* bottom_type() const { return TypeInt::INT; }
 113 };
 114 
 115 //------------------------------StrIndexOfChar-------------------------------------
 116 class StrIndexOfCharNode: public StrIntrinsicNode {
 117  public:
 118   StrIndexOfCharNode(Node* control, Node* char_array_mem,
 119                      Node* s1, Node* c1, Node* c, ArgEncoding encoding):
 120   StrIntrinsicNode(control, char_array_mem, s1, c1, c, encoding) {};
 121   virtual int Opcode() const;
 122   virtual const Type* bottom_type() const { return TypeInt::INT; }
 123 };
 124 
 125 //--------------------------StrCompressedCopy-------------------------------
 126 class StrCompressedCopyNode: public StrIntrinsicNode {
 127  public:
 128   StrCompressedCopyNode(Node* control, Node* arymem,
 129                         Node* s1, Node* s2, Node* c):
 130   StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
 131   virtual int Opcode() const;
 132   virtual const Type* bottom_type() const { return TypeInt::INT; }
 133   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
 134   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
 135 };
 136 
 137 //--------------------------StrInflatedCopy---------------------------------
 138 class StrInflatedCopyNode: public StrIntrinsicNode {
 139  public:
 140   StrInflatedCopyNode(Node* control, Node* arymem,
 141                       Node* s1, Node* s2, Node* c):
 142   StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
 143   virtual int Opcode() const;
 144   virtual const Type* bottom_type() const { return Type::MEMORY; }
 145   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
 146   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
 147 };
 148 
 149 //------------------------------AryEq---------------------------------------
 150 class AryEqNode: public StrIntrinsicNode {
 151  public:
 152   AryEqNode(Node* control, Node* char_array_mem,
 153             Node* s1, Node* s2, ArgEncoding encoding):
 154   StrIntrinsicNode(control, char_array_mem, s1, s2, encoding) {};
 155   virtual int Opcode() const;
 156   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
 157 };
 158 
 159 //------------------------------HasNegatives---------------------------------
 160 class HasNegativesNode: public StrIntrinsicNode {
 161  public:
 162   HasNegativesNode(Node* control, Node* char_array_mem, Node* s1, Node* c1):
 163   StrIntrinsicNode(control, char_array_mem, s1, c1, none) {};
 164   virtual int Opcode() const;
 165   virtual const Type* bottom_type() const { return TypeInt::BOOL; }
 166 };
 167 
 168 
 169 //------------------------------EncodeISOArray--------------------------------
 170 // encode char[] to byte[] in ISO_8859_1
 171 class EncodeISOArrayNode: public Node {
 172  public:
 173   EncodeISOArrayNode(Node* control, Node* arymem, Node* s1, Node* s2, Node* c): Node(control, arymem, s1, s2, c) {};
 174   virtual int Opcode() const;
 175   virtual bool depends_only_on_test() const { return false; }
 176   virtual const Type* bottom_type() const { return TypeInt::INT; }
 177   virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
 178   virtual uint match_edge(uint idx) const;
 179   virtual uint ideal_reg() const { return Op_RegI; }
 180   virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
 181   virtual const Type* Value(PhaseGVN* phase) const;
 182 };
 183 
 184 //-------------------------------DigitNode----------------------------------------
 185 class DigitNode : public Node {
 186 public:
 187   DigitNode(Node* control, Node *in1) : Node(control, in1) {}
 188   virtual int Opcode() const;
 189   const Type* bottom_type() const { return TypeInt::BOOL; }
 190   virtual uint ideal_reg() const { return Op_RegI; }
 191 };
 192 
 193 //------------------------------LowerCaseNode------------------------------------
 194 class LowerCaseNode : public Node {
 195 public:
 196   LowerCaseNode(Node* control, Node *in1) : Node(control, in1) {}
 197   virtual int Opcode() const;
 198   const Type* bottom_type() const { return TypeInt::BOOL; }
 199   virtual uint ideal_reg() const { return Op_RegI; }
 200 };
 201 
 202 //------------------------------UpperCaseNode------------------------------------
 203 class UpperCaseNode : public Node {
 204 public:
 205   UpperCaseNode(Node* control, Node *in1) : Node(control, in1) {}
 206   virtual int Opcode() const;
 207   const Type* bottom_type() const { return TypeInt::BOOL; }
 208   virtual uint ideal_reg() const { return Op_RegI; }
 209 };
 210 
 211 //------------------------------WhitespaceCode-----------------------------------
 212 class WhitespaceNode : public Node {
 213 public:
 214   WhitespaceNode(Node* control, Node *in1) : Node(control, in1) {}
 215   virtual int Opcode() const;
 216   const Type* bottom_type() const { return TypeInt::BOOL; }
 217   virtual uint ideal_reg() const { return Op_RegI; }
 218 };
 219 
 220 //------------------------------CopySign-----------------------------------------
 221 class CopySignDNode : public Node {
 222  protected:
 223   CopySignDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
 224  public:
 225   static CopySignDNode* make(PhaseGVN& gvn, Node* in1, Node* in2);
 226   virtual int Opcode() const;
 227   const Type* bottom_type() const { return TypeLong::DOUBLE; }
 228   virtual uint ideal_reg() const { return Op_RegD; }
 229 };
 230 
 231 class CopySignFNode : public Node {
 232  public:
 233   CopySignFNode(Node* in1, Node* in2) : Node(0, in1, in2) {}
 234   virtual int Opcode() const;
 235   const Type* bottom_type() const { return TypeLong::FLOAT; }
 236   virtual uint ideal_reg() const { return Op_RegF; }
 237 };
 238 
 239 //------------------------------Signum-------------------------------------------
 240 class SignumDNode : public Node {
 241  protected:
 242   SignumDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
 243  public:
 244   static SignumDNode* make(PhaseGVN& gvn, Node* in);
 245   virtual int Opcode() const;
 246   virtual const Type* bottom_type() const { return Type::DOUBLE; }
 247   virtual uint ideal_reg() const { return Op_RegD; }
 248 };
 249 
 250 class SignumFNode : public Node {
 251  protected:
 252   SignumFNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {}
 253  public:
 254   static SignumFNode* make(PhaseGVN& gvn, Node* in);
 255   virtual int Opcode() const;
 256   virtual const Type* bottom_type() const { return Type::FLOAT; }
 257   virtual uint ideal_reg() const { return Op_RegF; }
 258 };
 259 
 260 #endif // SHARE_VM_OPTO_INTRINSICNODE_HPP