13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#if defined(V8_TARGET_ARCH_ARM)
31f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#include "codegen.h"
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "macro-assembler.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define __ ACCESS_MASM(masm)
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochUnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  switch (type) {
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case TranscendentalCache::SIN: return &sin;
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case TranscendentalCache::COS: return &cos;
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case TranscendentalCache::TAN: return &tan;
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case TranscendentalCache::LOG: return &log;
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    default: UNIMPLEMENTED();
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return NULL;
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochUnaryMathFunction CreateSqrtFunction() {
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return &sqrt;
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// -------------------------------------------------------------------------
577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Platform-specific RuntimeCallHelper functions.
587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  masm->EnterFrame(StackFrame::INTERNAL);
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!masm->has_frame());
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  masm->set_has_frame(true);
637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  masm->LeaveFrame(StackFrame::INTERNAL);
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(masm->has_frame());
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  masm->set_has_frame(false);
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// -------------------------------------------------------------------------
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Code generators
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid ElementsTransitionGenerator::GenerateSmiOnlyToObject(
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MacroAssembler* masm) {
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ----------- S t a t e -------------
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r0    : value
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r1    : key
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r2    : receiver
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- lr    : return address
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r3    : target map, scratch for subsequent call
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r4    : scratch (elements)
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // -----------------------------------
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set transitioned map.
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ RecordWriteField(r2,
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      HeapObject::kMapOffset,
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r3,
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r9,
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kLRHasNotBeenSaved,
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kDontSaveFPRegs,
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      EMIT_REMEMBERED_SET,
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_SMI_CHECK);
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MacroAssembler* masm, Label* fail) {
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ----------- S t a t e -------------
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r0    : value
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r1    : key
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r2    : receiver
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- lr    : return address
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r3    : target map, scratch for subsequent call
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r4    : scratch (elements)
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // -----------------------------------
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label loop, entry, convert_hole, gc_required, only_change_map, done;
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool vfp3_supported = CpuFeatures::IsSupported(VFP3);
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check for empty arrays, which only require a map transition and no changes
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // to the backing store.
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset));
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ CompareRoot(r4, Heap::kEmptyFixedArrayRootIndex);
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(eq, &only_change_map);
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ push(lr);
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset));
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r4: source FixedArray
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r5: number of elements (smi-tagged)
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Allocate new FixedDoubleArray.
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(lr, Operand(FixedDoubleArray::kHeaderSize));
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(lr, lr, Operand(r5, LSL, 2));
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r6: destination FixedDoubleArray, not tagged as heap object
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set destination FixedDoubleArray's length and map.
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex);
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset));
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r9, MemOperand(r6, HeapObject::kMapOffset));
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Update receiver's map.
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ RecordWriteField(r2,
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      HeapObject::kMapOffset,
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r3,
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r9,
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kLRHasBeenSaved,
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kDontSaveFPRegs,
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_REMEMBERED_SET,
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_SMI_CHECK);
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Replace receiver's backing store with newly created FixedDoubleArray.
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r3, r6, Operand(kHeapObjectTag));
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r3, FieldMemOperand(r2, JSObject::kElementsOffset));
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ RecordWriteField(r2,
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      JSObject::kElementsOffset,
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r3,
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r9,
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kLRHasBeenSaved,
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kDontSaveFPRegs,
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      EMIT_REMEMBERED_SET,
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_SMI_CHECK);
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Prepare for conversion loop.
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r7, r6, Operand(FixedDoubleArray::kHeaderSize));
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r6, r7, Operand(r5, LSL, 2));
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r4, Operand(kHoleNanLower32));
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r5, Operand(kHoleNanUpper32));
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r3: begin of source FixedArray element fields, not tagged
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r4: kHoleNanLower32
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r5: kHoleNanUpper32
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r6: end of destination FixedDoubleArray, not tagged
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r7: begin of FixedDoubleArray element fields, not tagged
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!vfp3_supported) __ Push(r1, r0);
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(&entry);
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&only_change_map);
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ RecordWriteField(r2,
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      HeapObject::kMapOffset,
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r3,
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r9,
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kLRHasBeenSaved,
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kDontSaveFPRegs,
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_REMEMBERED_SET,
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_SMI_CHECK);
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(&done);
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Call into runtime if GC is required.
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&gc_required);
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ pop(lr);
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(fail);
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Convert and copy elements.
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&loop);
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r9, MemOperand(r3, 4, PostIndex));
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r9: current element
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ UntagAndJumpIfNotSmi(r9, r9, &convert_hole);
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Normal smi, convert to double and store.
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (vfp3_supported) {
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CpuFeatures::Scope scope(VFP3);
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ vmov(s0, r9);
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ vcvt_f64_s32(d0, s0);
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ vstr(d0, r7, 0);
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ add(r7, r7, Operand(8));
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FloatingPointHelper::ConvertIntToDouble(masm,
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            r9,
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            FloatingPointHelper::kCoreRegisters,
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            d0,
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            r0,
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            r1,
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            lr,
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            s0);
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ Strd(r0, r1, MemOperand(r7, 8, PostIndex));
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(&entry);
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Hole found, store the-hole NaN.
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&convert_hole);
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_debug_code) {
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Restore a "smi-untagged" heap object.
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ SmiTag(r9);
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ orr(r9, r9, Operand(1));
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ CompareRoot(r9, Heap::kTheHoleValueRootIndex);
2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ Assert(eq, "object found in smi-only array");
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Strd(r4, r5, MemOperand(r7, 8, PostIndex));
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&entry);
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ cmp(r7, r6);
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(lt, &loop);
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!vfp3_supported) __ Pop(r1, r0);
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ pop(lr);
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&done);
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid ElementsTransitionGenerator::GenerateDoubleToObject(
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MacroAssembler* masm, Label* fail) {
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ----------- S t a t e -------------
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r0    : value
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r1    : key
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r2    : receiver
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- lr    : return address
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r3    : target map, scratch for subsequent call
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- r4    : scratch (elements)
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // -----------------------------------
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label entry, loop, convert_hole, gc_required, only_change_map;
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check for empty arrays, which only require a map transition and no changes
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // to the backing store.
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset));
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ CompareRoot(r4, Heap::kEmptyFixedArrayRootIndex);
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(eq, &only_change_map);
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ push(lr);
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Push(r3, r2, r1, r0);
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset));
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r4: source FixedDoubleArray
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r5: number of elements (smi-tagged)
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Allocate new FixedArray.
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r0, Operand(FixedDoubleArray::kHeaderSize));
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r0, r0, Operand(r5, LSL, 1));
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r6: destination FixedArray, not tagged as heap object
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set destination FixedDoubleArray's length and map.
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex);
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r5, MemOperand(r6, FixedDoubleArray::kLengthOffset));
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r9, MemOperand(r6, HeapObject::kMapOffset));
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Prepare for conversion loop.
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r4, r4, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r3, r6, Operand(FixedArray::kHeaderSize));
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r6, r6, Operand(kHeapObjectTag));
2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(r5, r3, Operand(r5, LSL, 1));
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ LoadRoot(r7, Heap::kTheHoleValueRootIndex);
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ LoadRoot(r9, Heap::kHeapNumberMapRootIndex);
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Using offsetted addresses in r4 to fully take advantage of post-indexing.
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r3: begin of destination FixedArray element fields, not tagged
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r4: begin of source FixedDoubleArray element fields, not tagged, +4
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r5: end of destination FixedArray, not tagged
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r6: destination FixedArray
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r7: the-hole pointer
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r9: heap number map
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(&entry);
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Call into runtime if GC is required.
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&gc_required);
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Pop(r3, r2, r1, r0);
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ pop(lr);
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(fail);
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&loop);
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r1, MemOperand(r4, 8, PostIndex));
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // lr: current element's upper 32 bit
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r4: address of next element's upper 32 bit
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ cmp(r1, Operand(kHoleNanUpper32));
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(eq, &convert_hole);
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Non-hole double, copy value into a heap number.
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ AllocateHeapNumber(r2, r0, lr, r9, &gc_required);
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // r2: new heap number
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r0, MemOperand(r4, 12, NegOffset));
3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Strd(r0, r1, FieldMemOperand(r2, HeapNumber::kValueOffset));
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r0, r3);
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r2, MemOperand(r3, 4, PostIndex));
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ RecordWrite(r6,
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 r0,
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 r2,
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 kLRHasBeenSaved,
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 kDontSaveFPRegs,
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 EMIT_REMEMBERED_SET,
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 OMIT_SMI_CHECK);
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(&entry);
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Replace the-hole NaN with the-hole pointer.
3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&convert_hole);
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r7, MemOperand(r3, 4, PostIndex));
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&entry);
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ cmp(r3, r5);
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(lt, &loop);
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Pop(r3, r2, r1, r0);
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Replace receiver's backing store with newly created and filled FixedArray.
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r6, FieldMemOperand(r2, JSObject::kElementsOffset));
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ RecordWriteField(r2,
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      JSObject::kElementsOffset,
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r6,
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r9,
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kLRHasBeenSaved,
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kDontSaveFPRegs,
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      EMIT_REMEMBERED_SET,
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_SMI_CHECK);
3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ pop(lr);
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&only_change_map);
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Update receiver's map.
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ RecordWriteField(r2,
3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      HeapObject::kMapOffset,
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r3,
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      r9,
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kLRHasNotBeenSaved,
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      kDontSaveFPRegs,
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_REMEMBERED_SET,
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      OMIT_SMI_CHECK);
3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StringCharLoadGenerator::Generate(MacroAssembler* masm,
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Register string,
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Register index,
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Register result,
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Label* call_runtime) {
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Fetch the instance type of the receiver into result register.
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset));
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // We need special handling for indirect strings.
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label check_sequential;
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ tst(result, Operand(kIsIndirectStringMask));
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(eq, &check_sequential);
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Dispatch on the indirect string shape: slice or cons.
3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label cons_string;
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ tst(result, Operand(kSlicedNotConsMask));
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(eq, &cons_string);
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Handle slices.
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label indirect_string_loaded;
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(string, FieldMemOperand(string, SlicedString::kParentOffset));
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(index, index, Operand(result, ASR, kSmiTagSize));
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ jmp(&indirect_string_loaded);
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Handle cons strings.
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check whether the right hand side is the empty string (i.e. if
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // this is really a flat string in a cons string). If that is not
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the case we would rather go to the runtime system now to flatten
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the string.
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&cons_string);
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset));
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ CompareRoot(result, Heap::kEmptyStringRootIndex);
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(ne, call_runtime);
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Get the first of the two strings and load its instance type.
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset));
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&indirect_string_loaded);
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset));
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Distinguish sequential and external strings. Only these two string
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // representations can reach here (slices and flat cons strings have been
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // reduced to the underlying sequential or external string).
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label external_string, check_encoding;
3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&check_sequential);
3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATIC_ASSERT(kSeqStringTag == 0);
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ tst(result, Operand(kStringRepresentationMask));
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(ne, &external_string);
3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Prepare sequential strings
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ add(string,
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         string,
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ jmp(&check_encoding);
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Handle external strings.
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&external_string);
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_debug_code) {
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Assert that we do not have a cons or slice (indirect strings) here.
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Sequential strings have already been ruled out.
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ tst(result, Operand(kIsIndirectStringMask));
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ Assert(eq, "external string expected, but not found");
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Rule out short external strings.
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATIC_CHECK(kShortExternalStringTag != 0);
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ tst(result, Operand(kShortExternalStringMask));
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(ne, call_runtime);
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(string, FieldMemOperand(string, ExternalString::kResourceDataOffset));
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label ascii, done;
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&check_encoding);
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATIC_ASSERT(kTwoByteStringTag == 0);
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ tst(result, Operand(kStringEncodingMask));
4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ b(ne, &ascii);
4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Two-byte string.
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldrh(result, MemOperand(string, index, LSL, 1));
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ jmp(&done);
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&ascii);
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Ascii string.
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldrb(result, MemOperand(string, index));
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ bind(&done);
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef __
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
437f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
438f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif  // V8_TARGET_ARCH_ARM
439