Commit ad9835e5 authored by Predrag Rudic's avatar Predrag Rudic Committed by Commit Bot

MIPS[64]: Fix failing atomic64-stress test

64-bit implementations of ExtractBits and InsertBits were using 32-bit
instructions. Masking when representation of instruction is 64 is now
correct.
Also added optimization for 32-bit InsertBits.

Change-Id: I3d5117835daa67708e544d01d1d9058dcc0cc64e
Reviewed-on: https://chromium-review.googlesource.com/c/1355141Reviewed-by: 's avatarSreten Kovacevic <skovacevic@wavecomp.com>
Commit-Queue: Sreten Kovacevic <skovacevic@wavecomp.com>
Cr-Commit-Position: refs/heads/master@{#57961}
parent d3e40641
...@@ -348,11 +348,16 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, ...@@ -348,11 +348,16 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} while (0) } while (0)
#define ASSEMBLE_ATOMIC_BINOP_EXT(load_linked, store_conditional, sign_extend, \ #define ASSEMBLE_ATOMIC_BINOP_EXT(load_linked, store_conditional, sign_extend, \
size, bin_instr) \ size, bin_instr, representation) \
do { \ do { \
Label binop; \ Label binop; \
__ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ __ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ andi(i.TempRegister(3), i.TempRegister(0), 0x3); \ __ andi(i.TempRegister(3), i.TempRegister(0), 0x3); \
} else { \
DCHECK_EQ(representation, 64); \
__ andi(i.TempRegister(3), i.TempRegister(0), 0x7); \
} \
__ Dsubu(i.TempRegister(0), i.TempRegister(0), \ __ Dsubu(i.TempRegister(0), i.TempRegister(0), \
Operand(i.TempRegister(3))); \ Operand(i.TempRegister(3))); \
__ sll(i.TempRegister(3), i.TempRegister(3), 3); \ __ sll(i.TempRegister(3), i.TempRegister(3), 3); \
...@@ -383,12 +388,17 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, ...@@ -383,12 +388,17 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
__ sync(); \ __ sync(); \
} while (0) } while (0)
#define ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(load_linked, store_conditional, \ #define ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT( \
sign_extend, size) \ load_linked, store_conditional, sign_extend, size, representation) \
do { \ do { \
Label exchange; \ Label exchange; \
__ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ __ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ andi(i.TempRegister(1), i.TempRegister(0), 0x3); \ __ andi(i.TempRegister(1), i.TempRegister(0), 0x3); \
} else { \
DCHECK_EQ(representation, 64); \
__ andi(i.TempRegister(1), i.TempRegister(0), 0x7); \
} \
__ Dsubu(i.TempRegister(0), i.TempRegister(0), \ __ Dsubu(i.TempRegister(0), i.TempRegister(0), \
Operand(i.TempRegister(1))); \ Operand(i.TempRegister(1))); \
__ sll(i.TempRegister(1), i.TempRegister(1), 3); \ __ sll(i.TempRegister(1), i.TempRegister(1), 3); \
...@@ -424,12 +434,17 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, ...@@ -424,12 +434,17 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} while (0) } while (0)
#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT( \ #define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT( \
load_linked, store_conditional, sign_extend, size) \ load_linked, store_conditional, sign_extend, size, representation) \
do { \ do { \
Label compareExchange; \ Label compareExchange; \
Label exit; \ Label exit; \
__ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ __ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ andi(i.TempRegister(1), i.TempRegister(0), 0x3); \ __ andi(i.TempRegister(1), i.TempRegister(0), 0x3); \
} else { \
DCHECK_EQ(representation, 64); \
__ andi(i.TempRegister(1), i.TempRegister(0), 0x7); \
} \
__ Dsubu(i.TempRegister(0), i.TempRegister(0), \ __ Dsubu(i.TempRegister(0), i.TempRegister(0), \
Operand(i.TempRegister(1))); \ Operand(i.TempRegister(1))); \
__ sll(i.TempRegister(1), i.TempRegister(1), 3); \ __ sll(i.TempRegister(1), i.TempRegister(1), 3); \
...@@ -1868,72 +1883,72 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1868,72 +1883,72 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_ATOMIC_STORE_INTEGER(Sd); ASSEMBLE_ATOMIC_STORE_INTEGER(Sd);
break; break;
case kWord32AtomicExchangeInt8: case kWord32AtomicExchangeInt8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8, 32);
break; break;
case kWord32AtomicExchangeUint8: case kWord32AtomicExchangeUint8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8, 32);
break; break;
case kWord32AtomicExchangeInt16: case kWord32AtomicExchangeInt16:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16, 32);
break; break;
case kWord32AtomicExchangeUint16: case kWord32AtomicExchangeUint16:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16, 32);
break; break;
case kWord32AtomicExchangeWord32: case kWord32AtomicExchangeWord32:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Ll, Sc); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Ll, Sc);
break; break;
case kMips64Word64AtomicExchangeUint8: case kMips64Word64AtomicExchangeUint8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8, 64);
break; break;
case kMips64Word64AtomicExchangeUint16: case kMips64Word64AtomicExchangeUint16:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16, 64);
break; break;
case kMips64Word64AtomicExchangeUint32: case kMips64Word64AtomicExchangeUint32:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32, 64);
break; break;
case kMips64Word64AtomicExchangeUint64: case kMips64Word64AtomicExchangeUint64:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Lld, Scd); ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Lld, Scd);
break; break;
case kWord32AtomicCompareExchangeInt8: case kWord32AtomicCompareExchangeInt8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8, 32);
break; break;
case kWord32AtomicCompareExchangeUint8: case kWord32AtomicCompareExchangeUint8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8, 32);
break; break;
case kWord32AtomicCompareExchangeInt16: case kWord32AtomicCompareExchangeInt16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16, 32);
break; break;
case kWord32AtomicCompareExchangeUint16: case kWord32AtomicCompareExchangeUint16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16, 32);
break; break;
case kWord32AtomicCompareExchangeWord32: case kWord32AtomicCompareExchangeWord32:
__ sll(i.InputRegister(2), i.InputRegister(2), 0); __ sll(i.InputRegister(2), i.InputRegister(2), 0);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc);
break; break;
case kMips64Word64AtomicCompareExchangeUint8: case kMips64Word64AtomicCompareExchangeUint8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8, 64);
break; break;
case kMips64Word64AtomicCompareExchangeUint16: case kMips64Word64AtomicCompareExchangeUint16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16, 64);
break; break;
case kMips64Word64AtomicCompareExchangeUint32: case kMips64Word64AtomicCompareExchangeUint32:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32, 64);
break; break;
case kMips64Word64AtomicCompareExchangeUint64: case kMips64Word64AtomicCompareExchangeUint64:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Lld, Scd); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Lld, Scd);
break; break;
#define ATOMIC_BINOP_CASE(op, inst) \ #define ATOMIC_BINOP_CASE(op, inst) \
case kWord32Atomic##op##Int8: \ case kWord32Atomic##op##Int8: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 8, inst); \ ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 8, inst, 32); \
break; \ break; \
case kWord32Atomic##op##Uint8: \ case kWord32Atomic##op##Uint8: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 8, inst); \ ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 8, inst, 32); \
break; \ break; \
case kWord32Atomic##op##Int16: \ case kWord32Atomic##op##Int16: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 16, inst); \ ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 16, inst, 32); \
break; \ break; \
case kWord32Atomic##op##Uint16: \ case kWord32Atomic##op##Uint16: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 16, inst); \ ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 16, inst, 32); \
break; \ break; \
case kWord32Atomic##op##Word32: \ case kWord32Atomic##op##Word32: \
ASSEMBLE_ATOMIC_BINOP(Ll, Sc, inst); \ ASSEMBLE_ATOMIC_BINOP(Ll, Sc, inst); \
...@@ -1946,13 +1961,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1946,13 +1961,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#undef ATOMIC_BINOP_CASE #undef ATOMIC_BINOP_CASE
#define ATOMIC_BINOP_CASE(op, inst) \ #define ATOMIC_BINOP_CASE(op, inst) \
case kMips64Word64Atomic##op##Uint8: \ case kMips64Word64Atomic##op##Uint8: \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 8, inst); \ ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 8, inst, 64); \
break; \ break; \
case kMips64Word64Atomic##op##Uint16: \ case kMips64Word64Atomic##op##Uint16: \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 16, inst); \ ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 16, inst, 64); \
break; \ break; \
case kMips64Word64Atomic##op##Uint32: \ case kMips64Word64Atomic##op##Uint32: \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 32, inst); \ ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 32, inst, 64); \
break; \ break; \
case kMips64Word64Atomic##op##Uint64: \ case kMips64Word64Atomic##op##Uint64: \
ASSEMBLE_ATOMIC_BINOP(Lld, Scd, inst); \ ASSEMBLE_ATOMIC_BINOP(Lld, Scd, inst); \
......
...@@ -1755,8 +1755,7 @@ void TurboAssembler::InsertBits(Register dest, Register source, Register pos, ...@@ -1755,8 +1755,7 @@ void TurboAssembler::InsertBits(Register dest, Register source, Register pos,
{ {
UseScratchRegisterScope temps(this); UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire(); Register scratch = temps.Acquire();
Subu(scratch, pos, Operand(32)); Subu(scratch, zero_reg, pos);
Neg(scratch, Operand(scratch));
Ror(dest, dest, scratch); Ror(dest, dest, scratch);
} }
} }
......
...@@ -2069,7 +2069,7 @@ void TurboAssembler::Dins(Register rt, Register rs, uint16_t pos, ...@@ -2069,7 +2069,7 @@ void TurboAssembler::Dins(Register rt, Register rs, uint16_t pos,
void TurboAssembler::ExtractBits(Register dest, Register source, Register pos, void TurboAssembler::ExtractBits(Register dest, Register source, Register pos,
int size, bool sign_extend) { int size, bool sign_extend) {
srav(dest, source, pos); dsrav(dest, source, pos);
Dext(dest, dest, 0, size); Dext(dest, dest, 0, size);
if (sign_extend) { if (sign_extend) {
switch (size) { switch (size) {
...@@ -2091,14 +2091,13 @@ void TurboAssembler::ExtractBits(Register dest, Register source, Register pos, ...@@ -2091,14 +2091,13 @@ void TurboAssembler::ExtractBits(Register dest, Register source, Register pos,
void TurboAssembler::InsertBits(Register dest, Register source, Register pos, void TurboAssembler::InsertBits(Register dest, Register source, Register pos,
int size) { int size) {
Ror(dest, dest, pos); Dror(dest, dest, pos);
Dins(dest, source, 0, size); Dins(dest, source, 0, size);
{ {
UseScratchRegisterScope temps(this); UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire(); Register scratch = temps.Acquire();
Dsubu(scratch, pos, Operand(64)); Dsubu(scratch, zero_reg, pos);
Neg(scratch, Operand(scratch)); Dror(dest, dest, scratch);
Ror(dest, dest, scratch);
} }
} }
......
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