hotspot/src/cpu/ppc/vm/ppc.ad
changeset 39444 2eae9b74c1f3
parent 39424 1045973b8c6a
child 41673 e8b3ccb2cfcf
equal deleted inserted replaced
39443:ca6dfb34e46c 39444:2eae9b74c1f3
   963 
   963 
   964 // Compute padding required for nodes which need alignment. The padding
   964 // Compute padding required for nodes which need alignment. The padding
   965 // is the number of bytes (not instructions) which will be inserted before
   965 // is the number of bytes (not instructions) which will be inserted before
   966 // the instruction. The padding must match the size of a NOP instruction.
   966 // the instruction. The padding must match the size of a NOP instruction.
   967 
   967 
   968 int string_indexOf_imm1_charNode::compute_padding(int current_offset) const {
       
   969   return (3*4-current_offset)&31;  // see MacroAssembler::string_indexof_1
       
   970 }
       
   971 
       
   972 int string_indexOf_imm1Node::compute_padding(int current_offset) const {
       
   973   return (3*4-current_offset)&31;  // see MacroAssembler::string_indexof_1
       
   974 }
       
   975 
       
   976 int string_indexOfCharNode::compute_padding(int current_offset) const {
       
   977   return (3*4-current_offset)&31;  // see MacroAssembler::string_indexof_1
       
   978 }
       
   979 
       
   980 int string_indexOf_immNode::compute_padding(int current_offset) const {
       
   981   return (3*4-current_offset)&31;  // see MacroAssembler::string_indexof(constant needlecount)
       
   982 }
       
   983 
       
   984 int string_indexOfNode::compute_padding(int current_offset) const {
       
   985   return (1*4-current_offset)&31;  // see MacroAssembler::string_indexof(variable needlecount)
       
   986 }
       
   987 
       
   988 int string_compareNode::compute_padding(int current_offset) const {
       
   989   return (2*4-current_offset)&31;  // see MacroAssembler::string_compare
       
   990 }
       
   991 
       
   992 int string_equals_immNode::compute_padding(int current_offset) const {
       
   993   if (opnd_array(3)->constant() < 16) return 0; // For strlen < 16 no nops because loop completely unrolled
       
   994   return (2*4-current_offset)&31;               // Genral case - see MacroAssembler::char_arrays_equalsImm
       
   995 }
       
   996 
       
   997 int string_equalsNode::compute_padding(int current_offset) const {
       
   998   return (7*4-current_offset)&31;  // see MacroAssembler::char_arrays_equals
       
   999 }
       
  1000 
       
  1001 int inlineCallClearArrayNode::compute_padding(int current_offset) const {
   968 int inlineCallClearArrayNode::compute_padding(int current_offset) const {
  1002   return (2*4-current_offset)&31;  // see MacroAssembler::clear_memory_doubleword
   969   int desired_padding = (2*4-current_offset)&31; // see MacroAssembler::clear_memory_doubleword
       
   970   return (desired_padding <= 3*4) ? desired_padding : 0;
  1003 }
   971 }
  1004 
   972 
  1005 //=============================================================================
   973 //=============================================================================
  1006 
   974 
  1007 // Indicate if the safepoint node needs the polling page as an input.
   975 // Indicate if the safepoint node needs the polling page as an input.
  3060     // Branch if not (cmp crx).
  3028     // Branch if not (cmp crx).
  3061     __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
  3029     __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
  3062     __ li($dst$$Register, $src$$constant);
  3030     __ li($dst$$Register, $src$$constant);
  3063     // TODO PPC port __ endgroup_if_needed(_size == 12);
  3031     // TODO PPC port __ endgroup_if_needed(_size == 12);
  3064     __ bind(done);
  3032     __ bind(done);
  3065   %}
       
  3066 
       
  3067   // New atomics.
       
  3068   enc_class enc_GetAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
       
  3069     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  3070 
       
  3071     MacroAssembler _masm(&cbuf);
       
  3072     Register Rtmp   = R0;
       
  3073     Register Rres   = $res$$Register;
       
  3074     Register Rsrc   = $src$$Register;
       
  3075     Register Rptr   = $mem_ptr$$Register;
       
  3076     bool RegCollision = (Rres == Rsrc) || (Rres == Rptr);
       
  3077     Register Rold   = RegCollision ? Rtmp : Rres;
       
  3078 
       
  3079     Label Lretry;
       
  3080     __ bind(Lretry);
       
  3081     __ lwarx(Rold, Rptr, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  3082     __ add(Rtmp, Rsrc, Rold);
       
  3083     __ stwcx_(Rtmp, Rptr);
       
  3084     if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
       
  3085       __ bne_predict_not_taken(CCR0, Lretry);
       
  3086     } else {
       
  3087       __ bne(                  CCR0, Lretry);
       
  3088     }
       
  3089     if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
       
  3090     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  3091       __ isync();
       
  3092     } else {
       
  3093       __ sync();
       
  3094     }
       
  3095   %}
       
  3096 
       
  3097   enc_class enc_GetAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
       
  3098     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  3099 
       
  3100     MacroAssembler _masm(&cbuf);
       
  3101     Register Rtmp   = R0;
       
  3102     Register Rres   = $res$$Register;
       
  3103     Register Rsrc   = $src$$Register;
       
  3104     Register Rptr   = $mem_ptr$$Register;
       
  3105     bool RegCollision = (Rres == Rsrc) || (Rres == Rptr);
       
  3106     Register Rold   = RegCollision ? Rtmp : Rres;
       
  3107 
       
  3108     Label Lretry;
       
  3109     __ bind(Lretry);
       
  3110     __ ldarx(Rold, Rptr, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  3111     __ add(Rtmp, Rsrc, Rold);
       
  3112     __ stdcx_(Rtmp, Rptr);
       
  3113     if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
       
  3114       __ bne_predict_not_taken(CCR0, Lretry);
       
  3115     } else {
       
  3116       __ bne(                  CCR0, Lretry);
       
  3117     }
       
  3118     if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
       
  3119     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  3120       __ isync();
       
  3121     } else {
       
  3122       __ sync();
       
  3123     }
       
  3124   %}
       
  3125 
       
  3126   enc_class enc_GetAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
       
  3127     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  3128 
       
  3129     MacroAssembler _masm(&cbuf);
       
  3130     Register Rtmp   = R0;
       
  3131     Register Rres   = $res$$Register;
       
  3132     Register Rsrc   = $src$$Register;
       
  3133     Register Rptr   = $mem_ptr$$Register;
       
  3134     bool RegCollision = (Rres == Rsrc) || (Rres == Rptr);
       
  3135     Register Rold   = RegCollision ? Rtmp : Rres;
       
  3136 
       
  3137     Label Lretry;
       
  3138     __ bind(Lretry);
       
  3139     __ lwarx(Rold, Rptr, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  3140     __ stwcx_(Rsrc, Rptr);
       
  3141     if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
       
  3142       __ bne_predict_not_taken(CCR0, Lretry);
       
  3143     } else {
       
  3144       __ bne(                  CCR0, Lretry);
       
  3145     }
       
  3146     if (RegCollision) __ mr(Rres, Rtmp);
       
  3147     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  3148       __ isync();
       
  3149     } else {
       
  3150       __ sync();
       
  3151     }
       
  3152   %}
       
  3153 
       
  3154   enc_class enc_GetAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
       
  3155     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  3156 
       
  3157     MacroAssembler _masm(&cbuf);
       
  3158     Register Rtmp   = R0;
       
  3159     Register Rres   = $res$$Register;
       
  3160     Register Rsrc   = $src$$Register;
       
  3161     Register Rptr   = $mem_ptr$$Register;
       
  3162     bool RegCollision = (Rres == Rsrc) || (Rres == Rptr);
       
  3163     Register Rold   = RegCollision ? Rtmp : Rres;
       
  3164 
       
  3165     Label Lretry;
       
  3166     __ bind(Lretry);
       
  3167     __ ldarx(Rold, Rptr, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  3168     __ stdcx_(Rsrc, Rptr);
       
  3169     if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
       
  3170       __ bne_predict_not_taken(CCR0, Lretry);
       
  3171     } else {
       
  3172       __ bne(                  CCR0, Lretry);
       
  3173     }
       
  3174     if (RegCollision) __ mr(Rres, Rtmp);
       
  3175     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  3176       __ isync();
       
  3177     } else {
       
  3178       __ sync();
       
  3179     }
       
  3180   %}
  3033   %}
  3181 
  3034 
  3182   // This enc_class is needed so that scheduler gets proper
  3035   // This enc_class is needed so that scheduler gets proper
  3183   // input mapping for latency computation.
  3036   // input mapping for latency computation.
  3184   enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
  3037   enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
  7573 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))"  cannot be
  7426 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))"  cannot be
  7574 // matched.
  7427 // matched.
  7575 
  7428 
  7576 // Strong versions:
  7429 // Strong versions:
  7577 
  7430 
       
  7431 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7432   match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
       
  7433   predicate(VM_Version::has_lqarx());
       
  7434   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
       
  7435   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7436   ins_encode %{
       
  7437     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7438     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7439     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7440                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7441                 $res$$Register, true);
       
  7442     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7443       __ isync();
       
  7444     } else {
       
  7445       __ sync();
       
  7446     }
       
  7447   %}
       
  7448   ins_pipe(pipe_class_default);
       
  7449 %}
       
  7450 
       
  7451 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
       
  7452   match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
       
  7453   predicate(!VM_Version::has_lqarx());
       
  7454   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
       
  7455   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7456   ins_encode %{
       
  7457     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7458     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7459     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
       
  7460                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7461                 $res$$Register, true);
       
  7462     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7463       __ isync();
       
  7464     } else {
       
  7465       __ sync();
       
  7466     }
       
  7467   %}
       
  7468   ins_pipe(pipe_class_default);
       
  7469 %}
       
  7470 
       
  7471 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7472   match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
       
  7473   predicate(VM_Version::has_lqarx());
       
  7474   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
       
  7475   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7476   ins_encode %{
       
  7477     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7478     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7479     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7480                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7481                 $res$$Register, true);
       
  7482     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7483       __ isync();
       
  7484     } else {
       
  7485       __ sync();
       
  7486     }
       
  7487   %}
       
  7488   ins_pipe(pipe_class_default);
       
  7489 %}
       
  7490 
       
  7491 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
       
  7492   match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
       
  7493   predicate(!VM_Version::has_lqarx());
       
  7494   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
       
  7495   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7496   ins_encode %{
       
  7497     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7498     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7499     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
       
  7500                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7501                 $res$$Register, true);
       
  7502     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7503       __ isync();
       
  7504     } else {
       
  7505       __ sync();
       
  7506     }
       
  7507   %}
       
  7508   ins_pipe(pipe_class_default);
       
  7509 %}
       
  7510 
  7578 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7511 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7579   match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
  7512   match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
  7580   effect(TEMP cr0);
  7513   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7581   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7514   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7582   // Variable size: instruction count smaller if regs are disjoint.
       
  7583   ins_encode %{
  7515   ins_encode %{
  7584     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7516     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7585     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7517     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7586     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7518     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7587                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7519                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7595   ins_pipe(pipe_class_default);
  7527   ins_pipe(pipe_class_default);
  7596 %}
  7528 %}
  7597 
  7529 
  7598 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7530 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7599   match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
  7531   match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
  7600   effect(TEMP cr0);
  7532   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7601   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7533   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7602   // Variable size: instruction count smaller if regs are disjoint.
       
  7603   ins_encode %{
  7534   ins_encode %{
  7604     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7535     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7605     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7536     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7606     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7537     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7607                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7538                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7615   ins_pipe(pipe_class_default);
  7546   ins_pipe(pipe_class_default);
  7616 %}
  7547 %}
  7617 
  7548 
  7618 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7549 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7619   match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
  7550   match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
  7620   effect(TEMP cr0);
  7551   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7621   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
  7552   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
  7622   // Variable size: instruction count smaller if regs are disjoint.
       
  7623   ins_encode %{
  7553   ins_encode %{
  7624     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7554     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7625     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7555     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7626     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7556     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7627                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7557                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7635   ins_pipe(pipe_class_default);
  7565   ins_pipe(pipe_class_default);
  7636 %}
  7566 %}
  7637 
  7567 
  7638 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7568 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7639   match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
  7569   match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
  7640   effect(TEMP cr0);
  7570   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7641   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
  7571   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
  7642   // Variable size: instruction count smaller if regs are disjoint.
       
  7643   ins_encode %{
  7572   ins_encode %{
  7644     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7573     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7645     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7574     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7646     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7575     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7647                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7576                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7655   ins_pipe(pipe_class_default);
  7584   ins_pipe(pipe_class_default);
  7656 %}
  7585 %}
  7657 
  7586 
  7658 // Weak versions:
  7587 // Weak versions:
  7659 
  7588 
       
  7589 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7590   match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
       
  7591   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
       
  7592   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
       
  7593   format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7594   ins_encode %{
       
  7595     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7596     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7597     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7598                 MacroAssembler::MemBarNone,
       
  7599                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7600   %}
       
  7601   ins_pipe(pipe_class_default);
       
  7602 %}
       
  7603 
       
  7604 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
       
  7605   match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
       
  7606   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
       
  7607   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
       
  7608   format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7609   ins_encode %{
       
  7610     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7611     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7612     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
       
  7613                 MacroAssembler::MemBarNone,
       
  7614                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7615   %}
       
  7616   ins_pipe(pipe_class_default);
       
  7617 %}
       
  7618 
       
  7619 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7620   match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
       
  7621   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
       
  7622   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
       
  7623   format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7624   ins_encode %{
       
  7625     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7626     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7627     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7628                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
       
  7629                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7630   %}
       
  7631   ins_pipe(pipe_class_default);
       
  7632 %}
       
  7633 
       
  7634 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
       
  7635   match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
       
  7636   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
       
  7637   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
       
  7638   format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7639   ins_encode %{
       
  7640     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7641     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7642     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
       
  7643                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
       
  7644                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7645   %}
       
  7646   ins_pipe(pipe_class_default);
       
  7647 %}
       
  7648 
       
  7649 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7650   match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
       
  7651   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
       
  7652   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
       
  7653   format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7654   ins_encode %{
       
  7655     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7656     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7657     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7658                 MacroAssembler::MemBarNone,
       
  7659                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7660   %}
       
  7661   ins_pipe(pipe_class_default);
       
  7662 %}
       
  7663 
       
  7664 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
       
  7665   match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
       
  7666   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
       
  7667   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
       
  7668   format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7669   ins_encode %{
       
  7670     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7671     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7672     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
       
  7673                 MacroAssembler::MemBarNone,
       
  7674                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7675   %}
       
  7676   ins_pipe(pipe_class_default);
       
  7677 %}
       
  7678 
       
  7679 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7680   match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
       
  7681   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
       
  7682   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
       
  7683   format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7684   ins_encode %{
       
  7685     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7686     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7687     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7688                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
       
  7689                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7690   %}
       
  7691   ins_pipe(pipe_class_default);
       
  7692 %}
       
  7693 
       
  7694 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
       
  7695   match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
       
  7696   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
       
  7697   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
       
  7698   format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
       
  7699   ins_encode %{
       
  7700     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7701     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7702     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
       
  7703                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
       
  7704                 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
       
  7705   %}
       
  7706   ins_pipe(pipe_class_default);
       
  7707 %}
       
  7708 
  7660 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7709 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7661   match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
  7710   match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
  7662   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7711   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7663   effect(TEMP cr0);
  7712   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7664   format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7713   format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7665   // Variable size: instruction count smaller if regs are disjoint.
       
  7666   ins_encode %{
  7714   ins_encode %{
  7667     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7715     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7668     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7716     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7669     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7717     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7670                 MacroAssembler::MemBarNone,
  7718                 MacroAssembler::MemBarNone,
  7674 %}
  7722 %}
  7675 
  7723 
  7676 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7724 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7677   match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
  7725   match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
  7678   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7726   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7679   effect(TEMP cr0);
  7727   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7680   format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
  7728   format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
  7681   // Variable size: instruction count smaller if regs are disjoint.
       
  7682   ins_encode %{
  7729   ins_encode %{
  7683     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7730     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7684     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7731     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7685     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7732     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7686     // value is never passed to caller.
  7733     // value is never passed to caller.
  7692 %}
  7739 %}
  7693 
  7740 
  7694 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7741 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7695   match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
  7742   match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
  7696   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7743   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7697   effect(TEMP cr0);
  7744   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7698   format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7745   format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
  7699   // Variable size: instruction count smaller if regs are disjoint.
       
  7700   ins_encode %{
  7746   ins_encode %{
  7701     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7747     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7702     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7748     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7703     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7749     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7704                 MacroAssembler::MemBarNone,
  7750                 MacroAssembler::MemBarNone,
  7708 %}
  7754 %}
  7709 
  7755 
  7710 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7756 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7711   match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
  7757   match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
  7712   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7758   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7713   effect(TEMP cr0);
  7759   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7714   format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
  7760   format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
  7715   // Variable size: instruction count smaller if regs are disjoint.
       
  7716   ins_encode %{
  7761   ins_encode %{
  7717     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7762     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7718     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7763     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7719     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7764     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7720     // value is never passed to caller.
  7765     // value is never passed to caller.
  7726 %}
  7771 %}
  7727 
  7772 
  7728 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7773 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7729   match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
  7774   match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
  7730   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7775   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7731   effect(TEMP cr0);
  7776   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7732   format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
  7777   format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
  7733   // Variable size: instruction count smaller if regs are disjoint.
       
  7734   ins_encode %{
  7778   ins_encode %{
  7735     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7779     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7736     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7780     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7737     // value is never passed to caller.
  7781     // value is never passed to caller.
  7738     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7782     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7743 %}
  7787 %}
  7744 
  7788 
  7745 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7789 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7746   match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
  7790   match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
  7747   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7791   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7748   effect(TEMP cr0);
  7792   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7749   format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
  7793   format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
  7750   // Variable size: instruction count smaller if regs are disjoint.
       
  7751   ins_encode %{
  7794   ins_encode %{
  7752     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7795     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7753     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7796     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7754     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7797     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7755     // value is never passed to caller.
  7798     // value is never passed to caller.
  7761 %}
  7804 %}
  7762 
  7805 
  7763 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7806 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7764   match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
  7807   match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
  7765   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7808   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7766   effect(TEMP cr0);
  7809   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7767   format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
  7810   format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
  7768   // Variable size: instruction count smaller if regs are disjoint.
       
  7769   ins_encode %{
  7811   ins_encode %{
  7770     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7812     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7771     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7813     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7772     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7814     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7773                 MacroAssembler::MemBarNone,
  7815                 MacroAssembler::MemBarNone,
  7777 %}
  7819 %}
  7778 
  7820 
  7779 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7821 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7780   match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
  7822   match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
  7781   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7823   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7782   effect(TEMP cr0);
  7824   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
  7783   format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
  7825   format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
  7784   // Variable size: instruction count smaller if regs are disjoint.
       
  7785   ins_encode %{
  7826   ins_encode %{
  7786     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7827     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7787     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7828     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7788     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7829     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
  7789     // value is never passed to caller.
  7830     // value is never passed to caller.
  7794   ins_pipe(pipe_class_default);
  7835   ins_pipe(pipe_class_default);
  7795 %}
  7836 %}
  7796 
  7837 
  7797 // CompareAndExchange
  7838 // CompareAndExchange
  7798 
  7839 
       
  7840 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7841   match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
       
  7842   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
       
  7843   effect(TEMP_DEF res, TEMP cr0);
       
  7844   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
       
  7845   ins_encode %{
       
  7846     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7847     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7848     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7849                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7850                 noreg, true);
       
  7851   %}
       
  7852   ins_pipe(pipe_class_default);
       
  7853 %}
       
  7854 
       
  7855 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
       
  7856   match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
       
  7857   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
       
  7858   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
       
  7859   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
       
  7860   ins_encode %{
       
  7861     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7862     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7863     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
       
  7864                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7865                 noreg, true);
       
  7866   %}
       
  7867   ins_pipe(pipe_class_default);
       
  7868 %}
       
  7869 
       
  7870 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7871   match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
       
  7872   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
       
  7873   effect(TEMP_DEF res, TEMP cr0);
       
  7874   format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
       
  7875   ins_encode %{
       
  7876     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7877     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7878     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7879                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7880                 noreg, true);
       
  7881     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7882       __ isync();
       
  7883     } else {
       
  7884       // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
       
  7885       __ sync();
       
  7886     }
       
  7887   %}
       
  7888   ins_pipe(pipe_class_default);
       
  7889 %}
       
  7890 
       
  7891 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
       
  7892   match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
       
  7893   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
       
  7894   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
       
  7895   format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
       
  7896   ins_encode %{
       
  7897     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7898     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7899     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
       
  7900                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7901                 noreg, true);
       
  7902     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7903       __ isync();
       
  7904     } else {
       
  7905       // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
       
  7906       __ sync();
       
  7907     }
       
  7908   %}
       
  7909   ins_pipe(pipe_class_default);
       
  7910 %}
       
  7911 
       
  7912 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7913   match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
       
  7914   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
       
  7915   effect(TEMP_DEF res, TEMP cr0);
       
  7916   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
       
  7917   ins_encode %{
       
  7918     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7919     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7920     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7921                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7922                 noreg, true);
       
  7923   %}
       
  7924   ins_pipe(pipe_class_default);
       
  7925 %}
       
  7926 
       
  7927 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
       
  7928   match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
       
  7929   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
       
  7930   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
       
  7931   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
       
  7932   ins_encode %{
       
  7933     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7934     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7935     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
       
  7936                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7937                 noreg, true);
       
  7938   %}
       
  7939   ins_pipe(pipe_class_default);
       
  7940 %}
       
  7941 
       
  7942 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
       
  7943   match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
       
  7944   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
       
  7945   effect(TEMP_DEF res, TEMP cr0);
       
  7946   format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
       
  7947   ins_encode %{
       
  7948     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7949     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7950     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
       
  7951                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7952                 noreg, true);
       
  7953     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7954       __ isync();
       
  7955     } else {
       
  7956       // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
       
  7957       __ sync();
       
  7958     }
       
  7959   %}
       
  7960   ins_pipe(pipe_class_default);
       
  7961 %}
       
  7962 
       
  7963 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
       
  7964   match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
       
  7965   predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
       
  7966   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
       
  7967   format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
       
  7968   ins_encode %{
       
  7969     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
  7970     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
       
  7971     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
       
  7972                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
       
  7973                 noreg, true);
       
  7974     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  7975       __ isync();
       
  7976     } else {
       
  7977       // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
       
  7978       __ sync();
       
  7979     }
       
  7980   %}
       
  7981   ins_pipe(pipe_class_default);
       
  7982 %}
       
  7983 
  7799 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7984 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7800   match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
  7985   match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
  7801   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7986   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7802   effect(TEMP_DEF res, TEMP cr0);
  7987   effect(TEMP_DEF res, TEMP cr0);
  7803   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
  7988   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
  7804   // Variable size: instruction count smaller if regs are disjoint.
       
  7805   ins_encode %{
  7989   ins_encode %{
  7806     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7990     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7807     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7991     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7808     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7992     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7809                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7993                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7815 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7999 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
  7816   match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
  8000   match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
  7817   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  8001   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7818   effect(TEMP_DEF res, TEMP cr0);
  8002   effect(TEMP_DEF res, TEMP cr0);
  7819   format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
  8003   format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
  7820   // Variable size: instruction count smaller if regs are disjoint.
       
  7821   ins_encode %{
  8004   ins_encode %{
  7822     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  8005     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7823     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  8006     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7824     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  8007     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7825                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  8008                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7837 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  8020 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7838   match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
  8021   match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
  7839   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  8022   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7840   effect(TEMP_DEF res, TEMP cr0);
  8023   effect(TEMP_DEF res, TEMP cr0);
  7841   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
  8024   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
  7842   // Variable size: instruction count smaller if regs are disjoint.
       
  7843   ins_encode %{
  8025   ins_encode %{
  7844     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  8026     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7845     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  8027     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7846     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  8028     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7847                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  8029                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7853 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  8035 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
  7854   match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
  8036   match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
  7855   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  8037   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7856   effect(TEMP_DEF res, TEMP cr0);
  8038   effect(TEMP_DEF res, TEMP cr0);
  7857   format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
  8039   format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
  7858   // Variable size: instruction count smaller if regs are disjoint.
       
  7859   ins_encode %{
  8040   ins_encode %{
  7860     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  8041     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7861     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  8042     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7862     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  8043     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7863                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  8044                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7875 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  8056 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7876   match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
  8057   match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
  7877   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  8058   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7878   effect(TEMP_DEF res, TEMP cr0);
  8059   effect(TEMP_DEF res, TEMP cr0);
  7879   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
  8060   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
  7880   // Variable size: instruction count smaller if regs are disjoint.
       
  7881   ins_encode %{
  8061   ins_encode %{
  7882     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  8062     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7883     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  8063     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7884     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  8064     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7885                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  8065                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7891 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  8071 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
  7892   match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
  8072   match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
  7893   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  8073   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7894   effect(TEMP_DEF res, TEMP cr0);
  8074   effect(TEMP_DEF res, TEMP cr0);
  7895   format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
  8075   format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
  7896   // Variable size: instruction count smaller if regs are disjoint.
       
  7897   ins_encode %{
  8076   ins_encode %{
  7898     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  8077     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7899     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  8078     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7900     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  8079     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7901                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  8080                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7913 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  8092 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7914   match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
  8093   match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
  7915   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  8094   predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
  7916   effect(TEMP_DEF res, TEMP cr0);
  8095   effect(TEMP_DEF res, TEMP cr0);
  7917   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
  8096   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
  7918   // Variable size: instruction count smaller if regs are disjoint.
       
  7919   ins_encode %{
  8097   ins_encode %{
  7920     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  8098     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7921     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  8099     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7922     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  8100     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7923                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  8101                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7929 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  8107 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
  7930   match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
  8108   match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
  7931   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  8109   predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
  7932   effect(TEMP_DEF res, TEMP cr0);
  8110   effect(TEMP_DEF res, TEMP cr0);
  7933   format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
  8111   format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
  7934   // Variable size: instruction count smaller if regs are disjoint.
       
  7935   ins_encode %{
  8112   ins_encode %{
  7936     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  8113     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
  7937     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  8114     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
  7938     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  8115     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
  7939                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  8116                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
  7948   ins_pipe(pipe_class_default);
  8125   ins_pipe(pipe_class_default);
  7949 %}
  8126 %}
  7950 
  8127 
  7951 // Special RMW
  8128 // Special RMW
  7952 
  8129 
       
  8130 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
       
  8131   match(Set res (GetAndAddB mem_ptr src));
       
  8132   predicate(VM_Version::has_lqarx());
       
  8133   effect(TEMP_DEF res, TEMP cr0);
       
  8134   format %{ "GetAndAddB $res, $mem_ptr, $src" %}
       
  8135   ins_encode %{
       
  8136     __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8137                   R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8138     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8139       __ isync();
       
  8140     } else {
       
  8141       __ sync();
       
  8142     }
       
  8143   %}
       
  8144   ins_pipe(pipe_class_default);
       
  8145 %}
       
  8146 
       
  8147 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
       
  8148   match(Set res (GetAndAddB mem_ptr src));
       
  8149   predicate(!VM_Version::has_lqarx());
       
  8150   effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
       
  8151   format %{ "GetAndAddB $res, $mem_ptr, $src" %}
       
  8152   ins_encode %{
       
  8153     __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8154                   R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8155     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8156       __ isync();
       
  8157     } else {
       
  8158       __ sync();
       
  8159     }
       
  8160   %}
       
  8161   ins_pipe(pipe_class_default);
       
  8162 %}
       
  8163 
       
  8164 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
       
  8165   match(Set res (GetAndAddS mem_ptr src));
       
  8166   predicate(VM_Version::has_lqarx());
       
  8167   effect(TEMP_DEF res, TEMP cr0);
       
  8168   format %{ "GetAndAddS $res, $mem_ptr, $src" %}
       
  8169   ins_encode %{
       
  8170     __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8171                   R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8172     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8173       __ isync();
       
  8174     } else {
       
  8175       __ sync();
       
  8176     }
       
  8177   %}
       
  8178   ins_pipe(pipe_class_default);
       
  8179 %}
       
  8180 
       
  8181 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
       
  8182   match(Set res (GetAndAddS mem_ptr src));
       
  8183   predicate(!VM_Version::has_lqarx());
       
  8184   effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
       
  8185   format %{ "GetAndAddS $res, $mem_ptr, $src" %}
       
  8186   ins_encode %{
       
  8187     __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8188                   R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8189     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8190       __ isync();
       
  8191     } else {
       
  8192       __ sync();
       
  8193     }
       
  8194   %}
       
  8195   ins_pipe(pipe_class_default);
       
  8196 %}
       
  8197 
  7953 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
  8198 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
  7954   match(Set res (GetAndAddI mem_ptr src));
  8199   match(Set res (GetAndAddI mem_ptr src));
  7955   effect(TEMP cr0);
  8200   effect(TEMP_DEF res, TEMP cr0);
  7956   format %{ "GetAndAddI $res, $mem_ptr, $src" %}
  8201   format %{ "GetAndAddI $res, $mem_ptr, $src" %}
  7957   // Variable size: instruction count smaller if regs are disjoint.
  8202   ins_encode %{
  7958   ins_encode( enc_GetAndAddI(res, mem_ptr, src) );
  8203     __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8204                   R0, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8205     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8206       __ isync();
       
  8207     } else {
       
  8208       __ sync();
       
  8209     }
       
  8210   %}
  7959   ins_pipe(pipe_class_default);
  8211   ins_pipe(pipe_class_default);
  7960 %}
  8212 %}
  7961 
  8213 
  7962 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
  8214 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
  7963   match(Set res (GetAndAddL mem_ptr src));
  8215   match(Set res (GetAndAddL mem_ptr src));
  7964   effect(TEMP cr0);
  8216   effect(TEMP_DEF res, TEMP cr0);
  7965   format %{ "GetAndAddL $res, $mem_ptr, $src" %}
  8217   format %{ "GetAndAddL $res, $mem_ptr, $src" %}
  7966   // Variable size: instruction count smaller if regs are disjoint.
  8218   ins_encode %{
  7967   ins_encode( enc_GetAndAddL(res, mem_ptr, src) );
  8219     __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8220                   R0, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8221     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8222       __ isync();
       
  8223     } else {
       
  8224       __ sync();
       
  8225     }
       
  8226   %}
       
  8227   ins_pipe(pipe_class_default);
       
  8228 %}
       
  8229 
       
  8230 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
       
  8231   match(Set res (GetAndSetB mem_ptr src));
       
  8232   predicate(VM_Version::has_lqarx());
       
  8233   effect(TEMP_DEF res, TEMP cr0);
       
  8234   format %{ "GetAndSetB $res, $mem_ptr, $src" %}
       
  8235   ins_encode %{
       
  8236     __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8237                   noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8238     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8239       __ isync();
       
  8240     } else {
       
  8241       __ sync();
       
  8242     }
       
  8243   %}
       
  8244   ins_pipe(pipe_class_default);
       
  8245 %}
       
  8246 
       
  8247 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
       
  8248   match(Set res (GetAndSetB mem_ptr src));
       
  8249   predicate(!VM_Version::has_lqarx());
       
  8250   effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
       
  8251   format %{ "GetAndSetB $res, $mem_ptr, $src" %}
       
  8252   ins_encode %{
       
  8253     __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8254                   R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8255     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8256       __ isync();
       
  8257     } else {
       
  8258       __ sync();
       
  8259     }
       
  8260   %}
       
  8261   ins_pipe(pipe_class_default);
       
  8262 %}
       
  8263 
       
  8264 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
       
  8265   match(Set res (GetAndSetS mem_ptr src));
       
  8266   predicate(VM_Version::has_lqarx());
       
  8267   effect(TEMP_DEF res, TEMP cr0);
       
  8268   format %{ "GetAndSetS $res, $mem_ptr, $src" %}
       
  8269   ins_encode %{
       
  8270     __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8271                   noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8272     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8273       __ isync();
       
  8274     } else {
       
  8275       __ sync();
       
  8276     }
       
  8277   %}
       
  8278   ins_pipe(pipe_class_default);
       
  8279 %}
       
  8280 
       
  8281 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
       
  8282   match(Set res (GetAndSetS mem_ptr src));
       
  8283   predicate(!VM_Version::has_lqarx());
       
  8284   effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
       
  8285   format %{ "GetAndSetS $res, $mem_ptr, $src" %}
       
  8286   ins_encode %{
       
  8287     __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8288                   R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8289     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8290       __ isync();
       
  8291     } else {
       
  8292       __ sync();
       
  8293     }
       
  8294   %}
  7968   ins_pipe(pipe_class_default);
  8295   ins_pipe(pipe_class_default);
  7969 %}
  8296 %}
  7970 
  8297 
  7971 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
  8298 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
  7972   match(Set res (GetAndSetI mem_ptr src));
  8299   match(Set res (GetAndSetI mem_ptr src));
  7973   effect(TEMP cr0);
  8300   effect(TEMP_DEF res, TEMP cr0);
  7974   format %{ "GetAndSetI $res, $mem_ptr, $src" %}
  8301   format %{ "GetAndSetI $res, $mem_ptr, $src" %}
  7975   // Variable size: instruction count smaller if regs are disjoint.
  8302   ins_encode %{
  7976   ins_encode( enc_GetAndSetI(res, mem_ptr, src) );
  8303     __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8304                   MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8305     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8306       __ isync();
       
  8307     } else {
       
  8308       __ sync();
       
  8309     }
       
  8310   %}
  7977   ins_pipe(pipe_class_default);
  8311   ins_pipe(pipe_class_default);
  7978 %}
  8312 %}
  7979 
  8313 
  7980 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
  8314 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
  7981   match(Set res (GetAndSetL mem_ptr src));
  8315   match(Set res (GetAndSetL mem_ptr src));
  7982   effect(TEMP cr0);
  8316   effect(TEMP_DEF res, TEMP cr0);
  7983   format %{ "GetAndSetL $res, $mem_ptr, $src" %}
  8317   format %{ "GetAndSetL $res, $mem_ptr, $src" %}
  7984   // Variable size: instruction count smaller if regs are disjoint.
  8318   ins_encode %{
  7985   ins_encode( enc_GetAndSetL(res, mem_ptr, src) );
  8319     __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8320                   MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8321     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8322       __ isync();
       
  8323     } else {
       
  8324       __ sync();
       
  8325     }
       
  8326   %}
  7986   ins_pipe(pipe_class_default);
  8327   ins_pipe(pipe_class_default);
  7987 %}
  8328 %}
  7988 
  8329 
  7989 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
  8330 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
  7990   match(Set res (GetAndSetP mem_ptr src));
  8331   match(Set res (GetAndSetP mem_ptr src));
  7991   effect(TEMP cr0);
  8332   effect(TEMP_DEF res, TEMP cr0);
  7992   format %{ "GetAndSetP $res, $mem_ptr, $src" %}
  8333   format %{ "GetAndSetP $res, $mem_ptr, $src" %}
  7993   // Variable size: instruction count smaller if regs are disjoint.
  8334   ins_encode %{
  7994   ins_encode( enc_GetAndSetL(res, mem_ptr, src) );
  8335     __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8336                   MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8337     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8338       __ isync();
       
  8339     } else {
       
  8340       __ sync();
       
  8341     }
       
  8342   %}
  7995   ins_pipe(pipe_class_default);
  8343   ins_pipe(pipe_class_default);
  7996 %}
  8344 %}
  7997 
  8345 
  7998 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
  8346 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
  7999   match(Set res (GetAndSetN mem_ptr src));
  8347   match(Set res (GetAndSetN mem_ptr src));
  8000   effect(TEMP cr0);
  8348   effect(TEMP_DEF res, TEMP cr0);
  8001   format %{ "GetAndSetN $res, $mem_ptr, $src" %}
  8349   format %{ "GetAndSetN $res, $mem_ptr, $src" %}
  8002   // Variable size: instruction count smaller if regs are disjoint.
  8350   ins_encode %{
  8003   ins_encode( enc_GetAndSetI(res, mem_ptr, src) );
  8351     __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
       
  8352                   MacroAssembler::cmpxchgx_hint_atomic_update());
       
  8353     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
  8354       __ isync();
       
  8355     } else {
       
  8356       __ sync();
       
  8357     }
       
  8358   %}
  8004   ins_pipe(pipe_class_default);
  8359   ins_pipe(pipe_class_default);
  8005 %}
  8360 %}
  8006 
  8361 
  8007 //----------Arithmetic Instructions--------------------------------------------
  8362 //----------Arithmetic Instructions--------------------------------------------
  8008 // Addition Instructions
  8363 // Addition Instructions
 11358 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
 11713 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
 11359   match(Set dummy (ClearArray cnt base));
 11714   match(Set dummy (ClearArray cnt base));
 11360   effect(USE_KILL cnt, USE_KILL base, KILL ctr);
 11715   effect(USE_KILL cnt, USE_KILL base, KILL ctr);
 11361   ins_cost(MEMORY_REF_COST);
 11716   ins_cost(MEMORY_REF_COST);
 11362 
 11717 
 11363   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
 11718   ins_alignment(4); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
 11364 
 11719 
 11365   format %{ "ClearArray $cnt, $base" %}
 11720   format %{ "ClearArray $cnt, $base" %}
 11366   ins_encode %{
 11721   ins_encode %{
 11367     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
 11722     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
 11368     __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0
 11723     __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0
 11684 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
 12039 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
 11685                        iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
 12040                        iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
 11686                        flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
 12041                        flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
 11687   match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
 12042   match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
 11688   effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
 12043   effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
 11689   predicate(CompactStrings);
       
 11690   ins_cost(180);
 12044   ins_cost(180);
 11691 
 12045 
 11692   format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
 12046   format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
 11693             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
 12047             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
 11694   ins_encode %{
 12048   ins_encode %{
 11945     __ subf($result$$Register, $result$$Register, $len$$Register);
 12299     __ subf($result$$Register, $result$$Register, $len$$Register);
 11946   %}
 12300   %}
 11947   ins_pipe(pipe_class_default);
 12301   ins_pipe(pipe_class_default);
 11948 %}
 12302 %}
 11949 
 12303 
 11950 
       
 11951 // String_IndexOf for needle of length 1.
       
 11952 //
       
 11953 // Match needle into immediate operands: no loadConP node needed. Saves one
       
 11954 // register and two instructions over string_indexOf_imm1Node.
       
 11955 //
       
 11956 // Assumes register result differs from all input registers.
       
 11957 //
       
 11958 // Preserves registers haystack, haycnt
       
 11959 // Kills     registers tmp1, tmp2
       
 11960 // Defines   registers result
       
 11961 //
       
 11962 // Use dst register classes if register gets killed, as it is the case for tmp registers!
       
 11963 //
       
 11964 // Unfortunately this does not match too often. In many situations the AddP is used
       
 11965 // by several nodes, even several StrIndexOf nodes, breaking the match tree.
       
 11966 instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
       
 11967                                   immP needleImm, immL offsetImm, immI_1 needlecntImm,
       
 11968                                   iRegIdst tmp1, iRegIdst tmp2,
       
 11969                                   flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
       
 11970   predicate(SpecialStringIndexOf && !CompactStrings);  // type check implicit by parameter type, See Matcher::match_rule_supported
       
 11971   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
       
 11972 
       
 11973   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
       
 11974 
       
 11975   ins_cost(150);
       
 11976   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
       
 11977             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
       
 11978 
       
 11979   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted
       
 11980   ins_encode %{
       
 11981     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
 11982     immPOper *needleOper = (immPOper *)$needleImm;
       
 11983     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
       
 11984     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
       
 11985     jchar chr;
       
 11986     if (java_lang_String::has_coder_field()) {
       
 11987       // New compact strings byte array strings
       
 11988 #ifdef VM_LITTLE_ENDIAN
       
 11989     chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
       
 11990            ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
       
 11991 #else
       
 11992     chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
       
 11993            ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
       
 11994 #endif
       
 11995     } else {
       
 11996       // Old char array strings
       
 11997       chr = needle_values->char_at(0);
       
 11998     }
       
 11999     __ string_indexof_1($result$$Register,
       
 12000                         $haystack$$Register, $haycnt$$Register,
       
 12001                         R0, chr,
       
 12002                         $tmp1$$Register, $tmp2$$Register);
       
 12003   %}
       
 12004   ins_pipe(pipe_class_compare);
       
 12005 %}
       
 12006 
       
 12007 // String_IndexOf for needle of length 1.
       
 12008 //
       
 12009 // Special case requires less registers and emits less instructions.
       
 12010 //
       
 12011 // Assumes register result differs from all input registers.
       
 12012 //
       
 12013 // Preserves registers haystack, haycnt
       
 12014 // Kills     registers tmp1, tmp2, needle
       
 12015 // Defines   registers result
       
 12016 //
       
 12017 // Use dst register classes if register gets killed, as it is the case for tmp registers!
       
 12018 instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
       
 12019                              rscratch2RegP needle, immI_1 needlecntImm,
       
 12020                              iRegIdst tmp1, iRegIdst tmp2,
       
 12021                              flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
       
 12022   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
       
 12023   effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
       
 12024          TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
       
 12025   // Required for EA: check if it is still a type_array.
       
 12026   predicate(SpecialStringIndexOf && !CompactStrings &&
       
 12027             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
       
 12028             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
       
 12029   ins_cost(180);
       
 12030 
       
 12031   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
       
 12032 
       
 12033   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
       
 12034             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
       
 12035   ins_encode %{
       
 12036     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
 12037     Node *ndl = in(operand_index($needle));  // The node that defines needle.
       
 12038     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
       
 12039     guarantee(needle_values, "sanity");
       
 12040     jchar chr;
       
 12041     if (java_lang_String::has_coder_field()) {
       
 12042       // New compact strings byte array strings
       
 12043 #ifdef VM_LITTLE_ENDIAN
       
 12044     chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
       
 12045            ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
       
 12046 #else
       
 12047     chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
       
 12048            ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
       
 12049 #endif
       
 12050     } else {
       
 12051       // Old char array strings
       
 12052       chr = needle_values->char_at(0);
       
 12053     }
       
 12054     __ string_indexof_1($result$$Register,
       
 12055                         $haystack$$Register, $haycnt$$Register,
       
 12056                         R0, chr,
       
 12057                         $tmp1$$Register, $tmp2$$Register);
       
 12058   %}
       
 12059   ins_pipe(pipe_class_compare);
       
 12060 %}
       
 12061 
       
 12062 // String_IndexOfChar
       
 12063 //
       
 12064 // Assumes register result differs from all input registers.
       
 12065 //
       
 12066 // Preserves registers haystack, haycnt
       
 12067 // Kills     registers tmp1, tmp2
       
 12068 // Defines   registers result
       
 12069 //
       
 12070 // Use dst register classes if register gets killed, as it is the case for tmp registers!
       
 12071 instruct string_indexOfChar(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
       
 12072                             iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
       
 12073                             flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
       
 12074   match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
       
 12075   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
       
 12076   predicate(SpecialStringIndexOf && !CompactStrings);
       
 12077   ins_cost(180);
       
 12078 
       
 12079   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
       
 12080 
       
 12081   format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
       
 12082             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
       
 12083   ins_encode %{
       
 12084     __ string_indexof_1($result$$Register,
       
 12085                         $haystack$$Register, $haycnt$$Register,
       
 12086                         $ch$$Register, 0 /* this is not used if the character is already in a register */,
       
 12087                         $tmp1$$Register, $tmp2$$Register);
       
 12088   %}
       
 12089   ins_pipe(pipe_class_compare);
       
 12090 %}
       
 12091 
       
 12092 // String_IndexOf.
       
 12093 //
       
 12094 // Length of needle as immediate. This saves instruction loading constant needle
       
 12095 // length.
       
 12096 // @@@ TODO Specify rules for length < 8 or so, and roll out comparison of needle
       
 12097 // completely or do it in vector instruction. This should save registers for
       
 12098 // needlecnt and needle.
       
 12099 //
       
 12100 // Assumes register result differs from all input registers.
       
 12101 // Overwrites haycnt, needlecnt.
       
 12102 // Use dst register classes if register gets killed, as it is the case for tmp registers!
       
 12103 instruct string_indexOf_imm(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
       
 12104                             iRegPsrc needle, uimmI15 needlecntImm,
       
 12105                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
       
 12106                             flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
       
 12107   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
       
 12108   effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
       
 12109          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
       
 12110   // Required for EA: check if it is still a type_array.
       
 12111   predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
       
 12112             n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
       
 12113   ins_cost(250);
       
 12114 
       
 12115   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
       
 12116 
       
 12117   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
       
 12118             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
       
 12119   ins_encode %{
       
 12120     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
 12121     Node *ndl = in(operand_index($needle));  // The node that defines needle.
       
 12122     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
       
 12123 
       
 12124     __ string_indexof($result$$Register,
       
 12125                       $haystack$$Register, $haycnt$$Register,
       
 12126                       $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
       
 12127                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
       
 12128   %}
       
 12129   ins_pipe(pipe_class_compare);
       
 12130 %}
       
 12131 
       
 12132 // StrIndexOf node.
       
 12133 //
       
 12134 // Assumes register result differs from all input registers.
       
 12135 // Overwrites haycnt, needlecnt.
       
 12136 // Use dst register classes if register gets killed, as it is the case for tmp registers!
       
 12137 instruct string_indexOf(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
       
 12138                         iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
       
 12139                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
       
 12140   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
       
 12141   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
       
 12142          TEMP_DEF result,
       
 12143          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
       
 12144   predicate(SpecialStringIndexOf && !CompactStrings);  // See Matcher::match_rule_supported.
       
 12145   ins_cost(300);
       
 12146 
       
 12147   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
       
 12148 
       
 12149   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
       
 12150              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
       
 12151   ins_encode %{
       
 12152     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
 12153     __ string_indexof($result$$Register,
       
 12154                       $haystack$$Register, $haycnt$$Register,
       
 12155                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
       
 12156                       $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
       
 12157   %}
       
 12158   ins_pipe(pipe_class_compare);
       
 12159 %}
       
 12160 
       
 12161 // String equals with immediate.
       
 12162 instruct string_equals_imm(iRegPsrc str1, iRegPsrc str2, uimmI15 cntImm, iRegIdst result,
       
 12163                            iRegPdst tmp1, iRegPdst tmp2,
       
 12164                            flagsRegCR0 cr0, flagsRegCR6 cr6, regCTR ctr) %{
       
 12165   match(Set result (StrEquals (Binary str1 str2) cntImm));
       
 12166   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2,
       
 12167          KILL cr0, KILL cr6, KILL ctr);
       
 12168   predicate(SpecialStringEquals && !CompactStrings);  // See Matcher::match_rule_supported.
       
 12169   ins_cost(250);
       
 12170 
       
 12171   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
       
 12172 
       
 12173   format %{ "String Equals SCL [0..$cntImm]($str1),[0..$cntImm]($str2)"
       
 12174             " -> $result \t// KILL $cr0, $cr6, $ctr, TEMP $result, $tmp1, $tmp2" %}
       
 12175   ins_encode %{
       
 12176     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
 12177     __ char_arrays_equalsImm($str1$$Register, $str2$$Register, $cntImm$$constant,
       
 12178                              $result$$Register, $tmp1$$Register, $tmp2$$Register);
       
 12179   %}
       
 12180   ins_pipe(pipe_class_compare);
       
 12181 %}
       
 12182 
       
 12183 // String equals.
       
 12184 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
       
 12185 instruct string_equals(iRegPsrc str1, iRegPsrc str2, iRegIsrc cnt, iRegIdst result,
       
 12186                        iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, iRegPdst tmp4, iRegPdst tmp5,
       
 12187                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
       
 12188   match(Set result (StrEquals (Binary str1 str2) cnt));
       
 12189   effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
       
 12190          KILL cr0, KILL cr1, KILL cr6, KILL ctr);
       
 12191   predicate(SpecialStringEquals && !CompactStrings);  // See Matcher::match_rule_supported.
       
 12192   ins_cost(300);
       
 12193 
       
 12194   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
       
 12195 
       
 12196   format %{ "String Equals [0..$cnt]($str1),[0..$cnt]($str2) -> $result"
       
 12197             " \t// KILL $cr0, $cr1, $cr6, $ctr, TEMP $result, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
       
 12198   ins_encode %{
       
 12199     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
 12200     __ char_arrays_equals($str1$$Register, $str2$$Register, $cnt$$Register, $result$$Register,
       
 12201                           $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
       
 12202   %}
       
 12203   ins_pipe(pipe_class_compare);
       
 12204 %}
       
 12205 
       
 12206 // String compare.
       
 12207 // Char[] pointers are passed in.
       
 12208 // Use dst register classes if register gets killed, as it is the case for TEMP operands!
       
 12209 instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
       
 12210                         iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{
       
 12211   predicate(!CompactStrings);
       
 12212   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
       
 12213   effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP_DEF result, TEMP tmp, KILL cr0, KILL ctr);
       
 12214   ins_cost(300);
       
 12215 
       
 12216   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
       
 12217 
       
 12218   format %{ "String Compare $str1[0..$cnt1], $str2[0..$cnt2] -> $result"
       
 12219             " \t// TEMP $tmp, $result KILLs $str1, $cnt1, $str2, $cnt2, $cr0, $ctr" %}
       
 12220   ins_encode %{
       
 12221     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
       
 12222     __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register,
       
 12223                       $result$$Register, $tmp$$Register);
       
 12224   %}
       
 12225   ins_pipe(pipe_class_compare);
       
 12226 %}
       
 12227 
 12304 
 12228 //---------- Min/Max Instructions ---------------------------------------------
 12305 //---------- Min/Max Instructions ---------------------------------------------
 12229 
 12306 
 12230 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
 12307 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
 12231   match(Set dst (MinI src1 src2));
 12308   match(Set dst (MinI src1 src2));