Reviewers: Toon Verwaest,
Message:
PTAL.
Description:
Specially handle the key of the LoadKeyed and StoreKeyed instruction for x32
port.
Please review this at https://codereview.chromium.org/324913002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+88, -3 lines):
M src/x64/lithium-codegen-x64.h
M src/x64/lithium-codegen-x64.cc
M src/x64/lithium-x64.h
M src/x64/lithium-x64.cc
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index
75ba04e48170f0ed94975dc180d28f5cd9625ae3..41f16bc2830aa5b39d1bf8697011ab7905d0d33e
100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -264,6 +264,37 @@ void
LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
if (!instr->IsLazyBailout() && !instr->IsGap()) {
safepoints_.BumpLastLazySafepointIndex();
}
+ if (kPointerSize == kInt32Size) {
+ if (instr->IsLoadKeyed() || instr->IsStoreKeyed()) {
+ ElementsKind elements_kind = INT8_ELEMENTS; // Bogus initialization.
+ LOperand* key = NULL;
+ Representation key_representation = Representation::None();
+ bool is_dehoisted = false;
+ if (instr->IsLoadKeyed()) {
+ LLoadKeyed* load = LLoadKeyed::cast(instr);
+ elements_kind = load->elements_kind();
+ key = load->key();
+ key_representation = load->hydrogen()->key()->representation();
+ is_dehoisted = load->hydrogen()->IsDehoisted();
+ } else {
+ LStoreKeyed* store = LStoreKeyed::cast(instr);
+ elements_kind = store->elements_kind();
+ key = store->key();
+ key_representation = store->hydrogen()->key()->representation();
+ is_dehoisted = store->hydrogen()->IsDehoisted();
+ }
+ if (!key->IsConstantOperand()) {
+ Register key_reg = ToRegister(key);
+ if (KeyedLoadOrStoreRequiresTemp(key_representation,
elements_kind)) {
+ __ SmiToInteger64(key_reg, key_reg);
+ } else if (is_dehoisted) {
+ // 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);
+ }
+ }
+ }
+ }
}
@@ -3037,6 +3068,7 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed*
instr) {
Operand operand(BuildFastArrayOperand(
instr->elements(),
key,
+ instr->hydrogen()->key()->representation(),
elements_kind,
instr->base_offset()));
@@ -3107,6 +3139,7 @@ void
LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
Operand hole_check_operand = BuildFastArrayOperand(
instr->elements(),
key,
+ instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS,
instr->base_offset() + sizeof(kHoleNanLower32));
__ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
@@ -3116,6 +3149,7 @@ void
LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
Operand double_load_operand = BuildFastArrayOperand(
instr->elements(),
key,
+ instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS,
instr->base_offset());
__ movsd(result, double_load_operand);
@@ -3138,6 +3172,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed*
instr) {
__ Load(scratch,
BuildFastArrayOperand(instr->elements(),
key,
+
instr->hydrogen()->key()->representation(),
FAST_ELEMENTS,
offset),
Representation::Smi());
@@ -3152,6 +3187,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed*
instr) {
__ Load(result,
BuildFastArrayOperand(instr->elements(),
key,
+ instr->hydrogen()->key()->representation(),
FAST_ELEMENTS,
offset),
representation);
@@ -3183,6 +3219,7 @@ void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
Operand LCodeGen::BuildFastArrayOperand(
LOperand* elements_pointer,
LOperand* key,
+ Representation key_representation,
ElementsKind elements_kind,
uint32_t offset) {
Register elements_pointer_reg = ToRegister(elements_pointer);
@@ -3195,6 +3232,11 @@ Operand LCodeGen::BuildFastArrayOperand(
return Operand(elements_pointer_reg,
(constant_value << shift_size) + offset);
} 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);
return Operand(elements_pointer_reg,
ToRegister(key),
@@ -4171,6 +4213,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed*
instr) {
Operand operand(BuildFastArrayOperand(
instr->elements(),
key,
+ instr->hydrogen()->key()->representation(),
elements_kind,
instr->base_offset()));
@@ -4243,6 +4286,7 @@ void
LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
Operand double_store_operand = BuildFastArrayOperand(
instr->elements(),
key,
+ instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS,
instr->base_offset());
@@ -4264,6 +4308,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed*
instr) {
__ Load(scratch,
BuildFastArrayOperand(instr->elements(),
key,
+
instr->hydrogen()->key()->representation(),
FAST_ELEMENTS,
offset),
Representation::Smi());
@@ -4278,6 +4323,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed*
instr) {
Operand operand =
BuildFastArrayOperand(instr->elements(),
key,
+ instr->hydrogen()->key()->representation(),
FAST_ELEMENTS,
offset);
if (instr->value()->IsRegister()) {
Index: src/x64/lithium-codegen-x64.h
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index
712c974ef803cfa8c93b557e2d4ddcb4c39030dd..51b76457e753a785a4fba571377bed2eecc00d60
100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -231,6 +231,7 @@ class LCodeGen: public LCodeGenBase {
Operand BuildFastArrayOperand(
LOperand* elements_pointer,
LOperand* key,
+ Representation key_representation,
ElementsKind elements_kind,
uint32_t base_offset);
Index: src/x64/lithium-x64.cc
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index
bb2ecc06b8e4e374e838cf2847f08221ed9f8faa..708f98bbebe26fa4b2360088edd0d79b40d57ebc
100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -2121,11 +2121,24 @@ void
LChunkBuilder::FindDehoistedKeyDefinitions(HValue* candidate) {
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();
- LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+ LOperand* key = NULL;
LInstruction* result = NULL;
+ if (kPointerSize == kInt64Size) {
+ key = UseRegisterOrConstantAtStart(instr->key());
+ } else {
+ bool clobbers_key = KeyedLoadOrStoreRequiresTemp(
+ instr->key()->representation(), elements_kind);
+ key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstantAtStart(instr->key());
+ }
+
if (instr->IsDehoisted()) {
FindDehoistedKeyDefinitions(instr->key());
}
@@ -2219,7 +2232,16 @@ LInstruction*
LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
elements_kind == FLOAT32_ELEMENTS;
LOperand* val = val_is_temp_register ? UseTempRegister(instr->value())
: UseRegister(instr->value());
- LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+ LOperand* key = NULL;
+ if (kPointerSize == kInt64Size) {
+ key = UseRegisterOrConstantAtStart(instr->key());
+ } else {
+ bool clobbers_key = KeyedLoadOrStoreRequiresTemp(
+ instr->key()->representation(), elements_kind);
+ key = clobbers_key
+ ? UseTempRegister(instr->key())
+ : UseRegisterOrConstantAtStart(instr->key());
+ }
LOperand* backing_store = UseRegister(instr->elements());
return new(zone()) LStoreKeyed(backing_store, key, val);
}
Index: src/x64/lithium-x64.h
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index
429d47406beee6ed0c27f71fda590c8859eb0a9c..15e59284ea88aeabf3cf4461118b669ca4ea960a
100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -1608,6 +1608,22 @@ class LLoadRoot V8_FINAL : public
LTemplateInstruction<1, 0, 0> {
};
+inline static bool KeyedLoadOrStoreRequiresTemp(
+ 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> {
public:
LLoadKeyed(LOperand* elements, LOperand* key) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.