165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/heap.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h" 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1630ce411529579186181838984710b0b0980857aaricow@chromium.org 1730ce411529579186181838984710b0b0980857aaricow@chromium.org// ------------------------------------------------------------------------- 1830ce411529579186181838984710b0b0980857aaricow@chromium.org// Platform-specific RuntimeCallHelper functions. 1930ce411529579186181838984710b0b0980857aaricow@chromium.org 20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { 21c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->EnterFrame(StackFrame::INTERNAL); 22e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!masm->has_frame()); 23c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->set_has_frame(true); 2430ce411529579186181838984710b0b0980857aaricow@chromium.org} 2530ce411529579186181838984710b0b0980857aaricow@chromium.org 2630ce411529579186181838984710b0b0980857aaricow@chromium.org 27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { 28c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->LeaveFrame(StackFrame::INTERNAL); 29e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(masm->has_frame()); 30c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->set_has_frame(false); 3130ce411529579186181838984710b0b0980857aaricow@chromium.org} 3230ce411529579186181838984710b0b0980857aaricow@chromium.org 3330ce411529579186181838984710b0b0980857aaricow@chromium.org 341af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#define __ masm. 351af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 369a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 371f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgUnaryMathFunction CreateExpFunction() { 38e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (!FLAG_fast_math) return &std::exp; 391f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org size_t actual_size; 405de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = 415de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); 42e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (buffer == NULL) return &std::exp; 431f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org ExternalReference::InitializeMathExpData(); 441f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org // esp[1 * kPointerSize]: raw double input 471f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org // esp[0 * kPointerSize]: return address 481f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org { 491f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister input = xmm1; 501f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister result = xmm2; 510fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(input, Operand(esp, 1 * kPointerSize)); 521f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ push(eax); 531f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ push(ebx); 541f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 551f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org MathExpGenerator::EmitMathExp(&masm, input, result, xmm0, eax, ebx); 561f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 571f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ pop(ebx); 581f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ pop(eax); 590fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(Operand(esp, 1 * kPointerSize), result); 601f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ fld_d(Operand(esp, 1 * kPointerSize)); 611f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ Ret(); 621f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org } 631f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 641f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org CodeDesc desc; 651f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org masm.GetCode(&desc); 66e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!RelocInfo::RequiresRelocation(desc)); 671f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 685de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(buffer, actual_size); 695de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::ProtectCode(buffer, actual_size); 701f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org return FUNCTION_CAST<UnaryMathFunction>(buffer); 711f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 721f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 731f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 74154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUnaryMathFunction CreateSqrtFunction() { 75154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org size_t actual_size; 76154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // Allocate buffer in executable space. 775de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = 785de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); 793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (buffer == NULL) return &std::sqrt; 80154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 81154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // esp[1 * kPointerSize]: raw double input 82154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // esp[0 * kPointerSize]: return address 83154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // Move double input into registers. 84154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org { 850fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(xmm0, Operand(esp, 1 * kPointerSize)); 86154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ sqrtsd(xmm0, xmm0); 870fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(Operand(esp, 1 * kPointerSize), xmm0); 88154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // Load result into floating point register as return value. 89154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ fld_d(Operand(esp, 1 * kPointerSize)); 90154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ Ret(); 91154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } 92154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 93154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org CodeDesc desc; 94154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org masm.GetCode(&desc); 95e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!RelocInfo::RequiresRelocation(desc)); 96154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 975de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(buffer, actual_size); 985de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::ProtectCode(buffer, actual_size); 99154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org return FUNCTION_CAST<UnaryMathFunction>(buffer); 1009a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org} 1019a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 1029a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 103e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Helper functions for CreateMemMoveFunction. 104e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#undef __ 105e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#define __ ACCESS_MASM(masm) 106e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 107e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgenum Direction { FORWARD, BACKWARD }; 108e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgenum Alignment { MOVE_ALIGNED, MOVE_UNALIGNED }; 109e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 110e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Expects registers: 111e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// esi - source, aligned if alignment == ALIGNED 112e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// edi - destination, always aligned 113e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// ecx - count (copy size in bytes) 114e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// edx - loop count (number of 64 byte chunks) 115e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid MemMoveEmitMainLoop(MacroAssembler* masm, 116e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label* move_last_15, 117e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Direction direction, 118e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Alignment alignment) { 119e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register src = esi; 120e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register dst = edi; 121e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register count = ecx; 122e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register loop_count = edx; 123e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label loop, move_last_31, move_last_63; 124e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(loop_count, 0); 125e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(equal, &move_last_63); 126e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&loop); 127e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Main loop. Copy in 64 byte chunks. 128e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == BACKWARD) __ sub(src, Immediate(0x40)); 129e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0x00)); 130e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdq(alignment == MOVE_ALIGNED, xmm1, Operand(src, 0x10)); 131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdq(alignment == MOVE_ALIGNED, xmm2, Operand(src, 0x20)); 132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdq(alignment == MOVE_ALIGNED, xmm3, Operand(src, 0x30)); 133e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == FORWARD) __ add(src, Immediate(0x40)); 134e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == BACKWARD) __ sub(dst, Immediate(0x40)); 135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdqa(Operand(dst, 0x00), xmm0); 136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdqa(Operand(dst, 0x10), xmm1); 137e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdqa(Operand(dst, 0x20), xmm2); 138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdqa(Operand(dst, 0x30), xmm3); 139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == FORWARD) __ add(dst, Immediate(0x40)); 140e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ dec(loop_count); 141e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_zero, &loop); 142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // At most 63 bytes left to copy. 143e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&move_last_63); 144e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(count, Immediate(0x20)); 145e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(zero, &move_last_31); 146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == BACKWARD) __ sub(src, Immediate(0x20)); 147e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0x00)); 148e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdq(alignment == MOVE_ALIGNED, xmm1, Operand(src, 0x10)); 149e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == FORWARD) __ add(src, Immediate(0x20)); 150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == BACKWARD) __ sub(dst, Immediate(0x20)); 151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdqa(Operand(dst, 0x00), xmm0); 152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdqa(Operand(dst, 0x10), xmm1); 153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == FORWARD) __ add(dst, Immediate(0x20)); 154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // At most 31 bytes left to copy. 155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&move_last_31); 156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(count, Immediate(0x10)); 157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(zero, move_last_15); 158e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == BACKWARD) __ sub(src, Immediate(0x10)); 159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdq(alignment == MOVE_ALIGNED, xmm0, Operand(src, 0)); 160e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == FORWARD) __ add(src, Immediate(0x10)); 161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == BACKWARD) __ sub(dst, Immediate(0x10)); 162e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdqa(Operand(dst, 0), xmm0); 163e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (direction == FORWARD) __ add(dst, Immediate(0x10)); 164e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 165e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 166e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 167e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid MemMoveEmitPopAndReturn(MacroAssembler* masm) { 168e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ pop(esi); 169e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ pop(edi); 170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ ret(0); 171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 174e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#undef __ 175e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#define __ masm. 176e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 177e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 178639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgclass LabelConverter { 179639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org public: 180639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org explicit LabelConverter(byte* buffer) : buffer_(buffer) {} 181639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org int32_t address(Label* l) const { 182639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org return reinterpret_cast<int32_t>(buffer_) + l->pos(); 183639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 184639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org private: 185639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org byte* buffer_; 186639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org}; 187639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 188639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 189d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgMemMoveFunction CreateMemMoveFunction() { 190c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org size_t actual_size; 191c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Allocate buffer in executable space. 1925de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = 1935de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); 194e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (buffer == NULL) return NULL; 195c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 196639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org LabelConverter conv(buffer); 1971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 198e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Generated code is put into a fixed, unmovable buffer, and not into 1991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // the V8 heap. We can't, and don't, refer to any relocatable addresses 2001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // (e.g. the JavaScript nan-object). 2011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 2021af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // 32-bit C declaration function calls pass arguments on stack. 2031af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 2041af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // Stack layout: 2051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // esp[12]: Third argument, size. 2061af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // esp[8]: Second argument, source pointer. 2071af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // esp[4]: First argument, destination pointer. 2081af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // esp[0]: return address 2091af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 2101af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org const int kDestinationOffset = 1 * kPointerSize; 2111af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org const int kSourceOffset = 2 * kPointerSize; 2121af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org const int kSizeOffset = 3 * kPointerSize; 2131af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 214e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // When copying up to this many bytes, use special "small" handlers. 215e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const size_t kSmallCopySize = 8; 216e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // When copying up to this many bytes, use special "medium" handlers. 217e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const size_t kMediumCopySize = 63; 218e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // When non-overlapping region of src and dst is less than this, 219e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // use a more careful implementation (slightly slower). 220e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const size_t kMinMoveDistance = 16; 221e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Note that these values are dictated by the implementation below, 222e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // do not just change them and hope things will work! 223e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 2241af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org int stack_offset = 0; // Update if we change the stack height. 2251af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 226e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label backward, backward_much_overlap; 227e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label forward_much_overlap, small_size, medium_size, pop_and_return; 228e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ push(edi); 229e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ push(esi); 230e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org stack_offset += 2 * kPointerSize; 231e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register dst = edi; 232e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register src = esi; 233e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register count = ecx; 234e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register loop_count = edx; 235e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); 236e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(src, Operand(esp, stack_offset + kSourceOffset)); 237e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(count, Operand(esp, stack_offset + kSizeOffset)); 238e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 239e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(dst, src); 240e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(equal, &pop_and_return); 241e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 2423c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ prefetch(Operand(src, 0), 1); 2433c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(count, kSmallCopySize); 2443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(below_equal, &small_size); 2453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(count, kMediumCopySize); 2463c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(below_equal, &medium_size); 2473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(dst, src); 2483c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(above, &backward); 2493c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 2503c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org { 2513c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // |dst| is a lower address than |src|. Copy front-to-back. 2523c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label unaligned_source, move_last_15, skip_last_move; 2533c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(eax, src); 2543c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(eax, dst); 2553c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(eax, kMinMoveDistance); 2563c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(below, &forward_much_overlap); 2573c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Copy first 16 bytes. 2583c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm0, Operand(src, 0)); 2593c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0), xmm0); 2603c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Determine distance to alignment: 16 - (dst & 0xF). 2613c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(edx, dst); 2623c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ and_(edx, 0xF); 2633c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ neg(edx); 2643c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ add(edx, Immediate(16)); 2653c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ add(dst, edx); 2663c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ add(src, edx); 2673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(count, edx); 2683c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // dst is now aligned. Main copy loop. 2693c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(loop_count, count); 2703c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ shr(loop_count, 6); 2713c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Check if src is also aligned. 2723c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ test(src, Immediate(0xF)); 2733c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(not_zero, &unaligned_source); 2743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Copy loop for aligned source and destination. 2753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, MOVE_ALIGNED); 2763c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // At most 15 bytes to copy. Copy 16 bytes at end of string. 2773c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&move_last_15); 2783c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ and_(count, 0xF); 2793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(zero, &skip_last_move, Label::kNear); 2803c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm0, Operand(src, count, times_1, -0x10)); 2813c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, count, times_1, -0x10), xmm0); 2823c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&skip_last_move); 2833c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 2843c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 2853c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Copy loop for unaligned source and aligned destination. 2863c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&unaligned_source); 2873c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, MOVE_UNALIGNED); 2883c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ jmp(&move_last_15); 2893c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 2903c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Less than kMinMoveDistance offset between dst and src. 2913c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label loop_until_aligned, last_15_much_overlap; 2923c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&loop_until_aligned); 2933c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(eax, Operand(src, 0)); 2943c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ inc(src); 2953c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(Operand(dst, 0), eax); 2963c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ inc(dst); 2973c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dec(count); 2983c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&forward_much_overlap); // Entry point into this block. 2993c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ test(dst, Immediate(0xF)); 3003c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(not_zero, &loop_until_aligned); 3013c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // dst is now aligned, src can't be. Main copy loop. 3023c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(loop_count, count); 3033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ shr(loop_count, 6); 3043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitMainLoop(&masm, &last_15_much_overlap, 3053c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org FORWARD, MOVE_UNALIGNED); 3063c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&last_15_much_overlap); 3073c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ and_(count, 0xF); 3083c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(zero, &pop_and_return); 309e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(count, kSmallCopySize); 310e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(below_equal, &small_size); 3113c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ jmp(&medium_size); 3123c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } 3131af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 3143c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org { 3153c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // |dst| is a higher address than |src|. Copy backwards. 3163c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label unaligned_source, move_first_15, skip_last_move; 3173c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&backward); 3183c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // |dst| and |src| always point to the end of what's left to copy. 3193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ add(dst, count); 3203c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ add(src, count); 3213c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(eax, dst); 3223c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(eax, src); 3233c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(eax, kMinMoveDistance); 3243c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(below, &backward_much_overlap); 3253c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Copy last 16 bytes. 3263c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm0, Operand(src, -0x10)); 3273c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, -0x10), xmm0); 3283c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Find distance to alignment: dst & 0xF 3293c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(edx, dst); 3303c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ and_(edx, 0xF); 3313c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(dst, edx); 3323c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(src, edx); 3333c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(count, edx); 3343c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // dst is now aligned. Main copy loop. 3353c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(loop_count, count); 3363c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ shr(loop_count, 6); 3373c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Check if src is also aligned. 3383c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ test(src, Immediate(0xF)); 3393c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(not_zero, &unaligned_source); 3403c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Copy loop for aligned source and destination. 3413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, MOVE_ALIGNED); 3423c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // At most 15 bytes to copy. Copy 16 bytes at beginning of string. 3433c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&move_first_15); 3443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ and_(count, 0xF); 3453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(zero, &skip_last_move, Label::kNear); 3463c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(src, count); 3473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(dst, count); 3483c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm0, Operand(src, 0)); 3493c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0), xmm0); 3503c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&skip_last_move); 3513c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 3523c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 3533c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Copy loop for unaligned source and aligned destination. 3543c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&unaligned_source); 3553c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, MOVE_UNALIGNED); 3563c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ jmp(&move_first_15); 3573c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 3583c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Less than kMinMoveDistance offset between dst and src. 3593c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label loop_until_aligned, first_15_much_overlap; 3603c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&loop_until_aligned); 3613c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dec(src); 3623c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dec(dst); 3633c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(eax, Operand(src, 0)); 3643c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(Operand(dst, 0), eax); 3653c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dec(count); 3663c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&backward_much_overlap); // Entry point into this block. 3673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ test(dst, Immediate(0xF)); 3683c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(not_zero, &loop_until_aligned); 3693c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // dst is now aligned, src can't be. Main copy loop. 3703c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(loop_count, count); 3713c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ shr(loop_count, 6); 3723c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitMainLoop(&masm, &first_15_much_overlap, 3733c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org BACKWARD, MOVE_UNALIGNED); 3743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&first_15_much_overlap); 3753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ and_(count, 0xF); 3763c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(zero, &pop_and_return); 3773c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Small/medium handlers expect dst/src to point to the beginning. 3783c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(dst, count); 3793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ sub(src, count); 3803c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(count, kSmallCopySize); 3813c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(below_equal, &small_size); 3823c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ jmp(&medium_size); 3833c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } 3843c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org { 3853c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Special handlers for 9 <= copy_size < 64. No assumptions about 3863c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // alignment or move distance, so all reads must be unaligned and 3873c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // must happen before any writes. 3883c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label medium_handlers, f9_16, f17_32, f33_48, f49_63; 3893c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 3903c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f9_16); 3913c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(xmm0, Operand(src, 0)); 3923c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(xmm1, Operand(src, count, times_1, -8)); 3933c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(Operand(dst, 0), xmm0); 3943c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(Operand(dst, count, times_1, -8), xmm1); 3953c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 3963c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 3973c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f17_32); 3983c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm0, Operand(src, 0)); 3993c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm1, Operand(src, count, times_1, -0x10)); 4003c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0x00), xmm0); 4013c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, count, times_1, -0x10), xmm1); 4023c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f33_48); 4053c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm0, Operand(src, 0x00)); 4063c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm1, Operand(src, 0x10)); 4073c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm2, Operand(src, count, times_1, -0x10)); 4083c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0x00), xmm0); 4093c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0x10), xmm1); 4103c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, count, times_1, -0x10), xmm2); 4113c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4123c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4133c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f49_63); 4143c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm0, Operand(src, 0x00)); 4153c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm1, Operand(src, 0x10)); 4163c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm2, Operand(src, 0x20)); 4173c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(xmm3, Operand(src, count, times_1, -0x10)); 4183c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0x00), xmm0); 4193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0x10), xmm1); 4203c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, 0x20), xmm2); 4213c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movdqu(Operand(dst, count, times_1, -0x10), xmm3); 4223c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4233c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4243c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&medium_handlers); 4253c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f9_16)); 4263c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f17_32)); 4273c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f33_48)); 4283c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f49_63)); 4293c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4303c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&medium_size); // Entry point into this block. 4313c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(eax, count); 4323c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dec(eax); 4333c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ shr(eax, 4); 4343c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (FLAG_debug_code) { 4353c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label ok; 4363c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(eax, 3); 4373c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(below_equal, &ok); 4383c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ int3(); 4393c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&ok); 440e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(eax, Operand(eax, times_4, conv.address(&medium_handlers))); 4423c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ jmp(eax); 4433c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } 4443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org { 4453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // Specialized copiers for copy_size <= 8 bytes. 4463c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label small_handlers, f0, f1, f2, f3, f4, f5_8; 4473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f0); 4483c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4493c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4503c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f1); 4513c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(eax, Operand(src, 0)); 4523c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(Operand(dst, 0), eax); 4533c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4543c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4553c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f2); 4563c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_w(eax, Operand(src, 0)); 4573c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_w(Operand(dst, 0), eax); 4583c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4593c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4603c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f3); 4613c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_w(eax, Operand(src, 0)); 4623c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(edx, Operand(src, 2)); 4633c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_w(Operand(dst, 0), eax); 4643c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov_b(Operand(dst, 2), edx); 4653c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4663c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f4); 4683c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(eax, Operand(src, 0)); 4693c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(Operand(dst, 0), eax); 4703c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4713c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4723c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&f5_8); 4733c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(eax, Operand(src, 0)); 4743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(edx, Operand(src, count, times_1, -4)); 4753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(Operand(dst, 0), eax); 4763c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(Operand(dst, count, times_1, -4), edx); 4773c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org MemMoveEmitPopAndReturn(&masm); 4783c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&small_handlers); 4803c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f0)); 4813c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f1)); 4823c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f2)); 4833c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f3)); 4843c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f4)); 4853c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f5_8)); 4863c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f5_8)); 4873c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f5_8)); 4883c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ dd(conv.address(&f5_8)); 4893c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 4903c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&small_size); // Entry point into this block. 4913c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (FLAG_debug_code) { 4923c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Label ok; 4933c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ cmp(count, 8); 4943c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ j(below_equal, &ok); 4953c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ int3(); 4963c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ bind(&ok); 497e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4983c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ mov(eax, Operand(count, times_4, conv.address(&small_handlers))); 4993c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ jmp(eax); 5001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 5011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 502e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&pop_and_return); 503e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org MemMoveEmitPopAndReturn(&masm); 504e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org CodeDesc desc; 5061af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org masm.GetCode(&desc); 507e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!RelocInfo::RequiresRelocation(desc)); 5085de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(buffer, actual_size); 5095de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::ProtectCode(buffer, actual_size); 51077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // TODO(jkummerow): It would be nice to register this code creation event 51177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // with the PROFILE / GDBJIT system. 512d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org return FUNCTION_CAST<MemMoveFunction>(buffer); 5131af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 5141af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 515e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5161af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#undef __ 5171af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 518394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// ------------------------------------------------------------------------- 519394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Code generators 520394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 521394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#define __ ACCESS_MASM(masm) 522394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 52359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 524830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 5259bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org MacroAssembler* masm, 5269bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register receiver, 5279bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register key, 5289bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register value, 5299bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register target_map, 5309bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org AllocationSiteMode mode, 531ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label* allocation_memento_found) { 5329bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register scratch = edi; 533e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AreAliased(receiver, key, value, target_map, scratch)); 5349bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 53546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allocation_memento_found != NULL); 5379bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org __ JumpIfJSArrayHasAllocationMemento( 5389bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org receiver, scratch, allocation_memento_found); 53946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org } 54046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 541394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set transitioned map. 5429bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org __ mov(FieldOperand(receiver, HeapObject::kMapOffset), target_map); 5439bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org __ RecordWriteField(receiver, 544394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject::kMapOffset, 5459bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org target_map, 5469bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org scratch, 547394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 548394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 549394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 550394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 551394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 552394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 553830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateSmiToDouble( 5549bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org MacroAssembler* masm, 5559bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register receiver, 5569bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register key, 5579bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register value, 5589bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register target_map, 5599bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org AllocationSiteMode mode, 5609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Label* fail) { 5619bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Return address is on the stack. 562e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(edx)); 563e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(key.is(ecx)); 564e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value.is(eax)); 565e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_map.is(ebx)); 5669bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 56765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org Label loop, entry, convert_hole, gc_required, only_change_map; 56865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 56946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 570b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail); 57159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 57259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 57365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Check for empty arrays, which only require a map transition and no changes 57465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // to the backing store. 57565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 57665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array())); 57765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ j(equal, &only_change_map); 57865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 579394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ push(eax); 580394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ push(ebx); 581394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 582394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(edi, FieldOperand(edi, FixedArray::kLengthOffset)); 583394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 584394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Allocate new FixedDoubleArray. 585394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edx: receiver 586394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edi: length of source FixedArray (smi-tagged) 5874cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org AllocationFlags flags = 5884cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org static_cast<AllocationFlags>(TAG_OBJECT | DOUBLE_ALIGNMENT); 589f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(FixedDoubleArray::kHeaderSize, times_8, edi, 590f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org REGISTER_VALUE_IS_SMI, eax, ebx, no_reg, &gc_required, flags); 591ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 592394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // eax: destination FixedDoubleArray 593394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edi: number of elements 594394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edx: receiver 595394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(eax, HeapObject::kMapOffset), 596394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Immediate(masm->isolate()->factory()->fixed_double_array_map())); 597394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(eax, FixedDoubleArray::kLengthOffset), edi); 598394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(esi, FieldOperand(edx, JSObject::kElementsOffset)); 599394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace receiver's backing store with newly created FixedDoubleArray. 600394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(edx, JSObject::kElementsOffset), eax); 601394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(ebx, eax); 602394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(edx, 603394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSObject::kElementsOffset, 604394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ebx, 605394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com edi, 606394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 607394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 608394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 609394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 610394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(edi, FieldOperand(esi, FixedArray::kLengthOffset)); 611394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 612394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Prepare for conversion loop. 613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ExternalReference canonical_the_hole_nan_reference = 614394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ExternalReference::address_of_the_hole_nan(); 615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com XMMRegister the_hole_nan = xmm1; 6163c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(the_hole_nan, 6173c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Operand::StaticVariable(canonical_the_hole_nan_reference)); 618394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry); 619394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 620394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Call into runtime if GC is required. 621394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&gc_required); 622394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Restore registers before jumping into runtime. 623394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 624394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(ebx); 625394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(eax); 626394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(fail); 627394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 628394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Convert and copy elements 629394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // esi: source FixedArray 630394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&loop); 631394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(ebx, FieldOperand(esi, edi, times_2, FixedArray::kHeaderSize)); 632394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ebx: current element from source 633394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edi: index of current element 634394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ JumpIfNotSmi(ebx, &convert_hole); 635394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 636394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Normal smi, convert it to double and store. 637394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ SmiUntag(ebx); 6383c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ Cvtsi2sd(xmm0, ebx); 6393c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize), 6403c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org xmm0); 641394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry); 642394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 643394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Found hole, store hole_nan_as_double instead. 644394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&convert_hole); 645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 646c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (FLAG_debug_code) { 647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ cmp(ebx, masm->isolate()->factory()->the_hole_value()); 648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(equal, kObjectFoundInSmiOnlyArray); 649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 6513c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize), 6523c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org the_hole_nan); 653394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 654394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&entry); 655becbc5247ca44bb32846a82794e96425980e9d50erik.corry@gmail.com __ sub(edi, Immediate(Smi::FromInt(1))); 656becbc5247ca44bb32846a82794e96425980e9d50erik.corry@gmail.com __ j(not_sign, &loop); 657394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 658394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(ebx); 659394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(eax); 66065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 66165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Restore esi. 66265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 66365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 66465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ bind(&only_change_map); 665394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // eax: value 666394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ebx: target map 667394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set transitioned map. 668394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx); 669394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(edx, 670394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject::kMapOffset, 671394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ebx, 672394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com edi, 673394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 67465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_REMEMBERED_SET, 675394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 676394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 677394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 678394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 679394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid ElementsTransitionGenerator::GenerateDoubleToObject( 6809bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org MacroAssembler* masm, 6819bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register receiver, 6829bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register key, 6839bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register value, 6849bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register target_map, 6859bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org AllocationSiteMode mode, 6869bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Label* fail) { 6879bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Return address is on the stack. 688e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(edx)); 689e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(key.is(ecx)); 690e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value.is(eax)); 691e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_map.is(ebx)); 6929bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 69365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org Label loop, entry, convert_hole, gc_required, only_change_map, success; 69465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 69546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 696b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail); 69746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org } 69846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 69965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Check for empty arrays, which only require a map transition and no changes 70065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // to the backing store. 70165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 70265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array())); 70365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ j(equal, &only_change_map); 70465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 705394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ push(eax); 706394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ push(edx); 707394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ push(ebx); 708394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 709394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(ebx, FieldOperand(edi, FixedDoubleArray::kLengthOffset)); 710394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 711394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Allocate new FixedArray. 712394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ebx: length of source FixedDoubleArray (smi-tagged) 713394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lea(edi, Operand(ebx, times_2, FixedArray::kHeaderSize)); 714f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(edi, eax, esi, no_reg, &gc_required, TAG_OBJECT); 715394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 716394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // eax: destination FixedArray 717394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ebx: number of elements 718394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(eax, HeapObject::kMapOffset), 719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Immediate(masm->isolate()->factory()->fixed_array_map())); 720394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(eax, FixedArray::kLengthOffset), ebx); 721394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 723394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry); 724394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 72565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // ebx: target map 72665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // edx: receiver 72765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Set transitioned map. 72865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ bind(&only_change_map); 72965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx); 73065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ RecordWriteField(edx, 73165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org HeapObject::kMapOffset, 73265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org ebx, 73365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org edi, 73465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org kDontSaveFPRegs, 73565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_REMEMBERED_SET, 73665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_SMI_CHECK); 73765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ jmp(&success); 73865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 739394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Call into runtime if GC is required. 740394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&gc_required); 741394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 742394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(ebx); 743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(edx); 744394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(eax); 745394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(fail); 746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Box doubles into heap numbers. 748394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edi: source FixedDoubleArray 749394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // eax: destination FixedArray 750394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&loop); 751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ebx: index of current element (smi-tagged) 752394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); 753394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmp(FieldOperand(edi, ebx, times_4, offset), Immediate(kHoleNanUpper32)); 754394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(equal, &convert_hole); 755394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 756394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Non-hole double, copy value into a heap number. 757394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ AllocateHeapNumber(edx, esi, no_reg, &gc_required); 758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edx: new heap number 7593c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(xmm0, 7603c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize)); 7613c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ movsd(FieldOperand(edx, HeapNumber::kValueOffset), xmm0); 762394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize), edx); 763394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(esi, ebx); 764394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteArray(eax, 765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com edx, 766394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com esi, 767394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 768394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 769394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 770394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry, Label::kNear); 771394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 772394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace the-hole NaN with the-hole pointer. 773394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&convert_hole); 774394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize), 775394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com masm->isolate()->factory()->the_hole_value()); 776394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 777394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&entry); 778becbc5247ca44bb32846a82794e96425980e9d50erik.corry@gmail.com __ sub(ebx, Immediate(Smi::FromInt(1))); 779becbc5247ca44bb32846a82794e96425980e9d50erik.corry@gmail.com __ j(not_sign, &loop); 780394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 781394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(ebx); 782394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(edx); 783394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ebx: target map 784394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // edx: receiver 785394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set transitioned map. 786394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx); 787394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(edx, 788394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject::kMapOffset, 789394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ebx, 790394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com edi, 791394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 79265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_REMEMBERED_SET, 793394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 794394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace receiver's backing store with newly created and filled FixedArray. 795394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(FieldOperand(edx, JSObject::kElementsOffset), eax); 796394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(edx, 797394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSObject::kElementsOffset, 798394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com eax, 799394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com edi, 800394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 801394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 802394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 803394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 804394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Restore registers. 805394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(eax); 806394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 80765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 80865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ bind(&success); 809394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 810394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 8110ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8120ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid StringCharLoadGenerator::Generate(MacroAssembler* masm, 8130ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Factory* factory, 8140ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Register string, 8150ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Register index, 8160ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Register result, 8170ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Label* call_runtime) { 8180ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Fetch the instance type of the receiver into result register. 8190ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); 8200ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); 8210ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8220ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // We need special handling for indirect strings. 8230ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Label check_sequential; 8240ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ test(result, Immediate(kIsIndirectStringMask)); 8251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(zero, &check_sequential, Label::kNear); 8260ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8270ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Dispatch on the indirect string shape: slice or cons. 8280ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Label cons_string; 8290ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ test(result, Immediate(kSlicedNotConsMask)); 8301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(zero, &cons_string, Label::kNear); 8310ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8320ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Handle slices. 8330ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Label indirect_string_loaded; 8340ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ mov(result, FieldOperand(string, SlicedString::kOffsetOffset)); 8350ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ SmiUntag(result); 8360ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ add(index, result); 8370ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ mov(string, FieldOperand(string, SlicedString::kParentOffset)); 8381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ jmp(&indirect_string_loaded, Label::kNear); 8390ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Handle cons strings. 8410ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Check whether the right hand side is the empty string (i.e. if 8420ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // this is really a flat string in a cons string). If that is not 8430ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // the case we would rather go to the runtime system now to flatten 8440ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // the string. 8450ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ bind(&cons_string); 8460ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ cmp(FieldOperand(string, ConsString::kSecondOffset), 8470ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Immediate(factory->empty_string())); 8480ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ j(not_equal, call_runtime); 8490ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); 8500ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8510ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ bind(&indirect_string_loaded); 8520ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); 8530ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); 8540ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Distinguish sequential and external strings. Only these two string 8561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // representations can reach here (slices and flat cons strings have been 8571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // reduced to the underlying sequential or external string). 8581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Label seq_string; 8590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ bind(&check_sequential); 8600ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry STATIC_ASSERT(kSeqStringTag == 0); 8610ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ test(result, Immediate(kStringRepresentationMask)); 8621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(zero, &seq_string, Label::kNear); 8631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 8641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Handle external strings. 8652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label one_byte_external, done; 8661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_debug_code) { 8671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Assert that we do not have a cons or slice (indirect strings) here. 8681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Sequential strings have already been ruled out. 8691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ test(result, Immediate(kIsIndirectStringMask)); 870594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(zero, kExternalStringExpectedButNotFound); 8711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 8721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Rule out short external strings. 873d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org STATIC_ASSERT(kShortExternalStringTag != 0); 8741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ test_b(result, kShortExternalStringMask); 8751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(not_zero, call_runtime); 8761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Check encoding. 8771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org STATIC_ASSERT(kTwoByteStringTag == 0); 8781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ test_b(result, kStringEncodingMask); 8791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ mov(result, FieldOperand(string, ExternalString::kResourceDataOffset)); 8802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ j(not_equal, &one_byte_external, Label::kNear); 8811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Two-byte string. 8821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzx_w(result, Operand(result, index, times_2, 0)); 8831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ jmp(&done, Label::kNear); 8842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ bind(&one_byte_external); 8852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // One-byte string. 8861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzx_b(result, Operand(result, index, times_1, 0)); 8871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ jmp(&done, Label::kNear); 8880ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Dispatch on the encoding: one-byte or two-byte. 8902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label one_byte; 8911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ bind(&seq_string); 892e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); 8930ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 8940ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ test(result, Immediate(kStringEncodingMask)); 8952c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ j(not_zero, &one_byte, Label::kNear); 8960ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 8970ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Two-byte string. 8980ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Load the two-byte character code into the result register. 8990ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ movzx_w(result, FieldOperand(string, 9000ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry index, 9010ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry times_2, 9020ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry SeqTwoByteString::kHeaderSize)); 9030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ jmp(&done, Label::kNear); 9040ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 9052c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // One-byte string. 9060ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Load the byte into the result register. 9072c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ bind(&one_byte); 9080ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ movzx_b(result, FieldOperand(string, 9090ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry index, 9100ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry times_1, 911fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org SeqOneByteString::kHeaderSize)); 9120ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ bind(&done); 9130ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 9140ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 9151f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 9161f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgstatic Operand ExpConstant(int index) { 9171f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org return Operand::StaticVariable(ExternalReference::math_exp_constants(index)); 9181f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 9191f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 9201f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 9211f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid MathExpGenerator::EmitMathExp(MacroAssembler* masm, 9221f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister input, 9231f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister result, 9241f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister double_scratch, 9251f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp1, 9261f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp2) { 927e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(double_scratch)); 928e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(result)); 929e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(double_scratch)); 930e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!temp1.is(temp2)); 931e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); 9329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK(!masm->serializer_enabled()); // External references not serializable. 9331f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 9341f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Label done; 9351f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 9360fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(double_scratch, ExpConstant(0)); 9371f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ xorpd(result, result); 9381f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ ucomisd(double_scratch, input); 9391f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ j(above_equal, &done); 9401f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ ucomisd(input, ExpConstant(1)); 9410fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(result, ExpConstant(2)); 9421f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ j(above_equal, &done); 9430fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(double_scratch, ExpConstant(3)); 9440fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(result, ExpConstant(4)); 9451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(double_scratch, input); 9461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ addsd(double_scratch, result); 9471f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movd(temp2, double_scratch); 9481f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(double_scratch, result); 9490fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(result, ExpConstant(6)); 9501f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(double_scratch, ExpConstant(5)); 9511f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(double_scratch, input); 9521f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(result, double_scratch); 9531f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(input, double_scratch); 9541f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(input, double_scratch); 9551f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(result, input); 9561f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mov(temp1, temp2); 9571f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(result, ExpConstant(7)); 9581f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(result, double_scratch); 9591f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ add(temp1, Immediate(0x1ff800)); 9601f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ addsd(result, ExpConstant(8)); 9611f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ and_(temp2, Immediate(0x7ff)); 9621f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ shr(temp1, 11); 9631f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ shl(temp1, 20); 9641f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movd(input, temp1); 9651f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ pshufd(input, input, static_cast<uint8_t>(0xe1)); // Order: 11 10 00 01 9660fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(double_scratch, Operand::StaticArray( 9671f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org temp2, times_8, ExternalReference::math_exp_log_table())); 968057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ orps(input, double_scratch); 9691f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(result, input); 9701f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ bind(&done); 9711f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 9721f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 973394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#undef __ 974394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 975e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 9765924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgCodeAgingHelper::CodeAgingHelper() { 977e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength); 9785924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org CodePatcher patcher(young_sequence_.start(), young_sequence_.length()); 9795924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->push(ebp); 9805924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->mov(ebp, esp); 9815924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->push(esi); 9825924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->push(edi); 9835924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org} 9845924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 9855924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 9865924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org#ifdef DEBUG 9875924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgbool CodeAgingHelper::IsOld(byte* candidate) const { 9885924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org return *candidate == kCallOpcode; 989e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 9905924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org#endif 991e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 992e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 9935924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgbool Code::IsYoungSequence(Isolate* isolate, byte* sequence) { 9945924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org bool result = isolate->code_aging_helper()->IsYoung(sequence); 995e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result || isolate->code_aging_helper()->IsOld(sequence)); 996e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org return result; 997e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 998e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 999e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 10005924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgvoid Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age, 1001e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org MarkingParity* parity) { 10025924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org if (IsYoungSequence(isolate, sequence)) { 1003e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org *age = kNoAgeCodeAge; 1004e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org *parity = NO_MARKING_PARITY; 1005e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 1006e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org sequence++; // Skip the kCallOpcode byte 1007e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Address target_address = sequence + *reinterpret_cast<int*>(sequence) + 1008e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Assembler::kCallTargetAddressOffset; 1009e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Code* stub = GetCodeFromTargetAddress(target_address); 1010e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org GetCodeAgeAndParity(stub, age, parity); 1011e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 1012e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 1013e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 1014e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 1015528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Code::PatchPlatformCodeAge(Isolate* isolate, 1016528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org byte* sequence, 1017e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Code::Age age, 1018e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org MarkingParity parity) { 10195924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org uint32_t young_length = isolate->code_aging_helper()->young_sequence_length(); 1020e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org if (age == kNoAgeCodeAge) { 10215924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org isolate->code_aging_helper()->CopyYoungSequenceTo(sequence); 10225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(sequence, young_length); 1023e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 1024528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Code* stub = GetCodeAgeStub(isolate, age, parity); 1025e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org CodePatcher patcher(sequence, young_length); 102659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); 1027e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 1028e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 1029e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 1030e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 10329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 1034