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,
} while (0)
#define ASSEMBLE_ATOMIC_BINOP_EXT(load_linked, store_conditional, sign_extend, \
size, bin_instr) \
size, bin_instr, representation) \
do { \
Label binop; \
__ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ 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), \
Operand(i.TempRegister(3))); \
__ sll(i.TempRegister(3), i.TempRegister(3), 3); \
......@@ -383,12 +388,17 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
__ sync(); \
} while (0)
#define ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(load_linked, store_conditional, \
sign_extend, size) \
#define ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT( \
load_linked, store_conditional, sign_extend, size, representation) \
do { \
Label exchange; \
__ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ 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), \
Operand(i.TempRegister(1))); \
__ sll(i.TempRegister(1), i.TempRegister(1), 3); \
......@@ -424,12 +434,17 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} while (0)
#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT( \
load_linked, store_conditional, sign_extend, size) \
load_linked, store_conditional, sign_extend, size, representation) \
do { \
Label compareExchange; \
Label exit; \
__ daddu(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \
if (representation == 32) { \
__ 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), \
Operand(i.TempRegister(1))); \
__ sll(i.TempRegister(1), i.TempRegister(1), 3); \
......@@ -1868,72 +1883,72 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_ATOMIC_STORE_INTEGER(Sd);
break;
case kWord32AtomicExchangeInt8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8);
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8, 32);
break;
case kWord32AtomicExchangeUint8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8);
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8, 32);
break;
case kWord32AtomicExchangeInt16:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16);
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16, 32);
break;
case kWord32AtomicExchangeUint16:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16);
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16, 32);
break;
case kWord32AtomicExchangeWord32:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Ll, Sc);
break;
case kMips64Word64AtomicExchangeUint8:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8);
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8, 64);
break;
case kMips64Word64AtomicExchangeUint16:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16);
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16, 64);
break;
case kMips64Word64AtomicExchangeUint32:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32);
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32, 64);
break;
case kMips64Word64AtomicExchangeUint64:
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Lld, Scd);
break;
case kWord32AtomicCompareExchangeInt8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 8, 32);
break;
case kWord32AtomicCompareExchangeUint8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 8, 32);
break;
case kWord32AtomicCompareExchangeInt16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, true, 16, 32);
break;
case kWord32AtomicCompareExchangeUint16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, false, 16, 32);
break;
case kWord32AtomicCompareExchangeWord32:
__ sll(i.InputRegister(2), i.InputRegister(2), 0);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc);
break;
case kMips64Word64AtomicCompareExchangeUint8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 8, 64);
break;
case kMips64Word64AtomicCompareExchangeUint16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 16, 64);
break;
case kMips64Word64AtomicCompareExchangeUint32:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32);
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, false, 32, 64);
break;
case kMips64Word64AtomicCompareExchangeUint64:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Lld, Scd);
break;
#define ATOMIC_BINOP_CASE(op, inst) \
case kWord32Atomic##op##Int8: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 8, inst); \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 8, inst, 32); \
break; \
case kWord32Atomic##op##Uint8: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 8, inst); \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 8, inst, 32); \
break; \
case kWord32Atomic##op##Int16: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 16, inst); \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, true, 16, inst, 32); \
break; \
case kWord32Atomic##op##Uint16: \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 16, inst); \
ASSEMBLE_ATOMIC_BINOP_EXT(Ll, Sc, false, 16, inst, 32); \
break; \
case kWord32Atomic##op##Word32: \
ASSEMBLE_ATOMIC_BINOP(Ll, Sc, inst); \
......@@ -1946,13 +1961,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#undef ATOMIC_BINOP_CASE
#define ATOMIC_BINOP_CASE(op, inst) \
case kMips64Word64Atomic##op##Uint8: \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 8, inst); \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 8, inst, 64); \
break; \
case kMips64Word64Atomic##op##Uint16: \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 16, inst); \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 16, inst, 64); \
break; \
case kMips64Word64Atomic##op##Uint32: \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 32, inst); \
ASSEMBLE_ATOMIC_BINOP_EXT(Lld, Scd, false, 32, inst, 64); \
break; \
case kMips64Word64Atomic##op##Uint64: \
ASSEMBLE_ATOMIC_BINOP(Lld, Scd, inst); \
......
......@@ -1755,8 +1755,7 @@ void TurboAssembler::InsertBits(Register dest, Register source, Register pos,
{
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
Subu(scratch, pos, Operand(32));
Neg(scratch, Operand(scratch));
Subu(scratch, zero_reg, pos);
Ror(dest, dest, scratch);
}
}
......
......@@ -2069,7 +2069,7 @@ void TurboAssembler::Dins(Register rt, Register rs, uint16_t pos,
void TurboAssembler::ExtractBits(Register dest, Register source, Register pos,
int size, bool sign_extend) {
srav(dest, source, pos);
dsrav(dest, source, pos);
Dext(dest, dest, 0, size);
if (sign_extend) {
switch (size) {
......@@ -2091,14 +2091,13 @@ void TurboAssembler::ExtractBits(Register dest, Register source, Register pos,
void TurboAssembler::InsertBits(Register dest, Register source, Register pos,
int size) {
Ror(dest, dest, pos);
Dror(dest, dest, pos);
Dins(dest, source, 0, size);
{
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
Dsubu(scratch, pos, Operand(64));
Neg(scratch, Operand(scratch));
Ror(dest, dest, scratch);
Dsubu(scratch, zero_reg, pos);
Dror(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