From 137833248ae3e52f0ce913af51fb18431f55e06c Mon Sep 17 00:00:00 2001 From: "Jacob.Bramley@arm.com" Date: Tue, 22 Apr 2014 15:57:04 +0000 Subject: [PATCH] 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 --- src/arm64/lithium-arm64.cc | 8 +++-- src/arm64/lithium-codegen-arm64.cc | 67 +++++++++++++------------------------- 2 files changed, 28 insertions(+), 47 deletions(-) diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 68f839f..812fe12 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -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); } } diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index f8f06cf..969af2b 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -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()); -- 2.7.4