Commit 28e74e13 authored by haitao.feng@intel.com's avatar haitao.feng@intel.com

Specially handle the key of the LoadKeyed and StoreKeyed instruction for x32 port.

R=verwaest@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21826 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1eac6114
...@@ -3042,9 +3042,22 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { ...@@ -3042,9 +3042,22 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
LOperand* key = instr->key(); LOperand* key = instr->key();
if (kPointerSize == kInt32Size && !key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
Representation key_representation =
instr->hydrogen()->key()->representation();
if (ExternalArrayOpRequiresTemp(key_representation, elements_kind)) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
__ movsxlq(key_reg, key_reg);
}
}
Operand operand(BuildFastArrayOperand( Operand operand(BuildFastArrayOperand(
instr->elements(), instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
elements_kind, elements_kind,
instr->base_offset())); instr->base_offset()));
...@@ -3111,10 +3124,17 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { ...@@ -3111,10 +3124,17 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
XMMRegister result(ToDoubleRegister(instr->result())); XMMRegister result(ToDoubleRegister(instr->result()));
LOperand* key = instr->key(); LOperand* key = instr->key();
if (kPointerSize == kInt32Size && !key->IsConstantOperand() &&
instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
__ movsxlq(ToRegister(key), ToRegister(key));
}
if (instr->hydrogen()->RequiresHoleCheck()) { if (instr->hydrogen()->RequiresHoleCheck()) {
Operand hole_check_operand = BuildFastArrayOperand( Operand hole_check_operand = BuildFastArrayOperand(
instr->elements(), instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS, FAST_DOUBLE_ELEMENTS,
instr->base_offset() + sizeof(kHoleNanLower32)); instr->base_offset() + sizeof(kHoleNanLower32));
__ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
...@@ -3124,6 +3144,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { ...@@ -3124,6 +3144,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
Operand double_load_operand = BuildFastArrayOperand( Operand double_load_operand = BuildFastArrayOperand(
instr->elements(), instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS, FAST_DOUBLE_ELEMENTS,
instr->base_offset()); instr->base_offset());
__ movsd(result, double_load_operand); __ movsd(result, double_load_operand);
...@@ -3138,6 +3159,12 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { ...@@ -3138,6 +3159,12 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
Representation representation = hinstr->representation(); Representation representation = hinstr->representation();
int offset = instr->base_offset(); int offset = instr->base_offset();
if (kPointerSize == kInt32Size && !key->IsConstantOperand() &&
instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
__ movsxlq(ToRegister(key), ToRegister(key));
}
if (representation.IsInteger32() && SmiValuesAre32Bits() && if (representation.IsInteger32() && SmiValuesAre32Bits() &&
hinstr->elements_kind() == FAST_SMI_ELEMENTS) { hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
ASSERT(!requires_hole_check); ASSERT(!requires_hole_check);
...@@ -3146,6 +3173,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { ...@@ -3146,6 +3173,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
__ Load(scratch, __ Load(scratch,
BuildFastArrayOperand(instr->elements(), BuildFastArrayOperand(instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
FAST_ELEMENTS, FAST_ELEMENTS,
offset), offset),
Representation::Smi()); Representation::Smi());
...@@ -3160,6 +3188,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { ...@@ -3160,6 +3188,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
__ Load(result, __ Load(result,
BuildFastArrayOperand(instr->elements(), BuildFastArrayOperand(instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
FAST_ELEMENTS, FAST_ELEMENTS,
offset), offset),
representation); representation);
...@@ -3191,6 +3220,7 @@ void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { ...@@ -3191,6 +3220,7 @@ void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
Operand LCodeGen::BuildFastArrayOperand( Operand LCodeGen::BuildFastArrayOperand(
LOperand* elements_pointer, LOperand* elements_pointer,
LOperand* key, LOperand* key,
Representation key_representation,
ElementsKind elements_kind, ElementsKind elements_kind,
uint32_t offset) { uint32_t offset) {
Register elements_pointer_reg = ToRegister(elements_pointer); Register elements_pointer_reg = ToRegister(elements_pointer);
...@@ -3203,6 +3233,11 @@ Operand LCodeGen::BuildFastArrayOperand( ...@@ -3203,6 +3233,11 @@ Operand LCodeGen::BuildFastArrayOperand(
return Operand(elements_pointer_reg, return Operand(elements_pointer_reg,
(constant_value << shift_size) + offset); (constant_value << shift_size) + offset);
} else { } else {
// Take the tag bit into account while computing the shift size.
if (key_representation.IsSmi() && (shift_size >= 1)) {
ASSERT(SmiValuesAre31Bits());
shift_size -= kSmiTagSize;
}
ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
return Operand(elements_pointer_reg, return Operand(elements_pointer_reg,
ToRegister(key), ToRegister(key),
...@@ -4176,9 +4211,22 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { ...@@ -4176,9 +4211,22 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
LOperand* key = instr->key(); LOperand* key = instr->key();
if (kPointerSize == kInt32Size && !key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
Representation key_representation =
instr->hydrogen()->key()->representation();
if (ExternalArrayOpRequiresTemp(key_representation, elements_kind)) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
__ movsxlq(key_reg, key_reg);
}
}
Operand operand(BuildFastArrayOperand( Operand operand(BuildFastArrayOperand(
instr->elements(), instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
elements_kind, elements_kind,
instr->base_offset())); instr->base_offset()));
...@@ -4235,6 +4283,12 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { ...@@ -4235,6 +4283,12 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
XMMRegister value = ToDoubleRegister(instr->value()); XMMRegister value = ToDoubleRegister(instr->value());
LOperand* key = instr->key(); LOperand* key = instr->key();
if (kPointerSize == kInt32Size && !key->IsConstantOperand() &&
instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
__ movsxlq(ToRegister(key), ToRegister(key));
}
if (instr->NeedsCanonicalization()) { if (instr->NeedsCanonicalization()) {
Label have_value; Label have_value;
...@@ -4251,6 +4305,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { ...@@ -4251,6 +4305,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
Operand double_store_operand = BuildFastArrayOperand( Operand double_store_operand = BuildFastArrayOperand(
instr->elements(), instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS, FAST_DOUBLE_ELEMENTS,
instr->base_offset()); instr->base_offset());
...@@ -4264,6 +4319,12 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { ...@@ -4264,6 +4319,12 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
int offset = instr->base_offset(); int offset = instr->base_offset();
Representation representation = hinstr->value()->representation(); Representation representation = hinstr->value()->representation();
if (kPointerSize == kInt32Size && !key->IsConstantOperand() &&
instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
__ movsxlq(ToRegister(key), ToRegister(key));
}
if (representation.IsInteger32() && SmiValuesAre32Bits()) { if (representation.IsInteger32() && SmiValuesAre32Bits()) {
ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
...@@ -4272,6 +4333,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { ...@@ -4272,6 +4333,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
__ Load(scratch, __ Load(scratch,
BuildFastArrayOperand(instr->elements(), BuildFastArrayOperand(instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
FAST_ELEMENTS, FAST_ELEMENTS,
offset), offset),
Representation::Smi()); Representation::Smi());
...@@ -4286,6 +4348,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { ...@@ -4286,6 +4348,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
Operand operand = Operand operand =
BuildFastArrayOperand(instr->elements(), BuildFastArrayOperand(instr->elements(),
key, key,
instr->hydrogen()->key()->representation(),
FAST_ELEMENTS, FAST_ELEMENTS,
offset); offset);
if (instr->value()->IsRegister()) { if (instr->value()->IsRegister()) {
......
...@@ -231,6 +231,7 @@ class LCodeGen: public LCodeGenBase { ...@@ -231,6 +231,7 @@ class LCodeGen: public LCodeGenBase {
Operand BuildFastArrayOperand( Operand BuildFastArrayOperand(
LOperand* elements_pointer, LOperand* elements_pointer,
LOperand* key, LOperand* key,
Representation key_representation,
ElementsKind elements_kind, ElementsKind elements_kind,
uint32_t base_offset); uint32_t base_offset);
......
...@@ -2126,11 +2126,24 @@ void LChunkBuilder::FindDehoistedKeyDefinitions(HValue* candidate) { ...@@ -2126,11 +2126,24 @@ void LChunkBuilder::FindDehoistedKeyDefinitions(HValue* candidate) {
LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsInteger32()); ASSERT((kPointerSize == kInt64Size &&
instr->key()->representation().IsInteger32()) ||
(kPointerSize == kInt32Size &&
instr->key()->representation().IsSmiOrInteger32()));
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* key = NULL;
LInstruction* result = NULL; LInstruction* result = NULL;
if (kPointerSize == kInt64Size) {
key = UseRegisterOrConstantAtStart(instr->key());
} else {
bool clobbers_key = ExternalArrayOpRequiresTemp(
instr->key()->representation(), elements_kind);
key = clobbers_key
? UseTempRegister(instr->key())
: UseRegisterOrConstantAtStart(instr->key());
}
if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) { if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) {
FindDehoistedKeyDefinitions(instr->key()); FindDehoistedKeyDefinitions(instr->key());
} }
...@@ -2224,7 +2237,16 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { ...@@ -2224,7 +2237,16 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
elements_kind == FLOAT32_ELEMENTS; elements_kind == FLOAT32_ELEMENTS;
LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) LOperand* val = val_is_temp_register ? UseTempRegister(instr->value())
: UseRegister(instr->value()); : UseRegister(instr->value());
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* key = NULL;
if (kPointerSize == kInt64Size) {
key = UseRegisterOrConstantAtStart(instr->key());
} else {
bool clobbers_key = ExternalArrayOpRequiresTemp(
instr->key()->representation(), elements_kind);
key = clobbers_key
? UseTempRegister(instr->key())
: UseRegisterOrConstantAtStart(instr->key());
}
LOperand* backing_store = UseRegister(instr->elements()); LOperand* backing_store = UseRegister(instr->elements());
return new(zone()) LStoreKeyed(backing_store, key, val); return new(zone()) LStoreKeyed(backing_store, key, val);
} }
......
...@@ -1608,6 +1608,22 @@ class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> { ...@@ -1608,6 +1608,22 @@ class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> {
}; };
inline static bool ExternalArrayOpRequiresTemp(
Representation key_representation,
ElementsKind elements_kind) {
// Operations that require the key to be divided by two to be converted into
// an index cannot fold the scale operation into a load and need an extra
// temp register to do the work.
return SmiValuesAre31Bits() && key_representation.IsSmi() &&
(elements_kind == EXTERNAL_INT8_ELEMENTS ||
elements_kind == EXTERNAL_UINT8_ELEMENTS ||
elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
elements_kind == UINT8_ELEMENTS ||
elements_kind == INT8_ELEMENTS ||
elements_kind == UINT8_CLAMPED_ELEMENTS);
}
class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> { class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public: public:
LLoadKeyed(LOperand* elements, LOperand* key) { LLoadKeyed(LOperand* elements, LOperand* key) {
......
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