430 R9,
431 R10,
432 R11,
433 R12,
434 /*R13*/ // system thread id
435 R14,
436 R15,
437 /*R16*/ // R16_thread
438 R17,
439 R18,
440 R19,
441 R20,
442 R21,
443 R22,
444 R23,
445 R24,
446 R25,
447 R26,
448 R27,
449 R28,
450 /*R29*/ // global TOC
451 /*R30*/ // Narrow Oop Base
452 R31
453 );
454
455 // 32 bit registers that can only be read i.e. these registers can
456 // only be src of all instructions.
457 reg_class bits32_reg_ro(
458 /*R0*/ // R0
459 /*R1*/ // SP
460 R2 // TOC
461 R3,
462 R4,
463 R5,
464 R6,
465 R7,
466 R8,
467 R9,
468 R10,
469 R11,
470 R12,
471 /*R13*/ // system thread id
472 R14,
473 R15,
474 /*R16*/ // R16_thread
475 R17,
476 R18,
477 R19,
478 R20,
479 R21,
480 R22,
481 R23,
482 R24,
483 R25,
484 R26,
485 R27,
486 R28,
487 /*R29*/
488 /*R30*/ // Narrow Oop Base
489 R31
490 );
491
492 // Complement-required-in-pipeline operands for narrow oops.
493 reg_class bits32_reg_ro_not_complement (
494 /*R0*/ // R0
495 R1, // SP
496 R2, // TOC
497 R3,
498 R4,
499 R5,
500 R6,
501 R7,
502 R8,
503 R9,
504 R10,
505 R11,
506 R12,
507 /*R13,*/ // system thread id
508 R14,
509 R15,
510 R16, // R16_thread
511 R17,
512 R18,
513 R19,
514 R20,
515 R21,
516 R22,
517 /*R23,
518 R24,
519 R25,
520 R26,
521 R27,
522 R28,*/
523 /*R29,*/ // TODO: let allocator handle TOC!!
524 /*R30,*/
525 R31
526 );
527
528 // Complement-required-in-pipeline operands for narrow oops.
529 // See 64-bit declaration.
530 reg_class bits32_reg_ro_complement (
531 R23,
532 R24,
533 R25,
534 R26,
535 R27,
536 R28
537 );
538
539 reg_class rscratch1_bits32_reg(R11);
540 reg_class rscratch2_bits32_reg(R12);
541 reg_class rarg1_bits32_reg(R3);
542 reg_class rarg2_bits32_reg(R4);
543 reg_class rarg3_bits32_reg(R5);
544 reg_class rarg4_bits32_reg(R6);
545
546 // ----------------------------
547 // 64 Bit Register Classes
548 // ----------------------------
549 // 64-bit build means 64-bit pointers means hi/lo pairs
550
551 reg_class rscratch1_bits64_reg(R11_H, R11);
552 reg_class rscratch2_bits64_reg(R12_H, R12);
553 reg_class rarg1_bits64_reg(R3_H, R3);
554 reg_class rarg2_bits64_reg(R4_H, R4);
555 reg_class rarg3_bits64_reg(R5_H, R5);
556 reg_class rarg4_bits64_reg(R6_H, R6);
557 // Thread register, 'written' by tlsLoadP, see there.
558 reg_class thread_bits64_reg(R16_H, R16);
574 R9_H, R9,
575 R10_H, R10,
576 R11_H, R11,
577 R12_H, R12,
578 /*R13_H, R13*/ // system thread id
579 R14_H, R14,
580 R15_H, R15,
581 /*R16_H, R16*/ // R16_thread
582 R17_H, R17,
583 R18_H, R18,
584 R19_H, R19,
585 R20_H, R20,
586 R21_H, R21,
587 R22_H, R22,
588 R23_H, R23,
589 R24_H, R24,
590 R25_H, R25,
591 R26_H, R26,
592 R27_H, R27,
593 R28_H, R28,
594 /*R29_H, R29*/
595 /*R30_H, R30*/
596 R31_H, R31
597 );
598
599 // 64 bit registers used excluding r2, r11 and r12
600 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses
601 // r2, r11 and r12 internally.
602 reg_class bits64_reg_leaf_call(
603 /*R0_H, R0*/ // R0
604 /*R1_H, R1*/ // SP
605 /*R2_H, R2*/ // TOC
606 R3_H, R3,
607 R4_H, R4,
608 R5_H, R5,
609 R6_H, R6,
610 R7_H, R7,
611 R8_H, R8,
612 R9_H, R9,
613 R10_H, R10,
614 /*R11_H, R11*/
615 /*R12_H, R12*/
616 /*R13_H, R13*/ // system thread id
617 R14_H, R14,
618 R15_H, R15,
619 /*R16_H, R16*/ // R16_thread
620 R17_H, R17,
621 R18_H, R18,
622 R19_H, R19,
623 R20_H, R20,
624 R21_H, R21,
625 R22_H, R22,
626 R23_H, R23,
627 R24_H, R24,
628 R25_H, R25,
629 R26_H, R26,
630 R27_H, R27,
631 R28_H, R28,
632 /*R29_H, R29*/
633 /*R30_H, R30*/
634 R31_H, R31
635 );
636
637 // Used to hold the TOC to avoid collisions with expanded DynamicCall
638 // which uses r19 as inline cache internally and expanded LeafCall which uses
639 // r2, r11 and r12 internally.
640 reg_class bits64_constant_table_base(
641 /*R0_H, R0*/ // R0
642 /*R1_H, R1*/ // SP
643 /*R2_H, R2*/ // TOC
644 R3_H, R3,
645 R4_H, R4,
646 R5_H, R5,
647 R6_H, R6,
648 R7_H, R7,
649 R8_H, R8,
650 R9_H, R9,
651 R10_H, R10,
652 /*R11_H, R11*/
653 /*R12_H, R12*/
654 /*R13_H, R13*/ // system thread id
655 R14_H, R14,
656 R15_H, R15,
657 /*R16_H, R16*/ // R16_thread
658 R17_H, R17,
659 R18_H, R18,
660 /*R19_H, R19*/
661 R20_H, R20,
662 R21_H, R21,
663 R22_H, R22,
664 R23_H, R23,
665 R24_H, R24,
666 R25_H, R25,
667 R26_H, R26,
668 R27_H, R27,
669 R28_H, R28,
670 /*R29_H, R29*/
671 /*R30_H, R30*/
672 R31_H, R31
673 );
674
675 // 64 bit registers that can only be read i.e. these registers can
676 // only be src of all instructions.
677 reg_class bits64_reg_ro(
678 /*R0_H, R0*/ // R0
679 R1_H, R1,
680 R2_H, R2, // TOC
681 R3_H, R3,
682 R4_H, R4,
683 R5_H, R5,
684 R6_H, R6,
685 R7_H, R7,
686 R8_H, R8,
687 R9_H, R9,
688 R10_H, R10,
689 R11_H, R11,
690 R12_H, R12,
691 /*R13_H, R13*/ // system thread id
692 R14_H, R14,
693 R15_H, R15,
694 R16_H, R16, // R16_thread
695 R17_H, R17,
696 R18_H, R18,
697 R19_H, R19,
698 R20_H, R20,
699 R21_H, R21,
700 R22_H, R22,
701 R23_H, R23,
702 R24_H, R24,
703 R25_H, R25,
704 R26_H, R26,
705 R27_H, R27,
706 R28_H, R28,
707 /*R29_H, R29*/ // TODO: let allocator handle TOC!!
708 /*R30_H, R30,*/
709 R31_H, R31
710 );
711
712 // Complement-required-in-pipeline operands.
713 reg_class bits64_reg_ro_not_complement (
714 /*R0_H, R0*/ // R0
715 R1_H, R1, // SP
716 R2_H, R2, // TOC
717 R3_H, R3,
718 R4_H, R4,
719 R5_H, R5,
720 R6_H, R6,
721 R7_H, R7,
722 R8_H, R8,
723 R9_H, R9,
724 R10_H, R10,
725 R11_H, R11,
726 R12_H, R12,
727 /*R13_H, R13*/ // system thread id
728 R14_H, R14,
729 R15_H, R15,
730 R16_H, R16, // R16_thread
731 R17_H, R17,
732 R18_H, R18,
733 R19_H, R19,
734 R20_H, R20,
735 R21_H, R21,
736 R22_H, R22,
737 /*R23_H, R23,
738 R24_H, R24,
739 R25_H, R25,
740 R26_H, R26,
741 R27_H, R27,
742 R28_H, R28,*/
743 /*R29_H, R29*/ // TODO: let allocator handle TOC!!
744 /*R30_H, R30,*/
745 R31_H, R31
746 );
747
748 // Complement-required-in-pipeline operands.
749 // This register mask is used for the trap instructions that implement
750 // the null checks on AIX. The trap instruction first computes the
751 // complement of the value it shall trap on. Because of this, the
752 // instruction can not be scheduled in the same cycle as an other
753 // instruction reading the normal value of the same register. So we
754 // force the value to check into 'bits64_reg_ro_not_complement'
755 // and then copy it to 'bits64_reg_ro_complement' for the trap.
756 reg_class bits64_reg_ro_complement (
757 R23_H, R23,
758 R24_H, R24,
759 R25_H, R25,
760 R26_H, R26,
761 R27_H, R27,
762 R28_H, R28
763 );
764
765
766 // ----------------------------
767 // Special Class for Condition Code Flags Register
768
769 reg_class int_flags(
770 /*CCR0*/ // scratch
771 /*CCR1*/ // scratch
772 /*CCR2*/ // nv!
773 /*CCR3*/ // nv!
774 /*CCR4*/ // nv!
775 CCR5,
776 CCR6,
777 CCR7
778 );
779
780 reg_class int_flags_CR0(CCR0);
781 reg_class int_flags_CR1(CCR1);
782 reg_class int_flags_CR6(CCR6);
783 reg_class ctr_reg(SR_CTR);
784
785 // ----------------------------
786 // Float Register Classes
787 // ----------------------------
788
789 reg_class flt_reg(
790 /*F0*/ // scratch
791 F1,
792 F2,
793 F3,
794 F4,
795 F5,
796 F6,
797 F7,
798 F8,
799 F9,
2859 assert((Idisp & 0x3) == 0, "unaligned offset");
2860 __ std($src$$Register, Idisp, $mem$$base$$Register);
2861 %}
2862
2863 enc_class enc_stfs(RegF src, memory mem) %{
2864 // TODO: PPC port $archOpcode(ppc64Opcode_stfs);
2865 MacroAssembler _masm(&cbuf);
2866 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2867 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2868 %}
2869
2870 enc_class enc_stfd(RegF src, memory mem) %{
2871 // TODO: PPC port $archOpcode(ppc64Opcode_stfd);
2872 MacroAssembler _masm(&cbuf);
2873 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2874 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2875 %}
2876
2877 // Use release_store for card-marking to ensure that previous
2878 // oop-stores are visible before the card-mark change.
2879 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr) %{
2880 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2881 // FIXME: Implement this as a cmove and use a fixed condition code
2882 // register which is written on every transition to compiled code,
2883 // e.g. in call-stub and when returning from runtime stubs.
2884 //
2885 // Proposed code sequence for the cmove implementation:
2886 //
2887 // Label skip_release;
2888 // __ beq(CCRfixed, skip_release);
2889 // __ release();
2890 // __ bind(skip_release);
2891 // __ stb(card mark);
2892
2893 MacroAssembler _masm(&cbuf);
2894 Label skip_storestore;
2895
2896 #if 0 // TODO: PPC port
2897 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the
2898 // StoreStore barrier conditionally.
2899 __ lwz(R0, 0, $releaseFieldAddr$$Register);
2900 __ cmpwi(CCR0, R0, 0);
2901 __ beq_predict_taken(CCR0, skip_storestore);
2902 #endif
2903 __ li(R0, 0);
2904 __ membar(Assembler::StoreStore);
2905 #if 0 // TODO: PPC port
2906 __ bind(skip_storestore);
2907 #endif
2908
2909 // Do the store.
2910 if ($mem$$index == 0) {
2911 __ stb(R0, $mem$$disp, $mem$$base$$Register);
2912 } else {
2913 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc");
2914 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register);
2915 }
2916 %}
2917
2918 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2919
2920 if (VM_Version::has_isel()) {
2921 // use isel instruction with Power 7
3091 n1->add_req(n_region, n_src);
3092 n1->_opnds[0] = op_dst;
3093 n1->_opnds[1] = op_src;
3094 n1->_bottom_type = _bottom_type;
3095
3096 decodeN_addNode *n2 = new decodeN_addNode();
3097 n2->add_req(n_region, n1);
3098 n2->_opnds[0] = op_dst;
3099 n2->_opnds[1] = op_dst;
3100 n2->_bottom_type = _bottom_type;
3101 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3102 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3103
3104 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3105 ra_->set_oop(n2, true);
3106
3107 nodes->push(n1);
3108 nodes->push(n2);
3109 %}
3110
3111 enc_class enc_cmove_reg(iRegIdst dst, flagsReg crx, iRegIsrc src, cmpOp cmp) %{
3112 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3113
3114 MacroAssembler _masm(&cbuf);
3115 int cc = $cmp$$cmpcode;
3116 int flags_reg = $crx$$reg;
3117 Label done;
3118 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3119 // Branch if not (cmp crx).
3120 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done);
3121 __ mr($dst$$Register, $src$$Register);
3122 // TODO PPC port __ endgroup_if_needed(_size == 12);
3123 __ bind(done);
3124 %}
3125
3126 enc_class enc_cmove_imm(iRegIdst dst, flagsReg crx, immI16 src, cmpOp cmp) %{
3127 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3128
3129 MacroAssembler _masm(&cbuf);
3130 Label done;
3131 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3132 // Branch if not (cmp crx).
3133 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
3134 __ li($dst$$Register, $src$$constant);
3135 // TODO PPC port __ endgroup_if_needed(_size == 12);
3136 __ bind(done);
3137 %}
3138
3139 // New atomics.
3140 enc_class enc_GetAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
3141 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3142
3143 MacroAssembler _masm(&cbuf);
3144 Register Rtmp = R0;
3145 Register Rres = $res$$Register;
3146 Register Rsrc = $src$$Register;
3252 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3253 __ li($dst$$Register, $zero$$constant);
3254 __ beq($crx$$CondRegister, done);
3255 __ li($dst$$Register, $notzero$$constant);
3256 __ bind(done);
3257 %}
3258
3259 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3260 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3261
3262 MacroAssembler _masm(&cbuf);
3263
3264 Label done;
3265 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3266 __ li($dst$$Register, $zero$$constant);
3267 __ beq($crx$$CondRegister, done);
3268 __ li($dst$$Register, $notzero$$constant);
3269 __ bind(done);
3270 %}
3271
3272 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsReg crx, stackSlotL mem ) %{
3273 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3274
3275 MacroAssembler _masm(&cbuf);
3276 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3277 Label done;
3278 __ bso($crx$$CondRegister, done);
3279 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3280 // TODO PPC port __ endgroup_if_needed(_size == 12);
3281 __ bind(done);
3282 %}
3283
3284 enc_class enc_bc(flagsReg crx, cmpOp cmp, Label lbl) %{
3285 // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3286
3287 MacroAssembler _masm(&cbuf);
3288 Label d; // dummy
3289 __ bind(d);
3290 Label* p = ($lbl$$label);
3291 // `p' is `NULL' when this encoding class is used only to
3292 // determine the size of the encoded instruction.
3293 Label& l = (NULL == p)? d : *(p);
3294 int cc = $cmp$$cmpcode;
3295 int flags_reg = $crx$$reg;
3296 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3297 int bhint = Assembler::bhintNoHint;
3298
3299 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3300 if (_prob <= PROB_NEVER) {
3301 bhint = Assembler::bhintIsNotTaken;
3302 } else if (_prob >= PROB_ALWAYS) {
3303 bhint = Assembler::bhintIsTaken;
3304 }
3305 }
3306
3307 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3308 cc_to_biint(cc, flags_reg),
3309 l);
3310 %}
3311
3312 enc_class enc_bc_far(flagsReg crx, cmpOp cmp, Label lbl) %{
3313 // The scheduler doesn't know about branch shortening, so we set the opcode
3314 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3315 // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3316
3317 MacroAssembler _masm(&cbuf);
3318 Label d; // dummy
3319 __ bind(d);
3320 Label* p = ($lbl$$label);
3321 // `p' is `NULL' when this encoding class is used only to
3322 // determine the size of the encoded instruction.
3323 Label& l = (NULL == p)? d : *(p);
3324 int cc = $cmp$$cmpcode;
3325 int flags_reg = $crx$$reg;
3326 int bhint = Assembler::bhintNoHint;
3327
3328 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3329 if (_prob <= PROB_NEVER) {
3330 bhint = Assembler::bhintIsNotTaken;
3331 } else if (_prob >= PROB_ALWAYS) {
3332 bhint = Assembler::bhintIsTaken;
3333 }
3334 }
3335
3336 // Tell the conditional far branch to optimize itself when being relocated.
3337 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3338 cc_to_biint(cc, flags_reg),
3339 l,
3340 MacroAssembler::bc_far_optimize_on_relocate);
3341 %}
3342
3343 // Branch used with Power6 scheduling (can be shortened without changing the node).
3344 enc_class enc_bc_short_far(flagsReg crx, cmpOp cmp, Label lbl) %{
3345 // The scheduler doesn't know about branch shortening, so we set the opcode
3346 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3347 // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3348
3349 MacroAssembler _masm(&cbuf);
3350 Label d; // dummy
3351 __ bind(d);
3352 Label* p = ($lbl$$label);
3353 // `p' is `NULL' when this encoding class is used only to
3354 // determine the size of the encoded instruction.
3355 Label& l = (NULL == p)? d : *(p);
3356 int cc = $cmp$$cmpcode;
3357 int flags_reg = $crx$$reg;
3358 int bhint = Assembler::bhintNoHint;
3359
3360 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3361 if (_prob <= PROB_NEVER) {
3362 bhint = Assembler::bhintIsNotTaken;
3363 } else if (_prob >= PROB_ALWAYS) {
3364 bhint = Assembler::bhintIsTaken;
4683 match(RegL);
4684 format %{ %}
4685 interface(REG_INTER);
4686 %}
4687
4688 operand rscratch2RegL() %{
4689 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4690 match(RegL);
4691 format %{ %}
4692 interface(REG_INTER);
4693 %}
4694
4695 // Condition Code Flag Registers
4696 operand flagsReg() %{
4697 constraint(ALLOC_IN_RC(int_flags));
4698 match(RegFlags);
4699 format %{ %}
4700 interface(REG_INTER);
4701 %}
4702
4703 // Condition Code Flag Register CR0
4704 operand flagsRegCR0() %{
4705 constraint(ALLOC_IN_RC(int_flags_CR0));
4706 match(RegFlags);
4707 format %{ "CR0" %}
4708 interface(REG_INTER);
4709 %}
4710
4711 operand flagsRegCR1() %{
4712 constraint(ALLOC_IN_RC(int_flags_CR1));
4713 match(RegFlags);
4714 format %{ "CR1" %}
4715 interface(REG_INTER);
4716 %}
4717
4718 operand flagsRegCR6() %{
4719 constraint(ALLOC_IN_RC(int_flags_CR6));
4720 match(RegFlags);
4721 format %{ "CR6" %}
4722 interface(REG_INTER);
4766 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg
4767 match(reg);
4768 format %{ %}
4769 interface(REG_INTER);
4770 %}
4771
4772 // Operands to remove register moves in unscaled mode.
4773 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4774 operand iRegP2N(iRegPsrc reg) %{
4775 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0);
4776 constraint(ALLOC_IN_RC(bits64_reg_ro));
4777 match(EncodeP reg);
4778 format %{ "$reg" %}
4779 interface(REG_INTER)
4780 %}
4781
4782 operand iRegN2P(iRegNsrc reg) %{
4783 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4784 constraint(ALLOC_IN_RC(bits32_reg_ro));
4785 match(DecodeN reg);
4786 match(DecodeNKlass reg);
4787 format %{ "$reg" %}
4788 interface(REG_INTER)
4789 %}
4790
4791 //----------Complex Operands---------------------------------------------------
4792 // Indirect Memory Reference
4793 operand indirect(iRegPsrc reg) %{
4794 constraint(ALLOC_IN_RC(bits64_reg_ro));
4795 match(reg);
4796 op_cost(100);
4797 format %{ "[$reg]" %}
4798 interface(MEMORY_INTER) %{
4799 base($reg);
4800 index(0x0);
4801 scale(0x0);
4802 disp(0x0);
4803 %}
4804 %}
4805
4822 constraint(ALLOC_IN_RC(bits64_reg_ro));
4823 match(AddP reg offset);
4824 op_cost(100);
4825 format %{ "[$reg + $offset]" %}
4826 interface(MEMORY_INTER) %{
4827 base($reg);
4828 index(0x0);
4829 scale(0x0);
4830 disp($offset);
4831 %}
4832 %}
4833
4834 //----------Complex Operands for Compressed OOPs-------------------------------
4835 // Compressed OOPs with narrow_oop_shift == 0.
4836
4837 // Indirect Memory Reference, compressed OOP
4838 operand indirectNarrow(iRegNsrc reg) %{
4839 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4840 constraint(ALLOC_IN_RC(bits64_reg_ro));
4841 match(DecodeN reg);
4842 match(DecodeNKlass reg);
4843 op_cost(100);
4844 format %{ "[$reg]" %}
4845 interface(MEMORY_INTER) %{
4846 base($reg);
4847 index(0x0);
4848 scale(0x0);
4849 disp(0x0);
4850 %}
4851 %}
4852
4853 // Indirect with Offset, compressed OOP
4854 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4855 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4856 constraint(ALLOC_IN_RC(bits64_reg_ro));
4857 match(AddP (DecodeN reg) offset);
4858 match(AddP (DecodeNKlass reg) offset);
4859 op_cost(100);
4860 format %{ "[$reg + $offset]" %}
4861 interface(MEMORY_INTER) %{
4862 base($reg);
4863 index(0x0);
4864 scale(0x0);
4865 disp($offset);
4866 %}
4867 %}
4868
4869 // Indirect with 4-aligned Offset, compressed OOP
4870 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4871 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4872 constraint(ALLOC_IN_RC(bits64_reg_ro));
4873 match(AddP (DecodeN reg) offset);
4874 match(AddP (DecodeNKlass reg) offset);
4875 op_cost(100);
4876 format %{ "[$reg + $offset]" %}
4877 interface(MEMORY_INTER) %{
4878 base($reg);
4879 index(0x0);
4880 scale(0x0);
4881 disp($offset);
4882 %}
4883 %}
4884
4885 //----------Special Memory Operands--------------------------------------------
4886 // Stack Slot Operand
4887 //
4888 // This operand is used for loading and storing temporary values on
4889 // the stack where a match requires a value to flow through memory.
4890 operand stackSlotI(sRegI reg) %{
4891 constraint(ALLOC_IN_RC(stack_slots));
4892 op_cost(100);
4893 //match(RegI);
4981 // BO & BI
4982 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4983 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4984 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4985 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4986 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4987 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4988 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4989 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4990 %}
4991 %}
4992
4993 //----------OPERAND CLASSES----------------------------------------------------
4994 // Operand Classes are groups of operands that are used to simplify
4995 // instruction definitions by not requiring the AD writer to specify
4996 // seperate instructions for every form of operand when the
4997 // instruction accepts multiple operand types with the same basic
4998 // encoding and format. The classic case of this is memory operands.
4999 // Indirect is not included since its use is limited to Compare & Swap.
5000
5001 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indOffset16Narrow);
5002 // Memory operand where offsets are 4-aligned. Required for ld, std.
5003 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4);
5004 opclass indirectMemory(indirect, indirectNarrow);
5005
5006 // Special opclass for I and ConvL2I.
5007 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
5008
5009 // Operand classes to match encode and decode. iRegN_P2N is only used
5010 // for storeN. I have never seen an encode node elsewhere.
5011 opclass iRegN_P2N(iRegNsrc, iRegP2N);
5012 opclass iRegP_N2P(iRegPsrc, iRegN2P);
5013
5014 //----------PIPELINE-----------------------------------------------------------
5015
5016 pipeline %{
5017
5018 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
5019 // J. Res. & Dev., No. 1, Jan. 2002.
5020
5021 //----------ATTRIBUTES---------------------------------------------------------
5022 attributes %{
5023
5024 // Power4 instructions are of fixed length.
5025 fixed_size_instructions;
5026
5027 // TODO: if `bundle' means number of instructions fetched
5028 // per cycle, this is 8. If `bundle' means Power4 `group', that is
5029 // max instructions issued per cycle, this is 5.
5030 max_instructions_per_bundle = 8;
5031
5032 // A Power4 instruction is 4 bytes long.
5576 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5577 "TWI $dst\n\t"
5578 "ISYNC" %}
5579 size(12);
5580 ins_encode( enc_lwz_ac(dst, mem) );
5581 ins_pipe(pipe_class_memory);
5582 %}
5583
5584 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5585 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5586 match(Set dst (DecodeN (LoadN mem)));
5587 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0);
5588 ins_cost(MEMORY_REF_COST);
5589
5590 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5591 size(4);
5592 ins_encode( enc_lwz(dst, mem) );
5593 ins_pipe(pipe_class_memory);
5594 %}
5595
5596 // Load Pointer
5597 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5598 match(Set dst (LoadP mem));
5599 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5600 ins_cost(MEMORY_REF_COST);
5601
5602 format %{ "LD $dst, $mem \t// ptr" %}
5603 size(4);
5604 ins_encode( enc_ld(dst, mem) );
5605 ins_pipe(pipe_class_memory);
5606 %}
5607
5608 // Load Pointer acquire.
5609 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5610 match(Set dst (LoadP mem));
5611 ins_cost(3*MEMORY_REF_COST);
5612
5613 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5614 "TWI $dst\n\t"
5615 "ISYNC" %}
5652 ins_pipe(pipe_class_memory);
5653 %}
5654
5655 // Load Float
5656 instruct loadF(regF dst, memory mem) %{
5657 match(Set dst (LoadF mem));
5658 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5659 ins_cost(MEMORY_REF_COST);
5660
5661 format %{ "LFS $dst, $mem" %}
5662 size(4);
5663 ins_encode %{
5664 // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
5665 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5666 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5667 %}
5668 ins_pipe(pipe_class_memory);
5669 %}
5670
5671 // Load Float acquire.
5672 instruct loadF_ac(regF dst, memory mem) %{
5673 match(Set dst (LoadF mem));
5674 ins_cost(3*MEMORY_REF_COST);
5675
5676 format %{ "LFS $dst, $mem \t// acquire\n\t"
5677 "FCMPU cr0, $dst, $dst\n\t"
5678 "BNE cr0, next\n"
5679 "next:\n\t"
5680 "ISYNC" %}
5681 size(16);
5682 ins_encode %{
5683 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5684 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5685 Label next;
5686 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5687 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5688 __ bne(CCR0, next);
5689 __ bind(next);
5690 __ isync();
5691 %}
5692 ins_pipe(pipe_class_memory);
5693 %}
5694
5695 // Load Double - aligned
5696 instruct loadD(regD dst, memory mem) %{
5697 match(Set dst (LoadD mem));
5698 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5699 ins_cost(MEMORY_REF_COST);
5700
5701 format %{ "LFD $dst, $mem" %}
5702 size(4);
5703 ins_encode( enc_lfd(dst, mem) );
5704 ins_pipe(pipe_class_memory);
5705 %}
5706
5707 // Load Double - aligned acquire.
5708 instruct loadD_ac(regD dst, memory mem) %{
5709 match(Set dst (LoadD mem));
5710 ins_cost(3*MEMORY_REF_COST);
5711
5712 format %{ "LFD $dst, $mem \t// acquire\n\t"
5713 "FCMPU cr0, $dst, $dst\n\t"
5714 "BNE cr0, next\n"
5715 "next:\n\t"
5716 "ISYNC" %}
5717 size(16);
5718 ins_encode %{
5719 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5720 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5721 Label next;
5722 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5723 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5724 __ bne(CCR0, next);
5725 __ bind(next);
5726 __ isync();
5727 %}
5728 ins_pipe(pipe_class_memory);
5729 %}
6017 // This clears these bits: dst = src & 0xFFFFFFFF.
6018 // TODO: Eventually call this maskN_regN_FFFFFFFF.
6019 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
6020 effect(DEF dst, USE src);
6021 predicate(false);
6022
6023 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
6024 size(4);
6025 ins_encode %{
6026 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6027 __ clrldi($dst$$Register, $src$$Register, 0x20);
6028 %}
6029 ins_pipe(pipe_class_default);
6030 %}
6031
6032 // Optimize DecodeN for disjoint base.
6033 // Load base of compressed oops into a register
6034 instruct loadBase(iRegLdst dst) %{
6035 effect(DEF dst);
6036
6037 format %{ "MR $dst, r30_heapbase" %}
6038 size(4);
6039 ins_encode %{
6040 // TODO: PPC port $archOpcode(ppc64Opcode_or);
6041 __ mr($dst$$Register, R30);
6042 %}
6043 ins_pipe(pipe_class_default);
6044 %}
6045
6046 // Loading ConN must be postalloc expanded so that edges between
6047 // the nodes are safe. They may not interfere with a safepoint.
6048 // GL TODO: This needs three instructions: better put this into the constant pool.
6049 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6050 match(Set dst src);
6051 ins_cost(DEFAULT_COST*2);
6052
6053 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6054 postalloc_expand %{
6055 MachNode *m1 = new loadConN_hiNode();
6056 MachNode *m2 = new loadConN_loNode();
6057 MachNode *m3 = new clearMs32bNode();
6058 m1->add_req(NULL);
6059 m2->add_req(NULL, m1);
6060 m3->add_req(NULL, m2);
6061 m1->_opnds[0] = op_dst;
6546 %}
6547
6548 // Store Double
6549 instruct storeD(memory mem, regD src) %{
6550 match(Set mem (StoreD mem src));
6551 ins_cost(MEMORY_REF_COST);
6552
6553 format %{ "STFD $src, $mem" %}
6554 size(4);
6555 ins_encode( enc_stfd(src, mem) );
6556 ins_pipe(pipe_class_memory);
6557 %}
6558
6559 //----------Store Instructions With Zeros--------------------------------------
6560
6561 // Card-mark for CMS garbage collection.
6562 // This cardmark does an optimization so that it must not always
6563 // do a releasing store. For this, it gets the address of
6564 // CMSCollectorCardTableModRefBSExt::_requires_release as input.
6565 // (Using releaseFieldAddr in the match rule is a hack.)
6566 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr) %{
6567 match(Set mem (StoreCM mem releaseFieldAddr));
6568 predicate(false);
6569 ins_cost(MEMORY_REF_COST);
6570
6571 // See loadConP.
6572 ins_cannot_rematerialize(true);
6573
6574 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %}
6575 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr) );
6576 ins_pipe(pipe_class_memory);
6577 %}
6578
6579 // Card-mark for CMS garbage collection.
6580 // This cardmark does an optimization so that it must not always
6581 // do a releasing store. For this, it needs the constant address of
6582 // CMSCollectorCardTableModRefBSExt::_requires_release.
6583 // This constant address is split off here by expand so we can use
6584 // adlc / matcher functionality to load it from the constant section.
6585 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{
6586 match(Set mem (StoreCM mem zero));
6587 predicate(UseConcMarkSweepGC);
6588
6589 expand %{
6590 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %}
6591 iRegLdst releaseFieldAddress;
6592 loadConL_Ex(releaseFieldAddress, baseImm);
6593 storeCM_CMS(mem, releaseFieldAddress);
6594 %}
6595 %}
6596
6597 instruct storeCM_G1(memory mem, immI_0 zero) %{
6598 match(Set mem (StoreCM mem zero));
6599 predicate(UseG1GC);
6600 ins_cost(MEMORY_REF_COST);
6601
6602 ins_cannot_rematerialize(true);
6603
6604 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %}
6605 size(8);
6606 ins_encode %{
6607 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6608 __ li(R0, 0);
6609 //__ release(); // G1: oops are allowed to get visible after dirty marking
6610 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias");
6611 __ stb(R0, $mem$$disp, $mem$$base$$Register);
6612 %}
6613 ins_pipe(pipe_class_memory);
6622 // The match rule is needed to make it a 'MachTypeNode'!
6623 match(Set dst (EncodeP src));
6624 predicate(false);
6625
6626 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6627 size(4);
6628 ins_encode %{
6629 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6630 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f);
6631 %}
6632 ins_pipe(pipe_class_default);
6633 %}
6634
6635 // Add node for expand.
6636 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6637 // The match rule is needed to make it a 'MachTypeNode'!
6638 match(Set dst (EncodeP src));
6639 predicate(false);
6640
6641 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6642 size(4);
6643 ins_encode %{
6644 // TODO: PPC port $archOpcode(ppc64Opcode_subf);
6645 __ subf($dst$$Register, R30, $src$$Register);
6646 %}
6647 ins_pipe(pipe_class_default);
6648 %}
6649
6650 // Conditional sub base.
6651 instruct cond_sub_base(iRegNdst dst, flagsReg crx, iRegPsrc src1) %{
6652 // The match rule is needed to make it a 'MachTypeNode'!
6653 match(Set dst (EncodeP (Binary crx src1)));
6654 predicate(false);
6655
6656 ins_variable_size_depending_on_alignment(true);
6657
6658 format %{ "BEQ $crx, done\n\t"
6659 "SUB $dst, $src1, R30 \t// encode: subtract base if != NULL\n"
6660 "done:" %}
6661 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
6662 ins_encode %{
6663 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
6664 Label done;
6665 __ beq($crx$$CondRegister, done);
6666 __ subf($dst$$Register, R30, $src1$$Register);
6667 // TODO PPC port __ endgroup_if_needed(_size == 12);
6668 __ bind(done);
6669 %}
6670 ins_pipe(pipe_class_default);
6671 %}
6672
6673 // Power 7 can use isel instruction
6674 instruct cond_set_0_oop(iRegNdst dst, flagsReg crx, iRegPsrc src1) %{
6675 // The match rule is needed to make it a 'MachTypeNode'!
6676 match(Set dst (EncodeP (Binary crx src1)));
6677 predicate(false);
6678
6679 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6680 size(4);
6681 ins_encode %{
6682 // This is a Power7 instruction for which no machine description exists.
6683 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6684 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6685 %}
6686 ins_pipe(pipe_class_default);
6687 %}
6688
6689 // Disjoint narrow oop base.
6690 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6691 match(Set dst (EncodeP src));
6692 predicate(Universe::narrow_oop_base_disjoint());
6693
6694 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6760 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6761 // The match rule is needed to make it a 'MachTypeNode'!
6762 match(Set dst (DecodeN src));
6763 predicate(false);
6764
6765 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6766 size(4);
6767 ins_encode %{
6768 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
6769 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift());
6770 %}
6771 ins_pipe(pipe_class_default);
6772 %}
6773
6774 // Add node for expand.
6775 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6776 // The match rule is needed to make it a 'MachTypeNode'!
6777 match(Set dst (DecodeN src));
6778 predicate(false);
6779
6780 format %{ "ADD $dst, $src, R30 \t// DecodeN, add oop base" %}
6781 size(4);
6782 ins_encode %{
6783 // TODO: PPC port $archOpcode(ppc64Opcode_add);
6784 __ add($dst$$Register, $src$$Register, R30);
6785 %}
6786 ins_pipe(pipe_class_default);
6787 %}
6788
6789 // conditianal add base for expand
6790 instruct cond_add_base(iRegPdst dst, flagsReg crx, iRegPsrc src1) %{
6791 // The match rule is needed to make it a 'MachTypeNode'!
6792 // NOTICE that the rule is nonsense - we just have to make sure that:
6793 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6794 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6795 match(Set dst (DecodeN (Binary crx src1)));
6796 predicate(false);
6797
6798 ins_variable_size_depending_on_alignment(true);
6799
6800 format %{ "BEQ $crx, done\n\t"
6801 "ADD $dst, $src1, R30 \t// DecodeN: add oop base if $src1 != NULL\n"
6802 "done:" %}
6803 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling()) */? 12 : 8);
6804 ins_encode %{
6805 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
6806 Label done;
6807 __ beq($crx$$CondRegister, done);
6808 __ add($dst$$Register, $src1$$Register, R30);
6809 // TODO PPC port __ endgroup_if_needed(_size == 12);
6810 __ bind(done);
6811 %}
6812 ins_pipe(pipe_class_default);
6813 %}
6814
6815 instruct cond_set_0_ptr(iRegPdst dst, flagsReg crx, iRegPsrc src1) %{
6816 // The match rule is needed to make it a 'MachTypeNode'!
6817 // NOTICE that the rule is nonsense - we just have to make sure that:
6818 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6819 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6820 match(Set dst (DecodeN (Binary crx src1)));
6821 predicate(false);
6822
6823 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6824 size(4);
6825 ins_encode %{
6826 // This is a Power7 instruction for which no machine description exists.
6827 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6828 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6829 %}
6830 ins_pipe(pipe_class_default);
6831 %}
6832
6833 // shift != 0, base != 0
6834 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6835 match(Set dst (DecodeN src));
6871 size(4);
6872 ins_encode %{
6873 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
6874 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
6875 %}
6876 ins_pipe(pipe_class_default);
6877 %}
6878
6879 // Optimize DecodeN for disjoint base.
6880 // This node requires only one cycle on the critical path.
6881 // We must postalloc_expand as we can not express use_def effects where
6882 // the used register is L and the def'ed register P.
6883 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6884 match(Set dst (DecodeN src));
6885 effect(TEMP_DEF dst);
6886 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6887 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6888 Universe::narrow_oop_base_disjoint());
6889 ins_cost(DEFAULT_COST);
6890
6891 format %{ "MOV $dst, R30 \t\n"
6892 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6893 postalloc_expand %{
6894 loadBaseNode *n1 = new loadBaseNode();
6895 n1->add_req(NULL);
6896 n1->_opnds[0] = op_dst;
6897
6898 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6899 n2->add_req(n_region, n_src, n1);
6900 n2->_opnds[0] = op_dst;
6901 n2->_opnds[1] = op_src;
6902 n2->_opnds[2] = op_dst;
6903 n2->_bottom_type = _bottom_type;
6904
6905 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6906 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6907
6908 nodes->push(n1);
6909 nodes->push(n2);
6910 %}
6911 %}
7286 //
7287 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
7288 // size(0);
7289 // ins_encode( /*empty*/ );
7290 // ins_pipe(pipe_class_default);
7291 //%}
7292
7293 instruct membar_CPUOrder() %{
7294 match(MemBarCPUOrder);
7295 ins_cost(0);
7296
7297 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
7298 size(0);
7299 ins_encode( /*empty*/ );
7300 ins_pipe(pipe_class_default);
7301 %}
7302
7303 //----------Conditional Move---------------------------------------------------
7304
7305 // Cmove using isel.
7306 instruct cmovI_reg_isel(cmpOp cmp, flagsReg crx, iRegIdst dst, iRegIsrc src) %{
7307 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7308 predicate(VM_Version::has_isel());
7309 ins_cost(DEFAULT_COST);
7310
7311 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7312 size(4);
7313 ins_encode %{
7314 // This is a Power7 instruction for which no machine description
7315 // exists. Anyways, the scheduler should be off on Power7.
7316 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7317 int cc = $cmp$$cmpcode;
7318 __ isel($dst$$Register, $crx$$CondRegister,
7319 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7320 %}
7321 ins_pipe(pipe_class_default);
7322 %}
7323
7324 instruct cmovI_reg(cmpOp cmp, flagsReg crx, iRegIdst dst, iRegIsrc src) %{
7325 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7326 predicate(!VM_Version::has_isel());
7327 ins_cost(DEFAULT_COST+BRANCH_COST);
7328
7329 ins_variable_size_depending_on_alignment(true);
7330
7331 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7332 // Worst case is branch + move + stop, no stop without scheduler
7333 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7334 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7335 ins_pipe(pipe_class_default);
7336 %}
7337
7338 instruct cmovI_imm(cmpOp cmp, flagsReg crx, iRegIdst dst, immI16 src) %{
7339 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7340 ins_cost(DEFAULT_COST+BRANCH_COST);
7341
7342 ins_variable_size_depending_on_alignment(true);
7343
7344 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7345 // Worst case is branch + move + stop, no stop without scheduler
7346 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7347 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7348 ins_pipe(pipe_class_default);
7349 %}
7350
7351 // Cmove using isel.
7352 instruct cmovL_reg_isel(cmpOp cmp, flagsReg crx, iRegLdst dst, iRegLsrc src) %{
7353 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7354 predicate(VM_Version::has_isel());
7355 ins_cost(DEFAULT_COST);
7356
7357 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7358 size(4);
7359 ins_encode %{
7360 // This is a Power7 instruction for which no machine description
7361 // exists. Anyways, the scheduler should be off on Power7.
7362 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7363 int cc = $cmp$$cmpcode;
7364 __ isel($dst$$Register, $crx$$CondRegister,
7365 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7366 %}
7367 ins_pipe(pipe_class_default);
7368 %}
7369
7370 instruct cmovL_reg(cmpOp cmp, flagsReg crx, iRegLdst dst, iRegLsrc src) %{
7371 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7372 predicate(!VM_Version::has_isel());
7373 ins_cost(DEFAULT_COST+BRANCH_COST);
7374
7375 ins_variable_size_depending_on_alignment(true);
7376
7377 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7378 // Worst case is branch + move + stop, no stop without scheduler.
7379 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7380 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7381 ins_pipe(pipe_class_default);
7382 %}
7383
7384 instruct cmovL_imm(cmpOp cmp, flagsReg crx, iRegLdst dst, immL16 src) %{
7385 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7386 ins_cost(DEFAULT_COST+BRANCH_COST);
7387
7388 ins_variable_size_depending_on_alignment(true);
7389
7390 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7391 // Worst case is branch + move + stop, no stop without scheduler.
7392 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7393 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7394 ins_pipe(pipe_class_default);
7395 %}
7396
7397 // Cmove using isel.
7398 instruct cmovN_reg_isel(cmpOp cmp, flagsReg crx, iRegNdst dst, iRegNsrc src) %{
7399 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7400 predicate(VM_Version::has_isel());
7401 ins_cost(DEFAULT_COST);
7402
7403 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7404 size(4);
7405 ins_encode %{
7406 // This is a Power7 instruction for which no machine description
7407 // exists. Anyways, the scheduler should be off on Power7.
7408 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7409 int cc = $cmp$$cmpcode;
7410 __ isel($dst$$Register, $crx$$CondRegister,
7411 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7412 %}
7413 ins_pipe(pipe_class_default);
7414 %}
7415
7416 // Conditional move for RegN. Only cmov(reg, reg).
7417 instruct cmovN_reg(cmpOp cmp, flagsReg crx, iRegNdst dst, iRegNsrc src) %{
7418 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7419 predicate(!VM_Version::has_isel());
7420 ins_cost(DEFAULT_COST+BRANCH_COST);
7421
7422 ins_variable_size_depending_on_alignment(true);
7423
7424 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7425 // Worst case is branch + move + stop, no stop without scheduler.
7426 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7427 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7428 ins_pipe(pipe_class_default);
7429 %}
7430
7431 instruct cmovN_imm(cmpOp cmp, flagsReg crx, iRegNdst dst, immN_0 src) %{
7432 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7433 ins_cost(DEFAULT_COST+BRANCH_COST);
7434
7435 ins_variable_size_depending_on_alignment(true);
7436
7437 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7438 // Worst case is branch + move + stop, no stop without scheduler.
7439 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7440 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7441 ins_pipe(pipe_class_default);
7442 %}
7443
7444 // Cmove using isel.
7445 instruct cmovP_reg_isel(cmpOp cmp, flagsReg crx, iRegPdst dst, iRegPsrc src) %{
7446 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7447 predicate(VM_Version::has_isel());
7448 ins_cost(DEFAULT_COST);
7449
7450 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7451 size(4);
7452 ins_encode %{
7453 // This is a Power7 instruction for which no machine description
7454 // exists. Anyways, the scheduler should be off on Power7.
7455 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7456 int cc = $cmp$$cmpcode;
7457 __ isel($dst$$Register, $crx$$CondRegister,
7458 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7459 %}
7460 ins_pipe(pipe_class_default);
7461 %}
7462
7463 instruct cmovP_reg(cmpOp cmp, flagsReg crx, iRegPdst dst, iRegP_N2P src) %{
7464 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7465 predicate(!VM_Version::has_isel());
7466 ins_cost(DEFAULT_COST+BRANCH_COST);
7467
7468 ins_variable_size_depending_on_alignment(true);
7469
7470 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7471 // Worst case is branch + move + stop, no stop without scheduler.
7472 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7473 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7474 ins_pipe(pipe_class_default);
7475 %}
7476
7477 instruct cmovP_imm(cmpOp cmp, flagsReg crx, iRegPdst dst, immP_0 src) %{
7478 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7479 ins_cost(DEFAULT_COST+BRANCH_COST);
7480
7481 ins_variable_size_depending_on_alignment(true);
7482
7483 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7484 // Worst case is branch + move + stop, no stop without scheduler.
7485 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7486 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7487 ins_pipe(pipe_class_default);
7488 %}
7489
7490 instruct cmovF_reg(cmpOp cmp, flagsReg crx, regF dst, regF src) %{
7491 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7492 ins_cost(DEFAULT_COST+BRANCH_COST);
7493
7494 ins_variable_size_depending_on_alignment(true);
7495
7496 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7497 // Worst case is branch + move + stop, no stop without scheduler.
7498 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
7499 ins_encode %{
7500 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
7501 Label done;
7502 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7503 // Branch if not (cmp crx).
7504 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7505 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7506 // TODO PPC port __ endgroup_if_needed(_size == 12);
7507 __ bind(done);
7508 %}
7509 ins_pipe(pipe_class_default);
7510 %}
7511
7512 instruct cmovD_reg(cmpOp cmp, flagsReg crx, regD dst, regD src) %{
7513 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7514 ins_cost(DEFAULT_COST+BRANCH_COST);
7515
7516 ins_variable_size_depending_on_alignment(true);
7517
7518 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7519 // Worst case is branch + move + stop, no stop without scheduler.
7520 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
7521 ins_encode %{
7522 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
7523 Label done;
7524 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7525 // Branch if not (cmp crx).
7526 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7527 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7528 // TODO PPC port __ endgroup_if_needed(_size == 12);
7529 __ bind(done);
7530 %}
7531 ins_pipe(pipe_class_default);
7532 %}
7533
7534 //----------Conditional_store--------------------------------------------------
7535 // Conditional-store of the updated heap-top.
7536 // Used during allocation of the shared heap.
7537 // Sets flags (EQ) on success. Implemented with a CASA on Sparc.
7538
7539 // As compareAndSwapL, but return flag register instead of boolean value in
7540 // int register.
7541 // Used by sun/misc/AtomicLongCSImpl.java.
7542 // Mem_ptr must be a memory operand, else this node does not get
7543 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7544 // can be rematerialized which leads to errors.
7545 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal) %{
7546 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal)));
7547 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7548 ins_encode %{
7549 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7550 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7551 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
7552 noreg, NULL, true);
7553 %}
7554 ins_pipe(pipe_class_default);
7555 %}
7556
7557 // As compareAndSwapP, but return flag register instead of boolean value in
7558 // int register.
7559 // This instruction is matched if UseTLAB is off.
7560 // Mem_ptr must be a memory operand, else this node does not get
7561 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7562 // can be rematerialized which leads to errors.
7563 instruct storePConditional_regP_regP_regP(flagsReg crx, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{
7564 match(Set crx (StorePConditional mem_ptr (Binary oldVal newVal)));
7565 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7566 ins_encode %{
7567 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7568 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7569 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7570 noreg, NULL, true);
7571 %}
7572 ins_pipe(pipe_class_default);
7573 %}
7574
7575 // Implement LoadPLocked. Must be ordered against changes of the memory location
7576 // by storePConditional.
7577 // Don't know whether this is ever used.
7578 instruct loadPLocked(iRegPdst dst, memory mem) %{
7579 match(Set dst (LoadPLocked mem));
7580 ins_cost(MEMORY_REF_COST);
7581
7582 format %{ "LD $dst, $mem \t// loadPLocked\n\t"
7583 "TWI $dst\n\t"
7584 "ISYNC" %}
7585 size(12);
7586 ins_encode( enc_ld_ac(dst, mem) );
7587 ins_pipe(pipe_class_memory);
7588 %}
7589
7590 //----------Compare-And-Swap---------------------------------------------------
7591
7592 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7593 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7594 // matched.
7595
7596 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2) %{
7597 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7598 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7599 // Variable size: instruction count smaller if regs are disjoint.
7600 ins_encode %{
7601 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7602 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7603 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7604 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7605 $res$$Register, true);
7606 %}
7607 ins_pipe(pipe_class_default);
7608 %}
7609
7610 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2) %{
7611 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7612 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7613 // Variable size: instruction count smaller if regs are disjoint.
7614 ins_encode %{
7615 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7616 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7617 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7618 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7619 $res$$Register, true);
7620 %}
7621 ins_pipe(pipe_class_default);
7622 %}
7623
7624 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2) %{
7625 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7626 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7627 // Variable size: instruction count smaller if regs are disjoint.
7628 ins_encode %{
7629 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7630 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7631 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7632 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7633 $res$$Register, NULL, true);
7634 %}
7635 ins_pipe(pipe_class_default);
7636 %}
7637
7638 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2) %{
7639 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7640 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7641 // Variable size: instruction count smaller if regs are disjoint.
7642 ins_encode %{
7643 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7644 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7645 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7646 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7647 $res$$Register, NULL, true);
7648 %}
7649 ins_pipe(pipe_class_default);
7650 %}
7651
7652 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
7653 match(Set res (GetAndAddI mem_ptr src));
7654 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7655 // Variable size: instruction count smaller if regs are disjoint.
7656 ins_encode( enc_GetAndAddI(res, mem_ptr, src) );
7657 ins_pipe(pipe_class_default);
7658 %}
7659
7660 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
7661 match(Set res (GetAndAddL mem_ptr src));
7662 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7663 // Variable size: instruction count smaller if regs are disjoint.
7664 ins_encode( enc_GetAndAddL(res, mem_ptr, src) );
7665 ins_pipe(pipe_class_default);
7666 %}
7667
7668 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
7669 match(Set res (GetAndSetI mem_ptr src));
7670 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7671 // Variable size: instruction count smaller if regs are disjoint.
7672 ins_encode( enc_GetAndSetI(res, mem_ptr, src) );
7673 ins_pipe(pipe_class_default);
7674 %}
7675
7676 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
7677 match(Set res (GetAndSetL mem_ptr src));
7678 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7679 // Variable size: instruction count smaller if regs are disjoint.
7680 ins_encode( enc_GetAndSetL(res, mem_ptr, src) );
7681 ins_pipe(pipe_class_default);
7682 %}
7683
7684 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src) %{
7685 match(Set res (GetAndSetP mem_ptr src));
7686 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7687 // Variable size: instruction count smaller if regs are disjoint.
7688 ins_encode( enc_GetAndSetL(res, mem_ptr, src) );
7689 ins_pipe(pipe_class_default);
7690 %}
7691
7692 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src) %{
7693 match(Set res (GetAndSetN mem_ptr src));
7694 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7695 // Variable size: instruction count smaller if regs are disjoint.
7696 ins_encode( enc_GetAndSetI(res, mem_ptr, src) );
7697 ins_pipe(pipe_class_default);
7698 %}
7699
7700 //----------Arithmetic Instructions--------------------------------------------
7701 // Addition Instructions
7702
7703 // Register Addition
7704 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7705 match(Set dst (AddI src1 src2));
7706 format %{ "ADD $dst, $src1, $src2" %}
7707 size(4);
7708 ins_encode %{
7709 // TODO: PPC port $archOpcode(ppc64Opcode_add);
7710 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7711 %}
7712 ins_pipe(pipe_class_default);
7713 %}
7881 %}
7882 ins_pipe(pipe_class_default);
7883 %}
7884
7885 //---------------------
7886 // Subtraction Instructions
7887
7888 // Register Subtraction
7889 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7890 match(Set dst (SubI src1 src2));
7891 format %{ "SUBF $dst, $src2, $src1" %}
7892 size(4);
7893 ins_encode %{
7894 // TODO: PPC port $archOpcode(ppc64Opcode_subf);
7895 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7896 %}
7897 ins_pipe(pipe_class_default);
7898 %}
7899
7900 // Immediate Subtraction
7901 // The compiler converts "x-c0" into "x+ -c0" (see SubINode::Ideal),
7902 // so this rule seems to be unused.
7903 instruct subI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
7904 match(Set dst (SubI src1 src2));
7905 format %{ "SUBI $dst, $src1, $src2" %}
7906 size(4);
7907 ins_encode %{
7908 // TODO: PPC port $archOpcode(ppc64Opcode_addi);
7909 __ addi($dst$$Register, $src1$$Register, ($src2$$constant) * (-1));
7910 %}
7911 ins_pipe(pipe_class_default);
7912 %}
7913
7914 // SubI from constant (using subfic).
7915 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
7916 match(Set dst (SubI src1 src2));
7917 format %{ "SUBI $dst, $src1, $src2" %}
7918
7919 size(4);
7920 ins_encode %{
7921 // TODO: PPC port $archOpcode(ppc64Opcode_subfic);
7922 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
7923 %}
7924 ins_pipe(pipe_class_default);
7925 %}
7926
7927 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
7928 // positive integers and 0xF...F for negative ones.
7929 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
7930 // no match-rule, false predicate
7931 effect(DEF dst, USE src);
7932 predicate(false);
7972 ins_encode %{
7973 // TODO: PPC port $archOpcode(ppc64Opcode_subf);
7974 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7975 %}
7976 ins_pipe(pipe_class_default);
7977 %}
7978
7979 // SubL + convL2I.
7980 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7981 match(Set dst (ConvL2I (SubL src1 src2)));
7982
7983 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
7984 size(4);
7985 ins_encode %{
7986 // TODO: PPC port $archOpcode(ppc64Opcode_subf);
7987 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7988 %}
7989 ins_pipe(pipe_class_default);
7990 %}
7991
7992 // Immediate Subtraction
7993 // The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
7994 // so this rule seems to be unused.
7995 // No constant pool entries required.
7996 instruct subL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
7997 match(Set dst (SubL src1 src2));
7998
7999 format %{ "SUBI $dst, $src1, $src2 \t// long" %}
8000 size(4);
8001 ins_encode %{
8002 // TODO: PPC port $archOpcode(ppc64Opcode_addi);
8003 __ addi($dst$$Register, $src1$$Register, ($src2$$constant) * (-1));
8004 %}
8005 ins_pipe(pipe_class_default);
8006 %}
8007
8008 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8009 // positive longs and 0xF...F for negative ones.
8010 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8011 // no match-rule, false predicate
8012 effect(DEF dst, USE src);
8013 predicate(false);
8014
8015 format %{ "SRADI $dst, $src, #63" %}
8016 size(4);
8017 ins_encode %{
8018 // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
8019 __ sradi($dst$$Register, $src$$Register, 0x3f);
8020 %}
8021 ins_pipe(pipe_class_default);
8022 %}
8023
8024 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8025 // positive longs and 0xF...F for negative ones.
8026 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8027 // no match-rule, false predicate
8148 ins_pipe(pipe_class_default);
8149 %}
8150
8151 // Integer Division with constant, but not -1.
8152 // We should be able to improve this by checking the type of src2.
8153 // It might well be that src2 is known to be positive.
8154 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8155 match(Set dst (DivI src1 src2));
8156 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8157 ins_cost(2*DEFAULT_COST);
8158
8159 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8160 size(4);
8161 ins_encode %{
8162 // TODO: PPC port $archOpcode(ppc64Opcode_divw);
8163 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8164 %}
8165 ins_pipe(pipe_class_default);
8166 %}
8167
8168 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsReg crx, iRegIsrc src1) %{
8169 effect(USE_DEF dst, USE src1, USE crx);
8170 predicate(false);
8171
8172 ins_variable_size_depending_on_alignment(true);
8173
8174 format %{ "CMOVE $dst, neg($src1), $crx" %}
8175 // Worst case is branch + move + stop, no stop without scheduler.
8176 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
8177 ins_encode %{
8178 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
8179 Label done;
8180 __ bne($crx$$CondRegister, done);
8181 __ neg($dst$$Register, $src1$$Register);
8182 // TODO PPC port __ endgroup_if_needed(_size == 12);
8183 __ bind(done);
8184 %}
8185 ins_pipe(pipe_class_default);
8186 %}
8187
8188 // Integer Division with Registers not containing constants.
8211 __ neg($dst$$Register, $src1$$Register);
8212 %}
8213 ins_pipe(pipe_class_default);
8214 %}
8215
8216 // Long Division with constant, but not -1.
8217 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8218 match(Set dst (DivL src1 src2));
8219 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8220 ins_cost(2*DEFAULT_COST);
8221
8222 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8223 size(4);
8224 ins_encode %{
8225 // TODO: PPC port $archOpcode(ppc64Opcode_divd);
8226 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8227 %}
8228 ins_pipe(pipe_class_default);
8229 %}
8230
8231 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsReg crx, iRegLsrc src1) %{
8232 effect(USE_DEF dst, USE src1, USE crx);
8233 predicate(false);
8234
8235 ins_variable_size_depending_on_alignment(true);
8236
8237 format %{ "CMOVE $dst, neg($src1), $crx" %}
8238 // Worst case is branch + move + stop, no stop without scheduler.
8239 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
8240 ins_encode %{
8241 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
8242 Label done;
8243 __ bne($crx$$CondRegister, done);
8244 __ neg($dst$$Register, $src1$$Register);
8245 // TODO PPC port __ endgroup_if_needed(_size == 12);
8246 __ bind(done);
8247 %}
8248 ins_pipe(pipe_class_default);
8249 %}
8250
8251 // Long Division with Registers not containing constants.
8264
8265 // Integer Remainder with registers.
8266 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8267 match(Set dst (ModI src1 src2));
8268 ins_cost(10*DEFAULT_COST);
8269
8270 expand %{
8271 immI16 imm %{ (int)-1 %}
8272 flagsReg tmp1;
8273 iRegIdst tmp2;
8274 iRegIdst tmp3;
8275 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8276 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8277 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8278 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8279 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8280 %}
8281 %}
8282
8283 // Long Remainder with registers
8284 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8285 match(Set dst (ModL src1 src2));
8286 ins_cost(10*DEFAULT_COST);
8287
8288 expand %{
8289 immL16 imm %{ (int)-1 %}
8290 flagsReg tmp1;
8291 iRegLdst tmp2;
8292 iRegLdst tmp3;
8293 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8294 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8295 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8296 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8297 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8298 %}
8299 %}
8300
8301 // Integer Shift Instructions
8302
8303 // Register Shift Left
8304
8994 %}
8995
8996 // Register And Long
8997 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8998 match(Set dst (AndL src1 src2));
8999 ins_cost(DEFAULT_COST);
9000
9001 format %{ "AND $dst, $src1, $src2 \t// long" %}
9002 size(4);
9003 ins_encode %{
9004 // TODO: PPC port $archOpcode(ppc64Opcode_and);
9005 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9006 %}
9007 ins_pipe(pipe_class_default);
9008 %}
9009
9010 // Immediate And long
9011 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9012 match(Set dst (AndL src1 src2));
9013 effect(KILL cr0);
9014 ins_cost(DEFAULT_COST);
9015
9016 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
9017 size(4);
9018 ins_encode %{
9019 // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
9020 // FIXME: avoid andi_ ?
9021 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9022 %}
9023 ins_pipe(pipe_class_default);
9024 %}
9025
9026 // Immediate And Long where the immediate is a negative power of 2.
9027 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9028 match(Set dst (AndL src1 src2));
9029 format %{ "ANDDI $dst, $src1, $src2" %}
9030 size(4);
9031 ins_encode %{
9032 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
9033 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant));
9034 %}
9786 // TODO: PPC port $archOpcode(ppc64Opcode_or);
9787 __ mr_if_needed($dst$$Register, $src$$Register);
9788 %}
9789 ins_pipe(pipe_class_default);
9790 %}
9791
9792 instruct convD2IRaw_regD(regD dst, regD src) %{
9793 // no match-rule, false predicate
9794 effect(DEF dst, USE src);
9795 predicate(false);
9796
9797 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
9798 size(4);
9799 ins_encode %{
9800 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);;
9801 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
9802 %}
9803 ins_pipe(pipe_class_default);
9804 %}
9805
9806 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsReg crx, stackSlotL src) %{
9807 // no match-rule, false predicate
9808 effect(DEF dst, USE crx, USE src);
9809 predicate(false);
9810
9811 ins_variable_size_depending_on_alignment(true);
9812
9813 format %{ "cmovI $crx, $dst, $src" %}
9814 // Worst case is branch + move + stop, no stop without scheduler.
9815 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
9816 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9817 ins_pipe(pipe_class_default);
9818 %}
9819
9820 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsReg crx, stackSlotL mem) %{
9821 // no match-rule, false predicate
9822 effect(DEF dst, USE crx, USE mem);
9823 predicate(false);
9824
9825 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %}
9826 postalloc_expand %{
9827 //
9828 // replaces
9829 //
9830 // region dst crx mem
9831 // \ | | /
9832 // dst=cmovI_bso_stackSlotL_conLvalue0
9833 //
9834 // with
9835 //
9836 // region dst
9837 // \ /
9838 // dst=loadConI16(0)
9839 // |
9840 // ^ region dst crx mem
9955 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9956 __ clrldi($dst$$Register, $src$$Register, 32);
9957 %}
9958 ins_pipe(pipe_class_default);
9959 %}
9960
9961 instruct convF2LRaw_regF(regF dst, regF src) %{
9962 // no match-rule, false predicate
9963 effect(DEF dst, USE src);
9964 predicate(false);
9965
9966 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
9967 size(4);
9968 ins_encode %{
9969 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
9970 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
9971 %}
9972 ins_pipe(pipe_class_default);
9973 %}
9974
9975 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsReg crx, stackSlotL src) %{
9976 // no match-rule, false predicate
9977 effect(DEF dst, USE crx, USE src);
9978 predicate(false);
9979
9980 ins_variable_size_depending_on_alignment(true);
9981
9982 format %{ "cmovL $crx, $dst, $src" %}
9983 // Worst case is branch + move + stop, no stop without scheduler.
9984 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
9985 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9986 ins_pipe(pipe_class_default);
9987 %}
9988
9989 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsReg crx, stackSlotL mem) %{
9990 // no match-rule, false predicate
9991 effect(DEF dst, USE crx, USE mem);
9992 predicate(false);
9993
9994 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %}
9995 postalloc_expand %{
9996 //
9997 // replaces
9998 //
9999 // region dst crx mem
10000 // \ | | /
10001 // dst=cmovL_bso_stackSlotL_conLvalue0
10002 //
10003 // with
10004 //
10005 // region dst
10006 // \ /
10007 // dst=loadConL16(0)
10008 // |
10009 // ^ region dst crx mem
10238
10239 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10240 match(Set crx (CmpI src1 src2));
10241 format %{ "CMPWI $crx, $src1, $src2" %}
10242 size(4);
10243 ins_encode %{
10244 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
10245 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10246 %}
10247 ins_pipe(pipe_class_compare);
10248 %}
10249
10250 // (src1 & src2) == 0?
10251 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10252 match(Set cr0 (CmpI (AndI src1 src2) zero));
10253 // r0 is killed
10254 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10255 size(4);
10256 ins_encode %{
10257 // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
10258 // FIXME: avoid andi_ ?
10259 __ andi_(R0, $src1$$Register, $src2$$constant);
10260 %}
10261 ins_pipe(pipe_class_compare);
10262 %}
10263
10264 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10265 match(Set crx (CmpL src1 src2));
10266 format %{ "CMPD $crx, $src1, $src2" %}
10267 size(4);
10268 ins_encode %{
10269 // TODO: PPC port $archOpcode(ppc64Opcode_cmp);
10270 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10271 %}
10272 ins_pipe(pipe_class_compare);
10273 %}
10274
10275 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10276 match(Set crx (CmpL src1 src2));
10277 format %{ "CMPDI $crx, $src1, $src2" %}
10278 size(4);
10285
10286 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10287 match(Set cr0 (CmpL (AndL src1 src2) zero));
10288 // r0 is killed
10289 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10290 size(4);
10291 ins_encode %{
10292 // TODO: PPC port $archOpcode(ppc64Opcode_and_);
10293 __ and_(R0, $src1$$Register, $src2$$Register);
10294 %}
10295 ins_pipe(pipe_class_compare);
10296 %}
10297
10298 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10299 match(Set cr0 (CmpL (AndL src1 src2) zero));
10300 // r0 is killed
10301 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10302 size(4);
10303 ins_encode %{
10304 // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
10305 // FIXME: avoid andi_ ?
10306 __ andi_(R0, $src1$$Register, $src2$$constant);
10307 %}
10308 ins_pipe(pipe_class_compare);
10309 %}
10310
10311 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsReg crx) %{
10312 // no match-rule, false predicate
10313 effect(DEF dst, USE crx);
10314 predicate(false);
10315
10316 ins_variable_size_depending_on_alignment(true);
10317
10318 format %{ "cmovI $crx, $dst, -1, 0, +1" %}
10319 // Worst case is branch + move + branch + move + stop, no stop without scheduler.
10320 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16);
10321 ins_encode %{
10322 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
10323 Label done;
10324 // li(Rdst, 0); // equal -> 0
10325 __ beq($crx$$CondRegister, done);
10326 __ li($dst$$Register, 1); // greater -> +1
10327 __ bgt($crx$$CondRegister, done);
10328 __ li($dst$$Register, -1); // unordered or less -> -1
10329 // TODO: PPC port__ endgroup_if_needed(_size == 20);
10330 __ bind(done);
10331 %}
10332 ins_pipe(pipe_class_compare);
10333 %}
10334
10335 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsReg crx) %{
10336 // no match-rule, false predicate
10337 effect(DEF dst, USE crx);
10338 predicate(false);
10339
10340 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %}
10341 postalloc_expand %{
10342 //
10343 // replaces
10344 //
10345 // region crx
10346 // \ |
10347 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1
10348 //
10349 // with
10350 //
10351 // region
10352 // \
10353 // dst=loadConI16(0)
10354 // |
10355 // ^ region crx
10605 // Used in postalloc expand.
10606 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10607 // This match rule prevents reordering of node before a safepoint.
10608 // This only makes sense if this instructions is used exclusively
10609 // for the expansion of EncodeP!
10610 match(Set crx (CmpP src1 src2));
10611 predicate(false);
10612
10613 format %{ "CMPDI $crx, $src1, $src2" %}
10614 size(4);
10615 ins_encode %{
10616 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
10617 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10618 %}
10619 ins_pipe(pipe_class_compare);
10620 %}
10621
10622 //----------Float Compares----------------------------------------------------
10623
10624 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10625 // no match-rule, false predicate
10626 effect(DEF crx, USE src1, USE src2);
10627 predicate(false);
10628
10629 format %{ "cmpFUrd $crx, $src1, $src2" %}
10630 size(4);
10631 ins_encode %{
10632 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
10633 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10634 %}
10635 ins_pipe(pipe_class_default);
10636 %}
10637
10638 instruct cmov_bns_less(flagsReg crx) %{
10639 // no match-rule, false predicate
10640 effect(DEF crx);
10641 predicate(false);
10642
10643 ins_variable_size_depending_on_alignment(true);
10644
10645 format %{ "cmov $crx" %}
10646 // Worst case is branch + move + stop, no stop without scheduler.
10714
10715 // Insert new nodes.
10716 nodes->push(m1);
10717 nodes->push(m2);
10718 %}
10719 %}
10720
10721 // Compare float, generate -1,0,1
10722 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{
10723 match(Set dst (CmpF3 src1 src2));
10724 ins_cost(DEFAULT_COST*5+BRANCH_COST);
10725
10726 expand %{
10727 flagsReg tmp1;
10728 cmpFUnordered_reg_reg(tmp1, src1, src2);
10729 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1);
10730 %}
10731 %}
10732
10733 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10734 // no match-rule, false predicate
10735 effect(DEF crx, USE src1, USE src2);
10736 predicate(false);
10737
10738 format %{ "cmpFUrd $crx, $src1, $src2" %}
10739 size(4);
10740 ins_encode %{
10741 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
10742 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10743 %}
10744 ins_pipe(pipe_class_default);
10745 %}
10746
10747 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
10748 match(Set crx (CmpD src1 src2));
10749 ins_cost(DEFAULT_COST+BRANCH_COST);
10750
10751 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
10752 postalloc_expand %{
10753 //
10754 // replaces
10755 //
10813 match(Goto);
10814 effect(USE labl);
10815 ins_cost(BRANCH_COST);
10816
10817 format %{ "B $labl" %}
10818 size(4);
10819 ins_encode %{
10820 // TODO: PPC port $archOpcode(ppc64Opcode_b);
10821 Label d; // dummy
10822 __ bind(d);
10823 Label* p = $labl$$label;
10824 // `p' is `NULL' when this encoding class is used only to
10825 // determine the size of the encoded instruction.
10826 Label& l = (NULL == p)? d : *(p);
10827 __ b(l);
10828 %}
10829 ins_pipe(pipe_class_default);
10830 %}
10831
10832 // Conditional Near Branch
10833 instruct branchCon(cmpOp cmp, flagsReg crx, label lbl) %{
10834 // Same match rule as `branchConFar'.
10835 match(If cmp crx);
10836 effect(USE lbl);
10837 ins_cost(BRANCH_COST);
10838
10839 // If set to 1 this indicates that the current instruction is a
10840 // short variant of a long branch. This avoids using this
10841 // instruction in first-pass matching. It will then only be used in
10842 // the `Shorten_branches' pass.
10843 ins_short_branch(1);
10844
10845 format %{ "B$cmp $crx, $lbl" %}
10846 size(4);
10847 ins_encode( enc_bc(crx, cmp, lbl) );
10848 ins_pipe(pipe_class_default);
10849 %}
10850
10851 // This is for cases when the ppc64 `bc' instruction does not
10852 // reach far enough. So we emit a far branch here, which is more
10853 // expensive.
10854 //
10855 // Conditional Far Branch
10856 instruct branchConFar(cmpOp cmp, flagsReg crx, label lbl) %{
10857 // Same match rule as `branchCon'.
10858 match(If cmp crx);
10859 effect(USE crx, USE lbl);
10860 predicate(!false /* TODO: PPC port HB_Schedule*/);
10861 // Higher cost than `branchCon'.
10862 ins_cost(5*BRANCH_COST);
10863
10864 // This is not a short variant of a branch, but the long variant.
10865 ins_short_branch(0);
10866
10867 format %{ "B_FAR$cmp $crx, $lbl" %}
10868 size(8);
10869 ins_encode( enc_bc_far(crx, cmp, lbl) );
10870 ins_pipe(pipe_class_default);
10871 %}
10872
10873 // Conditional Branch used with Power6 scheduler (can be far or short).
10874 instruct branchConSched(cmpOp cmp, flagsReg crx, label lbl) %{
10875 // Same match rule as `branchCon'.
10876 match(If cmp crx);
10877 effect(USE crx, USE lbl);
10878 predicate(false /* TODO: PPC port HB_Schedule*/);
10879 // Higher cost than `branchCon'.
10880 ins_cost(5*BRANCH_COST);
10881
10882 // Actually size doesn't depend on alignment but on shortening.
10883 ins_variable_size_depending_on_alignment(true);
10884 // long variant.
10885 ins_short_branch(0);
10886
10887 format %{ "B_FAR$cmp $crx, $lbl" %}
10888 size(8); // worst case
10889 ins_encode( enc_bc_short_far(crx, cmp, lbl) );
10890 ins_pipe(pipe_class_default);
10891 %}
10892
10893 instruct branchLoopEnd(cmpOp cmp, flagsReg crx, label labl) %{
10894 match(CountedLoopEnd cmp crx);
10895 effect(USE labl);
10896 ins_cost(BRANCH_COST);
10897
10898 // short variant.
10899 ins_short_branch(1);
10900
10901 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
10902 size(4);
10903 ins_encode( enc_bc(crx, cmp, labl) );
10904 ins_pipe(pipe_class_default);
10905 %}
10906
10907 instruct branchLoopEndFar(cmpOp cmp, flagsReg crx, label labl) %{
10908 match(CountedLoopEnd cmp crx);
10909 effect(USE labl);
10910 predicate(!false /* TODO: PPC port HB_Schedule */);
10911 ins_cost(BRANCH_COST);
10912
10913 // Long variant.
10914 ins_short_branch(0);
10915
10916 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10917 size(8);
10918 ins_encode( enc_bc_far(crx, cmp, labl) );
10919 ins_pipe(pipe_class_default);
10920 %}
10921
10922 // Conditional Branch used with Power6 scheduler (can be far or short).
10923 instruct branchLoopEndSched(cmpOp cmp, flagsReg crx, label labl) %{
10924 match(CountedLoopEnd cmp crx);
10925 effect(USE labl);
10926 predicate(false /* TODO: PPC port HB_Schedule */);
10927 // Higher cost than `branchCon'.
10928 ins_cost(5*BRANCH_COST);
10929
10930 // Actually size doesn't depend on alignment but on shortening.
10931 ins_variable_size_depending_on_alignment(true);
10932 // Long variant.
10933 ins_short_branch(0);
10934
10935 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10936 size(8); // worst case
10937 ins_encode( enc_bc_short_far(crx, cmp, labl) );
10938 ins_pipe(pipe_class_default);
10939 %}
10940
10941 // ============================================================================
10942 // Java runtime operations, intrinsics and other complex operations.
10943
10952 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
10953 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
10954 match(Set result (PartialSubtypeCheck subklass superklass));
10955 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
10956 ins_cost(DEFAULT_COST*10);
10957
10958 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
10959 ins_encode %{
10960 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10961 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
10962 $tmp_klass$$Register, NULL, $result$$Register);
10963 %}
10964 ins_pipe(pipe_class_default);
10965 %}
10966
10967 // inlined locking and unlocking
10968
10969 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
10970 match(Set crx (FastLock oop box));
10971 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
10972 // TODO PPC port predicate(!UseNewFastLockPPC64 || UseBiasedLocking);
10973
10974 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
10975 ins_encode %{
10976 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10977 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
10978 $tmp3$$Register, $tmp1$$Register, $tmp2$$Register);
10979 // If locking was successfull, crx should indicate 'EQ'.
10980 // The compiler generates a branch to the runtime call to
10981 // _complete_monitor_locking_Java for the case where crx is 'NE'.
10982 %}
10983 ins_pipe(pipe_class_compare);
10984 %}
10985
10986 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
10987 match(Set crx (FastUnlock oop box));
10988 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
10989
10990 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
10991 ins_encode %{
10992 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10993 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
10994 $tmp3$$Register, $tmp1$$Register, $tmp2$$Register);
10995 // If unlocking was successfull, crx should indicate 'EQ'.
10996 // The compiler generates a branch to the runtime call to
10997 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
10998 %}
10999 ins_pipe(pipe_class_compare);
11000 %}
11001
11002 // Align address.
11003 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11004 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11005
11006 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11007 size(4);
11008 ins_encode %{
11009 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
11010 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant));
11011 %}
11012 ins_pipe(pipe_class_default);
11013 %}
11014
11640 match(Set dst (ReplicateF src));
11641 predicate(n->as_Vector()->length() == 2);
11642 ins_cost(5 * DEFAULT_COST);
11643
11644 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
11645 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
11646 %}
11647
11648 // Replicate scalar zero constant to packed float values in Double register
11649 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
11650 match(Set dst (ReplicateF zero));
11651 predicate(n->as_Vector()->length() == 2);
11652
11653 format %{ "LI $dst, #0 \t// replicate2F" %}
11654 ins_encode %{
11655 // TODO: PPC port $archOpcode(ppc64Opcode_addi);
11656 __ li($dst$$Register, 0x0);
11657 %}
11658 ins_pipe(pipe_class_default);
11659 %}
11660
11661 // ============================================================================
11662 // Safepoint Instruction
11663
11664 instruct safePoint_poll(iRegPdst poll) %{
11665 match(SafePoint poll);
11666 predicate(LoadPollAddressFromThread);
11667
11668 // It caused problems to add the effect that r0 is killed, but this
11669 // effect no longer needs to be mentioned, since r0 is not contained
11670 // in a reg_class.
11671
11672 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
11673 size(4);
11674 ins_encode( enc_poll(0x0, poll) );
11675 ins_pipe(pipe_class_default);
11676 %}
11677
11678 // Safepoint without per-thread support. Load address of page to poll
11679 // as constant.
|
430 R9,
431 R10,
432 R11,
433 R12,
434 /*R13*/ // system thread id
435 R14,
436 R15,
437 /*R16*/ // R16_thread
438 R17,
439 R18,
440 R19,
441 R20,
442 R21,
443 R22,
444 R23,
445 R24,
446 R25,
447 R26,
448 R27,
449 R28,
450 /*R29,*/ // global TOC
451 R30,
452 R31
453 );
454
455 // 32 bit registers that can only be read i.e. these registers can
456 // only be src of all instructions.
457 reg_class bits32_reg_ro(
458 /*R0*/ // R0
459 /*R1*/ // SP
460 R2 // TOC
461 R3,
462 R4,
463 R5,
464 R6,
465 R7,
466 R8,
467 R9,
468 R10,
469 R11,
470 R12,
471 /*R13*/ // system thread id
472 R14,
473 R15,
474 /*R16*/ // R16_thread
475 R17,
476 R18,
477 R19,
478 R20,
479 R21,
480 R22,
481 R23,
482 R24,
483 R25,
484 R26,
485 R27,
486 R28,
487 /*R29,*/
488 R30,
489 R31
490 );
491
492 reg_class rscratch1_bits32_reg(R11);
493 reg_class rscratch2_bits32_reg(R12);
494 reg_class rarg1_bits32_reg(R3);
495 reg_class rarg2_bits32_reg(R4);
496 reg_class rarg3_bits32_reg(R5);
497 reg_class rarg4_bits32_reg(R6);
498
499 // ----------------------------
500 // 64 Bit Register Classes
501 // ----------------------------
502 // 64-bit build means 64-bit pointers means hi/lo pairs
503
504 reg_class rscratch1_bits64_reg(R11_H, R11);
505 reg_class rscratch2_bits64_reg(R12_H, R12);
506 reg_class rarg1_bits64_reg(R3_H, R3);
507 reg_class rarg2_bits64_reg(R4_H, R4);
508 reg_class rarg3_bits64_reg(R5_H, R5);
509 reg_class rarg4_bits64_reg(R6_H, R6);
510 // Thread register, 'written' by tlsLoadP, see there.
511 reg_class thread_bits64_reg(R16_H, R16);
527 R9_H, R9,
528 R10_H, R10,
529 R11_H, R11,
530 R12_H, R12,
531 /*R13_H, R13*/ // system thread id
532 R14_H, R14,
533 R15_H, R15,
534 /*R16_H, R16*/ // R16_thread
535 R17_H, R17,
536 R18_H, R18,
537 R19_H, R19,
538 R20_H, R20,
539 R21_H, R21,
540 R22_H, R22,
541 R23_H, R23,
542 R24_H, R24,
543 R25_H, R25,
544 R26_H, R26,
545 R27_H, R27,
546 R28_H, R28,
547 /*R29_H, R29,*/
548 R30_H, R30,
549 R31_H, R31
550 );
551
552 // 64 bit registers used excluding r2, r11 and r12
553 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses
554 // r2, r11 and r12 internally.
555 reg_class bits64_reg_leaf_call(
556 /*R0_H, R0*/ // R0
557 /*R1_H, R1*/ // SP
558 /*R2_H, R2*/ // TOC
559 R3_H, R3,
560 R4_H, R4,
561 R5_H, R5,
562 R6_H, R6,
563 R7_H, R7,
564 R8_H, R8,
565 R9_H, R9,
566 R10_H, R10,
567 /*R11_H, R11*/
568 /*R12_H, R12*/
569 /*R13_H, R13*/ // system thread id
570 R14_H, R14,
571 R15_H, R15,
572 /*R16_H, R16*/ // R16_thread
573 R17_H, R17,
574 R18_H, R18,
575 R19_H, R19,
576 R20_H, R20,
577 R21_H, R21,
578 R22_H, R22,
579 R23_H, R23,
580 R24_H, R24,
581 R25_H, R25,
582 R26_H, R26,
583 R27_H, R27,
584 R28_H, R28,
585 /*R29_H, R29,*/
586 R30_H, R30,
587 R31_H, R31
588 );
589
590 // Used to hold the TOC to avoid collisions with expanded DynamicCall
591 // which uses r19 as inline cache internally and expanded LeafCall which uses
592 // r2, r11 and r12 internally.
593 reg_class bits64_constant_table_base(
594 /*R0_H, R0*/ // R0
595 /*R1_H, R1*/ // SP
596 /*R2_H, R2*/ // TOC
597 R3_H, R3,
598 R4_H, R4,
599 R5_H, R5,
600 R6_H, R6,
601 R7_H, R7,
602 R8_H, R8,
603 R9_H, R9,
604 R10_H, R10,
605 /*R11_H, R11*/
606 /*R12_H, R12*/
607 /*R13_H, R13*/ // system thread id
608 R14_H, R14,
609 R15_H, R15,
610 /*R16_H, R16*/ // R16_thread
611 R17_H, R17,
612 R18_H, R18,
613 /*R19_H, R19*/
614 R20_H, R20,
615 R21_H, R21,
616 R22_H, R22,
617 R23_H, R23,
618 R24_H, R24,
619 R25_H, R25,
620 R26_H, R26,
621 R27_H, R27,
622 R28_H, R28,
623 /*R29_H, R29,*/
624 R30_H, R30,
625 R31_H, R31
626 );
627
628 // 64 bit registers that can only be read i.e. these registers can
629 // only be src of all instructions.
630 reg_class bits64_reg_ro(
631 /*R0_H, R0*/ // R0
632 R1_H, R1,
633 R2_H, R2, // TOC
634 R3_H, R3,
635 R4_H, R4,
636 R5_H, R5,
637 R6_H, R6,
638 R7_H, R7,
639 R8_H, R8,
640 R9_H, R9,
641 R10_H, R10,
642 R11_H, R11,
643 R12_H, R12,
644 /*R13_H, R13*/ // system thread id
645 R14_H, R14,
646 R15_H, R15,
647 R16_H, R16, // R16_thread
648 R17_H, R17,
649 R18_H, R18,
650 R19_H, R19,
651 R20_H, R20,
652 R21_H, R21,
653 R22_H, R22,
654 R23_H, R23,
655 R24_H, R24,
656 R25_H, R25,
657 R26_H, R26,
658 R27_H, R27,
659 R28_H, R28,
660 /*R29_H, R29,*/ // TODO: let allocator handle TOC!!
661 R30_H, R30,
662 R31_H, R31
663 );
664
665
666 // ----------------------------
667 // Special Class for Condition Code Flags Register
668
669 reg_class int_flags(
670 /*CCR0*/ // scratch
671 /*CCR1*/ // scratch
672 /*CCR2*/ // nv!
673 /*CCR3*/ // nv!
674 /*CCR4*/ // nv!
675 CCR5,
676 CCR6,
677 CCR7
678 );
679
680 reg_class int_flags_ro(
681 CCR0,
682 CCR1,
683 CCR2,
684 CCR3,
685 CCR4,
686 CCR5,
687 CCR6,
688 CCR7
689 );
690
691 reg_class int_flags_CR0(CCR0);
692 reg_class int_flags_CR1(CCR1);
693 reg_class int_flags_CR6(CCR6);
694 reg_class ctr_reg(SR_CTR);
695
696 // ----------------------------
697 // Float Register Classes
698 // ----------------------------
699
700 reg_class flt_reg(
701 /*F0*/ // scratch
702 F1,
703 F2,
704 F3,
705 F4,
706 F5,
707 F6,
708 F7,
709 F8,
710 F9,
2770 assert((Idisp & 0x3) == 0, "unaligned offset");
2771 __ std($src$$Register, Idisp, $mem$$base$$Register);
2772 %}
2773
2774 enc_class enc_stfs(RegF src, memory mem) %{
2775 // TODO: PPC port $archOpcode(ppc64Opcode_stfs);
2776 MacroAssembler _masm(&cbuf);
2777 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2778 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2779 %}
2780
2781 enc_class enc_stfd(RegF src, memory mem) %{
2782 // TODO: PPC port $archOpcode(ppc64Opcode_stfd);
2783 MacroAssembler _masm(&cbuf);
2784 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2785 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2786 %}
2787
2788 // Use release_store for card-marking to ensure that previous
2789 // oop-stores are visible before the card-mark change.
2790 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{
2791 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2792 // FIXME: Implement this as a cmove and use a fixed condition code
2793 // register which is written on every transition to compiled code,
2794 // e.g. in call-stub and when returning from runtime stubs.
2795 //
2796 // Proposed code sequence for the cmove implementation:
2797 //
2798 // Label skip_release;
2799 // __ beq(CCRfixed, skip_release);
2800 // __ release();
2801 // __ bind(skip_release);
2802 // __ stb(card mark);
2803
2804 MacroAssembler _masm(&cbuf);
2805 Label skip_storestore;
2806
2807 #if 0 // TODO: PPC port
2808 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the
2809 // StoreStore barrier conditionally.
2810 __ lwz(R0, 0, $releaseFieldAddr$$Register);
2811 __ cmpwi($crx$$CondRegister, R0, 0);
2812 __ beq_predict_taken($crx$$CondRegister, skip_storestore);
2813 #endif
2814 __ li(R0, 0);
2815 __ membar(Assembler::StoreStore);
2816 #if 0 // TODO: PPC port
2817 __ bind(skip_storestore);
2818 #endif
2819
2820 // Do the store.
2821 if ($mem$$index == 0) {
2822 __ stb(R0, $mem$$disp, $mem$$base$$Register);
2823 } else {
2824 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc");
2825 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register);
2826 }
2827 %}
2828
2829 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2830
2831 if (VM_Version::has_isel()) {
2832 // use isel instruction with Power 7
3002 n1->add_req(n_region, n_src);
3003 n1->_opnds[0] = op_dst;
3004 n1->_opnds[1] = op_src;
3005 n1->_bottom_type = _bottom_type;
3006
3007 decodeN_addNode *n2 = new decodeN_addNode();
3008 n2->add_req(n_region, n1);
3009 n2->_opnds[0] = op_dst;
3010 n2->_opnds[1] = op_dst;
3011 n2->_bottom_type = _bottom_type;
3012 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3013 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3014
3015 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3016 ra_->set_oop(n2, true);
3017
3018 nodes->push(n1);
3019 nodes->push(n2);
3020 %}
3021
3022 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{
3023 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3024
3025 MacroAssembler _masm(&cbuf);
3026 int cc = $cmp$$cmpcode;
3027 int flags_reg = $crx$$reg;
3028 Label done;
3029 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3030 // Branch if not (cmp crx).
3031 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done);
3032 __ mr($dst$$Register, $src$$Register);
3033 // TODO PPC port __ endgroup_if_needed(_size == 12);
3034 __ bind(done);
3035 %}
3036
3037 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{
3038 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3039
3040 MacroAssembler _masm(&cbuf);
3041 Label done;
3042 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3043 // Branch if not (cmp crx).
3044 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
3045 __ li($dst$$Register, $src$$constant);
3046 // TODO PPC port __ endgroup_if_needed(_size == 12);
3047 __ bind(done);
3048 %}
3049
3050 // New atomics.
3051 enc_class enc_GetAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
3052 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3053
3054 MacroAssembler _masm(&cbuf);
3055 Register Rtmp = R0;
3056 Register Rres = $res$$Register;
3057 Register Rsrc = $src$$Register;
3163 __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3164 __ li($dst$$Register, $zero$$constant);
3165 __ beq($crx$$CondRegister, done);
3166 __ li($dst$$Register, $notzero$$constant);
3167 __ bind(done);
3168 %}
3169
3170 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3171 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3172
3173 MacroAssembler _masm(&cbuf);
3174
3175 Label done;
3176 __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3177 __ li($dst$$Register, $zero$$constant);
3178 __ beq($crx$$CondRegister, done);
3179 __ li($dst$$Register, $notzero$$constant);
3180 __ bind(done);
3181 %}
3182
3183 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3184 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3185
3186 MacroAssembler _masm(&cbuf);
3187 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3188 Label done;
3189 __ bso($crx$$CondRegister, done);
3190 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3191 // TODO PPC port __ endgroup_if_needed(_size == 12);
3192 __ bind(done);
3193 %}
3194
3195 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3196 // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3197
3198 MacroAssembler _masm(&cbuf);
3199 Label d; // dummy
3200 __ bind(d);
3201 Label* p = ($lbl$$label);
3202 // `p' is `NULL' when this encoding class is used only to
3203 // determine the size of the encoded instruction.
3204 Label& l = (NULL == p)? d : *(p);
3205 int cc = $cmp$$cmpcode;
3206 int flags_reg = $crx$$reg;
3207 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3208 int bhint = Assembler::bhintNoHint;
3209
3210 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3211 if (_prob <= PROB_NEVER) {
3212 bhint = Assembler::bhintIsNotTaken;
3213 } else if (_prob >= PROB_ALWAYS) {
3214 bhint = Assembler::bhintIsTaken;
3215 }
3216 }
3217
3218 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3219 cc_to_biint(cc, flags_reg),
3220 l);
3221 %}
3222
3223 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3224 // The scheduler doesn't know about branch shortening, so we set the opcode
3225 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3226 // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3227
3228 MacroAssembler _masm(&cbuf);
3229 Label d; // dummy
3230 __ bind(d);
3231 Label* p = ($lbl$$label);
3232 // `p' is `NULL' when this encoding class is used only to
3233 // determine the size of the encoded instruction.
3234 Label& l = (NULL == p)? d : *(p);
3235 int cc = $cmp$$cmpcode;
3236 int flags_reg = $crx$$reg;
3237 int bhint = Assembler::bhintNoHint;
3238
3239 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3240 if (_prob <= PROB_NEVER) {
3241 bhint = Assembler::bhintIsNotTaken;
3242 } else if (_prob >= PROB_ALWAYS) {
3243 bhint = Assembler::bhintIsTaken;
3244 }
3245 }
3246
3247 // Tell the conditional far branch to optimize itself when being relocated.
3248 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3249 cc_to_biint(cc, flags_reg),
3250 l,
3251 MacroAssembler::bc_far_optimize_on_relocate);
3252 %}
3253
3254 // Branch used with Power6 scheduling (can be shortened without changing the node).
3255 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3256 // The scheduler doesn't know about branch shortening, so we set the opcode
3257 // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3258 // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3259
3260 MacroAssembler _masm(&cbuf);
3261 Label d; // dummy
3262 __ bind(d);
3263 Label* p = ($lbl$$label);
3264 // `p' is `NULL' when this encoding class is used only to
3265 // determine the size of the encoded instruction.
3266 Label& l = (NULL == p)? d : *(p);
3267 int cc = $cmp$$cmpcode;
3268 int flags_reg = $crx$$reg;
3269 int bhint = Assembler::bhintNoHint;
3270
3271 if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3272 if (_prob <= PROB_NEVER) {
3273 bhint = Assembler::bhintIsNotTaken;
3274 } else if (_prob >= PROB_ALWAYS) {
3275 bhint = Assembler::bhintIsTaken;
4594 match(RegL);
4595 format %{ %}
4596 interface(REG_INTER);
4597 %}
4598
4599 operand rscratch2RegL() %{
4600 constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4601 match(RegL);
4602 format %{ %}
4603 interface(REG_INTER);
4604 %}
4605
4606 // Condition Code Flag Registers
4607 operand flagsReg() %{
4608 constraint(ALLOC_IN_RC(int_flags));
4609 match(RegFlags);
4610 format %{ %}
4611 interface(REG_INTER);
4612 %}
4613
4614 operand flagsRegSrc() %{
4615 constraint(ALLOC_IN_RC(int_flags_ro));
4616 match(RegFlags);
4617 match(flagsReg);
4618 match(flagsRegCR0);
4619 format %{ %}
4620 interface(REG_INTER);
4621 %}
4622
4623 // Condition Code Flag Register CR0
4624 operand flagsRegCR0() %{
4625 constraint(ALLOC_IN_RC(int_flags_CR0));
4626 match(RegFlags);
4627 format %{ "CR0" %}
4628 interface(REG_INTER);
4629 %}
4630
4631 operand flagsRegCR1() %{
4632 constraint(ALLOC_IN_RC(int_flags_CR1));
4633 match(RegFlags);
4634 format %{ "CR1" %}
4635 interface(REG_INTER);
4636 %}
4637
4638 operand flagsRegCR6() %{
4639 constraint(ALLOC_IN_RC(int_flags_CR6));
4640 match(RegFlags);
4641 format %{ "CR6" %}
4642 interface(REG_INTER);
4686 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg
4687 match(reg);
4688 format %{ %}
4689 interface(REG_INTER);
4690 %}
4691
4692 // Operands to remove register moves in unscaled mode.
4693 // Match read/write registers with an EncodeP node if neither shift nor add are required.
4694 operand iRegP2N(iRegPsrc reg) %{
4695 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0);
4696 constraint(ALLOC_IN_RC(bits64_reg_ro));
4697 match(EncodeP reg);
4698 format %{ "$reg" %}
4699 interface(REG_INTER)
4700 %}
4701
4702 operand iRegN2P(iRegNsrc reg) %{
4703 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4704 constraint(ALLOC_IN_RC(bits32_reg_ro));
4705 match(DecodeN reg);
4706 format %{ "$reg" %}
4707 interface(REG_INTER)
4708 %}
4709
4710 operand iRegN2P_klass(iRegNsrc reg) %{
4711 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4712 constraint(ALLOC_IN_RC(bits32_reg_ro));
4713 match(DecodeNKlass reg);
4714 format %{ "$reg" %}
4715 interface(REG_INTER)
4716 %}
4717
4718 //----------Complex Operands---------------------------------------------------
4719 // Indirect Memory Reference
4720 operand indirect(iRegPsrc reg) %{
4721 constraint(ALLOC_IN_RC(bits64_reg_ro));
4722 match(reg);
4723 op_cost(100);
4724 format %{ "[$reg]" %}
4725 interface(MEMORY_INTER) %{
4726 base($reg);
4727 index(0x0);
4728 scale(0x0);
4729 disp(0x0);
4730 %}
4731 %}
4732
4749 constraint(ALLOC_IN_RC(bits64_reg_ro));
4750 match(AddP reg offset);
4751 op_cost(100);
4752 format %{ "[$reg + $offset]" %}
4753 interface(MEMORY_INTER) %{
4754 base($reg);
4755 index(0x0);
4756 scale(0x0);
4757 disp($offset);
4758 %}
4759 %}
4760
4761 //----------Complex Operands for Compressed OOPs-------------------------------
4762 // Compressed OOPs with narrow_oop_shift == 0.
4763
4764 // Indirect Memory Reference, compressed OOP
4765 operand indirectNarrow(iRegNsrc reg) %{
4766 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4767 constraint(ALLOC_IN_RC(bits64_reg_ro));
4768 match(DecodeN reg);
4769 op_cost(100);
4770 format %{ "[$reg]" %}
4771 interface(MEMORY_INTER) %{
4772 base($reg);
4773 index(0x0);
4774 scale(0x0);
4775 disp(0x0);
4776 %}
4777 %}
4778
4779 operand indirectNarrow_klass(iRegNsrc reg) %{
4780 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4781 constraint(ALLOC_IN_RC(bits64_reg_ro));
4782 match(DecodeNKlass reg);
4783 op_cost(100);
4784 format %{ "[$reg]" %}
4785 interface(MEMORY_INTER) %{
4786 base($reg);
4787 index(0x0);
4788 scale(0x0);
4789 disp(0x0);
4790 %}
4791 %}
4792
4793 // Indirect with Offset, compressed OOP
4794 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4795 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4796 constraint(ALLOC_IN_RC(bits64_reg_ro));
4797 match(AddP (DecodeN reg) offset);
4798 op_cost(100);
4799 format %{ "[$reg + $offset]" %}
4800 interface(MEMORY_INTER) %{
4801 base($reg);
4802 index(0x0);
4803 scale(0x0);
4804 disp($offset);
4805 %}
4806 %}
4807
4808 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4809 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4810 constraint(ALLOC_IN_RC(bits64_reg_ro));
4811 match(AddP (DecodeNKlass reg) offset);
4812 op_cost(100);
4813 format %{ "[$reg + $offset]" %}
4814 interface(MEMORY_INTER) %{
4815 base($reg);
4816 index(0x0);
4817 scale(0x0);
4818 disp($offset);
4819 %}
4820 %}
4821
4822 // Indirect with 4-aligned Offset, compressed OOP
4823 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4824 predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4825 constraint(ALLOC_IN_RC(bits64_reg_ro));
4826 match(AddP (DecodeN reg) offset);
4827 op_cost(100);
4828 format %{ "[$reg + $offset]" %}
4829 interface(MEMORY_INTER) %{
4830 base($reg);
4831 index(0x0);
4832 scale(0x0);
4833 disp($offset);
4834 %}
4835 %}
4836
4837 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4838 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4839 constraint(ALLOC_IN_RC(bits64_reg_ro));
4840 match(AddP (DecodeNKlass reg) offset);
4841 op_cost(100);
4842 format %{ "[$reg + $offset]" %}
4843 interface(MEMORY_INTER) %{
4844 base($reg);
4845 index(0x0);
4846 scale(0x0);
4847 disp($offset);
4848 %}
4849 %}
4850
4851 //----------Special Memory Operands--------------------------------------------
4852 // Stack Slot Operand
4853 //
4854 // This operand is used for loading and storing temporary values on
4855 // the stack where a match requires a value to flow through memory.
4856 operand stackSlotI(sRegI reg) %{
4857 constraint(ALLOC_IN_RC(stack_slots));
4858 op_cost(100);
4859 //match(RegI);
4947 // BO & BI
4948 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal
4949 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal
4950 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less
4951 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less
4952 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater
4953 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater
4954 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow
4955 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow
4956 %}
4957 %}
4958
4959 //----------OPERAND CLASSES----------------------------------------------------
4960 // Operand Classes are groups of operands that are used to simplify
4961 // instruction definitions by not requiring the AD writer to specify
4962 // seperate instructions for every form of operand when the
4963 // instruction accepts multiple operand types with the same basic
4964 // encoding and format. The classic case of this is memory operands.
4965 // Indirect is not included since its use is limited to Compare & Swap.
4966
4967 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4968 // Memory operand where offsets are 4-aligned. Required for ld, std.
4969 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4970 opclass indirectMemory(indirect, indirectNarrow);
4971
4972 // Special opclass for I and ConvL2I.
4973 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4974
4975 // Operand classes to match encode and decode. iRegN_P2N is only used
4976 // for storeN. I have never seen an encode node elsewhere.
4977 opclass iRegN_P2N(iRegNsrc, iRegP2N);
4978 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4979
4980 //----------PIPELINE-----------------------------------------------------------
4981
4982 pipeline %{
4983
4984 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4985 // J. Res. & Dev., No. 1, Jan. 2002.
4986
4987 //----------ATTRIBUTES---------------------------------------------------------
4988 attributes %{
4989
4990 // Power4 instructions are of fixed length.
4991 fixed_size_instructions;
4992
4993 // TODO: if `bundle' means number of instructions fetched
4994 // per cycle, this is 8. If `bundle' means Power4 `group', that is
4995 // max instructions issued per cycle, this is 5.
4996 max_instructions_per_bundle = 8;
4997
4998 // A Power4 instruction is 4 bytes long.
5542 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t"
5543 "TWI $dst\n\t"
5544 "ISYNC" %}
5545 size(12);
5546 ins_encode( enc_lwz_ac(dst, mem) );
5547 ins_pipe(pipe_class_memory);
5548 %}
5549
5550 // Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5551 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5552 match(Set dst (DecodeN (LoadN mem)));
5553 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0);
5554 ins_cost(MEMORY_REF_COST);
5555
5556 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5557 size(4);
5558 ins_encode( enc_lwz(dst, mem) );
5559 ins_pipe(pipe_class_memory);
5560 %}
5561
5562 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5563 match(Set dst (DecodeNKlass (LoadNKlass mem)));
5564 // SAPJVM GL 2014-05-21 Differs.
5565 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 &&
5566 _kids[0]->_leaf->as_Load()->is_unordered());
5567 ins_cost(MEMORY_REF_COST);
5568
5569 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %}
5570 size(4);
5571 ins_encode( enc_lwz(dst, mem) );
5572 ins_pipe(pipe_class_memory);
5573 %}
5574
5575 // Load Pointer
5576 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5577 match(Set dst (LoadP mem));
5578 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5579 ins_cost(MEMORY_REF_COST);
5580
5581 format %{ "LD $dst, $mem \t// ptr" %}
5582 size(4);
5583 ins_encode( enc_ld(dst, mem) );
5584 ins_pipe(pipe_class_memory);
5585 %}
5586
5587 // Load Pointer acquire.
5588 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5589 match(Set dst (LoadP mem));
5590 ins_cost(3*MEMORY_REF_COST);
5591
5592 format %{ "LD $dst, $mem \t// ptr acquire\n\t"
5593 "TWI $dst\n\t"
5594 "ISYNC" %}
5631 ins_pipe(pipe_class_memory);
5632 %}
5633
5634 // Load Float
5635 instruct loadF(regF dst, memory mem) %{
5636 match(Set dst (LoadF mem));
5637 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5638 ins_cost(MEMORY_REF_COST);
5639
5640 format %{ "LFS $dst, $mem" %}
5641 size(4);
5642 ins_encode %{
5643 // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
5644 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5645 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5646 %}
5647 ins_pipe(pipe_class_memory);
5648 %}
5649
5650 // Load Float acquire.
5651 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5652 match(Set dst (LoadF mem));
5653 effect(TEMP cr0);
5654 ins_cost(3*MEMORY_REF_COST);
5655
5656 format %{ "LFS $dst, $mem \t// acquire\n\t"
5657 "FCMPU cr0, $dst, $dst\n\t"
5658 "BNE cr0, next\n"
5659 "next:\n\t"
5660 "ISYNC" %}
5661 size(16);
5662 ins_encode %{
5663 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5664 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5665 Label next;
5666 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5667 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5668 __ bne(CCR0, next);
5669 __ bind(next);
5670 __ isync();
5671 %}
5672 ins_pipe(pipe_class_memory);
5673 %}
5674
5675 // Load Double - aligned
5676 instruct loadD(regD dst, memory mem) %{
5677 match(Set dst (LoadD mem));
5678 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5679 ins_cost(MEMORY_REF_COST);
5680
5681 format %{ "LFD $dst, $mem" %}
5682 size(4);
5683 ins_encode( enc_lfd(dst, mem) );
5684 ins_pipe(pipe_class_memory);
5685 %}
5686
5687 // Load Double - aligned acquire.
5688 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5689 match(Set dst (LoadD mem));
5690 effect(TEMP cr0);
5691 ins_cost(3*MEMORY_REF_COST);
5692
5693 format %{ "LFD $dst, $mem \t// acquire\n\t"
5694 "FCMPU cr0, $dst, $dst\n\t"
5695 "BNE cr0, next\n"
5696 "next:\n\t"
5697 "ISYNC" %}
5698 size(16);
5699 ins_encode %{
5700 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5701 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5702 Label next;
5703 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5704 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5705 __ bne(CCR0, next);
5706 __ bind(next);
5707 __ isync();
5708 %}
5709 ins_pipe(pipe_class_memory);
5710 %}
5998 // This clears these bits: dst = src & 0xFFFFFFFF.
5999 // TODO: Eventually call this maskN_regN_FFFFFFFF.
6000 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
6001 effect(DEF dst, USE src);
6002 predicate(false);
6003
6004 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask
6005 size(4);
6006 ins_encode %{
6007 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6008 __ clrldi($dst$$Register, $src$$Register, 0x20);
6009 %}
6010 ins_pipe(pipe_class_default);
6011 %}
6012
6013 // Optimize DecodeN for disjoint base.
6014 // Load base of compressed oops into a register
6015 instruct loadBase(iRegLdst dst) %{
6016 effect(DEF dst);
6017
6018 format %{ "LoadConst $dst, heapbase" %}
6019 ins_encode %{
6020 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6021 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0);
6022 %}
6023 ins_pipe(pipe_class_default);
6024 %}
6025
6026 // Loading ConN must be postalloc expanded so that edges between
6027 // the nodes are safe. They may not interfere with a safepoint.
6028 // GL TODO: This needs three instructions: better put this into the constant pool.
6029 instruct loadConN_Ex(iRegNdst dst, immN src) %{
6030 match(Set dst src);
6031 ins_cost(DEFAULT_COST*2);
6032
6033 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask
6034 postalloc_expand %{
6035 MachNode *m1 = new loadConN_hiNode();
6036 MachNode *m2 = new loadConN_loNode();
6037 MachNode *m3 = new clearMs32bNode();
6038 m1->add_req(NULL);
6039 m2->add_req(NULL, m1);
6040 m3->add_req(NULL, m2);
6041 m1->_opnds[0] = op_dst;
6526 %}
6527
6528 // Store Double
6529 instruct storeD(memory mem, regD src) %{
6530 match(Set mem (StoreD mem src));
6531 ins_cost(MEMORY_REF_COST);
6532
6533 format %{ "STFD $src, $mem" %}
6534 size(4);
6535 ins_encode( enc_stfd(src, mem) );
6536 ins_pipe(pipe_class_memory);
6537 %}
6538
6539 //----------Store Instructions With Zeros--------------------------------------
6540
6541 // Card-mark for CMS garbage collection.
6542 // This cardmark does an optimization so that it must not always
6543 // do a releasing store. For this, it gets the address of
6544 // CMSCollectorCardTableModRefBSExt::_requires_release as input.
6545 // (Using releaseFieldAddr in the match rule is a hack.)
6546 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{
6547 match(Set mem (StoreCM mem releaseFieldAddr));
6548 effect(TEMP crx);
6549 predicate(false);
6550 ins_cost(MEMORY_REF_COST);
6551
6552 // See loadConP.
6553 ins_cannot_rematerialize(true);
6554
6555 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %}
6556 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) );
6557 ins_pipe(pipe_class_memory);
6558 %}
6559
6560 // Card-mark for CMS garbage collection.
6561 // This cardmark does an optimization so that it must not always
6562 // do a releasing store. For this, it needs the constant address of
6563 // CMSCollectorCardTableModRefBSExt::_requires_release.
6564 // This constant address is split off here by expand so we can use
6565 // adlc / matcher functionality to load it from the constant section.
6566 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{
6567 match(Set mem (StoreCM mem zero));
6568 predicate(UseConcMarkSweepGC);
6569
6570 expand %{
6571 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %}
6572 iRegLdst releaseFieldAddress;
6573 flagsReg crx;
6574 loadConL_Ex(releaseFieldAddress, baseImm);
6575 storeCM_CMS(mem, releaseFieldAddress, crx);
6576 %}
6577 %}
6578
6579 instruct storeCM_G1(memory mem, immI_0 zero) %{
6580 match(Set mem (StoreCM mem zero));
6581 predicate(UseG1GC);
6582 ins_cost(MEMORY_REF_COST);
6583
6584 ins_cannot_rematerialize(true);
6585
6586 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %}
6587 size(8);
6588 ins_encode %{
6589 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6590 __ li(R0, 0);
6591 //__ release(); // G1: oops are allowed to get visible after dirty marking
6592 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias");
6593 __ stb(R0, $mem$$disp, $mem$$base$$Register);
6594 %}
6595 ins_pipe(pipe_class_memory);
6604 // The match rule is needed to make it a 'MachTypeNode'!
6605 match(Set dst (EncodeP src));
6606 predicate(false);
6607
6608 format %{ "SRDI $dst, $src, 3 \t// encode" %}
6609 size(4);
6610 ins_encode %{
6611 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6612 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f);
6613 %}
6614 ins_pipe(pipe_class_default);
6615 %}
6616
6617 // Add node for expand.
6618 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6619 // The match rule is needed to make it a 'MachTypeNode'!
6620 match(Set dst (EncodeP src));
6621 predicate(false);
6622
6623 format %{ "SUB $dst, $src, oop_base \t// encode" %}
6624 ins_encode %{
6625 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6626 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0);
6627 %}
6628 ins_pipe(pipe_class_default);
6629 %}
6630
6631 // Conditional sub base.
6632 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6633 // The match rule is needed to make it a 'MachTypeNode'!
6634 match(Set dst (EncodeP (Binary crx src1)));
6635 predicate(false);
6636
6637 format %{ "BEQ $crx, done\n\t"
6638 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n"
6639 "done:" %}
6640 ins_encode %{
6641 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6642 Label done;
6643 __ beq($crx$$CondRegister, done);
6644 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0);
6645 __ bind(done);
6646 %}
6647 ins_pipe(pipe_class_default);
6648 %}
6649
6650 // Power 7 can use isel instruction
6651 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6652 // The match rule is needed to make it a 'MachTypeNode'!
6653 match(Set dst (EncodeP (Binary crx src1)));
6654 predicate(false);
6655
6656 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6657 size(4);
6658 ins_encode %{
6659 // This is a Power7 instruction for which no machine description exists.
6660 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6661 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6662 %}
6663 ins_pipe(pipe_class_default);
6664 %}
6665
6666 // Disjoint narrow oop base.
6667 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6668 match(Set dst (EncodeP src));
6669 predicate(Universe::narrow_oop_base_disjoint());
6670
6671 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %}
6737 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6738 // The match rule is needed to make it a 'MachTypeNode'!
6739 match(Set dst (DecodeN src));
6740 predicate(false);
6741
6742 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %}
6743 size(4);
6744 ins_encode %{
6745 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
6746 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift());
6747 %}
6748 ins_pipe(pipe_class_default);
6749 %}
6750
6751 // Add node for expand.
6752 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6753 // The match rule is needed to make it a 'MachTypeNode'!
6754 match(Set dst (DecodeN src));
6755 predicate(false);
6756
6757 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %}
6758 ins_encode %{
6759 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6760 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0);
6761 %}
6762 ins_pipe(pipe_class_default);
6763 %}
6764
6765 // conditianal add base for expand
6766 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6767 // The match rule is needed to make it a 'MachTypeNode'!
6768 // NOTICE that the rule is nonsense - we just have to make sure that:
6769 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6770 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6771 match(Set dst (DecodeN (Binary crx src)));
6772 predicate(false);
6773
6774 format %{ "BEQ $crx, done\n\t"
6775 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n"
6776 "done:" %}
6777 ins_encode %{
6778 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6779 Label done;
6780 __ beq($crx$$CondRegister, done);
6781 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0);
6782 __ bind(done);
6783 %}
6784 ins_pipe(pipe_class_default);
6785 %}
6786
6787 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6788 // The match rule is needed to make it a 'MachTypeNode'!
6789 // NOTICE that the rule is nonsense - we just have to make sure that:
6790 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6791 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6792 match(Set dst (DecodeN (Binary crx src1)));
6793 predicate(false);
6794
6795 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6796 size(4);
6797 ins_encode %{
6798 // This is a Power7 instruction for which no machine description exists.
6799 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6800 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6801 %}
6802 ins_pipe(pipe_class_default);
6803 %}
6804
6805 // shift != 0, base != 0
6806 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6807 match(Set dst (DecodeN src));
6843 size(4);
6844 ins_encode %{
6845 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
6846 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
6847 %}
6848 ins_pipe(pipe_class_default);
6849 %}
6850
6851 // Optimize DecodeN for disjoint base.
6852 // This node requires only one cycle on the critical path.
6853 // We must postalloc_expand as we can not express use_def effects where
6854 // the used register is L and the def'ed register P.
6855 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6856 match(Set dst (DecodeN src));
6857 effect(TEMP_DEF dst);
6858 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6859 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6860 Universe::narrow_oop_base_disjoint());
6861 ins_cost(DEFAULT_COST);
6862
6863 format %{ "MOV $dst, heapbase \t\n"
6864 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6865 postalloc_expand %{
6866 loadBaseNode *n1 = new loadBaseNode();
6867 n1->add_req(NULL);
6868 n1->_opnds[0] = op_dst;
6869
6870 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6871 n2->add_req(n_region, n_src, n1);
6872 n2->_opnds[0] = op_dst;
6873 n2->_opnds[1] = op_src;
6874 n2->_opnds[2] = op_dst;
6875 n2->_bottom_type = _bottom_type;
6876
6877 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6878 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6879
6880 nodes->push(n1);
6881 nodes->push(n2);
6882 %}
6883 %}
7258 //
7259 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
7260 // size(0);
7261 // ins_encode( /*empty*/ );
7262 // ins_pipe(pipe_class_default);
7263 //%}
7264
7265 instruct membar_CPUOrder() %{
7266 match(MemBarCPUOrder);
7267 ins_cost(0);
7268
7269 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
7270 size(0);
7271 ins_encode( /*empty*/ );
7272 ins_pipe(pipe_class_default);
7273 %}
7274
7275 //----------Conditional Move---------------------------------------------------
7276
7277 // Cmove using isel.
7278 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7279 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7280 predicate(VM_Version::has_isel());
7281 ins_cost(DEFAULT_COST);
7282
7283 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7284 size(4);
7285 ins_encode %{
7286 // This is a Power7 instruction for which no machine description
7287 // exists. Anyways, the scheduler should be off on Power7.
7288 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7289 int cc = $cmp$$cmpcode;
7290 __ isel($dst$$Register, $crx$$CondRegister,
7291 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7292 %}
7293 ins_pipe(pipe_class_default);
7294 %}
7295
7296 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7297 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7298 predicate(!VM_Version::has_isel());
7299 ins_cost(DEFAULT_COST+BRANCH_COST);
7300
7301 ins_variable_size_depending_on_alignment(true);
7302
7303 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7304 // Worst case is branch + move + stop, no stop without scheduler
7305 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7306 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7307 ins_pipe(pipe_class_default);
7308 %}
7309
7310 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{
7311 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7312 ins_cost(DEFAULT_COST+BRANCH_COST);
7313
7314 ins_variable_size_depending_on_alignment(true);
7315
7316 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7317 // Worst case is branch + move + stop, no stop without scheduler
7318 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7319 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7320 ins_pipe(pipe_class_default);
7321 %}
7322
7323 // Cmove using isel.
7324 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7325 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7326 predicate(VM_Version::has_isel());
7327 ins_cost(DEFAULT_COST);
7328
7329 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7330 size(4);
7331 ins_encode %{
7332 // This is a Power7 instruction for which no machine description
7333 // exists. Anyways, the scheduler should be off on Power7.
7334 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7335 int cc = $cmp$$cmpcode;
7336 __ isel($dst$$Register, $crx$$CondRegister,
7337 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7338 %}
7339 ins_pipe(pipe_class_default);
7340 %}
7341
7342 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7343 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7344 predicate(!VM_Version::has_isel());
7345 ins_cost(DEFAULT_COST+BRANCH_COST);
7346
7347 ins_variable_size_depending_on_alignment(true);
7348
7349 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7350 // Worst case is branch + move + stop, no stop without scheduler.
7351 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7352 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7353 ins_pipe(pipe_class_default);
7354 %}
7355
7356 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{
7357 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7358 ins_cost(DEFAULT_COST+BRANCH_COST);
7359
7360 ins_variable_size_depending_on_alignment(true);
7361
7362 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7363 // Worst case is branch + move + stop, no stop without scheduler.
7364 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7365 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7366 ins_pipe(pipe_class_default);
7367 %}
7368
7369 // Cmove using isel.
7370 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7371 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7372 predicate(VM_Version::has_isel());
7373 ins_cost(DEFAULT_COST);
7374
7375 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7376 size(4);
7377 ins_encode %{
7378 // This is a Power7 instruction for which no machine description
7379 // exists. Anyways, the scheduler should be off on Power7.
7380 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7381 int cc = $cmp$$cmpcode;
7382 __ isel($dst$$Register, $crx$$CondRegister,
7383 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7384 %}
7385 ins_pipe(pipe_class_default);
7386 %}
7387
7388 // Conditional move for RegN. Only cmov(reg, reg).
7389 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7390 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7391 predicate(!VM_Version::has_isel());
7392 ins_cost(DEFAULT_COST+BRANCH_COST);
7393
7394 ins_variable_size_depending_on_alignment(true);
7395
7396 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7397 // Worst case is branch + move + stop, no stop without scheduler.
7398 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7399 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7400 ins_pipe(pipe_class_default);
7401 %}
7402
7403 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{
7404 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7405 ins_cost(DEFAULT_COST+BRANCH_COST);
7406
7407 ins_variable_size_depending_on_alignment(true);
7408
7409 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7410 // Worst case is branch + move + stop, no stop without scheduler.
7411 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7412 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7413 ins_pipe(pipe_class_default);
7414 %}
7415
7416 // Cmove using isel.
7417 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
7418 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7419 predicate(VM_Version::has_isel());
7420 ins_cost(DEFAULT_COST);
7421
7422 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7423 size(4);
7424 ins_encode %{
7425 // This is a Power7 instruction for which no machine description
7426 // exists. Anyways, the scheduler should be off on Power7.
7427 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7428 int cc = $cmp$$cmpcode;
7429 __ isel($dst$$Register, $crx$$CondRegister,
7430 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7431 %}
7432 ins_pipe(pipe_class_default);
7433 %}
7434
7435 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{
7436 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7437 predicate(!VM_Version::has_isel());
7438 ins_cost(DEFAULT_COST+BRANCH_COST);
7439
7440 ins_variable_size_depending_on_alignment(true);
7441
7442 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7443 // Worst case is branch + move + stop, no stop without scheduler.
7444 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7445 ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7446 ins_pipe(pipe_class_default);
7447 %}
7448
7449 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{
7450 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7451 ins_cost(DEFAULT_COST+BRANCH_COST);
7452
7453 ins_variable_size_depending_on_alignment(true);
7454
7455 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %}
7456 // Worst case is branch + move + stop, no stop without scheduler.
7457 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7458 ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7459 ins_pipe(pipe_class_default);
7460 %}
7461
7462 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7463 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7464 ins_cost(DEFAULT_COST+BRANCH_COST);
7465
7466 ins_variable_size_depending_on_alignment(true);
7467
7468 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7469 // Worst case is branch + move + stop, no stop without scheduler.
7470 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
7471 ins_encode %{
7472 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
7473 Label done;
7474 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7475 // Branch if not (cmp crx).
7476 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7477 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7478 // TODO PPC port __ endgroup_if_needed(_size == 12);
7479 __ bind(done);
7480 %}
7481 ins_pipe(pipe_class_default);
7482 %}
7483
7484 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7485 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7486 ins_cost(DEFAULT_COST+BRANCH_COST);
7487
7488 ins_variable_size_depending_on_alignment(true);
7489
7490 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %}
7491 // Worst case is branch + move + stop, no stop without scheduler.
7492 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
7493 ins_encode %{
7494 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
7495 Label done;
7496 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7497 // Branch if not (cmp crx).
7498 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7499 __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7500 // TODO PPC port __ endgroup_if_needed(_size == 12);
7501 __ bind(done);
7502 %}
7503 ins_pipe(pipe_class_default);
7504 %}
7505
7506 //----------Conditional_store--------------------------------------------------
7507 // Conditional-store of the updated heap-top.
7508 // Used during allocation of the shared heap.
7509 // Sets flags (EQ) on success. Implemented with a CASA on Sparc.
7510
7511 // As compareAndSwapL, but return flag register instead of boolean value in
7512 // int register.
7513 // Used by sun/misc/AtomicLongCSImpl.java.
7514 // Mem_ptr must be a memory operand, else this node does not get
7515 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7516 // can be rematerialized which leads to errors.
7517 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{
7518 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal)));
7519 effect(TEMP cr0);
7520 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7521 ins_encode %{
7522 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7523 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7524 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
7525 noreg, NULL, true);
7526 %}
7527 ins_pipe(pipe_class_default);
7528 %}
7529
7530 // As compareAndSwapP, but return flag register instead of boolean value in
7531 // int register.
7532 // This instruction is matched if UseTLAB is off.
7533 // Mem_ptr must be a memory operand, else this node does not get
7534 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7535 // can be rematerialized which leads to errors.
7536 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{
7537 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal)));
7538 ins_cost(2*MEMORY_REF_COST);
7539
7540 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7541 ins_encode %{
7542 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_);
7543 __ stdcx_($newVal$$Register, $mem_ptr$$Register);
7544 %}
7545 ins_pipe(pipe_class_memory);
7546 %}
7547
7548 // Implement LoadPLocked. Must be ordered against changes of the memory location
7549 // by storePConditional.
7550 // Don't know whether this is ever used.
7551 instruct loadPLocked(iRegPdst dst, memory mem) %{
7552 match(Set dst (LoadPLocked mem));
7553 ins_cost(2*MEMORY_REF_COST);
7554
7555 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %}
7556 size(4);
7557 ins_encode %{
7558 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx);
7559 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
7560 %}
7561 ins_pipe(pipe_class_memory);
7562 %}
7563
7564 //----------Compare-And-Swap---------------------------------------------------
7565
7566 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7567 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7568 // matched.
7569
7570 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7571 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7572 effect(TEMP cr0);
7573 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7574 // Variable size: instruction count smaller if regs are disjoint.
7575 ins_encode %{
7576 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7577 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7578 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7579 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7580 $res$$Register, true);
7581 %}
7582 ins_pipe(pipe_class_default);
7583 %}
7584
7585 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7586 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7587 effect(TEMP cr0);
7588 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7589 // Variable size: instruction count smaller if regs are disjoint.
7590 ins_encode %{
7591 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7592 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7593 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7594 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7595 $res$$Register, true);
7596 %}
7597 ins_pipe(pipe_class_default);
7598 %}
7599
7600 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7601 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7602 effect(TEMP cr0);
7603 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7604 // Variable size: instruction count smaller if regs are disjoint.
7605 ins_encode %{
7606 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7607 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7608 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7609 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7610 $res$$Register, NULL, true);
7611 %}
7612 ins_pipe(pipe_class_default);
7613 %}
7614
7615 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7616 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7617 effect(TEMP cr0);
7618 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7619 // Variable size: instruction count smaller if regs are disjoint.
7620 ins_encode %{
7621 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7622 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7623 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7624 MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
7625 $res$$Register, NULL, true);
7626 %}
7627 ins_pipe(pipe_class_default);
7628 %}
7629
7630 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7631 match(Set res (GetAndAddI mem_ptr src));
7632 effect(TEMP cr0);
7633 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
7634 // Variable size: instruction count smaller if regs are disjoint.
7635 ins_encode( enc_GetAndAddI(res, mem_ptr, src) );
7636 ins_pipe(pipe_class_default);
7637 %}
7638
7639 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7640 match(Set res (GetAndAddL mem_ptr src));
7641 effect(TEMP cr0);
7642 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
7643 // Variable size: instruction count smaller if regs are disjoint.
7644 ins_encode( enc_GetAndAddL(res, mem_ptr, src) );
7645 ins_pipe(pipe_class_default);
7646 %}
7647
7648 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
7649 match(Set res (GetAndSetI mem_ptr src));
7650 effect(TEMP cr0);
7651 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
7652 // Variable size: instruction count smaller if regs are disjoint.
7653 ins_encode( enc_GetAndSetI(res, mem_ptr, src) );
7654 ins_pipe(pipe_class_default);
7655 %}
7656
7657 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
7658 match(Set res (GetAndSetL mem_ptr src));
7659 effect(TEMP cr0);
7660 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
7661 // Variable size: instruction count smaller if regs are disjoint.
7662 ins_encode( enc_GetAndSetL(res, mem_ptr, src) );
7663 ins_pipe(pipe_class_default);
7664 %}
7665
7666 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
7667 match(Set res (GetAndSetP mem_ptr src));
7668 effect(TEMP cr0);
7669 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
7670 // Variable size: instruction count smaller if regs are disjoint.
7671 ins_encode( enc_GetAndSetL(res, mem_ptr, src) );
7672 ins_pipe(pipe_class_default);
7673 %}
7674
7675 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
7676 match(Set res (GetAndSetN mem_ptr src));
7677 effect(TEMP cr0);
7678 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
7679 // Variable size: instruction count smaller if regs are disjoint.
7680 ins_encode( enc_GetAndSetI(res, mem_ptr, src) );
7681 ins_pipe(pipe_class_default);
7682 %}
7683
7684 //----------Arithmetic Instructions--------------------------------------------
7685 // Addition Instructions
7686
7687 // Register Addition
7688 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
7689 match(Set dst (AddI src1 src2));
7690 format %{ "ADD $dst, $src1, $src2" %}
7691 size(4);
7692 ins_encode %{
7693 // TODO: PPC port $archOpcode(ppc64Opcode_add);
7694 __ add($dst$$Register, $src1$$Register, $src2$$Register);
7695 %}
7696 ins_pipe(pipe_class_default);
7697 %}
7865 %}
7866 ins_pipe(pipe_class_default);
7867 %}
7868
7869 //---------------------
7870 // Subtraction Instructions
7871
7872 // Register Subtraction
7873 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
7874 match(Set dst (SubI src1 src2));
7875 format %{ "SUBF $dst, $src2, $src1" %}
7876 size(4);
7877 ins_encode %{
7878 // TODO: PPC port $archOpcode(ppc64Opcode_subf);
7879 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7880 %}
7881 ins_pipe(pipe_class_default);
7882 %}
7883
7884 // Immediate Subtraction
7885 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
7886 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
7887
7888 // SubI from constant (using subfic).
7889 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
7890 match(Set dst (SubI src1 src2));
7891 format %{ "SUBI $dst, $src1, $src2" %}
7892
7893 size(4);
7894 ins_encode %{
7895 // TODO: PPC port $archOpcode(ppc64Opcode_subfic);
7896 __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
7897 %}
7898 ins_pipe(pipe_class_default);
7899 %}
7900
7901 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
7902 // positive integers and 0xF...F for negative ones.
7903 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
7904 // no match-rule, false predicate
7905 effect(DEF dst, USE src);
7906 predicate(false);
7946 ins_encode %{
7947 // TODO: PPC port $archOpcode(ppc64Opcode_subf);
7948 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7949 %}
7950 ins_pipe(pipe_class_default);
7951 %}
7952
7953 // SubL + convL2I.
7954 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
7955 match(Set dst (ConvL2I (SubL src1 src2)));
7956
7957 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %}
7958 size(4);
7959 ins_encode %{
7960 // TODO: PPC port $archOpcode(ppc64Opcode_subf);
7961 __ subf($dst$$Register, $src2$$Register, $src1$$Register);
7962 %}
7963 ins_pipe(pipe_class_default);
7964 %}
7965
7966 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
7967 // positive longs and 0xF...F for negative ones.
7968 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
7969 // no match-rule, false predicate
7970 effect(DEF dst, USE src);
7971 predicate(false);
7972
7973 format %{ "SRADI $dst, $src, #63" %}
7974 size(4);
7975 ins_encode %{
7976 // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
7977 __ sradi($dst$$Register, $src$$Register, 0x3f);
7978 %}
7979 ins_pipe(pipe_class_default);
7980 %}
7981
7982 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
7983 // positive longs and 0xF...F for negative ones.
7984 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
7985 // no match-rule, false predicate
8106 ins_pipe(pipe_class_default);
8107 %}
8108
8109 // Integer Division with constant, but not -1.
8110 // We should be able to improve this by checking the type of src2.
8111 // It might well be that src2 is known to be positive.
8112 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8113 match(Set dst (DivI src1 src2));
8114 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8115 ins_cost(2*DEFAULT_COST);
8116
8117 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %}
8118 size(4);
8119 ins_encode %{
8120 // TODO: PPC port $archOpcode(ppc64Opcode_divw);
8121 __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8122 %}
8123 ins_pipe(pipe_class_default);
8124 %}
8125
8126 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8127 effect(USE_DEF dst, USE src1, USE crx);
8128 predicate(false);
8129
8130 ins_variable_size_depending_on_alignment(true);
8131
8132 format %{ "CMOVE $dst, neg($src1), $crx" %}
8133 // Worst case is branch + move + stop, no stop without scheduler.
8134 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
8135 ins_encode %{
8136 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
8137 Label done;
8138 __ bne($crx$$CondRegister, done);
8139 __ neg($dst$$Register, $src1$$Register);
8140 // TODO PPC port __ endgroup_if_needed(_size == 12);
8141 __ bind(done);
8142 %}
8143 ins_pipe(pipe_class_default);
8144 %}
8145
8146 // Integer Division with Registers not containing constants.
8169 __ neg($dst$$Register, $src1$$Register);
8170 %}
8171 ins_pipe(pipe_class_default);
8172 %}
8173
8174 // Long Division with constant, but not -1.
8175 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8176 match(Set dst (DivL src1 src2));
8177 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8178 ins_cost(2*DEFAULT_COST);
8179
8180 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %}
8181 size(4);
8182 ins_encode %{
8183 // TODO: PPC port $archOpcode(ppc64Opcode_divd);
8184 __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8185 %}
8186 ins_pipe(pipe_class_default);
8187 %}
8188
8189 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8190 effect(USE_DEF dst, USE src1, USE crx);
8191 predicate(false);
8192
8193 ins_variable_size_depending_on_alignment(true);
8194
8195 format %{ "CMOVE $dst, neg($src1), $crx" %}
8196 // Worst case is branch + move + stop, no stop without scheduler.
8197 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
8198 ins_encode %{
8199 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
8200 Label done;
8201 __ bne($crx$$CondRegister, done);
8202 __ neg($dst$$Register, $src1$$Register);
8203 // TODO PPC port __ endgroup_if_needed(_size == 12);
8204 __ bind(done);
8205 %}
8206 ins_pipe(pipe_class_default);
8207 %}
8208
8209 // Long Division with Registers not containing constants.
8222
8223 // Integer Remainder with registers.
8224 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8225 match(Set dst (ModI src1 src2));
8226 ins_cost(10*DEFAULT_COST);
8227
8228 expand %{
8229 immI16 imm %{ (int)-1 %}
8230 flagsReg tmp1;
8231 iRegIdst tmp2;
8232 iRegIdst tmp3;
8233 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1
8234 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8235 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8236 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8237 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8238 %}
8239 %}
8240
8241 // Long Remainder with registers
8242 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8243 match(Set dst (ModL src1 src2));
8244 ins_cost(10*DEFAULT_COST);
8245
8246 expand %{
8247 immL16 imm %{ (int)-1 %}
8248 flagsReg tmp1;
8249 iRegLdst tmp2;
8250 iRegLdst tmp3;
8251 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1
8252 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2
8253 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1
8254 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2
8255 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3
8256 %}
8257 %}
8258
8259 // Integer Shift Instructions
8260
8261 // Register Shift Left
8262
8952 %}
8953
8954 // Register And Long
8955 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8956 match(Set dst (AndL src1 src2));
8957 ins_cost(DEFAULT_COST);
8958
8959 format %{ "AND $dst, $src1, $src2 \t// long" %}
8960 size(4);
8961 ins_encode %{
8962 // TODO: PPC port $archOpcode(ppc64Opcode_and);
8963 __ andr($dst$$Register, $src1$$Register, $src2$$Register);
8964 %}
8965 ins_pipe(pipe_class_default);
8966 %}
8967
8968 // Immediate And long
8969 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
8970 match(Set dst (AndL src1 src2));
8971 effect(KILL cr0);
8972
8973 format %{ "ANDI $dst, $src1, $src2 \t// long" %}
8974 size(4);
8975 ins_encode %{
8976 // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
8977 // FIXME: avoid andi_ ?
8978 __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
8979 %}
8980 ins_pipe(pipe_class_default);
8981 %}
8982
8983 // Immediate And Long where the immediate is a negative power of 2.
8984 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
8985 match(Set dst (AndL src1 src2));
8986 format %{ "ANDDI $dst, $src1, $src2" %}
8987 size(4);
8988 ins_encode %{
8989 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
8990 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant));
8991 %}
9743 // TODO: PPC port $archOpcode(ppc64Opcode_or);
9744 __ mr_if_needed($dst$$Register, $src$$Register);
9745 %}
9746 ins_pipe(pipe_class_default);
9747 %}
9748
9749 instruct convD2IRaw_regD(regD dst, regD src) %{
9750 // no match-rule, false predicate
9751 effect(DEF dst, USE src);
9752 predicate(false);
9753
9754 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
9755 size(4);
9756 ins_encode %{
9757 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);;
9758 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
9759 %}
9760 ins_pipe(pipe_class_default);
9761 %}
9762
9763 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
9764 // no match-rule, false predicate
9765 effect(DEF dst, USE crx, USE src);
9766 predicate(false);
9767
9768 ins_variable_size_depending_on_alignment(true);
9769
9770 format %{ "cmovI $crx, $dst, $src" %}
9771 // Worst case is branch + move + stop, no stop without scheduler.
9772 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
9773 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9774 ins_pipe(pipe_class_default);
9775 %}
9776
9777 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{
9778 // no match-rule, false predicate
9779 effect(DEF dst, USE crx, USE mem);
9780 predicate(false);
9781
9782 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %}
9783 postalloc_expand %{
9784 //
9785 // replaces
9786 //
9787 // region dst crx mem
9788 // \ | | /
9789 // dst=cmovI_bso_stackSlotL_conLvalue0
9790 //
9791 // with
9792 //
9793 // region dst
9794 // \ /
9795 // dst=loadConI16(0)
9796 // |
9797 // ^ region dst crx mem
9912 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9913 __ clrldi($dst$$Register, $src$$Register, 32);
9914 %}
9915 ins_pipe(pipe_class_default);
9916 %}
9917
9918 instruct convF2LRaw_regF(regF dst, regF src) %{
9919 // no match-rule, false predicate
9920 effect(DEF dst, USE src);
9921 predicate(false);
9922
9923 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
9924 size(4);
9925 ins_encode %{
9926 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
9927 __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
9928 %}
9929 ins_pipe(pipe_class_default);
9930 %}
9931
9932 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
9933 // no match-rule, false predicate
9934 effect(DEF dst, USE crx, USE src);
9935 predicate(false);
9936
9937 ins_variable_size_depending_on_alignment(true);
9938
9939 format %{ "cmovL $crx, $dst, $src" %}
9940 // Worst case is branch + move + stop, no stop without scheduler.
9941 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
9942 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
9943 ins_pipe(pipe_class_default);
9944 %}
9945
9946 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{
9947 // no match-rule, false predicate
9948 effect(DEF dst, USE crx, USE mem);
9949 predicate(false);
9950
9951 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %}
9952 postalloc_expand %{
9953 //
9954 // replaces
9955 //
9956 // region dst crx mem
9957 // \ | | /
9958 // dst=cmovL_bso_stackSlotL_conLvalue0
9959 //
9960 // with
9961 //
9962 // region dst
9963 // \ /
9964 // dst=loadConL16(0)
9965 // |
9966 // ^ region dst crx mem
10195
10196 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
10197 match(Set crx (CmpI src1 src2));
10198 format %{ "CMPWI $crx, $src1, $src2" %}
10199 size(4);
10200 ins_encode %{
10201 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
10202 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10203 %}
10204 ins_pipe(pipe_class_compare);
10205 %}
10206
10207 // (src1 & src2) == 0?
10208 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
10209 match(Set cr0 (CmpI (AndI src1 src2) zero));
10210 // r0 is killed
10211 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %}
10212 size(4);
10213 ins_encode %{
10214 // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
10215 __ andi_(R0, $src1$$Register, $src2$$constant);
10216 %}
10217 ins_pipe(pipe_class_compare);
10218 %}
10219
10220 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
10221 match(Set crx (CmpL src1 src2));
10222 format %{ "CMPD $crx, $src1, $src2" %}
10223 size(4);
10224 ins_encode %{
10225 // TODO: PPC port $archOpcode(ppc64Opcode_cmp);
10226 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
10227 %}
10228 ins_pipe(pipe_class_compare);
10229 %}
10230
10231 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
10232 match(Set crx (CmpL src1 src2));
10233 format %{ "CMPDI $crx, $src1, $src2" %}
10234 size(4);
10241
10242 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
10243 match(Set cr0 (CmpL (AndL src1 src2) zero));
10244 // r0 is killed
10245 format %{ "AND R0, $src1, $src2 \t// BTST long" %}
10246 size(4);
10247 ins_encode %{
10248 // TODO: PPC port $archOpcode(ppc64Opcode_and_);
10249 __ and_(R0, $src1$$Register, $src2$$Register);
10250 %}
10251 ins_pipe(pipe_class_compare);
10252 %}
10253
10254 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
10255 match(Set cr0 (CmpL (AndL src1 src2) zero));
10256 // r0 is killed
10257 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %}
10258 size(4);
10259 ins_encode %{
10260 // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
10261 __ andi_(R0, $src1$$Register, $src2$$constant);
10262 %}
10263 ins_pipe(pipe_class_compare);
10264 %}
10265
10266 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{
10267 // no match-rule, false predicate
10268 effect(DEF dst, USE crx);
10269 predicate(false);
10270
10271 ins_variable_size_depending_on_alignment(true);
10272
10273 format %{ "cmovI $crx, $dst, -1, 0, +1" %}
10274 // Worst case is branch + move + branch + move + stop, no stop without scheduler.
10275 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16);
10276 ins_encode %{
10277 // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
10278 Label done;
10279 // li(Rdst, 0); // equal -> 0
10280 __ beq($crx$$CondRegister, done);
10281 __ li($dst$$Register, 1); // greater -> +1
10282 __ bgt($crx$$CondRegister, done);
10283 __ li($dst$$Register, -1); // unordered or less -> -1
10284 // TODO: PPC port__ endgroup_if_needed(_size == 20);
10285 __ bind(done);
10286 %}
10287 ins_pipe(pipe_class_compare);
10288 %}
10289
10290 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{
10291 // no match-rule, false predicate
10292 effect(DEF dst, USE crx);
10293 predicate(false);
10294
10295 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %}
10296 postalloc_expand %{
10297 //
10298 // replaces
10299 //
10300 // region crx
10301 // \ |
10302 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1
10303 //
10304 // with
10305 //
10306 // region
10307 // \
10308 // dst=loadConI16(0)
10309 // |
10310 // ^ region crx
10560 // Used in postalloc expand.
10561 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
10562 // This match rule prevents reordering of node before a safepoint.
10563 // This only makes sense if this instructions is used exclusively
10564 // for the expansion of EncodeP!
10565 match(Set crx (CmpP src1 src2));
10566 predicate(false);
10567
10568 format %{ "CMPDI $crx, $src1, $src2" %}
10569 size(4);
10570 ins_encode %{
10571 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
10572 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
10573 %}
10574 ins_pipe(pipe_class_compare);
10575 %}
10576
10577 //----------Float Compares----------------------------------------------------
10578
10579 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
10580 // Needs matchrule, see cmpDUnordered.
10581 match(Set crx (CmpF src1 src2));
10582 // no match-rule, false predicate
10583 predicate(false);
10584
10585 format %{ "cmpFUrd $crx, $src1, $src2" %}
10586 size(4);
10587 ins_encode %{
10588 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
10589 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10590 %}
10591 ins_pipe(pipe_class_default);
10592 %}
10593
10594 instruct cmov_bns_less(flagsReg crx) %{
10595 // no match-rule, false predicate
10596 effect(DEF crx);
10597 predicate(false);
10598
10599 ins_variable_size_depending_on_alignment(true);
10600
10601 format %{ "cmov $crx" %}
10602 // Worst case is branch + move + stop, no stop without scheduler.
10670
10671 // Insert new nodes.
10672 nodes->push(m1);
10673 nodes->push(m2);
10674 %}
10675 %}
10676
10677 // Compare float, generate -1,0,1
10678 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{
10679 match(Set dst (CmpF3 src1 src2));
10680 ins_cost(DEFAULT_COST*5+BRANCH_COST);
10681
10682 expand %{
10683 flagsReg tmp1;
10684 cmpFUnordered_reg_reg(tmp1, src1, src2);
10685 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1);
10686 %}
10687 %}
10688
10689 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
10690 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
10691 // node right before the conditional move using it.
10692 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
10693 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
10694 // crashed in register allocation where the flags Reg between cmpDUnoredered and a
10695 // conditional move was supposed to be spilled.
10696 match(Set crx (CmpD src1 src2));
10697 // False predicate, shall not be matched.
10698 predicate(false);
10699
10700 format %{ "cmpFUrd $crx, $src1, $src2" %}
10701 size(4);
10702 ins_encode %{
10703 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
10704 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
10705 %}
10706 ins_pipe(pipe_class_default);
10707 %}
10708
10709 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
10710 match(Set crx (CmpD src1 src2));
10711 ins_cost(DEFAULT_COST+BRANCH_COST);
10712
10713 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %}
10714 postalloc_expand %{
10715 //
10716 // replaces
10717 //
10775 match(Goto);
10776 effect(USE labl);
10777 ins_cost(BRANCH_COST);
10778
10779 format %{ "B $labl" %}
10780 size(4);
10781 ins_encode %{
10782 // TODO: PPC port $archOpcode(ppc64Opcode_b);
10783 Label d; // dummy
10784 __ bind(d);
10785 Label* p = $labl$$label;
10786 // `p' is `NULL' when this encoding class is used only to
10787 // determine the size of the encoded instruction.
10788 Label& l = (NULL == p)? d : *(p);
10789 __ b(l);
10790 %}
10791 ins_pipe(pipe_class_default);
10792 %}
10793
10794 // Conditional Near Branch
10795 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10796 // Same match rule as `branchConFar'.
10797 match(If cmp crx);
10798 effect(USE lbl);
10799 ins_cost(BRANCH_COST);
10800
10801 // If set to 1 this indicates that the current instruction is a
10802 // short variant of a long branch. This avoids using this
10803 // instruction in first-pass matching. It will then only be used in
10804 // the `Shorten_branches' pass.
10805 ins_short_branch(1);
10806
10807 format %{ "B$cmp $crx, $lbl" %}
10808 size(4);
10809 ins_encode( enc_bc(crx, cmp, lbl) );
10810 ins_pipe(pipe_class_default);
10811 %}
10812
10813 // This is for cases when the ppc64 `bc' instruction does not
10814 // reach far enough. So we emit a far branch here, which is more
10815 // expensive.
10816 //
10817 // Conditional Far Branch
10818 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10819 // Same match rule as `branchCon'.
10820 match(If cmp crx);
10821 effect(USE crx, USE lbl);
10822 predicate(!false /* TODO: PPC port HB_Schedule*/);
10823 // Higher cost than `branchCon'.
10824 ins_cost(5*BRANCH_COST);
10825
10826 // This is not a short variant of a branch, but the long variant.
10827 ins_short_branch(0);
10828
10829 format %{ "B_FAR$cmp $crx, $lbl" %}
10830 size(8);
10831 ins_encode( enc_bc_far(crx, cmp, lbl) );
10832 ins_pipe(pipe_class_default);
10833 %}
10834
10835 // Conditional Branch used with Power6 scheduler (can be far or short).
10836 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{
10837 // Same match rule as `branchCon'.
10838 match(If cmp crx);
10839 effect(USE crx, USE lbl);
10840 predicate(false /* TODO: PPC port HB_Schedule*/);
10841 // Higher cost than `branchCon'.
10842 ins_cost(5*BRANCH_COST);
10843
10844 // Actually size doesn't depend on alignment but on shortening.
10845 ins_variable_size_depending_on_alignment(true);
10846 // long variant.
10847 ins_short_branch(0);
10848
10849 format %{ "B_FAR$cmp $crx, $lbl" %}
10850 size(8); // worst case
10851 ins_encode( enc_bc_short_far(crx, cmp, lbl) );
10852 ins_pipe(pipe_class_default);
10853 %}
10854
10855 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
10856 match(CountedLoopEnd cmp crx);
10857 effect(USE labl);
10858 ins_cost(BRANCH_COST);
10859
10860 // short variant.
10861 ins_short_branch(1);
10862
10863 format %{ "B$cmp $crx, $labl \t// counted loop end" %}
10864 size(4);
10865 ins_encode( enc_bc(crx, cmp, labl) );
10866 ins_pipe(pipe_class_default);
10867 %}
10868
10869 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
10870 match(CountedLoopEnd cmp crx);
10871 effect(USE labl);
10872 predicate(!false /* TODO: PPC port HB_Schedule */);
10873 ins_cost(BRANCH_COST);
10874
10875 // Long variant.
10876 ins_short_branch(0);
10877
10878 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10879 size(8);
10880 ins_encode( enc_bc_far(crx, cmp, labl) );
10881 ins_pipe(pipe_class_default);
10882 %}
10883
10884 // Conditional Branch used with Power6 scheduler (can be far or short).
10885 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{
10886 match(CountedLoopEnd cmp crx);
10887 effect(USE labl);
10888 predicate(false /* TODO: PPC port HB_Schedule */);
10889 // Higher cost than `branchCon'.
10890 ins_cost(5*BRANCH_COST);
10891
10892 // Actually size doesn't depend on alignment but on shortening.
10893 ins_variable_size_depending_on_alignment(true);
10894 // Long variant.
10895 ins_short_branch(0);
10896
10897 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
10898 size(8); // worst case
10899 ins_encode( enc_bc_short_far(crx, cmp, labl) );
10900 ins_pipe(pipe_class_default);
10901 %}
10902
10903 // ============================================================================
10904 // Java runtime operations, intrinsics and other complex operations.
10905
10914 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
10915 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
10916 match(Set result (PartialSubtypeCheck subklass superklass));
10917 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
10918 ins_cost(DEFAULT_COST*10);
10919
10920 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
10921 ins_encode %{
10922 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10923 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
10924 $tmp_klass$$Register, NULL, $result$$Register);
10925 %}
10926 ins_pipe(pipe_class_default);
10927 %}
10928
10929 // inlined locking and unlocking
10930
10931 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
10932 match(Set crx (FastLock oop box));
10933 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
10934 predicate(/*(!UseNewFastLockPPC64 || UseBiasedLocking) &&*/ !Compile::current()->use_rtm());
10935
10936 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3" %}
10937 ins_encode %{
10938 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10939 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
10940 $tmp3$$Register, $tmp1$$Register, $tmp2$$Register,
10941 UseBiasedLocking && !UseOptoBiasInlining); // SAPJVM MD 2014-11-06 UseOptoBiasInlining
10942 // If locking was successfull, crx should indicate 'EQ'.
10943 // The compiler generates a branch to the runtime call to
10944 // _complete_monitor_locking_Java for the case where crx is 'NE'.
10945 %}
10946 ins_pipe(pipe_class_compare);
10947 %}
10948
10949 // Separate version for TM. Use bound register for box to enable USE_KILL.
10950 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
10951 match(Set crx (FastLock oop box));
10952 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box);
10953 predicate(Compile::current()->use_rtm());
10954
10955 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %}
10956 ins_encode %{
10957 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10958 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
10959 $tmp3$$Register, $tmp1$$Register, $tmp2$$Register,
10960 /*Biased Locking*/ false,
10961 _rtm_counters, _stack_rtm_counters,
10962 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
10963 /*TM*/ true, ra_->C->profile_rtm());
10964 // If locking was successfull, crx should indicate 'EQ'.
10965 // The compiler generates a branch to the runtime call to
10966 // _complete_monitor_locking_Java for the case where crx is 'NE'.
10967 %}
10968 ins_pipe(pipe_class_compare);
10969 %}
10970
10971 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
10972 match(Set crx (FastUnlock oop box));
10973 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
10974 predicate(!Compile::current()->use_rtm());
10975
10976 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %}
10977 ins_encode %{
10978 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10979 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
10980 $tmp3$$Register, $tmp1$$Register, $tmp2$$Register,
10981 UseBiasedLocking && !UseOptoBiasInlining,
10982 false);
10983 // If unlocking was successfull, crx should indicate 'EQ'.
10984 // The compiler generates a branch to the runtime call to
10985 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
10986 %}
10987 ins_pipe(pipe_class_compare);
10988 %}
10989
10990 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
10991 match(Set crx (FastUnlock oop box));
10992 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
10993 predicate(Compile::current()->use_rtm());
10994
10995 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %}
10996 ins_encode %{
10997 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
10998 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
10999 $tmp3$$Register, $tmp1$$Register, $tmp2$$Register,
11000 /*Biased Locking*/ false, /*TM*/ true);
11001 // If unlocking was successfull, crx should indicate 'EQ'.
11002 // The compiler generates a branch to the runtime call to
11003 // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11004 %}
11005 ins_pipe(pipe_class_compare);
11006 %}
11007
11008 // Align address.
11009 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11010 match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11011
11012 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %}
11013 size(4);
11014 ins_encode %{
11015 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
11016 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant));
11017 %}
11018 ins_pipe(pipe_class_default);
11019 %}
11020
11646 match(Set dst (ReplicateF src));
11647 predicate(n->as_Vector()->length() == 2);
11648 ins_cost(5 * DEFAULT_COST);
11649
11650 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
11651 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
11652 %}
11653
11654 // Replicate scalar zero constant to packed float values in Double register
11655 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
11656 match(Set dst (ReplicateF zero));
11657 predicate(n->as_Vector()->length() == 2);
11658
11659 format %{ "LI $dst, #0 \t// replicate2F" %}
11660 ins_encode %{
11661 // TODO: PPC port $archOpcode(ppc64Opcode_addi);
11662 __ li($dst$$Register, 0x0);
11663 %}
11664 ins_pipe(pipe_class_default);
11665 %}
11666
11667
11668 //----------Overflow Math Instructions-----------------------------------------
11669
11670 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
11671 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
11672 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
11673
11674 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
11675 match(Set cr0 (OverflowAddL op1 op2));
11676
11677 format %{ "add_ $op1, $op2\t# overflow check long" %}
11678 ins_encode %{
11679 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11680 __ li(R0, 0);
11681 __ mtxer(R0); // clear XER.SO
11682 __ addo_(R0, $op1$$Register, $op2$$Register);
11683 %}
11684 ins_pipe(pipe_class_default);
11685 %}
11686
11687 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
11688 match(Set cr0 (OverflowSubL op1 op2));
11689
11690 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %}
11691 ins_encode %{
11692 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11693 __ li(R0, 0);
11694 __ mtxer(R0); // clear XER.SO
11695 __ subfo_(R0, $op2$$Register, $op1$$Register);
11696 %}
11697 ins_pipe(pipe_class_default);
11698 %}
11699
11700 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
11701 match(Set cr0 (OverflowSubL zero op2));
11702
11703 format %{ "nego_ R0, $op2\t# overflow check long" %}
11704 ins_encode %{
11705 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11706 __ li(R0, 0);
11707 __ mtxer(R0); // clear XER.SO
11708 __ nego_(R0, $op2$$Register);
11709 %}
11710 ins_pipe(pipe_class_default);
11711 %}
11712
11713 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
11714 match(Set cr0 (OverflowMulL op1 op2));
11715
11716 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %}
11717 ins_encode %{
11718 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11719 __ li(R0, 0);
11720 __ mtxer(R0); // clear XER.SO
11721 __ mulldo_(R0, $op1$$Register, $op2$$Register);
11722 %}
11723 ins_pipe(pipe_class_default);
11724 %}
11725
11726
11727 // ============================================================================
11728 // Safepoint Instruction
11729
11730 instruct safePoint_poll(iRegPdst poll) %{
11731 match(SafePoint poll);
11732 predicate(LoadPollAddressFromThread);
11733
11734 // It caused problems to add the effect that r0 is killed, but this
11735 // effect no longer needs to be mentioned, since r0 is not contained
11736 // in a reg_class.
11737
11738 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %}
11739 size(4);
11740 ins_encode( enc_poll(0x0, poll) );
11741 ins_pipe(pipe_class_default);
11742 %}
11743
11744 // Safepoint without per-thread support. Load address of page to poll
11745 // as constant.
|