Commit 8d3f02e4 authored by Junliang Yan's avatar Junliang Yan Committed by V8 LUCI CQ

ppc: refactor atomic compare exchange

Change-Id: I83611a53426efff35960b2d90de909f2a6b07264
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3175369Reviewed-by: 's avatarMilad Fa <mfarazma@redhat.com>
Commit-Queue: Junliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/main@{#76991}
parent 03ff1b6d
......@@ -283,6 +283,118 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void CopySignF64(DoubleRegister dst, DoubleRegister lhs, DoubleRegister rhs,
RCBit r = LeaveRC);
template <class _type>
void SignedExtend(Register dst, Register value) {
switch (sizeof(_type)) {
case 1:
extsb(dst, value);
break;
case 2:
extsh(dst, value);
break;
case 4:
extsw(dst, value);
break;
case 8:
if (dst != value) mr(dst, value);
break;
default:
UNREACHABLE();
}
}
template <class _type>
void ZeroExtend(Register dst, Register value) {
switch (sizeof(_type)) {
case 1:
ZeroExtByte(dst, value);
break;
case 2:
ZeroExtHalfWord(dst, value);
break;
case 4:
ZeroExtWord32(dst, value);
break;
case 8:
if (dst != value) mr(dst, value);
break;
default:
UNREACHABLE();
}
}
template <class _type>
void ExtendValue(Register dst, Register value) {
if (std::is_signed<_type>::value) {
SignedExtend<_type>(dst, value);
} else {
ZeroExtend<_type>(dst, value);
}
}
template <class _type>
void LoadReserve(Register output, MemOperand dst) {
switch (sizeof(_type)) {
case 1:
lbarx(output, dst);
break;
case 2:
lharx(output, dst);
break;
case 4:
lwarx(output, dst);
break;
case 8:
ldarx(output, dst);
break;
default:
UNREACHABLE();
}
if (std::is_signed<_type>::value) {
SignedExtend<_type>(output, output);
}
}
template <class _type>
void StoreConditional(Register value, MemOperand dst) {
switch (sizeof(_type)) {
case 1:
stbcx(value, dst);
break;
case 2:
sthcx(value, dst);
break;
case 4:
stwcx(value, dst);
break;
case 8:
stdcx(value, dst);
break;
default:
UNREACHABLE();
}
}
template <class _type>
void AtomicCompareExchange(MemOperand dst, Register old_value,
Register new_value, Register output,
Register scratch) {
Label loop;
Label exit;
if (sizeof(_type) != 8) {
ExtendValue<_type>(scratch, old_value);
old_value = scratch;
}
lwsync();
bind(&loop);
LoadReserve<_type>(output, dst);
cmp(output, old_value, cr0);
bne(&exit, cr0);
StoreConditional<_type>(new_value, dst);
bne(&loop, cr0);
bind(&exit);
sync();
}
template <class _type, class bin_op>
void AtomicOps(MemOperand dst, Register value, Register output,
Register scratch, bin_op op) {
......
......@@ -595,43 +595,6 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
break; \
} while (false)
#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(cmp_inst, load_inst, store_inst, \
input_ext) \
do { \
MemOperand operand = MemOperand(i.InputRegister(0), i.InputRegister(1)); \
Label loop; \
Label exit; \
__ input_ext(r0, i.InputRegister(2)); \
__ lwsync(); \
__ bind(&loop); \
__ load_inst(i.OutputRegister(), operand); \
__ cmp_inst(i.OutputRegister(), r0, cr0); \
__ bne(&exit, cr0); \
__ store_inst(i.InputRegister(3), operand); \
__ bne(&loop, cr0); \
__ bind(&exit); \
__ sync(); \
} while (false)
#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_SIGN_EXT(cmp_inst, load_inst, \
store_inst, ext_instr) \
do { \
MemOperand operand = MemOperand(i.InputRegister(0), i.InputRegister(1)); \
Label loop; \
Label exit; \
__ ext_instr(r0, i.InputRegister(2)); \
__ lwsync(); \
__ bind(&loop); \
__ load_inst(i.OutputRegister(), operand); \
__ ext_instr(i.OutputRegister(), i.OutputRegister()); \
__ cmp_inst(i.OutputRegister(), r0, cr0); \
__ bne(&exit, cr0); \
__ store_inst(i.InputRegister(3), operand); \
__ bne(&loop, cr0); \
__ bind(&exit); \
__ sync(); \
} while (false)
void CodeGenerator::AssembleDeconstructFrame() {
__ LeaveFrame(StackFrame::MANUAL);
unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset());
......@@ -2038,22 +2001,40 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldarx, stdcx);
break;
case kAtomicCompareExchangeInt8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_SIGN_EXT(CmpS64, lbarx, stbcx, extsb);
__ AtomicCompareExchange<int8_t>(
MemOperand(i.InputRegister(0), i.InputRegister(1)),
i.InputRegister(2), i.InputRegister(3), i.OutputRegister(),
kScratchReg);
break;
case kPPC_AtomicCompareExchangeUint8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(CmpS64, lbarx, stbcx, ZeroExtByte);
__ AtomicCompareExchange<uint8_t>(
MemOperand(i.InputRegister(0), i.InputRegister(1)),
i.InputRegister(2), i.InputRegister(3), i.OutputRegister(),
kScratchReg);
break;
case kAtomicCompareExchangeInt16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_SIGN_EXT(CmpS64, lharx, sthcx, extsh);
__ AtomicCompareExchange<int16_t>(
MemOperand(i.InputRegister(0), i.InputRegister(1)),
i.InputRegister(2), i.InputRegister(3), i.OutputRegister(),
kScratchReg);
break;
case kPPC_AtomicCompareExchangeUint16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(CmpS64, lharx, sthcx, ZeroExtHalfWord);
__ AtomicCompareExchange<uint16_t>(
MemOperand(i.InputRegister(0), i.InputRegister(1)),
i.InputRegister(2), i.InputRegister(3), i.OutputRegister(),
kScratchReg);
break;
case kPPC_AtomicCompareExchangeWord32:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(cmpw, lwarx, stwcx, ZeroExtWord32);
__ AtomicCompareExchange<uint32_t>(
MemOperand(i.InputRegister(0), i.InputRegister(1)),
i.InputRegister(2), i.InputRegister(3), i.OutputRegister(),
kScratchReg);
break;
case kPPC_AtomicCompareExchangeWord64:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(CmpS64, ldarx, stdcx, mr);
__ AtomicCompareExchange<uint64_t>(
MemOperand(i.InputRegister(0), i.InputRegister(1)),
i.InputRegister(2), i.InputRegister(3), i.OutputRegister(),
kScratchReg);
break;
#define ATOMIC_BINOP_CASE(op, inst) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment