1 /* 2 * Copyright (c) 1997, 2013, 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_SUBNODE_HPP 26 #define SHARE_VM_OPTO_SUBNODE_HPP 27 28 #include "opto/node.hpp" 29 #include "opto/opcodes.hpp" 30 #include "opto/type.hpp" 31 32 // Portions of code courtesy of Clifford Click 33 34 //------------------------------SUBNode---------------------------------------- 35 // Class SUBTRACTION functionality. This covers all the usual 'subtract' 36 // behaviors. Subtract-integer, -float, -double, binary xor, compare-integer, 37 // -float, and -double are all inherited from this class. The compare 38 // functions behave like subtract functions, except that all negative answers 39 // are compressed into -1, and all positive answers compressed to 1. 40 class SubNode : public Node { 41 public: SubNode(Node * in1,Node * in2)42 SubNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { 43 init_class_id(Class_Sub); 44 } 45 46 // Handle algebraic identities here. If we have an identity, return the Node 47 // we are equivalent to. We look for "add of zero" as an identity. 48 virtual Node *Identity( PhaseTransform *phase ); 49 50 // Compute a new Type for this node. Basically we just do the pre-check, 51 // then call the virtual add() to set the type. 52 virtual const Type *Value( PhaseTransform *phase ) const; 53 const Type* Value_common( PhaseTransform *phase ) const; 54 55 // Supplied function returns the subtractend of the inputs. 56 // This also type-checks the inputs for sanity. Guaranteed never to 57 // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. 58 virtual const Type *sub( const Type *, const Type * ) const = 0; 59 60 // Supplied function to return the additive identity type. 61 // This is returned whenever the subtracts inputs are the same. 62 virtual const Type *add_id() const = 0; 63 64 }; 65 66 67 // NOTE: SubINode should be taken away and replaced by add and negate 68 //------------------------------SubINode--------------------------------------- 69 // Subtract 2 integers 70 class SubINode : public SubNode { 71 public: SubINode(Node * in1,Node * in2)72 SubINode( Node *in1, Node *in2 ) : SubNode(in1,in2) {} 73 virtual int Opcode() const; 74 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 75 virtual const Type *sub( const Type *, const Type * ) const; add_id() const76 const Type *add_id() const { return TypeInt::ZERO; } bottom_type() const77 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const78 virtual uint ideal_reg() const { return Op_RegI; } 79 }; 80 81 //------------------------------SubLNode--------------------------------------- 82 // Subtract 2 integers 83 class SubLNode : public SubNode { 84 public: SubLNode(Node * in1,Node * in2)85 SubLNode( Node *in1, Node *in2 ) : SubNode(in1,in2) {} 86 virtual int Opcode() const; 87 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 88 virtual const Type *sub( const Type *, const Type * ) const; add_id() const89 const Type *add_id() const { return TypeLong::ZERO; } bottom_type() const90 const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const91 virtual uint ideal_reg() const { return Op_RegL; } 92 }; 93 94 // NOTE: SubFPNode should be taken away and replaced by add and negate 95 //------------------------------SubFPNode-------------------------------------- 96 // Subtract 2 floats or doubles 97 class SubFPNode : public SubNode { 98 protected: SubFPNode(Node * in1,Node * in2)99 SubFPNode( Node *in1, Node *in2 ) : SubNode(in1,in2) {} 100 public: 101 const Type *Value( PhaseTransform *phase ) const; 102 }; 103 104 // NOTE: SubFNode should be taken away and replaced by add and negate 105 //------------------------------SubFNode--------------------------------------- 106 // Subtract 2 doubles 107 class SubFNode : public SubFPNode { 108 public: SubFNode(Node * in1,Node * in2)109 SubFNode( Node *in1, Node *in2 ) : SubFPNode(in1,in2) {} 110 virtual int Opcode() const; 111 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 112 virtual const Type *sub( const Type *, const Type * ) const; add_id() const113 const Type *add_id() const { return TypeF::ZERO; } bottom_type() const114 const Type *bottom_type() const { return Type::FLOAT; } ideal_reg() const115 virtual uint ideal_reg() const { return Op_RegF; } 116 }; 117 118 // NOTE: SubDNode should be taken away and replaced by add and negate 119 //------------------------------SubDNode--------------------------------------- 120 // Subtract 2 doubles 121 class SubDNode : public SubFPNode { 122 public: SubDNode(Node * in1,Node * in2)123 SubDNode( Node *in1, Node *in2 ) : SubFPNode(in1,in2) {} 124 virtual int Opcode() const; 125 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 126 virtual const Type *sub( const Type *, const Type * ) const; add_id() const127 const Type *add_id() const { return TypeD::ZERO; } bottom_type() const128 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const129 virtual uint ideal_reg() const { return Op_RegD; } 130 }; 131 132 //------------------------------CmpNode--------------------------------------- 133 // Compare 2 values, returning condition codes (-1, 0 or 1). 134 class CmpNode : public SubNode { 135 public: CmpNode(Node * in1,Node * in2)136 CmpNode( Node *in1, Node *in2 ) : SubNode(in1,in2) { 137 init_class_id(Class_Cmp); 138 } 139 virtual Node *Identity( PhaseTransform *phase ); add_id() const140 const Type *add_id() const { return TypeInt::ZERO; } bottom_type() const141 const Type *bottom_type() const { return TypeInt::CC; } ideal_reg() const142 virtual uint ideal_reg() const { return Op_RegFlags; } 143 }; 144 145 //------------------------------CmpINode--------------------------------------- 146 // Compare 2 signed values, returning condition codes (-1, 0 or 1). 147 class CmpINode : public CmpNode { 148 public: CmpINode(Node * in1,Node * in2)149 CmpINode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} 150 virtual int Opcode() const; 151 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 152 virtual const Type *sub( const Type *, const Type * ) const; 153 }; 154 155 //------------------------------CmpUNode--------------------------------------- 156 // Compare 2 unsigned values (integer or pointer), returning condition codes (-1, 0 or 1). 157 class CmpUNode : public CmpNode { 158 public: CmpUNode(Node * in1,Node * in2)159 CmpUNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} 160 virtual int Opcode() const; 161 virtual const Type *sub( const Type *, const Type * ) const; 162 const Type *Value( PhaseTransform *phase ) const; 163 bool is_index_range_check() const; 164 }; 165 166 //------------------------------CmpPNode--------------------------------------- 167 // Compare 2 pointer values, returning condition codes (-1, 0 or 1). 168 class CmpPNode : public CmpNode { 169 public: CmpPNode(Node * in1,Node * in2)170 CmpPNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} 171 virtual int Opcode() const; 172 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 173 virtual const Type *sub( const Type *, const Type * ) const; 174 }; 175 176 //------------------------------CmpNNode-------------------------------------- 177 // Compare 2 narrow oop values, returning condition codes (-1, 0 or 1). 178 class CmpNNode : public CmpNode { 179 public: CmpNNode(Node * in1,Node * in2)180 CmpNNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} 181 virtual int Opcode() const; 182 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 183 virtual const Type *sub( const Type *, const Type * ) const; 184 }; 185 186 //------------------------------CmpLNode--------------------------------------- 187 // Compare 2 long values, returning condition codes (-1, 0 or 1). 188 class CmpLNode : public CmpNode { 189 public: CmpLNode(Node * in1,Node * in2)190 CmpLNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} 191 virtual int Opcode() const; 192 virtual const Type *sub( const Type *, const Type * ) const; 193 }; 194 195 //------------------------------CmpULNode--------------------------------------- 196 // Compare 2 unsigned long values, returning condition codes (-1, 0 or 1). 197 class CmpULNode : public CmpNode { 198 public: CmpULNode(Node * in1,Node * in2)199 CmpULNode(Node* in1, Node* in2) : CmpNode(in1, in2) { } 200 virtual int Opcode() const; 201 virtual const Type* sub(const Type*, const Type*) const; 202 }; 203 204 //------------------------------CmpL3Node-------------------------------------- 205 // Compare 2 long values, returning integer value (-1, 0 or 1). 206 class CmpL3Node : public CmpLNode { 207 public: CmpL3Node(Node * in1,Node * in2)208 CmpL3Node( Node *in1, Node *in2 ) : CmpLNode(in1,in2) { 209 // Since it is not consumed by Bools, it is not really a Cmp. 210 init_class_id(Class_Sub); 211 } 212 virtual int Opcode() const; ideal_reg() const213 virtual uint ideal_reg() const { return Op_RegI; } 214 }; 215 216 //------------------------------CmpFNode--------------------------------------- 217 // Compare 2 float values, returning condition codes (-1, 0 or 1). 218 // This implements the Java bytecode fcmpl, so unordered returns -1. 219 // Operands may not commute. 220 class CmpFNode : public CmpNode { 221 public: CmpFNode(Node * in1,Node * in2)222 CmpFNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} 223 virtual int Opcode() const; sub(const Type *,const Type *) const224 virtual const Type *sub( const Type *, const Type * ) const { ShouldNotReachHere(); return NULL; } 225 const Type *Value( PhaseTransform *phase ) const; 226 }; 227 228 //------------------------------CmpF3Node-------------------------------------- 229 // Compare 2 float values, returning integer value (-1, 0 or 1). 230 // This implements the Java bytecode fcmpl, so unordered returns -1. 231 // Operands may not commute. 232 class CmpF3Node : public CmpFNode { 233 public: CmpF3Node(Node * in1,Node * in2)234 CmpF3Node( Node *in1, Node *in2 ) : CmpFNode(in1,in2) { 235 // Since it is not consumed by Bools, it is not really a Cmp. 236 init_class_id(Class_Sub); 237 } 238 virtual int Opcode() const; 239 // Since it is not consumed by Bools, it is not really a Cmp. ideal_reg() const240 virtual uint ideal_reg() const { return Op_RegI; } 241 }; 242 243 244 //------------------------------CmpDNode--------------------------------------- 245 // Compare 2 double values, returning condition codes (-1, 0 or 1). 246 // This implements the Java bytecode dcmpl, so unordered returns -1. 247 // Operands may not commute. 248 class CmpDNode : public CmpNode { 249 public: CmpDNode(Node * in1,Node * in2)250 CmpDNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} 251 virtual int Opcode() const; sub(const Type *,const Type *) const252 virtual const Type *sub( const Type *, const Type * ) const { ShouldNotReachHere(); return NULL; } 253 const Type *Value( PhaseTransform *phase ) const; 254 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 255 }; 256 257 //------------------------------CmpD3Node-------------------------------------- 258 // Compare 2 double values, returning integer value (-1, 0 or 1). 259 // This implements the Java bytecode dcmpl, so unordered returns -1. 260 // Operands may not commute. 261 class CmpD3Node : public CmpDNode { 262 public: CmpD3Node(Node * in1,Node * in2)263 CmpD3Node( Node *in1, Node *in2 ) : CmpDNode(in1,in2) { 264 // Since it is not consumed by Bools, it is not really a Cmp. 265 init_class_id(Class_Sub); 266 } 267 virtual int Opcode() const; ideal_reg() const268 virtual uint ideal_reg() const { return Op_RegI; } 269 }; 270 271 272 //------------------------------BoolTest--------------------------------------- 273 // Convert condition codes to a boolean test value (0 or -1). 274 // We pick the values as 3 bits; the low order 2 bits we compare against the 275 // condition codes, the high bit flips the sense of the result. 276 struct BoolTest VALUE_OBJ_CLASS_SPEC { 277 enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, illegal = 8 }; 278 mask _test; BoolTestVALUE_OBJ_CLASS_SPEC279 BoolTest( mask btm ) : _test(btm) {} 280 const Type *cc2logical( const Type *CC ) const; 281 // Commute the test. I use a small table lookup. The table is created as 282 // a simple char array where each element is the ASCII version of a 'mask' 283 // enum from above. commuteVALUE_OBJ_CLASS_SPEC284 mask commute( ) const { return mask("032147658"[_test]-'0'); } negateVALUE_OBJ_CLASS_SPEC285 mask negate( ) const { return mask(_test^4); } is_canonicalVALUE_OBJ_CLASS_SPEC286 bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); } 287 void dump_on(outputStream *st) const; 288 }; 289 290 //------------------------------BoolNode--------------------------------------- 291 // A Node to convert a Condition Codes to a Logical result. 292 class BoolNode : public Node { 293 virtual uint hash() const; 294 virtual uint cmp( const Node &n ) const; 295 virtual uint size_of() const; 296 public: 297 const BoolTest _test; BoolNode(Node * cc,BoolTest::mask t)298 BoolNode( Node *cc, BoolTest::mask t): _test(t), Node(0,cc) { 299 init_class_id(Class_Bool); 300 } 301 // Convert an arbitrary int value to a Bool or other suitable predicate. 302 static Node* make_predicate(Node* test_value, PhaseGVN* phase); 303 // Convert self back to an integer value. 304 Node* as_int_value(PhaseGVN* phase); 305 // Invert sense of self, returning new Bool. 306 BoolNode* negate(PhaseGVN* phase); 307 virtual int Opcode() const; 308 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 309 virtual const Type *Value( PhaseTransform *phase ) const; bottom_type() const310 virtual const Type *bottom_type() const { return TypeInt::BOOL; } match_edge(uint idx) const311 uint match_edge(uint idx) const { return 0; } ideal_reg() const312 virtual uint ideal_reg() const { return Op_RegI; } 313 314 bool is_counted_loop_exit_test(); 315 #ifndef PRODUCT 316 virtual void dump_spec(outputStream *st) const; 317 #endif 318 }; 319 320 //------------------------------AbsNode---------------------------------------- 321 // Abstract class for absolute value. Mostly used to get a handy wrapper 322 // for finding this pattern in the graph. 323 class AbsNode : public Node { 324 public: AbsNode(Node * value)325 AbsNode( Node *value ) : Node(0,value) {} 326 }; 327 328 //------------------------------AbsINode--------------------------------------- 329 // Absolute value an integer. Since a naive graph involves control flow, we 330 // "match" it in the ideal world (so the control flow can be removed). 331 class AbsINode : public AbsNode { 332 public: AbsINode(Node * in1)333 AbsINode( Node *in1 ) : AbsNode(in1) {} 334 virtual int Opcode() const; bottom_type() const335 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const336 virtual uint ideal_reg() const { return Op_RegI; } 337 }; 338 339 //------------------------------AbsFNode--------------------------------------- 340 // Absolute value a float, a common float-point idiom with a cheap hardware 341 // implemention on most chips. Since a naive graph involves control flow, we 342 // "match" it in the ideal world (so the control flow can be removed). 343 class AbsFNode : public AbsNode { 344 public: AbsFNode(Node * in1)345 AbsFNode( Node *in1 ) : AbsNode(in1) {} 346 virtual int Opcode() const; bottom_type() const347 const Type *bottom_type() const { return Type::FLOAT; } ideal_reg() const348 virtual uint ideal_reg() const { return Op_RegF; } 349 }; 350 351 //------------------------------AbsDNode--------------------------------------- 352 // Absolute value a double, a common float-point idiom with a cheap hardware 353 // implemention on most chips. Since a naive graph involves control flow, we 354 // "match" it in the ideal world (so the control flow can be removed). 355 class AbsDNode : public AbsNode { 356 public: AbsDNode(Node * in1)357 AbsDNode( Node *in1 ) : AbsNode(in1) {} 358 virtual int Opcode() const; bottom_type() const359 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const360 virtual uint ideal_reg() const { return Op_RegD; } 361 }; 362 363 364 //------------------------------CmpLTMaskNode---------------------------------- 365 // If p < q, return -1 else return 0. Nice for flow-free idioms. 366 class CmpLTMaskNode : public Node { 367 public: CmpLTMaskNode(Node * p,Node * q)368 CmpLTMaskNode( Node *p, Node *q ) : Node(0, p, q) {} 369 virtual int Opcode() const; bottom_type() const370 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const371 virtual uint ideal_reg() const { return Op_RegI; } 372 }; 373 374 375 //------------------------------NegNode---------------------------------------- 376 class NegNode : public Node { 377 public: NegNode(Node * in1)378 NegNode( Node *in1 ) : Node(0,in1) {} 379 }; 380 381 //------------------------------NegFNode--------------------------------------- 382 // Negate value a float. Negating 0.0 returns -0.0, but subtracting from 383 // zero returns +0.0 (per JVM spec on 'fneg' bytecode). As subtraction 384 // cannot be used to replace negation we have to implement negation as ideal 385 // node; note that negation and addition can replace subtraction. 386 class NegFNode : public NegNode { 387 public: NegFNode(Node * in1)388 NegFNode( Node *in1 ) : NegNode(in1) {} 389 virtual int Opcode() const; bottom_type() const390 const Type *bottom_type() const { return Type::FLOAT; } ideal_reg() const391 virtual uint ideal_reg() const { return Op_RegF; } 392 }; 393 394 //------------------------------NegDNode--------------------------------------- 395 // Negate value a double. Negating 0.0 returns -0.0, but subtracting from 396 // zero returns +0.0 (per JVM spec on 'dneg' bytecode). As subtraction 397 // cannot be used to replace negation we have to implement negation as ideal 398 // node; note that negation and addition can replace subtraction. 399 class NegDNode : public NegNode { 400 public: NegDNode(Node * in1)401 NegDNode( Node *in1 ) : NegNode(in1) {} 402 virtual int Opcode() const; bottom_type() const403 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const404 virtual uint ideal_reg() const { return Op_RegD; } 405 }; 406 407 //------------------------------CosDNode--------------------------------------- 408 // Cosinus of a double 409 class CosDNode : public Node { 410 public: CosDNode(Compile * C,Node * c,Node * in1)411 CosDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { 412 init_flags(Flag_is_expensive); 413 C->add_expensive_node(this); 414 } 415 virtual int Opcode() const; bottom_type() const416 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const417 virtual uint ideal_reg() const { return Op_RegD; } 418 virtual const Type *Value( PhaseTransform *phase ) const; 419 }; 420 421 //------------------------------CosDNode--------------------------------------- 422 // Sinus of a double 423 class SinDNode : public Node { 424 public: SinDNode(Compile * C,Node * c,Node * in1)425 SinDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { 426 init_flags(Flag_is_expensive); 427 C->add_expensive_node(this); 428 } 429 virtual int Opcode() const; bottom_type() const430 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const431 virtual uint ideal_reg() const { return Op_RegD; } 432 virtual const Type *Value( PhaseTransform *phase ) const; 433 }; 434 435 436 //------------------------------TanDNode--------------------------------------- 437 // tangens of a double 438 class TanDNode : public Node { 439 public: TanDNode(Compile * C,Node * c,Node * in1)440 TanDNode(Compile* C, Node *c,Node *in1) : Node(c, in1) { 441 init_flags(Flag_is_expensive); 442 C->add_expensive_node(this); 443 } 444 virtual int Opcode() const; bottom_type() const445 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const446 virtual uint ideal_reg() const { return Op_RegD; } 447 virtual const Type *Value( PhaseTransform *phase ) const; 448 }; 449 450 451 //------------------------------AtanDNode-------------------------------------- 452 // arcus tangens of a double 453 class AtanDNode : public Node { 454 public: AtanDNode(Node * c,Node * in1,Node * in2)455 AtanDNode(Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {} 456 virtual int Opcode() const; bottom_type() const457 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const458 virtual uint ideal_reg() const { return Op_RegD; } 459 }; 460 461 462 //------------------------------SqrtDNode-------------------------------------- 463 // square root a double 464 class SqrtDNode : public Node { 465 public: SqrtDNode(Compile * C,Node * c,Node * in1)466 SqrtDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { 467 init_flags(Flag_is_expensive); 468 C->add_expensive_node(this); 469 } 470 virtual int Opcode() const; bottom_type() const471 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const472 virtual uint ideal_reg() const { return Op_RegD; } 473 virtual const Type *Value( PhaseTransform *phase ) const; 474 }; 475 476 //------------------------------ExpDNode--------------------------------------- 477 // Exponentiate a double 478 class ExpDNode : public Node { 479 public: ExpDNode(Compile * C,Node * c,Node * in1)480 ExpDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { 481 init_flags(Flag_is_expensive); 482 C->add_expensive_node(this); 483 } 484 virtual int Opcode() const; bottom_type() const485 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const486 virtual uint ideal_reg() const { return Op_RegD; } 487 virtual const Type *Value( PhaseTransform *phase ) const; 488 }; 489 490 //------------------------------LogDNode--------------------------------------- 491 // Log_e of a double 492 class LogDNode : public Node { 493 public: LogDNode(Compile * C,Node * c,Node * in1)494 LogDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { 495 init_flags(Flag_is_expensive); 496 C->add_expensive_node(this); 497 } 498 virtual int Opcode() const; bottom_type() const499 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const500 virtual uint ideal_reg() const { return Op_RegD; } 501 virtual const Type *Value( PhaseTransform *phase ) const; 502 }; 503 504 //------------------------------Log10DNode--------------------------------------- 505 // Log_10 of a double 506 class Log10DNode : public Node { 507 public: Log10DNode(Compile * C,Node * c,Node * in1)508 Log10DNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { 509 init_flags(Flag_is_expensive); 510 C->add_expensive_node(this); 511 } 512 virtual int Opcode() const; bottom_type() const513 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const514 virtual uint ideal_reg() const { return Op_RegD; } 515 virtual const Type *Value( PhaseTransform *phase ) const; 516 }; 517 518 //------------------------------PowDNode--------------------------------------- 519 // Raise a double to a double power 520 class PowDNode : public Node { 521 public: PowDNode(Compile * C,Node * c,Node * in1,Node * in2)522 PowDNode(Compile* C, Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) { 523 init_flags(Flag_is_expensive); 524 C->add_expensive_node(this); 525 } 526 virtual int Opcode() const; bottom_type() const527 const Type *bottom_type() const { return Type::DOUBLE; } ideal_reg() const528 virtual uint ideal_reg() const { return Op_RegD; } 529 virtual const Type *Value( PhaseTransform *phase ) const; 530 }; 531 532 //-------------------------------ReverseBytesINode-------------------------------- 533 // reverse bytes of an integer 534 class ReverseBytesINode : public Node { 535 public: ReverseBytesINode(Node * c,Node * in1)536 ReverseBytesINode(Node *c, Node *in1) : Node(c, in1) {} 537 virtual int Opcode() const; bottom_type() const538 const Type *bottom_type() const { return TypeInt::INT; } ideal_reg() const539 virtual uint ideal_reg() const { return Op_RegI; } 540 }; 541 542 //-------------------------------ReverseBytesLNode-------------------------------- 543 // reverse bytes of a long 544 class ReverseBytesLNode : public Node { 545 public: ReverseBytesLNode(Node * c,Node * in1)546 ReverseBytesLNode(Node *c, Node *in1) : Node(c, in1) {} 547 virtual int Opcode() const; bottom_type() const548 const Type *bottom_type() const { return TypeLong::LONG; } ideal_reg() const549 virtual uint ideal_reg() const { return Op_RegL; } 550 }; 551 552 //-------------------------------ReverseBytesUSNode-------------------------------- 553 // reverse bytes of an unsigned short / char 554 class ReverseBytesUSNode : public Node { 555 public: ReverseBytesUSNode(Node * c,Node * in1)556 ReverseBytesUSNode(Node *c, Node *in1) : Node(c, in1) {} 557 virtual int Opcode() const; bottom_type() const558 const Type *bottom_type() const { return TypeInt::CHAR; } ideal_reg() const559 virtual uint ideal_reg() const { return Op_RegI; } 560 }; 561 562 //-------------------------------ReverseBytesSNode-------------------------------- 563 // reverse bytes of a short 564 class ReverseBytesSNode : public Node { 565 public: ReverseBytesSNode(Node * c,Node * in1)566 ReverseBytesSNode(Node *c, Node *in1) : Node(c, in1) {} 567 virtual int Opcode() const; bottom_type() const568 const Type *bottom_type() const { return TypeInt::SHORT; } ideal_reg() const569 virtual uint ideal_reg() const { return Op_RegI; } 570 }; 571 572 #endif // SHARE_VM_OPTO_SUBNODE_HPP 573