7931
7932 //----------Compare-And-Swap---------------------------------------------------
7933
7934 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7935 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7936 // matched.
7937
7938 // Strong versions:
7939
7940 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7941 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7942 predicate(VM_Version::has_lqarx());
7943 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7944 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7945 ins_encode %{
7946 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7947 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7948 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7949 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7950 $res$$Register, true);
7951 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7952 __ isync();
7953 } else {
7954 __ sync();
7955 }
7956 %}
7957 ins_pipe(pipe_class_default);
7958 %}
7959
7960 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7961 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7962 predicate(!VM_Version::has_lqarx());
7963 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7964 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7965 ins_encode %{
7966 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7967 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7968 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7969 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7970 $res$$Register, true);
7971 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7972 __ isync();
7973 } else {
7974 __ sync();
7975 }
7976 %}
7977 ins_pipe(pipe_class_default);
7978 %}
7979
7980 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7981 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7982 predicate(VM_Version::has_lqarx());
7983 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7984 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7985 ins_encode %{
7986 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7987 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7988 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7989 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7990 $res$$Register, true);
7991 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7992 __ isync();
7993 } else {
7994 __ sync();
7995 }
7996 %}
7997 ins_pipe(pipe_class_default);
7998 %}
7999
8000 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
8001 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
8002 predicate(!VM_Version::has_lqarx());
8003 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
8004 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
8005 ins_encode %{
8006 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8007 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8008 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8009 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8010 $res$$Register, true);
8011 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8012 __ isync();
8013 } else {
8014 __ sync();
8015 }
8016 %}
8017 ins_pipe(pipe_class_default);
8018 %}
8019
8020 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8021 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
8022 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8023 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8024 ins_encode %{
8025 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8026 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8027 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8028 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8029 $res$$Register, true);
8030 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8031 __ isync();
8032 } else {
8033 __ sync();
8034 }
8035 %}
8036 ins_pipe(pipe_class_default);
8037 %}
8038
8039 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8040 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
8041 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8042 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8043 ins_encode %{
8044 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8045 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8046 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8047 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8048 $res$$Register, true);
8049 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8050 __ isync();
8051 } else {
8052 __ sync();
8053 }
8054 %}
8055 ins_pipe(pipe_class_default);
8056 %}
8057
8058 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8059 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
8060 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8061 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
8062 ins_encode %{
8063 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8064 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8065 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8066 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8067 $res$$Register, NULL, true);
8068 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8069 __ isync();
8070 } else {
8071 __ sync();
8072 }
8073 %}
8074 ins_pipe(pipe_class_default);
8075 %}
8076
8077 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8078 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
8079 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8080 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
8081 ins_encode %{
8082 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8083 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8084 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8085 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8086 $res$$Register, NULL, true);
8087 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8088 __ isync();
8089 } else {
8090 __ sync();
8091 }
8092 %}
8093 ins_pipe(pipe_class_default);
8094 %}
8095
8096 // Weak versions:
8097
8098 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8099 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
8100 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8101 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8102 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
8103 ins_encode %{
8104 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8105 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8106 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8107 MacroAssembler::MemBarNone,
8117 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
8118 ins_encode %{
8119 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8120 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8121 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8122 MacroAssembler::MemBarNone,
8123 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8124 %}
8125 ins_pipe(pipe_class_default);
8126 %}
8127
8128 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8129 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
8130 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8131 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8132 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
8133 ins_encode %{
8134 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8135 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8136 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8137 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8138 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8139 %}
8140 ins_pipe(pipe_class_default);
8141 %}
8142
8143 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
8144 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
8145 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8146 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
8147 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
8148 ins_encode %{
8149 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8150 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8151 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8152 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8153 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8154 %}
8155 ins_pipe(pipe_class_default);
8156 %}
8157
8158 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8159 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
8160 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8161 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8162 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
8163 ins_encode %{
8164 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8165 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8166 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8167 MacroAssembler::MemBarNone,
8168 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8169 %}
8170 ins_pipe(pipe_class_default);
8171 %}
8172
8177 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
8178 ins_encode %{
8179 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8180 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8181 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8182 MacroAssembler::MemBarNone,
8183 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8184 %}
8185 ins_pipe(pipe_class_default);
8186 %}
8187
8188 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8189 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
8190 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8191 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8192 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
8193 ins_encode %{
8194 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8195 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8196 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8197 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8198 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8199 %}
8200 ins_pipe(pipe_class_default);
8201 %}
8202
8203 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
8204 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
8205 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8206 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
8207 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
8208 ins_encode %{
8209 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8210 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8211 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8212 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8213 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8214 %}
8215 ins_pipe(pipe_class_default);
8216 %}
8217
8218 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8219 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
8220 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8221 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8222 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8223 ins_encode %{
8224 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8225 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8226 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8227 MacroAssembler::MemBarNone,
8228 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8229 %}
8230 ins_pipe(pipe_class_default);
8231 %}
8232
8233 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8234 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
8235 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8236 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8237 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
8238 ins_encode %{
8239 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8240 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8241 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8242 // value is never passed to caller.
8243 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8244 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8245 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8246 %}
8247 ins_pipe(pipe_class_default);
8248 %}
8249
8250 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8251 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
8252 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8253 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8254 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8255 ins_encode %{
8256 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8257 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8258 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8259 MacroAssembler::MemBarNone,
8260 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8261 %}
8262 ins_pipe(pipe_class_default);
8263 %}
8264
8265 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8266 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
8267 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8268 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8269 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
8270 ins_encode %{
8271 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8272 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8273 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8274 // value is never passed to caller.
8275 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8276 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8277 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8278 %}
8279 ins_pipe(pipe_class_default);
8280 %}
8281
8282 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8283 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
8284 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8285 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8286 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
8287 ins_encode %{
8288 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8289 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8290 // value is never passed to caller.
8291 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8292 MacroAssembler::MemBarNone,
8293 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8294 %}
8295 ins_pipe(pipe_class_default);
8296 %}
8297
8298 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8299 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
8300 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8301 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8302 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
8303 ins_encode %{
8304 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8305 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8306 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8307 // value is never passed to caller.
8308 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8309 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8310 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8311 %}
8312 ins_pipe(pipe_class_default);
8313 %}
8314
8315 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8316 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
8317 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8318 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8319 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
8320 ins_encode %{
8321 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8322 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8323 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8324 MacroAssembler::MemBarNone,
8325 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8326 %}
8327 ins_pipe(pipe_class_default);
8328 %}
8329
8330 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8331 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
8332 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8333 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8334 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
8335 ins_encode %{
8336 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8337 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8338 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8339 // value is never passed to caller.
8340 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8341 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8342 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8343 %}
8344 ins_pipe(pipe_class_default);
8345 %}
8346
8347 // CompareAndExchange
8348
8349 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8350 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
8351 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8352 effect(TEMP_DEF res, TEMP cr0);
8353 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
8354 ins_encode %{
8355 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8356 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8357 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8358 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8359 noreg, true);
8360 %}
8361 ins_pipe(pipe_class_default);
8370 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8371 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8372 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8373 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8374 noreg, true);
8375 %}
8376 ins_pipe(pipe_class_default);
8377 %}
8378
8379 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8380 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
8381 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8382 effect(TEMP_DEF res, TEMP cr0);
8383 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
8384 ins_encode %{
8385 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8386 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8387 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8388 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8389 noreg, true);
8390 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8391 __ isync();
8392 } else {
8393 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8394 __ sync();
8395 }
8396 %}
8397 ins_pipe(pipe_class_default);
8398 %}
8399
8400 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
8401 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
8402 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8403 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
8404 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
8405 ins_encode %{
8406 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8407 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8408 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8409 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8410 noreg, true);
8411 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8412 __ isync();
8413 } else {
8414 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8415 __ sync();
8416 }
8417 %}
8418 ins_pipe(pipe_class_default);
8419 %}
8420
8421 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8422 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8423 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8424 effect(TEMP_DEF res, TEMP cr0);
8425 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
8426 ins_encode %{
8427 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8428 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8429 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8430 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8431 noreg, true);
8442 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8443 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8444 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8445 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8446 noreg, true);
8447 %}
8448 ins_pipe(pipe_class_default);
8449 %}
8450
8451 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8452 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8453 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8454 effect(TEMP_DEF res, TEMP cr0);
8455 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
8456 ins_encode %{
8457 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8458 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8459 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8460 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8461 noreg, true);
8462 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8463 __ isync();
8464 } else {
8465 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8466 __ sync();
8467 }
8468 %}
8469 ins_pipe(pipe_class_default);
8470 %}
8471
8472 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
8473 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8474 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8475 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
8476 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
8477 ins_encode %{
8478 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8479 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8480 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8481 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8482 noreg, true);
8483 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8484 __ isync();
8485 } else {
8486 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8487 __ sync();
8488 }
8489 %}
8490 ins_pipe(pipe_class_default);
8491 %}
8492
8493 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8494 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8495 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8496 effect(TEMP_DEF res, TEMP cr0);
8497 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
8498 ins_encode %{
8499 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8500 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8501 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8502 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8503 noreg, true);
8504 %}
8505 ins_pipe(pipe_class_default);
8506 %}
8507
8508 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8509 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8510 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8511 effect(TEMP_DEF res, TEMP cr0);
8512 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
8513 ins_encode %{
8514 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8515 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8516 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8517 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8518 noreg, true);
8519 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8520 __ isync();
8521 } else {
8522 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8523 __ sync();
8524 }
8525 %}
8526 ins_pipe(pipe_class_default);
8527 %}
8528
8529 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8530 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8531 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8532 effect(TEMP_DEF res, TEMP cr0);
8533 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8534 ins_encode %{
8535 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8536 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8537 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8539 noreg, true);
8540 %}
8541 ins_pipe(pipe_class_default);
8542 %}
8543
8544 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8545 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8546 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8547 effect(TEMP_DEF res, TEMP cr0);
8548 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8549 ins_encode %{
8550 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8551 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8552 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8553 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8554 noreg, true);
8555 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8556 __ isync();
8557 } else {
8558 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8559 __ sync();
8560 }
8561 %}
8562 ins_pipe(pipe_class_default);
8563 %}
8564
8565 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8566 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8567 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8568 effect(TEMP_DEF res, TEMP cr0);
8569 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
8570 ins_encode %{
8571 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8572 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8573 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8574 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8575 noreg, NULL, true);
8576 %}
8577 ins_pipe(pipe_class_default);
8578 %}
8579
8580 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8581 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8582 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8583 effect(TEMP_DEF res, TEMP cr0);
8584 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
8585 ins_encode %{
8586 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8587 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8588 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8589 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8590 noreg, NULL, true);
8591 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8592 __ isync();
8593 } else {
8594 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8595 __ sync();
8596 }
8597 %}
8598 ins_pipe(pipe_class_default);
8599 %}
8600
8601 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8602 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8603 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8604 effect(TEMP_DEF res, TEMP cr0);
8605 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8606 ins_encode %{
8607 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8608 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8609 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8610 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8611 noreg, NULL, true);
8612 %}
8613 ins_pipe(pipe_class_default);
8614 %}
8615
8616 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8617 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8618 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8619 effect(TEMP_DEF res, TEMP cr0);
8620 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8621 ins_encode %{
8622 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8623 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8624 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8625 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8626 noreg, NULL, true);
8627 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8628 __ isync();
8629 } else {
8630 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8631 __ sync();
8632 }
8633 %}
8634 ins_pipe(pipe_class_default);
8635 %}
8636
8637 // Special RMW
8638
8639 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8640 match(Set res (GetAndAddB mem_ptr src));
8641 predicate(VM_Version::has_lqarx());
8642 effect(TEMP_DEF res, TEMP cr0);
8643 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8644 ins_encode %{
8645 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8646 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8647 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8648 __ isync();
8649 } else {
8650 __ sync();
8651 }
8652 %}
8653 ins_pipe(pipe_class_default);
8654 %}
8655
8656 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8657 match(Set res (GetAndAddB mem_ptr src));
8658 predicate(!VM_Version::has_lqarx());
8659 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8660 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8661 ins_encode %{
8662 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8663 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8664 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8665 __ isync();
8666 } else {
8667 __ sync();
8668 }
8669 %}
8670 ins_pipe(pipe_class_default);
8671 %}
8672
8673 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8674 match(Set res (GetAndAddS mem_ptr src));
8675 predicate(VM_Version::has_lqarx());
8676 effect(TEMP_DEF res, TEMP cr0);
8677 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8678 ins_encode %{
8679 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8680 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8681 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8682 __ isync();
8683 } else {
8684 __ sync();
8685 }
8686 %}
8687 ins_pipe(pipe_class_default);
8688 %}
8689
8690 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8691 match(Set res (GetAndAddS mem_ptr src));
8692 predicate(!VM_Version::has_lqarx());
8693 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8694 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8695 ins_encode %{
8696 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8697 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8698 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8699 __ isync();
8700 } else {
8701 __ sync();
8702 }
8703 %}
8704 ins_pipe(pipe_class_default);
8705 %}
8706
8707 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8708 match(Set res (GetAndAddI mem_ptr src));
8709 effect(TEMP_DEF res, TEMP cr0);
8710 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
8711 ins_encode %{
8712 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
8713 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8714 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8715 __ isync();
8716 } else {
8717 __ sync();
8718 }
8719 %}
8720 ins_pipe(pipe_class_default);
8721 %}
8722
8723 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8724 match(Set res (GetAndAddL mem_ptr src));
8725 effect(TEMP_DEF res, TEMP cr0);
8726 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
8727 ins_encode %{
8728 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
8729 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8730 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8731 __ isync();
8732 } else {
8733 __ sync();
8734 }
8735 %}
8736 ins_pipe(pipe_class_default);
8737 %}
8738
8739 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8740 match(Set res (GetAndSetB mem_ptr src));
8741 predicate(VM_Version::has_lqarx());
8742 effect(TEMP_DEF res, TEMP cr0);
8743 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8744 ins_encode %{
8745 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8746 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8747 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8748 __ isync();
8749 } else {
8750 __ sync();
8751 }
8752 %}
8753 ins_pipe(pipe_class_default);
8754 %}
8755
8756 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8757 match(Set res (GetAndSetB mem_ptr src));
8758 predicate(!VM_Version::has_lqarx());
8759 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8760 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8761 ins_encode %{
8762 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8763 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8764 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8765 __ isync();
8766 } else {
8767 __ sync();
8768 }
8769 %}
8770 ins_pipe(pipe_class_default);
8771 %}
8772
8773 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8774 match(Set res (GetAndSetS mem_ptr src));
8775 predicate(VM_Version::has_lqarx());
8776 effect(TEMP_DEF res, TEMP cr0);
8777 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8778 ins_encode %{
8779 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8780 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8781 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8782 __ isync();
8783 } else {
8784 __ sync();
8785 }
8786 %}
8787 ins_pipe(pipe_class_default);
8788 %}
8789
8790 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8791 match(Set res (GetAndSetS mem_ptr src));
8792 predicate(!VM_Version::has_lqarx());
8793 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8794 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8795 ins_encode %{
8796 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8797 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8798 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8799 __ isync();
8800 } else {
8801 __ sync();
8802 }
8803 %}
8804 ins_pipe(pipe_class_default);
8805 %}
8806
8807 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8808 match(Set res (GetAndSetI mem_ptr src));
8809 effect(TEMP_DEF res, TEMP cr0);
8810 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
8811 ins_encode %{
8812 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8813 MacroAssembler::cmpxchgx_hint_atomic_update());
8814 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8815 __ isync();
8816 } else {
8817 __ sync();
8818 }
8819 %}
8820 ins_pipe(pipe_class_default);
8821 %}
8822
8823 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8824 match(Set res (GetAndSetL mem_ptr src));
8825 effect(TEMP_DEF res, TEMP cr0);
8826 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
8827 ins_encode %{
8828 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8829 MacroAssembler::cmpxchgx_hint_atomic_update());
8830 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8831 __ isync();
8832 } else {
8833 __ sync();
8834 }
8835 %}
8836 ins_pipe(pipe_class_default);
8837 %}
8838
8839 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
8840 match(Set res (GetAndSetP mem_ptr src));
8841 effect(TEMP_DEF res, TEMP cr0);
8842 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
8843 ins_encode %{
8844 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8845 MacroAssembler::cmpxchgx_hint_atomic_update());
8846 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8847 __ isync();
8848 } else {
8849 __ sync();
8850 }
8851 %}
8852 ins_pipe(pipe_class_default);
8853 %}
8854
8855 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
8856 match(Set res (GetAndSetN mem_ptr src));
8857 effect(TEMP_DEF res, TEMP cr0);
8858 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
8859 ins_encode %{
8860 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8861 MacroAssembler::cmpxchgx_hint_atomic_update());
8862 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8863 __ isync();
8864 } else {
8865 __ sync();
8866 }
8867 %}
8868 ins_pipe(pipe_class_default);
8869 %}
8870
8871 //----------Arithmetic Instructions--------------------------------------------
8872 // Addition Instructions
8873
8874 // Register Addition
8875 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
8876 match(Set dst (AddI src1 src2));
8877 format %{ "ADD $dst, $src1, $src2" %}
8878 size(4);
8879 ins_encode %{
8880 // TODO: PPC port $archOpcode(ppc64Opcode_add);
8881 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8882 %}
|
7931
7932 //----------Compare-And-Swap---------------------------------------------------
7933
7934 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7935 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
7936 // matched.
7937
7938 // Strong versions:
7939
7940 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7941 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7942 predicate(VM_Version::has_lqarx());
7943 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7944 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7945 ins_encode %{
7946 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7947 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7948 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7949 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7950 $res$$Register, true);
7951 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
7952 __ isync();
7953 } else {
7954 __ sync();
7955 }
7956 %}
7957 ins_pipe(pipe_class_default);
7958 %}
7959
7960 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7961 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7962 predicate(!VM_Version::has_lqarx());
7963 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7964 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7965 ins_encode %{
7966 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7967 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7968 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7969 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7970 $res$$Register, true);
7971 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
7972 __ isync();
7973 } else {
7974 __ sync();
7975 }
7976 %}
7977 ins_pipe(pipe_class_default);
7978 %}
7979
7980 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7981 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7982 predicate(VM_Version::has_lqarx());
7983 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7984 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7985 ins_encode %{
7986 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7987 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7988 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7989 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7990 $res$$Register, true);
7991 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
7992 __ isync();
7993 } else {
7994 __ sync();
7995 }
7996 %}
7997 ins_pipe(pipe_class_default);
7998 %}
7999
8000 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
8001 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
8002 predicate(!VM_Version::has_lqarx());
8003 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
8004 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
8005 ins_encode %{
8006 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8007 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8008 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8009 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8010 $res$$Register, true);
8011 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8012 __ isync();
8013 } else {
8014 __ sync();
8015 }
8016 %}
8017 ins_pipe(pipe_class_default);
8018 %}
8019
8020 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8021 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
8022 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8023 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8024 ins_encode %{
8025 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8026 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8027 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8028 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8029 $res$$Register, true);
8030 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8031 __ isync();
8032 } else {
8033 __ sync();
8034 }
8035 %}
8036 ins_pipe(pipe_class_default);
8037 %}
8038
8039 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8040 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
8041 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8042 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8043 ins_encode %{
8044 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8045 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8046 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8047 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8048 $res$$Register, true);
8049 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8050 __ isync();
8051 } else {
8052 __ sync();
8053 }
8054 %}
8055 ins_pipe(pipe_class_default);
8056 %}
8057
8058 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8059 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
8060 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8061 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
8062 ins_encode %{
8063 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8064 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8065 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8066 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8067 $res$$Register, NULL, true);
8068 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8069 __ isync();
8070 } else {
8071 __ sync();
8072 }
8073 %}
8074 ins_pipe(pipe_class_default);
8075 %}
8076
8077 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8078 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
8079 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8080 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
8081 ins_encode %{
8082 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8083 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8084 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8085 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8086 $res$$Register, NULL, true);
8087 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8088 __ isync();
8089 } else {
8090 __ sync();
8091 }
8092 %}
8093 ins_pipe(pipe_class_default);
8094 %}
8095
8096 // Weak versions:
8097
8098 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8099 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
8100 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8101 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8102 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
8103 ins_encode %{
8104 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8105 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8106 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8107 MacroAssembler::MemBarNone,
8117 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
8118 ins_encode %{
8119 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8120 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8121 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8122 MacroAssembler::MemBarNone,
8123 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8124 %}
8125 ins_pipe(pipe_class_default);
8126 %}
8127
8128 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8129 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
8130 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8131 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8132 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
8133 ins_encode %{
8134 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8135 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8136 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8137 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8138 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8139 %}
8140 ins_pipe(pipe_class_default);
8141 %}
8142
8143 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
8144 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
8145 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8146 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
8147 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
8148 ins_encode %{
8149 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8150 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8151 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8152 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8153 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8154 %}
8155 ins_pipe(pipe_class_default);
8156 %}
8157
8158 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8159 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
8160 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8161 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8162 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
8163 ins_encode %{
8164 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8165 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8166 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8167 MacroAssembler::MemBarNone,
8168 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8169 %}
8170 ins_pipe(pipe_class_default);
8171 %}
8172
8177 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
8178 ins_encode %{
8179 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8180 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8181 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8182 MacroAssembler::MemBarNone,
8183 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8184 %}
8185 ins_pipe(pipe_class_default);
8186 %}
8187
8188 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8189 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
8190 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8191 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8192 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
8193 ins_encode %{
8194 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8195 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8196 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8197 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8198 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8199 %}
8200 ins_pipe(pipe_class_default);
8201 %}
8202
8203 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
8204 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
8205 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8206 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
8207 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
8208 ins_encode %{
8209 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8210 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8211 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
8212 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8213 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8214 %}
8215 ins_pipe(pipe_class_default);
8216 %}
8217
8218 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8219 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
8220 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8221 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8222 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8223 ins_encode %{
8224 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8225 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8226 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8227 MacroAssembler::MemBarNone,
8228 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8229 %}
8230 ins_pipe(pipe_class_default);
8231 %}
8232
8233 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8234 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
8235 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8236 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8237 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
8238 ins_encode %{
8239 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8240 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8241 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8242 // value is never passed to caller.
8243 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8244 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8245 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8246 %}
8247 ins_pipe(pipe_class_default);
8248 %}
8249
8250 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8251 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
8252 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8253 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8254 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
8255 ins_encode %{
8256 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8257 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8258 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8259 MacroAssembler::MemBarNone,
8260 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8261 %}
8262 ins_pipe(pipe_class_default);
8263 %}
8264
8265 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8266 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
8267 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8268 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8269 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
8270 ins_encode %{
8271 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8272 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8273 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8274 // value is never passed to caller.
8275 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8276 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8277 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
8278 %}
8279 ins_pipe(pipe_class_default);
8280 %}
8281
8282 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8283 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
8284 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8285 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8286 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
8287 ins_encode %{
8288 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8289 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8290 // value is never passed to caller.
8291 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8292 MacroAssembler::MemBarNone,
8293 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8294 %}
8295 ins_pipe(pipe_class_default);
8296 %}
8297
8298 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8299 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
8300 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8301 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8302 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
8303 ins_encode %{
8304 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8305 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8306 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8307 // value is never passed to caller.
8308 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8309 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8310 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8311 %}
8312 ins_pipe(pipe_class_default);
8313 %}
8314
8315 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8316 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
8317 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8318 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8319 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
8320 ins_encode %{
8321 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8322 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8323 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8324 MacroAssembler::MemBarNone,
8325 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8326 %}
8327 ins_pipe(pipe_class_default);
8328 %}
8329
8330 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8331 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
8332 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8333 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
8334 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
8335 ins_encode %{
8336 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8337 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8338 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
8339 // value is never passed to caller.
8340 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8341 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
8342 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
8343 %}
8344 ins_pipe(pipe_class_default);
8345 %}
8346
8347 // CompareAndExchange
8348
8349 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8350 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
8351 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8352 effect(TEMP_DEF res, TEMP cr0);
8353 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
8354 ins_encode %{
8355 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8356 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8357 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8358 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8359 noreg, true);
8360 %}
8361 ins_pipe(pipe_class_default);
8370 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8371 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8372 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8373 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8374 noreg, true);
8375 %}
8376 ins_pipe(pipe_class_default);
8377 %}
8378
8379 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8380 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
8381 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8382 effect(TEMP_DEF res, TEMP cr0);
8383 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
8384 ins_encode %{
8385 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8386 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8387 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8388 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8389 noreg, true);
8390 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8391 __ isync();
8392 } else {
8393 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8394 __ sync();
8395 }
8396 %}
8397 ins_pipe(pipe_class_default);
8398 %}
8399
8400 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
8401 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
8402 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8403 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
8404 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
8405 ins_encode %{
8406 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8407 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8408 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8409 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8410 noreg, true);
8411 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8412 __ isync();
8413 } else {
8414 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8415 __ sync();
8416 }
8417 %}
8418 ins_pipe(pipe_class_default);
8419 %}
8420
8421 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8422 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8423 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
8424 effect(TEMP_DEF res, TEMP cr0);
8425 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
8426 ins_encode %{
8427 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8428 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8429 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8430 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8431 noreg, true);
8442 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8443 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8444 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8445 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8446 noreg, true);
8447 %}
8448 ins_pipe(pipe_class_default);
8449 %}
8450
8451 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8452 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8453 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
8454 effect(TEMP_DEF res, TEMP cr0);
8455 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
8456 ins_encode %{
8457 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8458 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8459 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
8460 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8461 noreg, true);
8462 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8463 __ isync();
8464 } else {
8465 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8466 __ sync();
8467 }
8468 %}
8469 ins_pipe(pipe_class_default);
8470 %}
8471
8472 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
8473 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
8474 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
8475 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
8476 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
8477 ins_encode %{
8478 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8479 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8480 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
8481 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8482 noreg, true);
8483 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8484 __ isync();
8485 } else {
8486 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8487 __ sync();
8488 }
8489 %}
8490 ins_pipe(pipe_class_default);
8491 %}
8492
8493 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8494 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8495 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8496 effect(TEMP_DEF res, TEMP cr0);
8497 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
8498 ins_encode %{
8499 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8500 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8501 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8502 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8503 noreg, true);
8504 %}
8505 ins_pipe(pipe_class_default);
8506 %}
8507
8508 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8509 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8510 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8511 effect(TEMP_DEF res, TEMP cr0);
8512 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
8513 ins_encode %{
8514 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8515 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8516 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8517 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8518 noreg, true);
8519 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8520 __ isync();
8521 } else {
8522 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8523 __ sync();
8524 }
8525 %}
8526 ins_pipe(pipe_class_default);
8527 %}
8528
8529 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8530 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8531 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8532 effect(TEMP_DEF res, TEMP cr0);
8533 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8534 ins_encode %{
8535 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8536 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8537 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8539 noreg, true);
8540 %}
8541 ins_pipe(pipe_class_default);
8542 %}
8543
8544 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8545 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8546 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8547 effect(TEMP_DEF res, TEMP cr0);
8548 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8549 ins_encode %{
8550 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8551 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8552 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8553 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8554 noreg, true);
8555 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8556 __ isync();
8557 } else {
8558 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8559 __ sync();
8560 }
8561 %}
8562 ins_pipe(pipe_class_default);
8563 %}
8564
8565 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8566 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8567 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8568 effect(TEMP_DEF res, TEMP cr0);
8569 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
8570 ins_encode %{
8571 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8572 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8573 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8574 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8575 noreg, NULL, true);
8576 %}
8577 ins_pipe(pipe_class_default);
8578 %}
8579
8580 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8581 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8582 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8583 effect(TEMP_DEF res, TEMP cr0);
8584 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
8585 ins_encode %{
8586 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8587 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8588 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8589 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8590 noreg, NULL, true);
8591 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8592 __ isync();
8593 } else {
8594 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8595 __ sync();
8596 }
8597 %}
8598 ins_pipe(pipe_class_default);
8599 %}
8600
8601 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8602 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8603 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8604 effect(TEMP_DEF res, TEMP cr0);
8605 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8606 ins_encode %{
8607 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8608 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8609 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8610 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8611 noreg, NULL, true);
8612 %}
8613 ins_pipe(pipe_class_default);
8614 %}
8615
8616 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8617 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8618 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8619 effect(TEMP_DEF res, TEMP cr0);
8620 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8621 ins_encode %{
8622 // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8623 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8624 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8625 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8626 noreg, NULL, true);
8627 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8628 __ isync();
8629 } else {
8630 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8631 __ sync();
8632 }
8633 %}
8634 ins_pipe(pipe_class_default);
8635 %}
8636
8637 // Special RMW
8638
8639 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8640 match(Set res (GetAndAddB mem_ptr src));
8641 predicate(VM_Version::has_lqarx());
8642 effect(TEMP_DEF res, TEMP cr0);
8643 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8644 ins_encode %{
8645 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8646 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8647 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8648 __ isync();
8649 } else {
8650 __ sync();
8651 }
8652 %}
8653 ins_pipe(pipe_class_default);
8654 %}
8655
8656 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8657 match(Set res (GetAndAddB mem_ptr src));
8658 predicate(!VM_Version::has_lqarx());
8659 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8660 format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8661 ins_encode %{
8662 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8663 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8664 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8665 __ isync();
8666 } else {
8667 __ sync();
8668 }
8669 %}
8670 ins_pipe(pipe_class_default);
8671 %}
8672
8673 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8674 match(Set res (GetAndAddS mem_ptr src));
8675 predicate(VM_Version::has_lqarx());
8676 effect(TEMP_DEF res, TEMP cr0);
8677 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8678 ins_encode %{
8679 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8680 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8681 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8682 __ isync();
8683 } else {
8684 __ sync();
8685 }
8686 %}
8687 ins_pipe(pipe_class_default);
8688 %}
8689
8690 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8691 match(Set res (GetAndAddS mem_ptr src));
8692 predicate(!VM_Version::has_lqarx());
8693 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8694 format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8695 ins_encode %{
8696 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8697 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8698 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8699 __ isync();
8700 } else {
8701 __ sync();
8702 }
8703 %}
8704 ins_pipe(pipe_class_default);
8705 %}
8706
8707 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8708 match(Set res (GetAndAddI mem_ptr src));
8709 effect(TEMP_DEF res, TEMP cr0);
8710 format %{ "GetAndAddI $res, $mem_ptr, $src" %}
8711 ins_encode %{
8712 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
8713 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8714 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8715 __ isync();
8716 } else {
8717 __ sync();
8718 }
8719 %}
8720 ins_pipe(pipe_class_default);
8721 %}
8722
8723 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8724 match(Set res (GetAndAddL mem_ptr src));
8725 effect(TEMP_DEF res, TEMP cr0);
8726 format %{ "GetAndAddL $res, $mem_ptr, $src" %}
8727 ins_encode %{
8728 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
8729 R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8730 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8731 __ isync();
8732 } else {
8733 __ sync();
8734 }
8735 %}
8736 ins_pipe(pipe_class_default);
8737 %}
8738
8739 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8740 match(Set res (GetAndSetB mem_ptr src));
8741 predicate(VM_Version::has_lqarx());
8742 effect(TEMP_DEF res, TEMP cr0);
8743 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8744 ins_encode %{
8745 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8746 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8747 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8748 __ isync();
8749 } else {
8750 __ sync();
8751 }
8752 %}
8753 ins_pipe(pipe_class_default);
8754 %}
8755
8756 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8757 match(Set res (GetAndSetB mem_ptr src));
8758 predicate(!VM_Version::has_lqarx());
8759 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8760 format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8761 ins_encode %{
8762 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8763 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8764 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8765 __ isync();
8766 } else {
8767 __ sync();
8768 }
8769 %}
8770 ins_pipe(pipe_class_default);
8771 %}
8772
8773 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8774 match(Set res (GetAndSetS mem_ptr src));
8775 predicate(VM_Version::has_lqarx());
8776 effect(TEMP_DEF res, TEMP cr0);
8777 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8778 ins_encode %{
8779 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8780 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8781 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8782 __ isync();
8783 } else {
8784 __ sync();
8785 }
8786 %}
8787 ins_pipe(pipe_class_default);
8788 %}
8789
8790 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8791 match(Set res (GetAndSetS mem_ptr src));
8792 predicate(!VM_Version::has_lqarx());
8793 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8794 format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8795 ins_encode %{
8796 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8797 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8798 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8799 __ isync();
8800 } else {
8801 __ sync();
8802 }
8803 %}
8804 ins_pipe(pipe_class_default);
8805 %}
8806
8807 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8808 match(Set res (GetAndSetI mem_ptr src));
8809 effect(TEMP_DEF res, TEMP cr0);
8810 format %{ "GetAndSetI $res, $mem_ptr, $src" %}
8811 ins_encode %{
8812 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8813 MacroAssembler::cmpxchgx_hint_atomic_update());
8814 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8815 __ isync();
8816 } else {
8817 __ sync();
8818 }
8819 %}
8820 ins_pipe(pipe_class_default);
8821 %}
8822
8823 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8824 match(Set res (GetAndSetL mem_ptr src));
8825 effect(TEMP_DEF res, TEMP cr0);
8826 format %{ "GetAndSetL $res, $mem_ptr, $src" %}
8827 ins_encode %{
8828 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8829 MacroAssembler::cmpxchgx_hint_atomic_update());
8830 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8831 __ isync();
8832 } else {
8833 __ sync();
8834 }
8835 %}
8836 ins_pipe(pipe_class_default);
8837 %}
8838
8839 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
8840 match(Set res (GetAndSetP mem_ptr src));
8841 effect(TEMP_DEF res, TEMP cr0);
8842 format %{ "GetAndSetP $res, $mem_ptr, $src" %}
8843 ins_encode %{
8844 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8845 MacroAssembler::cmpxchgx_hint_atomic_update());
8846 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8847 __ isync();
8848 } else {
8849 __ sync();
8850 }
8851 %}
8852 ins_pipe(pipe_class_default);
8853 %}
8854
8855 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
8856 match(Set res (GetAndSetN mem_ptr src));
8857 effect(TEMP_DEF res, TEMP cr0);
8858 format %{ "GetAndSetN $res, $mem_ptr, $src" %}
8859 ins_encode %{
8860 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8861 MacroAssembler::cmpxchgx_hint_atomic_update());
8862 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) {
8863 __ isync();
8864 } else {
8865 __ sync();
8866 }
8867 %}
8868 ins_pipe(pipe_class_default);
8869 %}
8870
8871 //----------Arithmetic Instructions--------------------------------------------
8872 // Addition Instructions
8873
8874 // Register Addition
8875 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
8876 match(Set dst (AddI src1 src2));
8877 format %{ "ADD $dst, $src1, $src2" %}
8878 size(4);
8879 ins_encode %{
8880 // TODO: PPC port $archOpcode(ppc64Opcode_add);
8881 __ add($dst$$Register, $src1$$Register, $src2$$Register);
8882 %}
|