Commit 4ab8215e authored by andrew-cc-chen's avatar andrew-cc-chen Committed by Commit Bot

[ppc] Implemented Atomic64 operations

Change-Id: Ic99e2e02ae644382873d9cf0621145bcde23b6b2
Reviewed-on: https://chromium-review.googlesource.com/1257807Reviewed-by: 's avatarJunliang Yan <jyan@ca.ibm.com>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#56353}
parent 28a9235c
......@@ -2428,7 +2428,7 @@ void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) {
#endif // !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS64 && \
!V8_TARGET_ARCH_S390
!V8_TARGET_ARCH_S390 && !V8_TARGET_ARCH_PPC
void InstructionSelector::VisitWord64AtomicLoad(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitWord64AtomicStore(Node* node) {
......@@ -2452,7 +2452,7 @@ void InstructionSelector::VisitWord64AtomicExchange(Node* node) {
void InstructionSelector::VisitWord64AtomicCompareExchange(Node* node) {
UNIMPLEMENTED();
}
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 &&
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_PPC
// !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_S390
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
......
......@@ -1979,32 +1979,45 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_ATOMIC_LOAD_INTEGER(lbz, lbzx);
__ extsb(i.OutputRegister(), i.OutputRegister());
break;
case kPPC_Word64AtomicLoadUint8:
case kWord32AtomicLoadUint8:
ASSEMBLE_ATOMIC_LOAD_INTEGER(lbz, lbzx);
break;
case kWord32AtomicLoadInt16:
ASSEMBLE_ATOMIC_LOAD_INTEGER(lha, lhax);
break;
case kPPC_Word64AtomicLoadUint16:
case kWord32AtomicLoadUint16:
ASSEMBLE_ATOMIC_LOAD_INTEGER(lhz, lhzx);
break;
case kPPC_Word64AtomicLoadUint32:
case kWord32AtomicLoadWord32:
ASSEMBLE_ATOMIC_LOAD_INTEGER(lwz, lwzx);
break;
case kPPC_Word64AtomicLoadUint64:
ASSEMBLE_ATOMIC_LOAD_INTEGER(ld, ldx);
break;
case kPPC_Word64AtomicStoreUint8:
case kWord32AtomicStoreWord8:
ASSEMBLE_ATOMIC_STORE_INTEGER(stb, stbx);
break;
case kPPC_Word64AtomicStoreUint16:
case kWord32AtomicStoreWord16:
ASSEMBLE_ATOMIC_STORE_INTEGER(sth, sthx);
break;
case kPPC_Word64AtomicStoreUint32:
case kWord32AtomicStoreWord32:
ASSEMBLE_ATOMIC_STORE_INTEGER(stw, stwx);
break;
case kPPC_Word64AtomicStoreUint64:
ASSEMBLE_ATOMIC_STORE_INTEGER(std, stdx);
break;
case kWord32AtomicExchangeInt8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(lbarx, stbcx);
__ extsb(i.OutputRegister(0), i.OutputRegister(0));
break;
case kPPC_Word64AtomicExchangeUint8:
case kWord32AtomicExchangeUint8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(lbarx, stbcx);
break;
......@@ -2012,44 +2025,57 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(lharx, sthcx);
__ extsh(i.OutputRegister(0), i.OutputRegister(0));
break;
case kPPC_Word64AtomicExchangeUint16:
case kWord32AtomicExchangeUint16:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(lharx, sthcx);
break;
case kPPC_Word64AtomicExchangeUint32:
case kWord32AtomicExchangeWord32:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(lwarx, stwcx);
break;
case kPPC_Word64AtomicExchangeUint64:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldarx, stdcx);
break;
case kWord32AtomicCompareExchangeInt8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_SIGN_EXT(cmp, lbarx, stbcx, extsb);
break;
case kPPC_Word64AtomicCompareExchangeUint8:
case kWord32AtomicCompareExchangeUint8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(cmp, lbarx, stbcx);
break;
case kWord32AtomicCompareExchangeInt16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_SIGN_EXT(cmp, lharx, sthcx, extsh);
break;
case kPPC_Word64AtomicCompareExchangeUint16:
case kWord32AtomicCompareExchangeUint16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(cmp, lharx, sthcx);
break;
case kPPC_Word64AtomicCompareExchangeUint32:
case kWord32AtomicCompareExchangeWord32:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(cmpw, lwarx, stwcx);
break;
#define ATOMIC_BINOP_CASE(op, inst) \
case kWord32Atomic##op##Int8: \
ASSEMBLE_ATOMIC_BINOP_SIGN_EXT(inst, lbarx, stbcx, extsb); \
break; \
case kWord32Atomic##op##Uint8: \
ASSEMBLE_ATOMIC_BINOP(inst, lbarx, stbcx); \
break; \
case kWord32Atomic##op##Int16: \
ASSEMBLE_ATOMIC_BINOP_SIGN_EXT(inst, lharx, sthcx, extsh); \
break; \
case kWord32Atomic##op##Uint16: \
ASSEMBLE_ATOMIC_BINOP(inst, lharx, sthcx); \
break; \
case kWord32Atomic##op##Word32: \
ASSEMBLE_ATOMIC_BINOP(inst, lwarx, stwcx); \
case kPPC_Word64AtomicCompareExchangeUint64:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE(cmp, ldarx, stdcx);
break;
#define ATOMIC_BINOP_CASE(op, inst) \
case kWord32Atomic##op##Int8: \
ASSEMBLE_ATOMIC_BINOP_SIGN_EXT(inst, lbarx, stbcx, extsb); \
break; \
case kPPC_Word64Atomic##op##Uint8: \
case kWord32Atomic##op##Uint8: \
ASSEMBLE_ATOMIC_BINOP(inst, lbarx, stbcx); \
break; \
case kWord32Atomic##op##Int16: \
ASSEMBLE_ATOMIC_BINOP_SIGN_EXT(inst, lharx, sthcx, extsh); \
break; \
case kPPC_Word64Atomic##op##Uint16: \
case kWord32Atomic##op##Uint16: \
ASSEMBLE_ATOMIC_BINOP(inst, lharx, sthcx); \
break; \
case kPPC_Word64Atomic##op##Uint32: \
case kWord32Atomic##op##Word32: \
ASSEMBLE_ATOMIC_BINOP(inst, lwarx, stwcx); \
break;
ATOMIC_BINOP_CASE(Add, add)
ATOMIC_BINOP_CASE(Sub, sub)
......@@ -2058,6 +2084,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ATOMIC_BINOP_CASE(Xor, xor_)
#undef ATOMIC_BINOP_CASE
#define ATOMIC64_BINOP_CASE(op, inst) \
case kPPC_Word64Atomic##op##Uint64: \
ASSEMBLE_ATOMIC_BINOP(inst, ldarx, stdcx); \
break;
ATOMIC64_BINOP_CASE(Add, add)
ATOMIC64_BINOP_CASE(Sub, sub)
ATOMIC64_BINOP_CASE(And, and_)
ATOMIC64_BINOP_CASE(Or, orx)
ATOMIC64_BINOP_CASE(Xor, xor_)
#undef ATOMIC64_BINOP_CASE
case kPPC_ByteRev32: {
Register input = i.InputRegister(0);
Register output = i.OutputRegister();
......
This diff is collapsed.
......@@ -135,6 +135,46 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_StoreToStackSlot:
return kHasSideEffect;
case kPPC_Word64AtomicLoadUint8:
case kPPC_Word64AtomicLoadUint16:
case kPPC_Word64AtomicLoadUint32:
case kPPC_Word64AtomicLoadUint64:
return kIsLoadOperation;
case kPPC_Word64AtomicStoreUint8:
case kPPC_Word64AtomicStoreUint16:
case kPPC_Word64AtomicStoreUint32:
case kPPC_Word64AtomicStoreUint64:
case kPPC_Word64AtomicExchangeUint8:
case kPPC_Word64AtomicExchangeUint16:
case kPPC_Word64AtomicExchangeUint32:
case kPPC_Word64AtomicExchangeUint64:
case kPPC_Word64AtomicCompareExchangeUint8:
case kPPC_Word64AtomicCompareExchangeUint16:
case kPPC_Word64AtomicCompareExchangeUint32:
case kPPC_Word64AtomicCompareExchangeUint64:
case kPPC_Word64AtomicAddUint8:
case kPPC_Word64AtomicAddUint16:
case kPPC_Word64AtomicAddUint32:
case kPPC_Word64AtomicAddUint64:
case kPPC_Word64AtomicSubUint8:
case kPPC_Word64AtomicSubUint16:
case kPPC_Word64AtomicSubUint32:
case kPPC_Word64AtomicSubUint64:
case kPPC_Word64AtomicAndUint8:
case kPPC_Word64AtomicAndUint16:
case kPPC_Word64AtomicAndUint32:
case kPPC_Word64AtomicAndUint64:
case kPPC_Word64AtomicOrUint8:
case kPPC_Word64AtomicOrUint16:
case kPPC_Word64AtomicOrUint32:
case kPPC_Word64AtomicOrUint64:
case kPPC_Word64AtomicXorUint8:
case kPPC_Word64AtomicXorUint16:
case kPPC_Word64AtomicXorUint32:
case kPPC_Word64AtomicXorUint64:
return kHasSideEffect;
#define CASE(Name) case k##Name:
COMMON_ARCH_OPCODE_LIST(CASE)
#undef CASE
......
......@@ -1201,13 +1201,15 @@ typedef uint32_t Instr;
/* Compare Logical */ \
V(cmpl, CMPL, 0x7C000040)
#define PPC_X_OPCODE_EH_S_FORM_LIST(V) \
/* Store Byte Conditional Indexed */ \
V(stbcx, STBCX, 0x7C00056D) \
/* Store Halfword Conditional Indexed Xform */ \
V(sthcx, STHCX, 0x7C0005AD) \
/* Store Word Conditional Indexed & record CR0 */ \
V(stwcx, STWCX, 0x7C00012D)
#define PPC_X_OPCODE_EH_S_FORM_LIST(V) \
/* Store Byte Conditional Indexed */ \
V(stbcx, STBCX, 0x7C00056D) \
/* Store Halfword Conditional Indexed Xform */ \
V(sthcx, STHCX, 0x7C0005AD) \
/* Store Word Conditional Indexed & record CR0 */ \
V(stwcx, STWCX, 0x7C00012D) \
/* Store Doubleword Conditional Indexed & record CR0 */ \
V(stdcx, STDCX, 0x7C0001AD)
#define PPC_X_OPCODE_EH_L_FORM_LIST(V) \
/* Load Byte And Reserve Indexed */ \
......@@ -1215,15 +1217,15 @@ typedef uint32_t Instr;
/* Load Halfword And Reserve Indexed Xform */ \
V(lharx, LHARX, 0x7C0000E8) \
/* Load Word and Reserve Indexed */ \
V(lwarx, LWARX, 0x7C000028)
V(lwarx, LWARX, 0x7C000028) \
/* Load Doubleword And Reserve Indexed */ \
V(ldarx, LDARX, 0x7C0000A8)
#define PPC_X_OPCODE_UNUSED_LIST(V) \
/* Bit Permute Doubleword */ \
V(bpermd, BPERMD, 0x7C0001F8) \
/* Extend Sign Word */ \
V(extsw, EXTSW, 0x7C0007B4) \
/* Load Doubleword And Reserve Indexed */ \
V(ldarx, LDARX, 0x7C0000A8) \
/* Load Word Algebraic with Update Indexed */ \
V(lwaux, LWAUX, 0x7C0002EA) \
/* Load Word Algebraic Indexed */ \
......@@ -1232,8 +1234,6 @@ typedef uint32_t Instr;
V(prtyd, PRTYD, 0x7C000174) \
/* Store Doubleword Byte-Reverse Indexed */ \
V(stdbrx, STDBRX, 0x7C000528) \
/* Store Doubleword Conditional Indexed & record CR0 */ \
V(stdcx, STDCX, 0x7C0001AD) \
/* Trap Doubleword */ \
V(td, TD, 0x7C000088) \
/* Branch Conditional to Branch Target Address Register */ \
......
......@@ -665,6 +665,10 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "stwcx 'rs, 'ra, 'rb");
return;
}
case STDCX: {
Format(instr, "stdcx 'rs, 'ra, 'rb");
return;
}
}
// ?? are all of these xo_form?
......@@ -898,6 +902,10 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "ldux 'rt, 'ra, 'rb");
return;
}
case LDARX: {
Format(instr, "ldarx 'rt, 'ra, 'rb");
return;
}
case STDX: {
Format(instr, "stdx 'rt, 'ra, 'rb");
return;
......
......@@ -870,6 +870,27 @@ void Simulator::TrashCallerSaveRegisters() {
#endif
}
int Simulator::WriteExDW(intptr_t addr, uint64_t value, Instruction* instr) {
base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
if (local_monitor_.NotifyStoreExcl(addr, TransactionSize::Word) &&
global_monitor_.Pointer()->NotifyStoreExcl_Locked(
addr, &global_monitor_processor_)) {
uint64_t* ptr = reinterpret_cast<uint64_t*>(addr);
*ptr = value;
return 0;
} else {
return 1;
}
}
uint64_t Simulator::ReadExDWU(intptr_t addr, Instruction* instr) {
base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
local_monitor_.NotifyLoadExcl(addr, TransactionSize::Word);
global_monitor_.Pointer()->NotifyLoadExcl_Locked(addr,
&global_monitor_processor_);
uint64_t* ptr = reinterpret_cast<uint64_t*>(addr);
return *ptr;
}
uint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) {
// All supported PPC targets allow unaligned accesses, so we don't need to
......@@ -2320,6 +2341,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
SetCR0(WriteExW(ra_val + rb_val, rs_val, instr));
break;
}
case STDCX: {
int rs = instr->RSValue();
int ra = instr->RAValue();
int rb = instr->RBValue();
intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
int64_t rs_val = get_register(rs);
intptr_t rb_val = get_register(rb);
SetCR0(WriteExDW(ra_val + rb_val, rs_val, instr));
break;
}
case TW: {
// used for call redirection in simulation mode
SoftwareInterrupt(instr);
......@@ -3087,6 +3118,15 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
set_register(rt, ReadExWU(ra_val + rb_val, instr));
break;
}
case LDARX: {
int rt = instr->RTValue();
int ra = instr->RAValue();
int rb = instr->RBValue();
intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
intptr_t rb_val = get_register(rb);
set_register(rt, ReadExDWU(ra_val + rb_val, instr));
break;
}
case DCBF: {
// todo - simulate dcbf
break;
......
......@@ -265,6 +265,8 @@ class Simulator : public SimulatorBase {
intptr_t* ReadDW(intptr_t addr);
void WriteDW(intptr_t addr, int64_t value);
inline int WriteExDW(intptr_t addr, uint64_t value, Instruction* instr);
inline uint64_t ReadExDWU(intptr_t addr, Instruction* instr);
void Trace(Instruction* instr);
void SetCR0(intptr_t result, bool setSO = false);
......
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