Commit bcaea997 authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: Tweak StoreKeyed.

Port r16771 (536eb66)

Original commit message:
Avoid corrupting its input in some cases.

BUG=none
TEST=test/mjsunit/lithium/StoreKeyed*.js
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/23537053

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16779 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d047afb4
......@@ -4232,20 +4232,25 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
Register address = scratch0();
FPURegister value(ToDoubleRegister(instr->value()));
if (key_is_constant) {
__ Addu(scratch0(), external_pointer, constant_key <<
element_size_shift);
if (constant_key != 0) {
__ Addu(address, external_pointer,
Operand(constant_key << element_size_shift));
} else {
address = external_pointer;
}
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
__ sll(address, key, shift_size);
__ Addu(address, external_pointer, address);
}
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ cvt_s_d(double_scratch0(), value);
__ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset));
__ swc1(double_scratch0(), MemOperand(address, additional_offset));
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ sdc1(value, MemOperand(scratch0(), additional_offset));
__ sdc1(value, MemOperand(address, additional_offset));
}
} else {
Register value(ToRegister(instr->value()));
......@@ -4287,33 +4292,29 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
DoubleRegister value = ToDoubleRegister(instr->value());
Register elements = ToRegister(instr->elements());
Register key = no_reg;
Register scratch = scratch0();
DoubleRegister double_scratch = double_scratch0();
bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0;
Label not_nan;
Label not_nan, done;
// Calculate the effective address of the slot in the array to store the
// double value.
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xF0000000) {
Abort(kArrayIndexConstantValueTooBig);
}
__ Addu(scratch, elements,
Operand((constant_key << element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
key = ToRegister(instr->key());
}
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
if (key_is_constant) {
__ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
__ Addu(scratch, elements, Operand(scratch));
__ Addu(scratch, scratch,
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
__ Addu(scratch, elements,
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
__ sll(at, ToRegister(instr->key()), shift_size);
__ Addu(scratch, scratch, at);
}
if (instr->NeedsCanonicalization()) {
......@@ -4324,12 +4325,17 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
// Only load canonical NaN if the comparison above set the overflow.
__ bind(&is_nan);
__ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
__ Move(double_scratch,
FixedDoubleArray::canonical_not_the_hole_nan_as_double());
__ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() <<
element_size_shift));
__ Branch(&done);
}
__ bind(&not_nan);
__ sdc1(value, MemOperand(scratch, instr->additional_index() <<
element_size_shift));
__ bind(&done);
}
......
......@@ -2125,8 +2125,6 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
ElementsKind elements_kind = instr->elements_kind();
if (!instr->is_external()) {
ASSERT(instr->elements()->representation().IsTagged());
bool needs_write_barrier = instr->NeedsWriteBarrier();
......@@ -2137,14 +2135,18 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
if (instr->value()->representation().IsDouble()) {
object = UseRegisterAtStart(instr->elements());
key = UseRegisterOrConstantAtStart(instr->key());
val = UseTempRegister(instr->value());
val = UseRegister(instr->value());
} else {
ASSERT(instr->value()->representation().IsSmiOrTagged());
object = UseTempRegister(instr->elements());
val = needs_write_barrier ? UseTempRegister(instr->value())
: UseRegisterAtStart(instr->value());
key = needs_write_barrier ? UseTempRegister(instr->key())
: UseRegisterOrConstantAtStart(instr->key());
if (needs_write_barrier) {
object = UseTempRegister(instr->elements());
val = UseTempRegister(instr->value());
key = UseTempRegister(instr->key());
} else {
object = UseRegisterAtStart(instr->elements());
val = UseRegisterAtStart(instr->value());
key = UseRegisterOrConstantAtStart(instr->key());
}
}
return new(zone()) LStoreKeyed(object, key, val);
......@@ -2152,17 +2154,13 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
ASSERT(
(instr->value()->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(instr->elements_kind() != EXTERNAL_FLOAT_ELEMENTS) &&
(instr->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS)) ||
(instr->value()->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
((instr->elements_kind() == EXTERNAL_FLOAT_ELEMENTS) ||
(instr->elements_kind() == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->elements()->representation().IsExternal());
bool val_is_temp_register =
elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
elements_kind == EXTERNAL_FLOAT_ELEMENTS;
LOperand* val = val_is_temp_register ? UseTempRegister(instr->value())
: UseRegister(instr->value());
LOperand* val = UseRegister(instr->value());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LOperand* external_pointer = UseRegister(instr->elements());
......
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