duke@435: /* xdono@631: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: // Portions of code courtesy of Clifford Click duke@435: duke@435: class PhaseTransform; duke@435: duke@435: //------------------------------MulNode---------------------------------------- duke@435: // Classic MULTIPLY functionality. This covers all the usual 'multiply' duke@435: // behaviors for an algebraic ring. Multiply-integer, multiply-float, duke@435: // multiply-double, and binary-and are all inherited from this class. The duke@435: // various identity values are supplied by virtual functions. duke@435: class MulNode : public Node { duke@435: virtual uint hash() const; duke@435: public: duke@435: MulNode( Node *in1, Node *in2 ): Node(0,in1,in2) { duke@435: init_class_id(Class_Mul); duke@435: } duke@435: duke@435: // Handle algebraic identities here. If we have an identity, return the Node duke@435: // we are equivalent to. We look for "add of zero" as an identity. duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: duke@435: // We also canonicalize the Node, moving constants to the right input, duke@435: // and flatten expressions (so that 1+x+2 becomes x+3). duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: duke@435: // Compute a new Type for this node. Basically we just do the pre-check, duke@435: // then call the virtual add() to set the type. duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: duke@435: // Supplied function returns the product of the inputs. duke@435: // This also type-checks the inputs for sanity. Guaranteed never to duke@435: // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. duke@435: // This call recognizes the multiplicative zero type. duke@435: virtual const Type *mul_ring( const Type *, const Type * ) const = 0; duke@435: duke@435: // Supplied function to return the multiplicative identity type duke@435: virtual const Type *mul_id() const = 0; duke@435: duke@435: // Supplied function to return the additive identity type duke@435: virtual const Type *add_id() const = 0; duke@435: duke@435: // Supplied function to return the additive opcode duke@435: virtual int add_opcode() const = 0; duke@435: duke@435: // Supplied function to return the multiplicative opcode duke@435: virtual int mul_opcode() const = 0; duke@435: duke@435: }; duke@435: duke@435: //------------------------------MulINode--------------------------------------- duke@435: // Multiply 2 integers duke@435: class MulINode : public MulNode { duke@435: public: duke@435: MulINode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *mul_ring( const Type *, const Type * ) const; duke@435: const Type *mul_id() const { return TypeInt::ONE; } duke@435: const Type *add_id() const { return TypeInt::ZERO; } duke@435: int add_opcode() const { return Op_AddI; } duke@435: int mul_opcode() const { return Op_MulI; } duke@435: const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------MulLNode--------------------------------------- duke@435: // Multiply 2 longs duke@435: class MulLNode : public MulNode { duke@435: public: duke@435: MulLNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *mul_ring( const Type *, const Type * ) const; duke@435: const Type *mul_id() const { return TypeLong::ONE; } duke@435: const Type *add_id() const { return TypeLong::ZERO; } duke@435: int add_opcode() const { return Op_AddL; } duke@435: int mul_opcode() const { return Op_MulL; } duke@435: const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: duke@435: //------------------------------MulFNode--------------------------------------- duke@435: // Multiply 2 floats duke@435: class MulFNode : public MulNode { duke@435: public: duke@435: MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *mul_ring( const Type *, const Type * ) const; duke@435: const Type *mul_id() const { return TypeF::ONE; } duke@435: const Type *add_id() const { return TypeF::ZERO; } duke@435: int add_opcode() const { return Op_AddF; } duke@435: int mul_opcode() const { return Op_MulF; } duke@435: const Type *bottom_type() const { return Type::FLOAT; } duke@435: virtual uint ideal_reg() const { return Op_RegF; } duke@435: }; duke@435: duke@435: //------------------------------MulDNode--------------------------------------- duke@435: // Multiply 2 doubles duke@435: class MulDNode : public MulNode { duke@435: public: duke@435: MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *mul_ring( const Type *, const Type * ) const; duke@435: const Type *mul_id() const { return TypeD::ONE; } duke@435: const Type *add_id() const { return TypeD::ZERO; } duke@435: int add_opcode() const { return Op_AddD; } duke@435: int mul_opcode() const { return Op_MulD; } duke@435: const Type *bottom_type() const { return Type::DOUBLE; } duke@435: virtual uint ideal_reg() const { return Op_RegD; } duke@435: }; duke@435: rasbold@580: //-------------------------------MulHiLNode------------------------------------ rasbold@580: // Upper 64 bits of a 64 bit by 64 bit multiply rasbold@580: class MulHiLNode : public Node { rasbold@580: public: rasbold@580: MulHiLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} rasbold@580: virtual int Opcode() const; rasbold@580: virtual const Type *Value( PhaseTransform *phase ) const; rasbold@580: const Type *bottom_type() const { return TypeLong::LONG; } rasbold@580: virtual uint ideal_reg() const { return Op_RegL; } rasbold@580: }; duke@435: duke@435: //------------------------------AndINode--------------------------------------- duke@435: // Logically AND 2 integers. Included with the MUL nodes because it inherits duke@435: // all the behavior of multiplication on a ring. duke@435: class AndINode : public MulINode { duke@435: public: duke@435: AndINode( Node *in1, Node *in2 ) : MulINode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *mul_ring( const Type *, const Type * ) const; duke@435: const Type *mul_id() const { return TypeInt::MINUS_1; } duke@435: const Type *add_id() const { return TypeInt::ZERO; } duke@435: int add_opcode() const { return Op_OrI; } duke@435: int mul_opcode() const { return Op_AndI; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------AndINode--------------------------------------- duke@435: // Logically AND 2 longs. Included with the MUL nodes because it inherits duke@435: // all the behavior of multiplication on a ring. duke@435: class AndLNode : public MulLNode { duke@435: public: duke@435: AndLNode( Node *in1, Node *in2 ) : MulLNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *mul_ring( const Type *, const Type * ) const; duke@435: const Type *mul_id() const { return TypeLong::MINUS_1; } duke@435: const Type *add_id() const { return TypeLong::ZERO; } duke@435: int add_opcode() const { return Op_OrL; } duke@435: int mul_opcode() const { return Op_AndL; } duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: //------------------------------LShiftINode------------------------------------ duke@435: // Logical shift left duke@435: class LShiftINode : public Node { duke@435: public: duke@435: LShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------LShiftLNode------------------------------------ duke@435: // Logical shift left duke@435: class LShiftLNode : public Node { duke@435: public: duke@435: LShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: //------------------------------RShiftINode------------------------------------ duke@435: // Signed shift right duke@435: class RShiftINode : public Node { duke@435: public: duke@435: RShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------RShiftLNode------------------------------------ duke@435: // Signed shift right duke@435: class RShiftLNode : public Node { duke@435: public: duke@435: RShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: duke@435: //------------------------------URShiftINode----------------------------------- duke@435: // Logical shift right duke@435: class URShiftINode : public Node { duke@435: public: duke@435: URShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------URShiftLNode----------------------------------- duke@435: // Logical shift right duke@435: class URShiftLNode : public Node { duke@435: public: duke@435: URShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: };