1 /*
   2  * Copyright (c) 2014, 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_MOVENODE_HPP
  26 #define SHARE_OPTO_MOVENODE_HPP
  27 
  28 #include "opto/node.hpp"
  29 
  30 //------------------------------CMoveNode--------------------------------------
  31 // Conditional move
  32 class CMoveNode : public TypeNode {
  33   public:
  34   enum { Control,               // When is it safe to do this cmove?
  35     Condition,             // Condition controlling the cmove
  36     IfFalse,               // Value if condition is false
  37     IfTrue };              // Value if condition is true
  38   CMoveNode( Node *bol, Node *left, Node *right, const Type *t ) : TypeNode(t,4)
  39   {
  40     init_class_id(Class_CMove);
  41     // all inputs are nullified in Node::Node(int)
  42     // init_req(Control,NULL);
  43     init_req(Condition,bol);
  44     init_req(IfFalse,left);
  45     init_req(IfTrue,right);
  46   }
  47   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  48   virtual const Type* Value(PhaseGVN* phase) const;
  49   virtual Node* Identity(PhaseGVN* phase);
  50   static CMoveNode *make(Node *c, Node *bol, Node *left, Node *right, const Type *t);
  51   // Helper function to spot cmove graph shapes
  52   static Node *is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b );
  53 };
  54 
  55 //------------------------------CMoveDNode-------------------------------------
  56 class CMoveDNode : public CMoveNode {
  57   public:
  58   CMoveDNode( Node *bol, Node *left, Node *right, const Type* t) : CMoveNode(bol,left,right,t){}
  59   virtual int Opcode() const;
  60   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  61 };
  62 
  63 //------------------------------CMoveFNode-------------------------------------
  64 class CMoveFNode : public CMoveNode {
  65   public:
  66   CMoveFNode( Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) {}
  67   virtual int Opcode() const;
  68   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  69 };
  70 
  71 //------------------------------CMoveINode-------------------------------------
  72 class CMoveINode : public CMoveNode {
  73   public:
  74   CMoveINode( Node *bol, Node *left, Node *right, const TypeInt *ti ) : CMoveNode(bol,left,right,ti){}
  75   virtual int Opcode() const;
  76   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  77 };
  78 
  79 //------------------------------CMoveLNode-------------------------------------
  80 class CMoveLNode : public CMoveNode {
  81   public:
  82   CMoveLNode(Node *bol, Node *left, Node *right, const TypeLong *tl ) : CMoveNode(bol,left,right,tl){}
  83   virtual int Opcode() const;
  84 };
  85 
  86 //------------------------------CMovePNode-------------------------------------
  87 class CMovePNode : public CMoveNode {
  88   public:
  89   CMovePNode( Node *c, Node *bol, Node *left, Node *right, const TypePtr* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); }
  90   virtual int Opcode() const;
  91 };
  92 
  93 //------------------------------CMoveNNode-------------------------------------
  94 class CMoveNNode : public CMoveNode {
  95   public:
  96   CMoveNNode( Node *c, Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); }
  97   virtual int Opcode() const;
  98 };
  99 
 100 //
 101 class MoveI2FNode : public Node {
 102   public:
 103   MoveI2FNode( Node *value ) : Node(0,value) {}
 104   virtual int Opcode() const;
 105   virtual const Type *bottom_type() const { return Type::FLOAT; }
 106   virtual uint ideal_reg() const { return Op_RegF; }
 107   virtual const Type* Value(PhaseGVN* phase) const;
 108 };
 109 
 110 class MoveL2DNode : public Node {
 111   public:
 112   MoveL2DNode( Node *value ) : Node(0,value) {}
 113   virtual int Opcode() const;
 114   virtual const Type *bottom_type() const { return Type::DOUBLE; }
 115   virtual uint ideal_reg() const { return Op_RegD; }
 116   virtual const Type* Value(PhaseGVN* phase) const;
 117 };
 118 
 119 class MoveF2INode : public Node {
 120   public:
 121   MoveF2INode( Node *value ) : Node(0,value) {}
 122   virtual int Opcode() const;
 123   virtual const Type *bottom_type() const { return TypeInt::INT; }
 124   virtual uint ideal_reg() const { return Op_RegI; }
 125   virtual const Type* Value(PhaseGVN* phase) const;
 126 };
 127 
 128 class MoveD2LNode : public Node {
 129   public:
 130   MoveD2LNode( Node *value ) : Node(0,value) {}
 131   virtual int Opcode() const;
 132   virtual const Type *bottom_type() const { return TypeLong::LONG; }
 133   virtual uint ideal_reg() const { return Op_RegL; }
 134   virtual const Type* Value(PhaseGVN* phase) const;
 135 };
 136 
 137 //------------------------------BinaryNode-------------------------------------
 138 // Place holder for the 2 conditional inputs to a CMove.  CMove needs 4
 139 // inputs: the Bool (for the lt/gt/eq/ne bits), the flags (result of some
 140 // compare), and the 2 values to select between.  The Matcher requires a
 141 // binary tree so we break it down like this:
 142 //     (CMove (Binary bol cmp) (Binary src1 src2))
 143 class BinaryNode : public Node {
 144   public:
 145   BinaryNode( Node *n1, Node *n2 ) : Node(0,n1,n2) { }
 146   virtual int Opcode() const;
 147   virtual uint ideal_reg() const { return 0; }
 148 
 149 #ifndef PRODUCT
 150   virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
 151 #endif
 152 };
 153 
 154 
 155 #endif // SHARE_OPTO_MOVENODE_HPP