Commit 1c3b3e99 authored by Vasili Skurydzin's avatar Vasili Skurydzin Committed by Commit Bot

s390: Implement Word32 atomic binary operations using LAA/LAN/LAO/LAX

Change-Id: I97cdf61a15c2141d3c552a792ac08c9865f272ff
Reviewed-on: https://chromium-review.googlesource.com/1066307
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#53291}
parent f46c6037
...@@ -1019,26 +1019,16 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) { ...@@ -1019,26 +1019,16 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) {
__ CmpAndSwap(output, new_val, MemOperand(addr)); \ __ CmpAndSwap(output, new_val, MemOperand(addr)); \
} while (false) } while (false)
// TODO(vasili.skurydzin): use immediate operand for value and #define ASSEMBLE_ATOMIC_BINOP_WORD(load_and_op) \
// SI-formatted instructions (i.e. ASI/AGSI for add) to update
// memory atomically
#define ASSEMBLE_ATOMIC_BINOP_WORD(bin_inst, load_and_ext) \
do { \ do { \
Register value = i.InputRegister(2); \ Register value = i.InputRegister(2); \
Register result = i.OutputRegister(0); \ Register result = i.OutputRegister(0); \
Register addr = r1; \ Register addr = r1; \
Register prev = r0; \
Register next = kScratchReg; \
AddressingMode mode = kMode_None; \ AddressingMode mode = kMode_None; \
MemOperand op = i.MemoryOperand(&mode); \ MemOperand op = i.MemoryOperand(&mode); \
Label do_cs; \
__ lay(addr, op); \ __ lay(addr, op); \
__ l(prev, MemOperand(addr)); \ __ load_and_op(result, value, MemOperand(addr)); \
__ bind(&do_cs); \ __ LoadlW(result, result); \
__ bin_inst(next, prev, value); \
__ CmpAndSwap(prev, next, MemOperand(addr)); \
__ bne(&do_cs, Label::kNear); \
__ load_and_ext(result, prev); \
} while (false) } while (false)
#define ATOMIC_BIN_OP(bin_inst, offset, shift_amount, start, end) \ #define ATOMIC_BIN_OP(bin_inst, offset, shift_amount, start, end) \
...@@ -2724,9 +2714,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -2724,9 +2714,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ risbg(result, prev, Operand(48), Operand(63), \ __ risbg(result, prev, Operand(48), Operand(63), \
Operand(static_cast<intptr_t>(rotate_left)), true); \ Operand(static_cast<intptr_t>(rotate_left)), true); \
}); \ }); \
break; \
case kWord32Atomic##op##Word32: \
ASSEMBLE_ATOMIC_BINOP_WORD(inst, LoadlW); \
break; break;
ATOMIC_BINOP_CASE(Add, Add32) ATOMIC_BINOP_CASE(Add, Add32)
ATOMIC_BINOP_CASE(Sub, Sub32) ATOMIC_BINOP_CASE(Sub, Sub32)
...@@ -2734,7 +2721,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -2734,7 +2721,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ATOMIC_BINOP_CASE(Or, Or) ATOMIC_BINOP_CASE(Or, Or)
ATOMIC_BINOP_CASE(Xor, Xor) ATOMIC_BINOP_CASE(Xor, Xor)
#undef ATOMIC_BINOP_CASE #undef ATOMIC_BINOP_CASE
case kWord32AtomicAddWord32:
ASSEMBLE_ATOMIC_BINOP_WORD(laa);
break;
case kWord32AtomicSubWord32:
ASSEMBLE_ATOMIC_BINOP_WORD(LoadAndSub32);
break;
case kWord32AtomicAndWord32:
ASSEMBLE_ATOMIC_BINOP_WORD(lan);
break;
case kWord32AtomicOrWord32:
ASSEMBLE_ATOMIC_BINOP_WORD(lao);
break;
case kWord32AtomicXorWord32:
ASSEMBLE_ATOMIC_BINOP_WORD(lax);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -2869,6 +2869,13 @@ void TurboAssembler::SubP_ExtendSrc(Register dst, const MemOperand& opnd) { ...@@ -2869,6 +2869,13 @@ void TurboAssembler::SubP_ExtendSrc(Register dst, const MemOperand& opnd) {
#endif #endif
} }
// Load And Subtract 32-bit (similar to laa/lan/lao/lax)
void TurboAssembler::LoadAndSub32(Register dst, Register src,
const MemOperand& opnd) {
lcr(dst, src);
laa(dst, dst, opnd);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Subtract Logical Instructions // Subtract Logical Instructions
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
......
...@@ -333,6 +333,7 @@ class TurboAssembler : public Assembler { ...@@ -333,6 +333,7 @@ class TurboAssembler : public Assembler {
void Sub32(Register dst, const MemOperand& opnd); void Sub32(Register dst, const MemOperand& opnd);
void SubP(Register dst, const MemOperand& opnd); void SubP(Register dst, const MemOperand& opnd);
void SubP_ExtendSrc(Register dst, const MemOperand& opnd); void SubP_ExtendSrc(Register dst, const MemOperand& opnd);
void LoadAndSub32(Register dst, Register src, const MemOperand& opnd);
// Subtract Logical (Register - Mem) // Subtract Logical (Register - Mem)
void SubLogical(Register dst, const MemOperand& opnd); void SubLogical(Register dst, const MemOperand& opnd);
......
...@@ -9194,28 +9194,38 @@ EVALUATE(STOC) { ...@@ -9194,28 +9194,38 @@ EVALUATE(STOC) {
return 0; return 0;
} }
#define ATOMIC_LOAD_AND_UPDATE_WORD32(op) \
DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); \
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); \
intptr_t addr = static_cast<intptr_t>(b2_val) + d2; \
int32_t r3_val = get_low_register<int32_t>(r3); \
DCHECK_EQ(target_addr & 0x3, 0); \
int32_t r1_val = op(reinterpret_cast<int32_t*>(addr), \
r3_val, __ATOMIC_SEQ_CST); \
set_low_register(r1, r1_val);
EVALUATE(LAN) { EVALUATE(LAN) {
UNIMPLEMENTED(); DCHECK_OPCODE(LAN);
USE(instr); ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_and);
return 0; return length;
} }
EVALUATE(LAO) { EVALUATE(LAO) {
UNIMPLEMENTED(); DCHECK_OPCODE(LAO);
USE(instr); ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_or);
return 0; return length;
} }
EVALUATE(LAX) { EVALUATE(LAX) {
UNIMPLEMENTED(); DCHECK_OPCODE(LAX);
USE(instr); ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_xor);
return 0; return length;
} }
EVALUATE(LAA) { EVALUATE(LAA) {
UNIMPLEMENTED(); DCHECK_OPCODE(LAA);
USE(instr); ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_add);
return 0; return length;
} }
EVALUATE(LAAL) { EVALUATE(LAAL) {
...@@ -9224,6 +9234,8 @@ EVALUATE(LAAL) { ...@@ -9224,6 +9234,8 @@ EVALUATE(LAAL) {
return 0; return 0;
} }
#undef ATOMIC_LOAD_AND_UPDATE_WORD32
EVALUATE(BRXHG) { EVALUATE(BRXHG) {
UNIMPLEMENTED(); UNIMPLEMENTED();
USE(instr); USE(instr);
......
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