Commit 13783324 authored by Jacob.Bramley@arm.com's avatar Jacob.Bramley@arm.com

ARM64: Move sign-extension to load instructions.

The SXTW extend mode is usually free when used in a load or store
operand, but it can slightly increase the latency of an arithmetic
instruction. This patch optimises some address calculations accordingly:
  - PrepareKeyedExternalArrayOperand.
  - BuildSeqStringOperand.
  - DoStringCharFromCode.

BUG=
R=ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20891 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5600046f
......@@ -1666,9 +1666,10 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsSmiOrInteger32());
ElementsKind elements_kind = instr->elements_kind();
LOperand* elements = UseRegister(instr->elements());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
if (!instr->is_typed_elements()) {
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
if (instr->representation().IsDouble()) {
LOperand* temp = (!instr->key()->IsConstant() ||
instr->RequiresHoleCheck())
......@@ -1696,6 +1697,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
(instr->representation().IsDouble() &&
IsDoubleOrFloatElementsKind(instr->elements_kind())));
LOperand* key = UseRegisterOrConstant(instr->key());
LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister();
LInstruction* result = DefineAsRegister(
new(zone()) LLoadKeyedExternal(elements, key, temp));
......@@ -2188,7 +2190,6 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
LOperand* temp = NULL;
LOperand* elements = NULL;
LOperand* val = NULL;
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
if (!instr->is_typed_elements() &&
instr->value()->representation().IsTagged() &&
......@@ -2212,16 +2213,19 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
instr->elements()->representation().IsTagged()) ||
(instr->is_external() &&
instr->elements()->representation().IsExternal()));
LOperand* key = UseRegisterOrConstant(instr->key());
return new(zone()) LStoreKeyedExternal(elements, key, val, temp);
} else if (instr->value()->representation().IsDouble()) {
ASSERT(instr->elements()->representation().IsTagged());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp);
} else {
ASSERT(instr->elements()->representation().IsTagged());
ASSERT(instr->value()->representation().IsSmiOrTagged() ||
instr->value()->representation().IsInteger32());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyedFixed(elements, key, val, temp);
}
}
......
......@@ -3333,51 +3333,28 @@ MemOperand LCodeGen::PrepareKeyedExternalArrayOperand(
ElementsKind elements_kind,
int additional_index) {
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
: 0;
int additional_offset = additional_index << element_size_shift;
if (IsFixedTypedArrayElementsKind(elements_kind)) {
additional_offset += FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
}
if (key_is_constant) {
int base_offset = ((constant_key + additional_index) << element_size_shift);
return MemOperand(base, base_offset + additional_offset);
int key_offset = constant_key << element_size_shift;
return MemOperand(base, key_offset + additional_offset);
}
if (additional_index == 0) {
if (key_is_smi) {
// Key is smi: untag, and scale by element size.
__ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift));
return MemOperand(scratch, additional_offset);
} else {
// Key is not smi, and element size is not byte: scale by element size.
if (additional_offset == 0) {
return MemOperand(base, key, SXTW, element_size_shift);
} else {
__ Add(scratch, base, Operand(key, SXTW, element_size_shift));
return MemOperand(scratch, additional_offset);
}
}
} else {
// TODO(all): Try to combine these cases a bit more intelligently.
if (additional_offset == 0) {
if (key_is_smi) {
__ SmiUntag(scratch, key);
__ Add(scratch.W(), scratch.W(), additional_index);
} else {
__ Add(scratch.W(), key.W(), additional_index);
}
return MemOperand(base, scratch, LSL, element_size_shift);
} else {
if (key_is_smi) {
__ Add(scratch, base,
Operand::UntagSmiAndScale(key, element_size_shift));
} else {
__ Add(scratch, base, Operand(key, SXTW, element_size_shift));
}
return MemOperand(
scratch,
(additional_index << element_size_shift) + additional_offset);
}
if (key_is_smi) {
__ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift));
return MemOperand(scratch, additional_offset);
}
if (additional_offset == 0) {
return MemOperand(base, key, SXTW, element_size_shift);
}
ASSERT(!AreAliased(scratch, key));
__ Add(scratch, base, additional_offset);
return MemOperand(scratch, key, SXTW, element_size_shift);
}
......@@ -4673,13 +4650,13 @@ MemOperand LCodeGen::BuildSeqStringOperand(Register string,
return FieldMemOperand(string, SeqString::kHeaderSize + offset);
}
__ Add(temp, string, SeqString::kHeaderSize - kHeapObjectTag);
if (encoding == String::ONE_BYTE_ENCODING) {
__ Add(temp, string, Operand(ToRegister32(index), SXTW));
return MemOperand(temp, ToRegister32(index), SXTW);
} else {
STATIC_ASSERT(kUC16Size == 2);
__ Add(temp, string, Operand(ToRegister32(index), SXTW, 1));
return MemOperand(temp, ToRegister32(index), SXTW, 1);
}
return FieldMemOperand(temp, SeqString::kHeaderSize);
}
......@@ -5410,8 +5387,8 @@ void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
__ Cmp(char_code, String::kMaxOneByteCharCode);
__ B(hi, deferred->entry());
__ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
__ Add(result, result, Operand(char_code, SXTW, kPointerSizeLog2));
__ Ldr(result, FieldMemOperand(result, FixedArray::kHeaderSize));
__ Add(result, result, FixedArray::kHeaderSize - kHeapObjectTag);
__ Ldr(result, MemOperand(result, char_code, SXTW, kPointerSizeLog2));
__ CompareRoot(result, Heap::kUndefinedValueRootIndex);
__ B(eq, deferred->entry());
__ Bind(deferred->exit());
......
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