< prev index next >
src/cpu/ppc/vm/ppc.ad
Print this page
*** 3081,3091 ****
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
! __ fence();
%}
enc_class enc_GetAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
--- 3081,3095 ----
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
! if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
! __ isync();
! } else {
! __ sync();
! }
%}
enc_class enc_GetAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
*** 3106,3116 ****
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
! __ fence();
%}
enc_class enc_GetAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
--- 3110,3124 ----
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
! if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
! __ isync();
! } else {
! __ sync();
! }
%}
enc_class enc_GetAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
*** 3130,3140 ****
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ mr(Rres, Rtmp);
! __ fence();
%}
enc_class enc_GetAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
--- 3138,3152 ----
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ mr(Rres, Rtmp);
! if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
! __ isync();
! } else {
! __ sync();
! }
%}
enc_class enc_GetAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
*** 3154,3164 ****
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ mr(Rres, Rtmp);
! __ fence();
%}
// This enc_class is needed so that scheduler gets proper
// input mapping for latency computation.
enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
--- 3166,3180 ----
__ bne_predict_not_taken(CCR0, Lretry);
} else {
__ bne( CCR0, Lretry);
}
if (RegCollision) __ mr(Rres, Rtmp);
! if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
! __ isync();
! } else {
! __ sync();
! }
%}
// This enc_class is needed so that scheduler gets proper
// input mapping for latency computation.
enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
*** 7551,7571 ****
// CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
// (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
// matched.
instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
effect(TEMP cr0);
format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, true);
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
--- 7567,7594 ----
// CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
// (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
// matched.
+ // Strong versions:
+
instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
effect(TEMP cr0);
format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ __ sync();
+ }
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
*** 7575,7586 ****
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, true);
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
--- 7598,7614 ----
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ __ sync();
+ }
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
*** 7590,7601 ****
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, NULL, true);
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
--- 7618,7634 ----
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, NULL, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ __ sync();
+ }
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
*** 7605,7620 ****
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, NULL, true);
%}
ins_pipe(pipe_class_default);
%}
instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
match(Set res (GetAndAddI mem_ptr src));
effect(TEMP cr0);
format %{ "GetAndAddI $res, $mem_ptr, $src" %}
// Variable size: instruction count smaller if regs are disjoint.
--- 7638,7953 ----
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
! MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, NULL, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ __ sync();
+ }
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ // Weak versions:
+
+ instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+ // value is never passed to caller.
+ __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+ // value is never passed to caller.
+ __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ // value is never passed to caller.
+ __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+ // value is never passed to caller.
+ __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP cr0);
+ format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+ // value is never passed to caller.
+ __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+ MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ // CompareAndExchange
+
+ instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+ __ sync();
+ }
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+ __ sync();
+ }
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, NULL, true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, NULL, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+ __ sync();
+ }
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, NULL, true);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+
+ instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+ match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
+ predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+ effect(TEMP_DEF res, TEMP cr0);
+ format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
+ // Variable size: instruction count smaller if regs are disjoint.
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+ // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+ __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+ MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+ noreg, NULL, true);
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ __ isync();
+ } else {
+ // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+ __ sync();
+ }
%}
ins_pipe(pipe_class_default);
%}
+ // Special RMW
+
instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
match(Set res (GetAndAddI mem_ptr src));
effect(TEMP cr0);
format %{ "GetAndAddI $res, $mem_ptr, $src" %}
// Variable size: instruction count smaller if regs are disjoint.
< prev index next >