1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// 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.
45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64
89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/assembler-x64.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/macro-assembler-x64.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/heap.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h"
1871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
1971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
2071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
2171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
22c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
23c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    : Assembler(arg_isolate, buffer, size),
249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      generating_stub_(false),
25c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      has_frame_(false),
26c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      root_array_available_(true) {
27c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (isolate() != NULL) {
28c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    code_object_ = Handle<Object>(isolate()->heap()->undefined_value(),
29c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                                  isolate());
30c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
31ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
32ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
33ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
344ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgstatic const int64_t kInvalidRootRegisterDelta = -1;
35000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
36000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
374ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgint64_t MacroAssembler::RootRegisterDelta(ExternalReference other) {
38000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (predictable_code_size() &&
39000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org      (other.address() < reinterpret_cast<Address>(isolate()) ||
40000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org       other.address() >= reinterpret_cast<Address>(isolate() + 1))) {
41000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    return kInvalidRootRegisterDelta;
42000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  }
43ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Address roots_register_value = kRootRegisterBias +
44000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org      reinterpret_cast<Address>(isolate()->heap()->roots_array_start());
454ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
464ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  int64_t delta = kInvalidRootRegisterDelta;  // Bogus initialization.
474ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  if (kPointerSize == kInt64Size) {
484ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    delta = other.address() - roots_register_value;
494ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  } else {
504ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    // For x32, zero extend the address to 64-bit and calculate the delta.
514ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    uint64_t o = static_cast<uint32_t>(
524ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org        reinterpret_cast<intptr_t>(other.address()));
534ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    uint64_t r = static_cast<uint32_t>(
544ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org        reinterpret_cast<intptr_t>(roots_register_value));
554ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    delta = o - r;
564ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
57ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return delta;
58ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
59ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
60ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
61ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgOperand MacroAssembler::ExternalOperand(ExternalReference target,
62ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        Register scratch) {
63874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (root_array_available_ && !serializer_enabled()) {
644ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    int64_t delta = RootRegisterDelta(target);
65000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      return Operand(kRootRegister, static_cast<int32_t>(delta));
67ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
68ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
69e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Move(scratch, target);
70ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return Operand(scratch, 0);
71ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
72ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
73ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
74ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::Load(Register destination, ExternalReference source) {
75874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (root_array_available_ && !serializer_enabled()) {
764ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    int64_t delta = RootRegisterDelta(source);
77000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
7843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
79ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return;
80ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
81ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
82ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Safe code.
83ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (destination.is(rax)) {
84ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    load_rax(source);
85ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else {
86e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Move(kScratchRegister, source);
8743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(destination, Operand(kScratchRegister, 0));
88ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
89ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
90ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
91ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
92ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::Store(ExternalReference destination, Register source) {
93874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (root_array_available_ && !serializer_enabled()) {
944ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    int64_t delta = RootRegisterDelta(destination);
95000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
9643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return;
98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Safe code.
101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (source.is(rax)) {
102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    store_rax(destination);
103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else {
104e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Move(kScratchRegister, destination);
10543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(Operand(kScratchRegister, 0), source);
106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
108ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::LoadAddress(Register destination,
111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 ExternalReference source) {
112874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (root_array_available_ && !serializer_enabled()) {
1134ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    int64_t delta = RootRegisterDelta(source);
114000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
115895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return;
117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
119ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Safe code.
120e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Move(destination, source);
121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint MacroAssembler::LoadAddressSize(ExternalReference source) {
125874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (root_array_available_ && !serializer_enabled()) {
126ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // This calculation depends on the internals of LoadAddress.
127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // It's correctness is ensured by the asserts in the Call
128ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // instruction below.
1294ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    int64_t delta = RootRegisterDelta(source);
130000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
131895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      // Operand is leap(scratch, Operand(kRootRegister, delta));
132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // Opcodes : REX.W 8D ModRM Disp8/Disp32  - 4 or 7.
133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      int size = 4;
134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (!is_int8(static_cast<int32_t>(delta))) {
135ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        size += 3;  // Need full four-byte displacement in lea.
136ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      }
137ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return size;
138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
139ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
14043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  // Size of movp(destination, src);
141594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Assembler::kMoveAddressIntoScratchRegisterInstructionLength;
14271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
14371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
144e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
145ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid MacroAssembler::PushAddress(ExternalReference source) {
146ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  int64_t address = reinterpret_cast<int64_t>(source.address());
147874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (is_int32(address) && !serializer_enabled()) {
148ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (emit_debug_code()) {
149af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone());
150ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
151763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(Immediate(static_cast<int32_t>(address)));
152ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return;
153ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
154ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  LoadAddress(kScratchRegister, source);
155763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(kScratchRegister);
156ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com}
157ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
158ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
160ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(root_array_available_);
16143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(destination, Operand(kRootRegister,
1628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                            (index << kPointerSizeLog2) - kRootRegisterBias));
1638f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org}
1648f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
1658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
1668f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid MacroAssembler::LoadRootIndexed(Register destination,
1678f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                     Register variable_offset,
1688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                     int fixed_offset) {
169ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(root_array_available_);
17043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(destination,
1718f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org       Operand(kRootRegister,
1728f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org               variable_offset, times_pointer_size,
1738f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org               (fixed_offset << kPointerSizeLog2) - kRootRegisterBias));
17418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
17518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
17618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
177720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.orgvoid MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) {
178ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(root_array_available_);
17943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias),
1808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org       source);
181720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org}
182720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
183720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
18418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::PushRoot(Heap::RootListIndex index) {
185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(root_array_available_);
186763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias));
18718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
18818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
18918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
1909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
191ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(root_array_available_);
1927a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(with, Operand(kRootRegister,
1938f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                     (index << kPointerSizeLog2) - kRootRegisterBias));
19418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
19518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
196b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org
19783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid MacroAssembler::CompareRoot(const Operand& with,
19883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                                 Heap::RootListIndex index) {
199ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(root_array_available_);
20083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  ASSERT(!with.AddressUsesRegister(kScratchRegister));
201c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  LoadRoot(kScratchRegister, index);
2027a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(with, kScratchRegister);
203c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
204c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
205c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RememberedSetHelper(Register object,  // For debug tests.
207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                         Register addr,
208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                         Register scratch,
209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                         SaveFPRegsMode save_fp,
210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                         RememberedSetFinalAction and_then) {
211000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (emit_debug_code()) {
212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label ok;
213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear);
214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int3();
215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bind(&ok);
216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Load store buffer top.
218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  LoadRoot(scratch, Heap::kStoreBufferTopRootIndex);
219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Store pointer to buffer.
22043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(scratch, 0), addr);
221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Increment buffer top.
222fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(scratch, Immediate(kPointerSize));
223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Write back new top of buffer.
224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  StoreRoot(scratch, Heap::kStoreBufferTopRootIndex);
225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Call stub on end of buffer.
226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label done;
227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check for end of buffer.
2287a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit));
229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (and_then == kReturnAtEnd) {
230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label buffer_overflowed;
231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    j(not_equal, &buffer_overflowed, Label::kNear);
232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ret(0);
233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bind(&buffer_overflowed);
234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(and_then == kFallThroughAtEnd);
236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    j(equal, &done, Label::kNear);
237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  StoreBufferOverflowStub store_buffer_overflow =
239f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      StoreBufferOverflowStub(isolate(), save_fp);
240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  CallStub(&store_buffer_overflow);
241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (and_then == kReturnAtEnd) {
242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ret(0);
243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(and_then == kFallThroughAtEnd);
245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bind(&done);
246ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  }
24730ce411529579186181838984710b0b0980857aaricow@chromium.org}
24830ce411529579186181838984710b0b0980857aaricow@chromium.org
24930ce411529579186181838984710b0b0980857aaricow@chromium.org
25083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::InNewSpace(Register object,
25183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                Register scratch,
25283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                Condition cc,
25383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                Label* branch,
254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                Label::Distance distance) {
255874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (serializer_enabled()) {
25683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Can't do arithmetic on external references if it might get serialized.
25783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // The mask isn't really an address.  We load it as an external reference in
25883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // case the size of the new space is different between the snapshot maker
25983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // and the running system.
26083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (scratch.is(object)) {
261e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      Move(kScratchRegister, ExternalReference::new_space_mask(isolate()));
262895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      andp(scratch, kScratchRegister);
26383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
264e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      Move(scratch, ExternalReference::new_space_mask(isolate()));
265895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      andp(scratch, object);
26683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
267e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Move(kScratchRegister, ExternalReference::new_space_start(isolate()));
2687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(scratch, kScratchRegister);
269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    j(cc, branch, distance);
27083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
271e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(kPointerSize == kInt64Size
272e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        ? is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask()))
273e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        : kPointerSize == kInt32Size);
27483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    intptr_t new_space_start =
275c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org        reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart());
2769cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start),
277af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org         Assembler::RelocInfoNone());
27883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (scratch.is(object)) {
279fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      addp(scratch, kScratchRegister);
28083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
281895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(scratch, Operand(object, kScratchRegister, times_1, 0));
28283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
283895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    andp(scratch,
284c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org         Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask())));
285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    j(cc, branch, distance);
28683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
28783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
28883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
28983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RecordWriteField(
291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register object,
292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int offset,
293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register value,
294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register dst,
295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    SaveFPRegsMode save_fp,
296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RememberedSetAction remembered_set_action,
297196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    SmiCheck smi_check,
298196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    PointersToHereCheck pointers_to_here_check_for_value) {
29930ce411529579186181838984710b0b0980857aaricow@chromium.org  // First, check if a write barrier is even needed. The tests below
300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // catch stores of Smis.
301b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org  Label done;
302b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org
303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Skip barrier if writing a smi.
304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (smi_check == INLINE_SMI_CHECK) {
305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    JumpIfSmi(value, &done);
306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Although the object register is tagged, the offset is relative to the start
309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // of the object, so so offset must be a multiple of kPointerSize.
310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(IsAligned(offset, kPointerSize));
311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
312895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(dst, FieldOperand(object, offset));
313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (emit_debug_code()) {
314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label ok;
315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    testb(dst, Immediate((1 << kPointerSizeLog2) - 1));
316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    j(zero, &ok, Label::kNear);
317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int3();
318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bind(&ok);
319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
321196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  RecordWrite(object, dst, value, save_fp, remembered_set_action,
322196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              OMIT_SMI_CHECK, pointers_to_here_check_for_value);
323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  bind(&done);
325b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Clobber clobbered input registers when running with the debug-code flag
327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // turned on to provoke errors.
328badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
329af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Move(value, kZapValue, Assembler::RelocInfoNone());
330af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Move(dst, kZapValue, Assembler::RelocInfoNone());
331b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
3329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
3339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
3349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
335196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWriteArray(
336196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Register object,
337196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Register value,
338196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Register index,
339196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    SaveFPRegsMode save_fp,
340196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    RememberedSetAction remembered_set_action,
341196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    SmiCheck smi_check,
342196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    PointersToHereCheck pointers_to_here_check_for_value) {
343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // First, check if a write barrier is even needed. The tests below
344394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // catch stores of Smis.
345394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Label done;
346394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
347394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Skip barrier if writing a smi.
348394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (smi_check == INLINE_SMI_CHECK) {
349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    JumpIfSmi(value, &done);
350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
351394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Array access: calculate the destination address. Index is not a smi.
353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register dst = index;
354895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(dst, Operand(object, index, times_pointer_size,
355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                   FixedArray::kHeaderSize - kHeapObjectTag));
356394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
357196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  RecordWrite(object, dst, value, save_fp, remembered_set_action,
358196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              OMIT_SMI_CHECK, pointers_to_here_check_for_value);
359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
360394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bind(&done);
361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Clobber clobbered input registers when running with the debug-code flag
363394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // turned on to provoke errors.
364394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (emit_debug_code()) {
365af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Move(value, kZapValue, Assembler::RelocInfoNone());
366af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Move(index, kZapValue, Assembler::RelocInfoNone());
367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
369394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
370394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
371196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWriteForMap(Register object,
372196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                       Register map,
373196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                       Register dst,
374196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                       SaveFPRegsMode fp_mode) {
375196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ASSERT(!object.is(kScratchRegister));
376196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ASSERT(!object.is(map));
377196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ASSERT(!object.is(dst));
378196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ASSERT(!map.is(dst));
379196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  AssertNotSmi(object);
380196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
381196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (emit_debug_code()) {
382196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Label ok;
383196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (map.is(kScratchRegister)) pushq(map);
384196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    CompareMap(map, isolate()->factory()->meta_map());
385196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (map.is(kScratchRegister)) popq(map);
386196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    j(equal, &ok, Label::kNear);
387196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    int3();
388196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    bind(&ok);
389196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
390196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
391196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (!FLAG_incremental_marking) {
392196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    return;
393196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
394196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
395196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (emit_debug_code()) {
396196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Label ok;
397196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (map.is(kScratchRegister)) pushq(map);
398196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    cmpp(map, FieldOperand(object, HeapObject::kMapOffset));
399196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (map.is(kScratchRegister)) popq(map);
400196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    j(equal, &ok, Label::kNear);
401196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    int3();
402196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    bind(&ok);
403196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
404196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
405196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // Compute the address.
406196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  leap(dst, FieldOperand(object, HeapObject::kMapOffset));
407196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
408196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // Count number of write barriers in generated code.
409196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  isolate()->counters()->write_barriers_static()->Increment();
410196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
411196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
412196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // First, check if a write barrier is even needed. The tests below
413196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // catch stores of smis and stores into the young generation.
414196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Label done;
415196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
416196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // A single check of the map's pages interesting flag suffices, since it is
417196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // only set during incremental collection, and then it's also guaranteed that
418196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // the from object's page's interesting flag is also set.  This optimization
419196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // relies on the fact that maps can never be in new space.
420196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CheckPageFlag(map,
421196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                map,  // Used as scratch.
422196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                MemoryChunk::kPointersToHereAreInterestingMask,
423196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                zero,
424196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                &done,
425196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                Label::kNear);
426196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
427196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
428196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                       fp_mode);
429196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CallStub(&stub);
430196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
431196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  bind(&done);
432196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
433196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // Clobber clobbered registers when running with the debug-code flag
434196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // turned on to provoke errors.
435196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (emit_debug_code()) {
436196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Move(dst, kZapValue, Assembler::RelocInfoNone());
437196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Move(map, kZapValue, Assembler::RelocInfoNone());
438196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
439196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
440196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
441196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
442196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWrite(
443196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Register object,
444196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Register address,
445196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Register value,
446196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    SaveFPRegsMode fp_mode,
447196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    RememberedSetAction remembered_set_action,
448196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    SmiCheck smi_check,
449196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    PointersToHereCheck pointers_to_here_check_for_value) {
450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!object.is(value));
451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!object.is(address));
452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!value.is(address));
453c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertNotSmi(object);
454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (remembered_set_action == OMIT_REMEMBERED_SET &&
456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !FLAG_incremental_marking) {
457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return;
45869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
45969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
460000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (emit_debug_code()) {
461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label ok;
4627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(value, Operand(address, 0));
463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    j(equal, &ok, Label::kNear);
464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int3();
465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bind(&ok);
466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
46769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
468f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // Count number of write barriers in generated code.
469f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  isolate()->counters()->write_barriers_static()->Increment();
470f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
471f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // First, check if a write barrier is even needed. The tests below
473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // catch stores of smis and stores into the young generation.
4749d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  Label done;
475b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (smi_check == INLINE_SMI_CHECK) {
477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Skip barrier if writing a smi.
478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    JumpIfSmi(value, &done);
479b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
480b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
481196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
482196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    CheckPageFlag(value,
483196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                  value,  // Used as scratch.
484196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                  MemoryChunk::kPointersToHereAreInterestingMask,
485196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                  zero,
486196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                  &done,
487196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                  Label::kNear);
488196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
489b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org
490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  CheckPageFlag(object,
491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                value,  // Used as scratch.
492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                MemoryChunk::kPointersFromHereAreInterestingMask,
493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                zero,
494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                &done,
495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Label::kNear);
496e88a9edffbbdbc4ccc9872560ac4d9ea6b188fbdwhesse@chromium.org
497f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
498f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                       fp_mode);
499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  CallStub(&stub);
500b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org
501b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org  bind(&done);
502b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Clobber clobbered registers when running with the debug-code flag
504b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // turned on to provoke errors.
505badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
506af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Move(address, kZapValue, Assembler::RelocInfoNone());
507af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Move(value, kZapValue, Assembler::RelocInfoNone());
508b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5095aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
5105aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
512594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) {
513594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (emit_debug_code()) Check(cc, reason);
514eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
515eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
516eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
5170b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MacroAssembler::AssertFastElements(Register elements) {
518badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
51983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label ok;
5200b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org    CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
5210b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                Heap::kFixedArrayMapRootIndex);
52283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(equal, &ok, Label::kNear);
5230b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org    CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
52484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                Heap::kFixedDoubleArrayMapRootIndex);
52584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    j(equal, &ok, Label::kNear);
52684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
5270b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                Heap::kFixedCOWArrayMapRootIndex);
52883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(equal, &ok, Label::kNear);
529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Abort(kJSObjectWithFastElementsMapHasSlowElements);
5300b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org    bind(&ok);
5310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  }
5320b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org}
5330b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
5340b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
535594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Check(Condition cc, BailoutReason reason) {
53683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label L;
53783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(cc, &L, Label::kNear);
538594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Abort(reason);
539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Control will not return here.
540eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  bind(&L);
541eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
542eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
543eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
544c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgvoid MacroAssembler::CheckStackAlignment() {
545c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  int frame_alignment = OS::ActivationFrameAlignment();
546c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  int frame_alignment_mask = frame_alignment - 1;
547c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  if (frame_alignment > kPointerSize) {
548c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    ASSERT(IsPowerOf2(frame_alignment));
54983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label alignment_as_expected;
5507a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    testp(rsp, Immediate(frame_alignment_mask));
55183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(zero, &alignment_as_expected, Label::kNear);
552c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    // Abort if stack is not aligned.
553c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    int3();
554c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    bind(&alignment_as_expected);
555c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
556c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
557c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
558c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5595aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::NegativeZeroTest(Register result,
5605aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org                                      Register op,
5615aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org                                      Label* then_label) {
56283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label ok;
5630b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  testl(result, result);
56483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_zero, &ok, Label::kNear);
5650b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  testl(op, op);
5665aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  j(sign, then_label);
5675aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  bind(&ok);
5685aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
5695aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
5705aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
571594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Abort(BailoutReason reason) {
572052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org#ifdef DEBUG
573f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  const char* msg = GetBailoutReason(reason);
574eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (msg != NULL) {
575eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    RecordComment("Abort message: ");
576eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    RecordComment(msg);
577eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
5781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
5791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (FLAG_trap_on_abort) {
5801e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    int3();
5811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    return;
5821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  }
583eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif
5841e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Move(kScratchRegister, Smi::FromInt(static_cast<int>(reason)),
586af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org       Assembler::RelocInfoNone());
587763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(kScratchRegister);
588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!has_frame_) {
590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // We don't actually want to generate a pile of code for this, so just
591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // claim there is a stack frame, without generating one.
592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FrameScope scope(this, StackFrame::NONE);
593f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    CallRuntime(Runtime::kAbort, 1);
594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
595f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    CallRuntime(Runtime::kAbort, 1);
596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Control will not return here.
598ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  int3();
599eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
600eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
601eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
602471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
603c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(AllowThisStubCall(stub));  // Calls are not allowed in some stubs
604f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
605eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
606eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
607eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
60813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::TailCallStub(CodeStub* stub) {
609f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
61013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
61113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
61213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
613eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::StubReturn(int argc) {
614eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(argc >= 1 && generating_stub());
615eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ret((argc - 1) * kPointerSize);
616eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
617eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
618eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
6208a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  return has_frame_ || !stub->SometimesSetsUpAFrame();
621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
624d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::IndexFromHash(Register hash, Register index) {
625d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // The assert checks that the constants for the maximum number of digits
626d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // for an array index cached in the hash field and the number of bits
627d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // reserved for it does not conflict.
628d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
629d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org         (1 << String::kArrayIndexValueBits));
630d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  if (!hash.is(index)) {
631d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    movl(index, hash);
632d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  }
633d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DecodeFieldToSmi<String::ArrayIndexValueBits>(index);
634d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org}
635d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
636d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::CallRuntime(const Runtime::Function* f,
638fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                 int num_arguments,
639fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                 SaveFPRegsMode save_doubles) {
640eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // If the expected number of arguments of the runtime function is
641eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // constant, we check that the actual number of arguments match the
642eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // expectation.
64329699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  CHECK(f->nargs < 0 || f->nargs == num_arguments);
644eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
645b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // TODO(1236192): Most runtime routines don't need the number of
646b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // arguments passed in because it is constant. At some point we
647b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // should remove this need and make the runtime routine entry code
648b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // smarter.
64932d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  Set(rax, num_arguments);
650ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(rbx, ExternalReference(f, isolate()));
651f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CEntryStub ces(isolate(), f->result_size, save_doubles);
652b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  CallStub(&ces);
653eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
654eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
655eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
6565c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CallExternalReference(const ExternalReference& ext,
6575c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                           int num_arguments) {
65832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  Set(rax, num_arguments);
659ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(rbx, ext);
6605c838251403b0be9a882540f1922577abba4c872ager@chromium.org
661f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CEntryStub stub(isolate(), 1);
6625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  CallStub(&stub);
6635c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
6645c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org
666ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
667ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                               int num_arguments,
668ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                               int result_size) {
6690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // ----------- S t a t e -------------
670c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  //  -- rsp[0]                 : return address
671c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  //  -- rsp[8]                 : argument num_arguments - 1
6720b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  //  ...
6730b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  //  -- rsp[8 * num_arguments] : argument 0 (receiver)
6740b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // -----------------------------------
6750b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
676eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // TODO(1236192): Most runtime routines don't need the number of
677eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // arguments passed in because it is constant. At some point we
678eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // should remove this need and make the runtime routine entry code
679eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // smarter.
68032d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  Set(rax, num_arguments);
681ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  JumpToExternalReference(ext, result_size);
682eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
683eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
684eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
685ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
686ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                     int num_arguments,
687ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                     int result_size) {
688ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  TailCallExternalReference(ExternalReference(fid, isolate()),
689ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            num_arguments,
690ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            result_size);
691ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
692ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
693ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
694e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.orgstatic int Offset(ExternalReference ref0, ExternalReference ref1) {
695e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  int64_t offset = (ref0.address() - ref1.address());
696e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  // Check that fits into int.
697e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  ASSERT(static_cast<int>(offset) == offset);
698e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  return static_cast<int>(offset);
699e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
700e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
701e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
702662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
7034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  EnterApiExitFrame(arg_stack_space);
704e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
705e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
706e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
707528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::CallApiFunctionAndReturn(
708e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org    Register function_address,
709a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    ExternalReference thunk_ref,
710528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Register thunk_last_arg,
711528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    int stack_space,
712528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Operand return_value_operand,
713528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Operand* context_restore_operand) {
714303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Label prologue;
715303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Label promote_scheduled_exception;
716528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Label exception_handled;
717303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Label delete_allocated_handles;
718303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Label leave_exit_frame;
719e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  Label write_back;
720e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
721160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  Factory* factory = isolate()->factory();
722303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  ExternalReference next_address =
72309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      ExternalReference::handle_scope_next_address(isolate());
724303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  const int kNextOffset = 0;
725303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  const int kLimitOffset = Offset(
72609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      ExternalReference::handle_scope_limit_address(isolate()),
727303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      next_address);
728303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  const int kLevelOffset = Offset(
72909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      ExternalReference::handle_scope_level_address(isolate()),
730303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      next_address);
731303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  ExternalReference scheduled_exception_address =
732ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ExternalReference::scheduled_exception_address(isolate());
733303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
734e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org  ASSERT(rdx.is(function_address) || r8.is(function_address));
735303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Allocate HandleScope in callee-save registers.
736303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Register prev_next_address_reg = r14;
737303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Register prev_limit_reg = rbx;
738b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  Register base_reg = r15;
739e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Move(base_reg, next_address);
74043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(prev_next_address_reg, Operand(base_reg, kNextOffset));
74143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(prev_limit_reg, Operand(base_reg, kLimitOffset));
742303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  addl(Operand(base_reg, kLevelOffset), Immediate(1));
74383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
74483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (FLAG_log_timer_events) {
74583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    FrameScope frame(this, StackFrame::MANUAL);
74683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    PushSafepointRegisters();
747ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    PrepareCallCFunction(1);
748ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate()));
749ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
75083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    PopSafepointRegisters();
75183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  }
75283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
753b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
754b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  Label profiler_disabled;
755b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  Label end_profiler_check;
756a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Move(rax, ExternalReference::is_profiling_address(isolate()));
757b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  cmpb(Operand(rax, 0), Immediate(0));
758b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  j(zero, &profiler_disabled);
759b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
760b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // Third parameter is the address of the actual getter function.
761e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org  Move(thunk_last_arg, function_address);
762a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Move(rax, thunk_ref);
763b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  jmp(&end_profiler_check);
764b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
765b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  bind(&profiler_disabled);
766303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Call the api function!
767e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org  Move(rax, function_address);
768b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
769b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  bind(&end_profiler_check);
770b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
771b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // Call the api function!
772303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  call(rax);
773e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
77483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (FLAG_log_timer_events) {
77583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    FrameScope frame(this, StackFrame::MANUAL);
77683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    PushSafepointRegisters();
777ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    PrepareCallCFunction(1);
778ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate()));
779ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1);
78083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    PopSafepointRegisters();
78183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  }
78283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
783bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // Load the value from ReturnValue
78443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rax, return_value_operand);
785303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  bind(&prologue);
786303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
787303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // No more valid handles (the result handle was the last one). Restore
788303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // previous handle scope.
789303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  subl(Operand(base_reg, kLevelOffset), Immediate(1));
79043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(base_reg, kNextOffset), prev_next_address_reg);
7917a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(prev_limit_reg, Operand(base_reg, kLimitOffset));
792303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  j(not_equal, &delete_allocated_handles);
793303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  bind(&leave_exit_frame);
794303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
795303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Check if the function scheduled an exception.
796e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Move(rsi, scheduled_exception_address);
797160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  Cmp(Operand(rsi, 0), factory->the_hole_value());
798303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  j(not_equal, &promote_scheduled_exception);
799528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bind(&exception_handled);
800303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
80167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#if ENABLE_EXTRA_CHECKS
80267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  // Check if the function returned a valid JavaScript value.
80367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  Label ok;
80467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  Register return_value = rax;
80567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  Register map = rcx;
80667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
80767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  JumpIfSmi(return_value, &ok, Label::kNear);
80843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(map, FieldOperand(return_value, HeapObject::kMapOffset));
80967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
81067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  CmpInstanceType(map, FIRST_NONSTRING_TYPE);
81167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  j(below, &ok, Label::kNear);
81267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
81367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
81467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  j(above_equal, &ok, Label::kNear);
81567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
81667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  CompareRoot(map, Heap::kHeapNumberMapRootIndex);
81767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  j(equal, &ok, Label::kNear);
81867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
81967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  CompareRoot(return_value, Heap::kUndefinedValueRootIndex);
82067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  j(equal, &ok, Label::kNear);
82167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
82267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  CompareRoot(return_value, Heap::kTrueValueRootIndex);
82367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  j(equal, &ok, Label::kNear);
82467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
82567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  CompareRoot(return_value, Heap::kFalseValueRootIndex);
82667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  j(equal, &ok, Label::kNear);
82767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
82867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  CompareRoot(return_value, Heap::kNullValueRootIndex);
82967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  j(equal, &ok, Label::kNear);
83067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
831594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Abort(kAPICallReturnedInvalidObject);
83267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
83367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  bind(&ok);
83467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#endif
83567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org
836528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bool restore_context = context_restore_operand != NULL;
837528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (restore_context) {
83843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(rsi, *context_restore_operand);
839528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
840528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  LeaveApiExitFrame(!restore_context);
8414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  ret(stack_space * kPointerSize);
842e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
843b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  bind(&promote_scheduled_exception);
844528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  {
845528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    FrameScope frame(this, StackFrame::INTERNAL);
846895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    CallRuntime(Runtime::kHiddenPromoteScheduledException, 0);
847528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
848528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  jmp(&exception_handled);
849b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
850303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // HandleScope limit has changed. Delete allocated extensions.
851303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  bind(&delete_allocated_handles);
85243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(base_reg, kLimitOffset), prev_limit_reg);
85343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(prev_limit_reg, rax);
854ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate()));
855ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(rax,
856ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org              ExternalReference::delete_handle_scope_extensions(isolate()));
857303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  call(rax);
85843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rax, prev_limit_reg);
859303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  jmp(&leave_exit_frame);
860e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
861e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
862e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
863ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
864ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                             int result_size) {
865eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Set the entry point and jump to the C entry runtime stub.
866ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(rbx, ext);
867f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CEntryStub ces(isolate(), result_size);
868f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
86971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
87071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
871e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
8723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
8733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                                   InvokeFlag flag,
874fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org                                   const CallWrapper& call_wrapper) {
875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // You can't call a builtin without a valid frame.
876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(flag == JUMP_FUNCTION || has_frame());
8775aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
8785c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Rely on the assertion to check that the number of provided
8795c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // arguments match the expected number of arguments. Fake a
8805c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // parameter count to avoid emitting code to do the check.
8815c838251403b0be9a882540f1922577abba4c872ager@chromium.org  ParameterCount expected(0);
8825c838251403b0be9a882540f1922577abba4c872ager@chromium.org  GetBuiltinEntry(rdx, id);
883e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  InvokeCode(rdx, expected, expected, flag, call_wrapper);
8845aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
8855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
8865c838251403b0be9a882540f1922577abba4c872ager@chromium.org
887145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinFunction(Register target,
888145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com                                        Builtins::JavaScript id) {
889c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Load the builtins object into target register.
89043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
89143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
89243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(target, FieldOperand(target,
893145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com                            JSBuiltinsObject::OffsetOfFunctionWithId(id)));
894145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com}
895c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
896c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
897145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
898145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  ASSERT(!target.is(rdi));
899145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  // Load the JavaScript builtin function from the builtins object.
900145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  GetBuiltinFunction(rdi, id);
90143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
9025aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
9035aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
9045aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
9051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#define REG(Name) { kRegister_ ## Name ## _Code }
9061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
9071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic const Register saved_regs[] = {
9081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8),
9091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  REG(r9), REG(r10), REG(r11)
9101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org};
9111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
9121456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#undef REG
9131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register);
915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode,
918c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                     Register exclusion1,
919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                     Register exclusion2,
920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                     Register exclusion3) {
921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // We don't allow a GC during a store buffer overflow so there is no need to
922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // store the registers in any particular way, but we do have to store and
923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // restore them.
924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < kNumberOfSavedRegs; i++) {
925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register reg = saved_regs[i];
926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
927763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      pushq(reg);
928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // R12 to r15 are callee save on all platforms.
931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (fp_mode == kSaveFPRegs) {
932fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
93394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      XMMRegister reg = XMMRegister::from_code(i);
935c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      movsd(Operand(rsp, i * kDoubleSize), reg);
936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode,
942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                    Register exclusion1,
943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                    Register exclusion2,
944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                    Register exclusion3) {
945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (fp_mode == kSaveFPRegs) {
94694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      XMMRegister reg = XMMRegister::from_code(i);
948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      movsd(reg, Operand(rsp, i * kDoubleSize));
949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
950fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) {
953c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register reg = saved_regs[i];
954c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
955763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      popq(reg);
956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
961528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) {
962528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  xorps(dst, dst);
963528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  cvtlsi2sd(dst, src);
964528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
965528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
966528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
967528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) {
968528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  xorps(dst, dst);
969528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  cvtlsi2sd(dst, src);
970528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
971528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
972528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
973d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) {
974dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  ASSERT(!r.IsDouble());
975935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (r.IsInteger8()) {
976935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    movsxbq(dst, src);
977935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  } else if (r.IsUInteger8()) {
978d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    movzxbl(dst, src);
979935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  } else if (r.IsInteger16()) {
980935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    movsxwq(dst, src);
981935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  } else if (r.IsUInteger16()) {
982935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    movzxwl(dst, src);
983d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  } else if (r.IsInteger32()) {
984d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    movl(dst, src);
985d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  } else {
98643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src);
987d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
988d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org}
989d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
990d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
991d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid MacroAssembler::Store(const Operand& dst, Register src, Representation r) {
992dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  ASSERT(!r.IsDouble());
993935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (r.IsInteger8() || r.IsUInteger8()) {
994d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    movb(dst, src);
995935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  } else if (r.IsInteger16() || r.IsUInteger16()) {
996935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    movw(dst, src);
997d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  } else if (r.IsInteger32()) {
998d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    movl(dst, src);
999d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  } else {
1000d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    if (r.IsHeapObject()) {
1001d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      AssertNotSmi(src);
1002d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    } else if (r.IsSmi()) {
1003d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      AssertSmi(src);
1004d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    }
100543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src);
1006d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1007d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org}
1008d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1009d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1010e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid MacroAssembler::Set(Register dst, int64_t x) {
101168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  if (x == 0) {
101269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    xorl(dst, dst);
1013e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  } else if (is_uint32(x)) {
1014c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    movl(dst, Immediate(static_cast<uint32_t>(x)));
1015a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  } else if (is_int32(x)) {
1016a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    movq(dst, Immediate(static_cast<int32_t>(x)));
1017e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  } else {
1018e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    movq(dst, x);
1019e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
1020e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org}
1021e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
1022e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1023f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MacroAssembler::Set(const Operand& dst, intptr_t x) {
1024f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (kPointerSize == kInt64Size) {
1025f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (is_int32(x)) {
1026f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      movp(dst, Immediate(static_cast<int32_t>(x)));
1027f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    } else {
1028f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Set(kScratchRegister, x);
1029f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      movp(dst, kScratchRegister);
1030f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
1031e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  } else {
1032f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    movp(dst, Immediate(static_cast<int32_t>(x)));
1033e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
1034e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org}
1035e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
10367a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
1037dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// ----------------------------------------------------------------------------
1038dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// Smi tagging, untagging and tag detection.
1039dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
1040dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgbool MacroAssembler::IsUnsafeInt(const int32_t x) {
10417a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  static const int kMaxBits = 17;
10427a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return !is_intn(x, kMaxBits);
10437a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
10447a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
10457a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
10467a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgvoid MacroAssembler::SafeMove(Register dst, Smi* src) {
10477a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(!dst.is(kScratchRegister));
10487a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
1049a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (SmiValuesAre32Bits()) {
1050a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      // JIT cookie can be converted to Smi.
1051a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
1052a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      Move(kScratchRegister, Smi::FromInt(jit_cookie()));
1053a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      xorp(dst, kScratchRegister);
1054a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    } else {
1055a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      ASSERT(SmiValuesAre31Bits());
1056a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
1057a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      movp(dst, Immediate(value ^ jit_cookie()));
1058a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      xorp(dst, Immediate(jit_cookie()));
1059a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
10607a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  } else {
10617a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org    Move(dst, src);
10627a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  }
10637a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
10647a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
10657a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
10667a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgvoid MacroAssembler::SafePush(Smi* src) {
10677a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
1068a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (SmiValuesAre32Bits()) {
1069a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      // JIT cookie can be converted to Smi.
1070a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      Push(Smi::FromInt(src->value() ^ jit_cookie()));
1071a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      Move(kScratchRegister, Smi::FromInt(jit_cookie()));
1072a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      xorp(Operand(rsp, 0), kScratchRegister);
1073a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    } else {
1074a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      ASSERT(SmiValuesAre31Bits());
1075a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
1076a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      Push(Immediate(value ^ jit_cookie()));
1077a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      xorp(Operand(rsp, 0), Immediate(jit_cookie()));
1078a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
10797a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  } else {
10807a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org    Push(src);
10817a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  }
10827a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
10837a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
10847a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
108569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgRegister MacroAssembler::GetSmiConstant(Smi* source) {
108669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  int value = source->value();
108769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  if (value == 0) {
108869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    xorl(kScratchRegister, kScratchRegister);
108969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    return kScratchRegister;
109069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
109169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  if (value == 1) {
109269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    return kSmiConstantRegister;
109369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
109469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  LoadSmiConstant(kScratchRegister, source);
109569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  return kScratchRegister;
109669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
109769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
1098e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
109969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid MacroAssembler::LoadSmiConstant(Register dst, Smi* source) {
1100badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
1101af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Move(dst, Smi::FromInt(kSmiConstantRegisterValue),
1102af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org         Assembler::RelocInfoNone());
110369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    cmpq(dst, kSmiConstantRegister);
11048a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Assert(equal, kUninitializedKSmiConstantRegister);
110569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
1106b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  int value = source->value();
1107b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  if (value == 0) {
110869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    xorl(dst, dst);
110969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    return;
111069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
111169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  bool negative = value < 0;
111269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  unsigned int uvalue = negative ? -value : value;
111369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
111469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  switch (uvalue) {
111569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 9:
1116895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(dst,
1117895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org           Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0));
111869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      break;
111969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 8:
112069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      xorl(dst, dst);
1121895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(dst, Operand(dst, kSmiConstantRegister, times_8, 0));
112269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      break;
112369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 4:
112469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      xorl(dst, dst);
1125895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(dst, Operand(dst, kSmiConstantRegister, times_4, 0));
112669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      break;
112769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 5:
1128895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(dst,
1129895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org           Operand(kSmiConstantRegister, kSmiConstantRegister, times_4, 0));
113069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      break;
113169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 3:
1132895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(dst,
1133895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org           Operand(kSmiConstantRegister, kSmiConstantRegister, times_2, 0));
113469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      break;
113569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 2:
1136895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      leap(dst,
1137895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org           Operand(kSmiConstantRegister, kSmiConstantRegister, times_1, 0));
113869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      break;
113969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 1:
114043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(dst, kSmiConstantRegister);
114169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      break;
114269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    case 0:
114369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      UNREACHABLE();
114469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      return;
114569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    default:
1146af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      Move(dst, source, Assembler::RelocInfoNone());
114769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      return;
114869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
114969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  if (negative) {
11507a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    negp(dst);
115169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
115269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
115369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
11544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1155c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::Integer32ToSmi(Register dst, Register src) {
115680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0);
11574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (!dst.is(src)) {
11584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    movl(dst, src);
11594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
11602f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shlp(dst, Immediate(kSmiShift));
11614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
11624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
11634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
11645ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
1165badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
11665ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    testb(dst, Immediate(0x01));
116783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label ok;
116883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(zero, &ok, Label::kNear);
11698a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Abort(kInteger32ToSmiFieldWritingToNonSmiLocation);
11705ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org    bind(&ok);
11715ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  }
117204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org
117304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (SmiValuesAre32Bits()) {
117404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    ASSERT(kSmiShift % kBitsPerByte == 0);
117504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movl(Operand(dst, kSmiShift / kBitsPerByte), src);
117604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  } else {
117704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
117804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    Integer32ToSmi(kScratchRegister, src);
117904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movp(dst, kScratchRegister);
118004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
11815ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
11825ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
11835ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
11849d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::Integer64PlusConstantToSmi(Register dst,
11859d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                                                Register src,
11869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                                                int constant) {
11879d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (dst.is(src)) {
11887979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    addl(dst, Immediate(constant));
11899d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
11907979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    leal(dst, Operand(src, constant));
11919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
11922f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shlp(dst, Immediate(kSmiShift));
11934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
11944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
11954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
11964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiToInteger32(Register dst, Register src) {
119780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0);
11984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (!dst.is(src)) {
119943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src);
12004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
120104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org
120204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (SmiValuesAre32Bits()) {
120304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    shrp(dst, Immediate(kSmiShift));
120404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  } else {
120504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
120604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    sarl(dst, Immediate(kSmiShift));
120704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
12084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
12094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
121130ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid MacroAssembler::SmiToInteger32(Register dst, const Operand& src) {
121204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (SmiValuesAre32Bits()) {
121304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movl(dst, Operand(src, kSmiShift / kBitsPerByte));
121404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  } else {
121504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
121604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movl(dst, src);
121704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    sarl(dst, Immediate(kSmiShift));
121804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
121930ce411529579186181838984710b0b0980857aaricow@chromium.org}
122030ce411529579186181838984710b0b0980857aaricow@chromium.org
122130ce411529579186181838984710b0b0980857aaricow@chromium.org
12224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiToInteger64(Register dst, Register src) {
122380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0);
12249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (!dst.is(src)) {
122543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src);
12264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
122704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  sarp(dst, Immediate(kSmiShift));
122804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (kPointerSize == kInt32Size) {
122904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    // Sign extend to 64-bit.
123004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movsxlq(dst, dst);
123104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
12324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
12334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12355ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
123604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (SmiValuesAre32Bits()) {
123704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
123804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  } else {
123904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
124004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movp(dst, src);
124104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    SmiToInteger64(dst, dst);
124204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
12435ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
12445ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
12455ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
12469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiTest(Register src) {
1247ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  AssertSmi(src);
12487a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(src, src);
12494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
12504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1252badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::SmiCompare(Register smi1, Register smi2) {
1253c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(smi1);
1254c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(smi2);
12557a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(smi1, smi2);
12564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
12574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(Register dst, Smi* src) {
1260c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(dst);
1261badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  Cmp(dst, src);
1262badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org}
1263badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
1264badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
1265badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::Cmp(Register dst, Smi* src) {
12669d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(!dst.is(kScratchRegister));
12679d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (src->value() == 0) {
12687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    testp(dst, dst);
12699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
1270ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    Register constant_reg = GetSmiConstant(src);
12717a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(dst, constant_reg);
12724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
12734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
12744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
12769155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgvoid MacroAssembler::SmiCompare(Register dst, const Operand& src) {
1277c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(dst);
1278c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(src);
12797a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(dst, src);
1280ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org}
1281ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
1282ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
12839d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(const Operand& dst, Register src) {
1284c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(dst);
1285c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(src);
12867a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(dst, src);
1287c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
1288c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
1289c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
12909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
1291c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  AssertSmi(dst);
129204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (SmiValuesAre32Bits()) {
129304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
129404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  } else {
129504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
129604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    cmpl(dst, Immediate(src));
129704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
12984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
12994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1301badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::Cmp(const Operand& dst, Smi* src) {
1302badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // The Operand cannot use the smi register.
1303badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  Register smi_reg = GetSmiConstant(src);
1304badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  ASSERT(!dst.AddressUsesRegister(smi_reg));
13057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(dst, smi_reg);
1306badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org}
1307badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
1308badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
13095ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) {
131004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (SmiValuesAre32Bits()) {
131104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
131204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  } else {
131304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
131404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    SmiToInteger32(kScratchRegister, dst);
131504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    cmpl(kScratchRegister, src);
131604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
13175ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
13185ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
13195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
13209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
13219d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                                                           Register src,
13229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                                                           int power) {
13239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(power >= 0);
13249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(power < 64);
13259d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (power == 0) {
13269d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    SmiToInteger64(dst, src);
13279d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    return;
13289d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
13299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (!dst.is(src)) {
133043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src);
13319d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
13329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (power < kSmiShift) {
13332f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    sarp(dst, Immediate(kSmiShift - power));
13349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else if (power > kSmiShift) {
13352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    shlp(dst, Immediate(power - kSmiShift));
13369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
13374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
13384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
134030ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst,
134130ce411529579186181838984710b0b0980857aaricow@chromium.org                                                         Register src,
134230ce411529579186181838984710b0b0980857aaricow@chromium.org                                                         int power) {
134330ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((0 <= power) && (power < 32));
134430ce411529579186181838984710b0b0980857aaricow@chromium.org  if (dst.is(src)) {
13452f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    shrp(dst, Immediate(power + kSmiShift));
134630ce411529579186181838984710b0b0980857aaricow@chromium.org  } else {
134730ce411529579186181838984710b0b0980857aaricow@chromium.org    UNIMPLEMENTED();  // Not used.
134830ce411529579186181838984710b0b0980857aaricow@chromium.org  }
134930ce411529579186181838984710b0b0980857aaricow@chromium.org}
135030ce411529579186181838984710b0b0980857aaricow@chromium.org
135130ce411529579186181838984710b0b0980857aaricow@chromium.org
135283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2,
135383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                 Label* on_not_smis,
135483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                 Label::Distance near_jump) {
135583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (dst.is(src1) || dst.is(src2)) {
135683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(!src1.is(kScratchRegister));
135783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(!src2.is(kScratchRegister));
135843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(kScratchRegister, src1);
1359895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    orp(kScratchRegister, src2);
136083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump);
136143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, kScratchRegister);
136283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
136343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src1);
1364895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    orp(dst, src2);
136583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    JumpIfNotSmi(dst, on_not_smis, near_jump);
136683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
136783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
136883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
136983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
13709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comCondition MacroAssembler::CheckSmi(Register src) {
137180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0);
13724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  testb(src, Immediate(kSmiTagMask));
13739d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  return zero;
13744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
13754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgCondition MacroAssembler::CheckSmi(const Operand& src) {
137880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0);
13790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  testb(src, Immediate(kSmiTagMask));
13800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  return zero;
13810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
13820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
13830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
1384eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgCondition MacroAssembler::CheckNonNegativeSmi(Register src) {
138580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0);
13868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Test that both bits of the mask 0x8000000000000001 are zero.
138743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(kScratchRegister, src);
13882f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  rolp(kScratchRegister, Immediate(1));
138969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  testb(kScratchRegister, Immediate(3));
13904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  return zero;
13914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
13924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckBothSmi(Register first, Register second) {
13954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (first.is(second)) {
13964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    return CheckSmi(first);
13974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
139880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3);
13994ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  if (SmiValuesAre32Bits()) {
14004ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    leal(kScratchRegister, Operand(first, second, times_1, 0));
14014ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    testb(kScratchRegister, Immediate(0x03));
14024ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  } else {
14034ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
14044ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    movl(kScratchRegister, first);
14054ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    orl(kScratchRegister, second);
14064ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    testb(kScratchRegister, Immediate(kSmiTagMask));
14074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
14089d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  return zero;
14094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
14104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
14114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1412eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgCondition MacroAssembler::CheckBothNonNegativeSmi(Register first,
1413eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org                                                  Register second) {
1414b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (first.is(second)) {
1415eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org    return CheckNonNegativeSmi(first);
1416b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
141743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(kScratchRegister, first);
1418895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  orp(kScratchRegister, second);
14192f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  rolp(kScratchRegister, Immediate(1));
1420eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  testl(kScratchRegister, Immediate(3));
1421b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return zero;
1422b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
1423b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1424b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1425c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgCondition MacroAssembler::CheckEitherSmi(Register first,
1426c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                                         Register second,
1427c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                                         Register scratch) {
1428b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (first.is(second)) {
1429b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return CheckSmi(first);
1430b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
1431c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  if (scratch.is(second)) {
1432c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    andl(scratch, first);
1433c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  } else {
1434c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    if (!scratch.is(first)) {
1435c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org      movl(scratch, first);
1436c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    }
1437c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org    andl(scratch, second);
1438c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  }
1439c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  testb(scratch, Immediate(kSmiTagMask));
1440b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return zero;
1441b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
1442b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1443b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
14444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckIsMinSmi(Register src) {
144569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  ASSERT(!src.is(kScratchRegister));
144669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // If we overflow by subtracting one, it's the minimal smi value.
14477a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(src, kSmiConstantRegister);
144869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  return overflow;
14494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
14504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1451c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
14524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckInteger32ValidSmiValue(Register src) {
14534ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  if (SmiValuesAre32Bits()) {
14544ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    // A 32-bit integer value can always be converted to a smi.
14554ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    return always;
14564ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  } else {
14574ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
14584ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    cmpl(src, Immediate(0xc0000000));
14594ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    return positive;
14604ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
14614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
14624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
14634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
14643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgCondition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) {
14654ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  if (SmiValuesAre32Bits()) {
14664ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    // An unsigned 32-bit integer value is valid as long as the high bit
14674ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    // is not set.
14684ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    testl(src, src);
14694ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    return positive;
14704ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  } else {
14714ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
14724ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    testl(src, Immediate(0xc0000000));
14734ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    return zero;
14744ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
14753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
14763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::CheckSmiToIndicator(Register dst, Register src) {
14790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (dst.is(src)) {
14800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    andl(dst, Immediate(kSmiTagMask));
14810ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  } else {
14820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    movl(dst, Immediate(kSmiTagMask));
14830ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    andl(dst, src);
14840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  }
14850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org}
14860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
14870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
14880ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) {
14890ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (!(src.AddressUsesRegister(dst))) {
14900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    movl(dst, Immediate(kSmiTagMask));
14910ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    andl(dst, src);
14920ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  } else {
14930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    movl(dst, src);
14940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    andl(dst, Immediate(kSmiTagMask));
14950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  }
14960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org}
14970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
14980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
1499e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid MacroAssembler::JumpIfValidSmiValue(Register src,
1500e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                         Label* on_valid,
1501e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                         Label::Distance near_jump) {
1502e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  Condition is_valid = CheckInteger32ValidSmiValue(src);
1503e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  j(is_valid, on_valid, near_jump);
1504e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org}
1505e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
1506e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
150783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotValidSmiValue(Register src,
150883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Label* on_invalid,
150983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Label::Distance near_jump) {
151083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition is_valid = CheckInteger32ValidSmiValue(src);
151183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(NegateCondition(is_valid), on_invalid, near_jump);
151283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
151383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
151483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1515e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid MacroAssembler::JumpIfUIntValidSmiValue(Register src,
1516e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                             Label* on_valid,
1517e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                             Label::Distance near_jump) {
1518e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  Condition is_valid = CheckUInteger32ValidSmiValue(src);
1519e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  j(is_valid, on_valid, near_jump);
1520e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org}
1521e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
1522e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
152383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfUIntNotValidSmiValue(Register src,
152483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                                Label* on_invalid,
152583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                                Label::Distance near_jump) {
152683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition is_valid = CheckUInteger32ValidSmiValue(src);
152783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(NegateCondition(is_valid), on_invalid, near_jump);
152883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
152983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
153083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
153183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfSmi(Register src,
153283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Label* on_smi,
153383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Label::Distance near_jump) {
153483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition smi = CheckSmi(src);
153583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(smi, on_smi, near_jump);
153683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
153783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
153883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
153983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotSmi(Register src,
154083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Label* on_not_smi,
154183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Label::Distance near_jump) {
154283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition smi = CheckSmi(src);
154383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(NegateCondition(smi), on_not_smi, near_jump);
154483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
154583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
154683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
154783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpUnlessNonNegativeSmi(
154883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register src, Label* on_not_smi_or_negative,
154983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label::Distance near_jump) {
155083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition non_negative_smi = CheckNonNegativeSmi(src);
155183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(NegateCondition(non_negative_smi), on_not_smi_or_negative, near_jump);
155283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
155383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
155483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
155583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfSmiEqualsConstant(Register src,
155683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                             Smi* constant,
155783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                             Label* on_equals,
155883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                             Label::Distance near_jump) {
155983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  SmiCompare(src, constant);
156083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(equal, on_equals, near_jump);
156183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
156283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
156383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
156483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotBothSmi(Register src1,
156583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                      Register src2,
156683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                      Label* on_not_both_smi,
156783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                      Label::Distance near_jump) {
156883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition both_smi = CheckBothSmi(src1, src2);
156983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(NegateCondition(both_smi), on_not_both_smi, near_jump);
157083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
157183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
157283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
157383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1,
157483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                                  Register src2,
157583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                                  Label* on_not_both_smi,
157683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                                  Label::Distance near_jump) {
157783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition both_smi = CheckBothNonNegativeSmi(src1, src2);
157883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(NegateCondition(both_smi), on_not_both_smi, near_jump);
157983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
158083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
158183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
15829d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
15839d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (constant->value() == 0) {
15849d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    if (!dst.is(src)) {
158543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(dst, src);
15869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    }
158769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    return;
15889d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else if (dst.is(src)) {
15899d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    ASSERT(!dst.is(kScratchRegister));
159069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    switch (constant->value()) {
159169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 1:
1592fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        addp(dst, kSmiConstantRegister);
159369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
159469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 2:
1595895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        leap(dst, Operand(src, kSmiConstantRegister, times_2, 0));
159669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
159769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 4:
1598895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        leap(dst, Operand(src, kSmiConstantRegister, times_4, 0));
159969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
160069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 8:
1601895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        leap(dst, Operand(src, kSmiConstantRegister, times_8, 0));
160269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
160369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      default:
160469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        Register constant_reg = GetSmiConstant(constant);
1605fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        addp(dst, constant_reg);
160669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
160769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    }
16084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  } else {
160969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    switch (constant->value()) {
161069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 1:
1611895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        leap(dst, Operand(src, kSmiConstantRegister, times_1, 0));
161269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
161369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 2:
1614895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        leap(dst, Operand(src, kSmiConstantRegister, times_2, 0));
161569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
161669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 4:
1617895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        leap(dst, Operand(src, kSmiConstantRegister, times_4, 0));
161869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
161969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      case 8:
1620895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        leap(dst, Operand(src, kSmiConstantRegister, times_8, 0));
162169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
162269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      default:
162369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        LoadSmiConstant(dst, constant);
1624fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        addp(dst, src);
162569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org        return;
162669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    }
16274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
16284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
16294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
16304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
16319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comvoid MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
16329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (constant->value() != 0) {
16334ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    if (SmiValuesAre32Bits()) {
16344ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org      addl(Operand(dst, kSmiShift / kBitsPerByte),
16354ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org           Immediate(constant->value()));
16364ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    } else {
16374ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org      ASSERT(SmiValuesAre31Bits());
16384ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org      addp(dst, Immediate(constant));
16394ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    }
16409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
16419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
16429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
16439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
164483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAddConstant(Register dst,
164583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Register src,
164683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Smi* constant,
1647e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                    SmiOperationExecutionMode mode,
1648e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                    Label* bailout_label,
164983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Label::Distance near_jump) {
165083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (constant->value() == 0) {
165183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (!dst.is(src)) {
165243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(dst, src);
165383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
165483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else if (dst.is(src)) {
165583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(!dst.is(kScratchRegister));
165683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    LoadSmiConstant(kScratchRegister, constant);
1657fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(dst, kScratchRegister);
1658e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) {
1659e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      j(no_overflow, bailout_label, near_jump);
1660e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1661fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      subp(dst, kScratchRegister);
1662e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) {
1663e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      if (mode.Contains(PRESERVE_SOURCE_REGISTER)) {
1664e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        Label done;
1665e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        j(no_overflow, &done, Label::kNear);
1666fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        subp(dst, kScratchRegister);
1667e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        jmp(bailout_label, near_jump);
1668e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        bind(&done);
1669e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      } else {
1670e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        // Bailout if overflow without reserving src.
1671e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        j(overflow, bailout_label, near_jump);
1672e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      }
1673e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    } else {
1674e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      CHECK(mode.IsEmpty());
1675e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
167683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
1677e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1678e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW));
167983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    LoadSmiConstant(dst, constant);
1680fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(dst, src);
1681e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    j(overflow, bailout_label, near_jump);
168283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
168383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
168483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
168583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
16869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) {
16879d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (constant->value() == 0) {
16884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    if (!dst.is(src)) {
168943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(dst, src);
16904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    }
16919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else if (dst.is(src)) {
16929d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    ASSERT(!dst.is(kScratchRegister));
169369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    Register constant_reg = GetSmiConstant(constant);
1694fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(dst, constant_reg);
16959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
16969d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    if (constant->value() == Smi::kMinValue) {
169769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      LoadSmiConstant(dst, constant);
16985ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org      // Adding and subtracting the min-value gives the same result, it only
16995ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org      // differs on the overflow bit, which we don't check here.
1700fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      addp(dst, src);
17014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    } else {
17025ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org      // Subtract by adding the negation.
170369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org      LoadSmiConstant(dst, Smi::FromInt(-constant->value()));
1704fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      addp(dst, src);
17054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    }
17064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
17074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
17084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
17094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
171083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiSubConstant(Register dst,
171183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Register src,
171283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Smi* constant,
1713e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                    SmiOperationExecutionMode mode,
1714e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                    Label* bailout_label,
171583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Label::Distance near_jump) {
171683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (constant->value() == 0) {
171783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (!dst.is(src)) {
171843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(dst, src);
171983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
172083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else if (dst.is(src)) {
172183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(!dst.is(kScratchRegister));
1722e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    LoadSmiConstant(kScratchRegister, constant);
1723fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(dst, kScratchRegister);
1724e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) {
1725e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      j(no_overflow, bailout_label, near_jump);
1726e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1727fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      addp(dst, kScratchRegister);
1728e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) {
1729e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      if (mode.Contains(PRESERVE_SOURCE_REGISTER)) {
1730e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        Label done;
1731e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        j(no_overflow, &done, Label::kNear);
1732fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        addp(dst, kScratchRegister);
1733e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        jmp(bailout_label, near_jump);
1734e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        bind(&done);
1735e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      } else {
1736e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        // Bailout if overflow without reserving src.
1737e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        j(overflow, bailout_label, near_jump);
1738e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      }
173983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
1740e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      CHECK(mode.IsEmpty());
174183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
174283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
1743e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER));
1744e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW));
174583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (constant->value() == Smi::kMinValue) {
1746e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      ASSERT(!dst.is(kScratchRegister));
174743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(dst, src);
1748e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      LoadSmiConstant(kScratchRegister, constant);
1749fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      subp(dst, kScratchRegister);
1750e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      j(overflow, bailout_label, near_jump);
175183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
175283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      // Subtract by adding the negation.
175383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      LoadSmiConstant(dst, Smi::FromInt(-(constant->value())));
1754fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      addp(dst, src);
1755e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      j(overflow, bailout_label, near_jump);
175683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
175783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
175883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
175983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
176083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
176183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiNeg(Register dst,
176283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src,
176383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_smi_result,
176483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump) {
176583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (dst.is(src)) {
176683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(!dst.is(kScratchRegister));
176743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(kScratchRegister, src);
17687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    negp(dst);  // Low 32 bits are retained as zero by negation.
176983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Test if result is zero or Smi::kMinValue.
17707a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(dst, kScratchRegister);
177183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(not_equal, on_smi_result, near_jump);
177243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(src, kScratchRegister);
177383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
177443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src);
17757a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    negp(dst);
17767a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(dst, src);
177783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // If the result is zero or Smi::kMinValue, negation failed to create a smi.
177883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(not_equal, on_smi_result, near_jump);
177983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
178083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
178183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
178283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1783d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgtemplate<class T>
1784d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic void SmiAddHelper(MacroAssembler* masm,
1785d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                         Register dst,
1786d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                         Register src1,
1787d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                         T src2,
1788d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                         Label* on_not_smi_result,
1789d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                         Label::Distance near_jump) {
1790d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (dst.is(src1)) {
1791d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    Label done;
1792fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    masm->addp(dst, src2);
1793d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    masm->j(no_overflow, &done, Label::kNear);
1794d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    // Restore src1.
1795fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    masm->subp(dst, src2);
1796d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    masm->jmp(on_not_smi_result, near_jump);
1797d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    masm->bind(&done);
1798d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  } else {
179943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    masm->movp(dst, src1);
1800fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    masm->addp(dst, src2);
1801d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    masm->j(overflow, on_not_smi_result, near_jump);
1802d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1803d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org}
1804d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1805d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
180683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAdd(Register dst,
180783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src1,
180883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src2,
180983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_not_smi_result,
181083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump) {
181183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT_NOT_NULL(on_not_smi_result);
181283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(src2));
1813d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
181483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
181583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
181683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
181783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAdd(Register dst,
181883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src1,
181983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            const Operand& src2,
182083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_not_smi_result,
182183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump) {
182283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT_NOT_NULL(on_not_smi_result);
1823d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  ASSERT(!src2.AddressUsesRegister(dst));
1824d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
182583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
182683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
182783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1828c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::SmiAdd(Register dst,
1829c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org                            Register src1,
1830c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org                            Register src2) {
1831c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // No overflow checking. Use only when it's known that
1832c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // overflowing is impossible.
18337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  if (!dst.is(src1)) {
1834160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (emit_debug_code()) {
183543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(kScratchRegister, src1);
1836fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      addp(kScratchRegister, src2);
1837594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Check(no_overflow, kSmiAdditionOverflow);
1838160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
1839895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    leap(dst, Operand(src1, src2, times_1, 0));
1840160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  } else {
1841fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(dst, src2);
1842594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Assert(no_overflow, kSmiAdditionOverflow);
18434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
18444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
18454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
18464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1847c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgtemplate<class T>
1848c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgstatic void SmiSubHelper(MacroAssembler* masm,
1849c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                         Register dst,
1850c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                         Register src1,
1851c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                         T src2,
1852c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                         Label* on_not_smi_result,
1853c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                         Label::Distance near_jump) {
185483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (dst.is(src1)) {
1855c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    Label done;
1856fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    masm->subp(dst, src2);
1857c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    masm->j(no_overflow, &done, Label::kNear);
1858c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    // Restore src1.
1859fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    masm->addp(dst, src2);
1860c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    masm->jmp(on_not_smi_result, near_jump);
1861c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    masm->bind(&done);
186283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
186343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    masm->movp(dst, src1);
1864fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    masm->subp(dst, src2);
1865c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    masm->j(overflow, on_not_smi_result, near_jump);
186683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
186783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
186883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
186983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1870c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst,
1871c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                            Register src1,
1872c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                            Register src2,
1873c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                            Label* on_not_smi_result,
1874c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                            Label::Distance near_jump) {
1875c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  ASSERT_NOT_NULL(on_not_smi_result);
1876c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  ASSERT(!dst.is(src2));
1877c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
18784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
18794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
18804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1881c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::SmiSub(Register dst,
18824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                            Register src1,
188383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            const Operand& src2,
188483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_not_smi_result,
188583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump) {
188683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT_NOT_NULL(on_not_smi_result);
1887c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  ASSERT(!src2.AddressUsesRegister(dst));
1888c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
188983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
189083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
189183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1892c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgtemplate<class T>
1893c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgstatic void SmiSubNoOverflowHelper(MacroAssembler* masm,
1894c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                                   Register dst,
1895c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                                   Register src1,
1896c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                                   T src2) {
1897c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // No overflow checking. Use only when it's known that
1898c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // overflowing is impossible (e.g., subtracting two positive smis).
18997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  if (!dst.is(src1)) {
190043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    masm->movp(dst, src1);
19014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
1902fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  masm->subp(dst, src2);
1903c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  masm->Assert(no_overflow, kSmiSubtractionOverflow);
1904c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org}
1905c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
1906c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
1907c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
1908c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  ASSERT(!dst.is(src2));
1909c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  SmiSubNoOverflowHelper<Register>(this, dst, src1, src2);
1910c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org}
1911c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
1912c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
1913c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst,
1914c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                            Register src1,
1915c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                            const Operand& src2) {
1916c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2);
19174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
19184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
19194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
192083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiMul(Register dst,
192183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src1,
192283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src2,
192383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_not_smi_result,
192483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump) {
192583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(src2));
192683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(kScratchRegister));
192783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(kScratchRegister));
192883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(kScratchRegister));
192983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
193083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (dst.is(src1)) {
193183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label failure, zero_correct_result;
193243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(kScratchRegister, src1);  // Create backup for later testing.
193383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    SmiToInteger64(dst, src1);
1934fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    imulp(dst, src2);
193583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(overflow, &failure, Label::kNear);
193683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
193783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Check for negative zero result.  If product is zero, and one
193883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // argument is negative, go to slow case.
193983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label correct_result;
19407a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    testp(dst, dst);
194183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(not_zero, &correct_result, Label::kNear);
194283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
194343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, kScratchRegister);
1944895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    xorp(dst, src2);
194583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Result was positive zero.
194683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(positive, &zero_correct_result, Label::kNear);
194783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
194883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    bind(&failure);  // Reused failure exit, restores src1.
194943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(src1, kScratchRegister);
195083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    jmp(on_not_smi_result, near_jump);
195183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
195283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    bind(&zero_correct_result);
195383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Set(dst, 0);
195483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
195583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    bind(&correct_result);
195683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
195783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    SmiToInteger64(dst, src1);
1958fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    imulp(dst, src2);
195983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(overflow, on_not_smi_result, near_jump);
196083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Check for negative zero result.  If product is zero, and one
196183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // argument is negative, go to slow case.
196283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label correct_result;
19637a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    testp(dst, dst);
196483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(not_zero, &correct_result, Label::kNear);
196583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // One of src1 and src2 is zero, the check whether the other is
196683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // negative.
196743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(kScratchRegister, src1);
1968895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    xorp(kScratchRegister, src2);
196983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(negative, on_not_smi_result, near_jump);
197083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    bind(&correct_result);
197183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
197283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
197383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
197483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
197583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiDiv(Register dst,
197683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src1,
197783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src2,
197883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_not_smi_result,
197983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump) {
198083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(kScratchRegister));
198183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(kScratchRegister));
198283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(kScratchRegister));
198383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(rax));
198483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(rdx));
198583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(rdx));
198683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
198783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Check for 0 divisor (result is +/-Infinity).
19887a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(src2, src2);
198983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(zero, on_not_smi_result, near_jump);
199083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
199183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (src1.is(rax)) {
199243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(kScratchRegister, src1);
199383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
199483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  SmiToInteger32(rax, src1);
199583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // We need to rule out dividing Smi::kMinValue by -1, since that would
199683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // overflow in idiv and raise an exception.
199783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // We combine this with negative zero test (negative zero only happens
199883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // when dividing zero by a negative number).
199983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
200083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // We overshoot a little and go to slow case if we divide min-value
200183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // by any negative value, not just -1.
200283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label safe_div;
2003e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  testl(rax, Immediate(~Smi::kMinValue));
200483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_zero, &safe_div, Label::kNear);
20057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(src2, src2);
200683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (src1.is(rax)) {
200783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(positive, &safe_div, Label::kNear);
200843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(src1, kScratchRegister);
200983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    jmp(on_not_smi_result, near_jump);
201083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
201183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(negative, on_not_smi_result, near_jump);
201283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
201383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  bind(&safe_div);
201483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
201583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  SmiToInteger32(src2, src2);
201683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Sign extend src1 into edx:eax.
201783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  cdq();
201883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  idivl(src2);
201983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Integer32ToSmi(src2, src2);
202083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Check that the remainder is zero.
202183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  testl(rdx, rdx);
202283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (src1.is(rax)) {
202383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label smi_result;
202483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(zero, &smi_result, Label::kNear);
202543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(src1, kScratchRegister);
202683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    jmp(on_not_smi_result, near_jump);
202783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    bind(&smi_result);
202883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
202983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    j(not_zero, on_not_smi_result, near_jump);
203083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
203183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (!dst.is(src1) && src1.is(rax)) {
203243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(src1, kScratchRegister);
203383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
203483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Integer32ToSmi(dst, rax);
203583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
203683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
203783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
203883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiMod(Register dst,
203983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src1,
204083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Register src2,
204183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_not_smi_result,
204283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump) {
204383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(kScratchRegister));
204483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(kScratchRegister));
204583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(kScratchRegister));
204683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(rax));
204783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(rdx));
204883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(rdx));
204983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(src2));
205083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
20517a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(src2, src2);
205283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(zero, on_not_smi_result, near_jump);
205383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
205483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (src1.is(rax)) {
205543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(kScratchRegister, src1);
205683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
205783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  SmiToInteger32(rax, src1);
205883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  SmiToInteger32(src2, src2);
205983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
206083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow).
206183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label safe_div;
206283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  cmpl(rax, Immediate(Smi::kMinValue));
206383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_equal, &safe_div, Label::kNear);
206483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  cmpl(src2, Immediate(-1));
206583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_equal, &safe_div, Label::kNear);
206683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Retag inputs and go slow case.
206783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Integer32ToSmi(src2, src2);
206883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (src1.is(rax)) {
206943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(src1, kScratchRegister);
207083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
207183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  jmp(on_not_smi_result, near_jump);
207283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  bind(&safe_div);
207383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
207483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Sign extend eax into edx:eax.
207583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  cdq();
207683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  idivl(src2);
207783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Restore smi tags on inputs.
207883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Integer32ToSmi(src2, src2);
207983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (src1.is(rax)) {
208043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(src1, kScratchRegister);
208183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
208283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Check for a negative zero result.  If the result is zero, and the
208383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // dividend is negative, go slow to return a floating point negative zero.
208483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label smi_result;
208583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  testl(rdx, rdx);
208683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_zero, &smi_result, Label::kNear);
20877a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(src1, src1);
208883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(negative, on_not_smi_result, near_jump);
208983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  bind(&smi_result);
209083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Integer32ToSmi(dst, rdx);
209183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
209283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
209383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
20944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiNot(Register dst, Register src) {
20959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(!dst.is(kScratchRegister));
20969d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(!src.is(kScratchRegister));
20974ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  if (SmiValuesAre32Bits()) {
20984ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    // Set tag and padding bits before negating, so that they are zero
20994ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    // afterwards.
21004ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    movl(kScratchRegister, Immediate(~0));
21014ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  } else {
21024ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
21034ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    movl(kScratchRegister, Immediate(1));
21044ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
21054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (dst.is(src)) {
2106895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    xorp(dst, kScratchRegister);
21074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  } else {
2108895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    leap(dst, Operand(src, kScratchRegister, times_1, 0));
21094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
2110895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  notp(dst);
21114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) {
21159d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(!dst.is(src2));
21164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (!dst.is(src1)) {
211743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src1);
21184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
2119895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(dst, src2);
21204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) {
21249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (constant->value() == 0) {
21255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    Set(dst, 0);
21269d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else if (dst.is(src)) {
21279d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    ASSERT(!dst.is(kScratchRegister));
212869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    Register constant_reg = GetSmiConstant(constant);
2129895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    andp(dst, constant_reg);
21309d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
213169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    LoadSmiConstant(dst, constant);
2132895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    andp(dst, src);
21334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
21344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiOr(Register dst, Register src1, Register src2) {
21384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (!dst.is(src1)) {
213944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    ASSERT(!src1.is(src2));
214043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src1);
21414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
2142895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  orp(dst, src2);
21434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) {
21479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (dst.is(src)) {
21489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    ASSERT(!dst.is(kScratchRegister));
214969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    Register constant_reg = GetSmiConstant(constant);
2150895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    orp(dst, constant_reg);
21519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
215269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    LoadSmiConstant(dst, constant);
2153895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    orp(dst, src);
21544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
21554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
21584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiXor(Register dst, Register src1, Register src2) {
21594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (!dst.is(src1)) {
216044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    ASSERT(!src1.is(src2));
216143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src1);
21624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
2163895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  xorp(dst, src2);
21644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21679d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) {
21689d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (dst.is(src)) {
21699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    ASSERT(!dst.is(kScratchRegister));
217069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    Register constant_reg = GetSmiConstant(constant);
2171895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    xorp(dst, constant_reg);
21729d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
217369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    LoadSmiConstant(dst, constant);
2174895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    xorp(dst, src);
21754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
21764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftArithmeticRightConstant(Register dst,
21804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                                     Register src,
21814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                                     int shift_value) {
21829d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(is_uint5(shift_value));
21834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  if (shift_value > 0) {
21844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    if (dst.is(src)) {
21852f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org      sarp(dst, Immediate(shift_value + kSmiShift));
21862f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org      shlp(dst, Immediate(kSmiShift));
21874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    } else {
21884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org      UNIMPLEMENTED();  // Not used.
21894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    }
21904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
21914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
21924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
21944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftLeftConstant(Register dst,
21954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                          Register src,
2196e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                          int shift_value,
2197e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                          Label* on_not_smi_result,
2198e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                          Label::Distance near_jump) {
2199e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  if (SmiValuesAre32Bits()) {
2200e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (!dst.is(src)) {
2201e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      movp(dst, src);
2202e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    }
2203e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (shift_value > 0) {
2204e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      // Shift amount specified by lower 5 bits, not six as the shl opcode.
2205e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      shlq(dst, Immediate(shift_value & 0x1f));
2206e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    }
2207e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  } else {
2208e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
2209e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (dst.is(src)) {
2210e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      UNIMPLEMENTED();  // Not used.
2211e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    } else {
2212e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      SmiToInteger32(dst, src);
2213e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      shll(dst, Immediate(shift_value));
2214e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump);
2215e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      Integer32ToSmi(dst, dst);
2216e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    }
22174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
22184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
22194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
22204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
222183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiShiftLogicalRightConstant(
222283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register dst, Register src, int shift_value,
222383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label* on_not_smi_result, Label::Distance near_jump) {
222483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Logic right shift interprets its result as an *unsigned* number.
222583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (dst.is(src)) {
222683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    UNIMPLEMENTED();  // Not used.
222783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
222883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (shift_value == 0) {
2229e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      testp(src, src);
223083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      j(negative, on_not_smi_result, near_jump);
223183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
2232e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (SmiValuesAre32Bits()) {
2233e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      movp(dst, src);
2234e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      shrp(dst, Immediate(shift_value + kSmiShift));
2235e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      shlp(dst, Immediate(kSmiShift));
2236e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    } else {
2237e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      ASSERT(SmiValuesAre31Bits());
2238e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      SmiToInteger32(dst, src);
2239e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      shrp(dst, Immediate(shift_value));
2240e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump);
2241e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      Integer32ToSmi(dst, dst);
2242e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    }
224383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
224483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
224583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
224683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
22474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftLeft(Register dst,
22484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                  Register src1,
2249e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                  Register src2,
2250e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                  Label* on_not_smi_result,
2251e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                  Label::Distance near_jump) {
2252e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  if (SmiValuesAre32Bits()) {
2253e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(!dst.is(rcx));
2254e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (!dst.is(src1)) {
2255e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      movp(dst, src1);
2256e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    }
2257e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    // Untag shift amount.
2258e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    SmiToInteger32(rcx, src2);
2259e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    // Shift amount specified by lower 5 bits, not six as the shl opcode.
2260e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    andp(rcx, Immediate(0x1f));
2261e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    shlq_cl(dst);
2262e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  } else {
2263e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
2264e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(!dst.is(kScratchRegister));
2265e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(!src1.is(kScratchRegister));
2266e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(!src2.is(kScratchRegister));
2267e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(!dst.is(src2));
2268e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    ASSERT(!dst.is(rcx));
2269e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
2270e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (src1.is(rcx) || src2.is(rcx)) {
2271e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      movq(kScratchRegister, rcx);
2272e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    }
2273e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (dst.is(src1)) {
2274e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      UNIMPLEMENTED();  // Not used.
2275e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    } else {
2276e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      Label valid_result;
2277e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      SmiToInteger32(dst, src1);
2278e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      SmiToInteger32(rcx, src2);
2279e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      shll_cl(dst);
2280e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      JumpIfValidSmiValue(dst, &valid_result, Label::kNear);
2281e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      // As src1 or src2 could not be dst, we do not need to restore them for
2282e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      // clobbering dst.
2283e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if (src1.is(rcx) || src2.is(rcx)) {
2284e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        if (src1.is(rcx)) {
2285e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          movq(src1, kScratchRegister);
2286e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        } else {
2287e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          movq(src2, kScratchRegister);
2288e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        }
2289e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      }
2290e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      jmp(on_not_smi_result, near_jump);
2291e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      bind(&valid_result);
2292e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      Integer32ToSmi(dst, dst);
2293e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    }
22944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
22954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
22964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
22974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
229883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiShiftLogicalRight(Register dst,
229983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                          Register src1,
230083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                          Register src2,
230183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                          Label* on_not_smi_result,
230283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                          Label::Distance near_jump) {
230383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(kScratchRegister));
230483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(kScratchRegister));
230583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(kScratchRegister));
2306e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  ASSERT(!dst.is(src2));
230783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(rcx));
230883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (src1.is(rcx) || src2.is(rcx)) {
230983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    movq(kScratchRegister, rcx);
231083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
2311e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  if (dst.is(src1)) {
2312e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    UNIMPLEMENTED();  // Not used.
231383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
2314e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    Label valid_result;
2315e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    SmiToInteger32(dst, src1);
2316e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    SmiToInteger32(rcx, src2);
2317e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    shrl_cl(dst);
2318e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    JumpIfUIntValidSmiValue(dst, &valid_result, Label::kNear);
2319e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    // As src1 or src2 could not be dst, we do not need to restore them for
2320e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    // clobbering dst.
2321e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (src1.is(rcx) || src2.is(rcx)) {
2322e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if (src1.is(rcx)) {
2323e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        movq(src1, kScratchRegister);
2324e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      } else {
2325e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        movq(src2, kScratchRegister);
2326e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      }
2327e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org     }
2328e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    jmp(on_not_smi_result, near_jump);
2329e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    bind(&valid_result);
2330e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    Integer32ToSmi(dst, dst);
233183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
233283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
233383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
233483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
23354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftArithmeticRight(Register dst,
23364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                             Register src1,
23374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                             Register src2) {
23389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(!dst.is(kScratchRegister));
23399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(!src1.is(kScratchRegister));
23409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(!src2.is(kScratchRegister));
23414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  ASSERT(!dst.is(rcx));
2342e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
2343e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  SmiToInteger32(rcx, src2);
23449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (!dst.is(src1)) {
234543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src1);
23469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
2347e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  SmiToInteger32(dst, dst);
2348e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  sarl_cl(dst);
2349e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  Integer32ToSmi(dst, dst);
23504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
23514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
23524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
235383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SelectNonSmi(Register dst,
235483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Register src1,
235583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Register src2,
235683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Label* on_not_smis,
235783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Label::Distance near_jump) {
235883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(kScratchRegister));
235983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src1.is(kScratchRegister));
236083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!src2.is(kScratchRegister));
236183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(src1));
236283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(!dst.is(src2));
236383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Both operands must not be smis.
236483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#ifdef DEBUG
23658a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2));
23668a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi);
236783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#endif
236880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kSmiTag == 0);
236983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT_EQ(0, Smi::FromInt(0));
237083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  movl(kScratchRegister, Immediate(kSmiTagMask));
2371895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(kScratchRegister, src1);
237283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  testl(kScratchRegister, src2);
237383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // If non-zero then both are smis.
237483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_zero, on_not_smis, near_jump);
237583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
237683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Exactly one operand is a smi.
237783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT_EQ(1, static_cast<int>(kSmiTagMask));
237883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // kScratchRegister still holds src1 & kSmiTag, which is either zero or one.
2379fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  subp(kScratchRegister, Immediate(1));
238083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // If src1 is a smi, then scratch register all 1s, else it is all 0s.
238143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(dst, src1);
2382895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  xorp(dst, src2);
2383895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(dst, kScratchRegister);
238483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // If src1 is a smi, dst holds src1 ^ src2, else it is zero.
2385895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  xorp(dst, src1);
238683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi.
238783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
238883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
238983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
23909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comSmiIndex MacroAssembler::SmiToIndex(Register dst,
23919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                                    Register src,
23929d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                                    int shift) {
2393a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (SmiValuesAre32Bits()) {
2394a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ASSERT(is_uint6(shift));
2395a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    // There is a possible optimization if shift is in the range 60-63, but that
2396a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    // will (and must) never happen.
2397a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!dst.is(src)) {
2398a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      movp(dst, src);
2399a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2400a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (shift < kSmiShift) {
2401a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      sarp(dst, Immediate(kSmiShift - shift));
2402a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    } else {
2403a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      shlp(dst, Immediate(shift - kSmiShift));
2404a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2405a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return SmiIndex(dst, times_1);
24069d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
2407a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
2408a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
2409a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!dst.is(src)) {
2410a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      movp(dst, src);
2411a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2412a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    // We have to sign extend the index register to 64-bit as the SMI might
2413a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    // be negative.
2414a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    movsxlq(dst, dst);
2415a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (shift == times_1) {
2416a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      sarq(dst, Immediate(kSmiShift));
2417a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      return SmiIndex(dst, times_1);
2418a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2419a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
24209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
24214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
24224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
2423a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
24244af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgSmiIndex MacroAssembler::SmiToNegativeIndex(Register dst,
24254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                            Register src,
24264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                            int shift) {
2427a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (SmiValuesAre32Bits()) {
2428a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    // Register src holds a positive smi.
2429a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ASSERT(is_uint6(shift));
2430a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!dst.is(src)) {
2431a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      movp(dst, src);
2432a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2433a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    negp(dst);
2434a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (shift < kSmiShift) {
2435a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      sarp(dst, Immediate(kSmiShift - shift));
2436a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    } else {
2437a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      shlp(dst, Immediate(shift - kSmiShift));
2438a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2439a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return SmiIndex(dst, times_1);
24409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
2441a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
2442a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
2443a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (!dst.is(src)) {
2444a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      movp(dst, src);
2445a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2446a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    negq(dst);
2447a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (shift == times_1) {
2448a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      sarq(dst, Immediate(kSmiShift));
2449a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      return SmiIndex(dst, times_1);
2450a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    }
2451a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
24529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
24534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
24544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
24554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
24567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgvoid MacroAssembler::AddSmiField(Register dst, const Operand& src) {
24574ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  if (SmiValuesAre32Bits()) {
24584ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    ASSERT_EQ(0, kSmiShift % kBitsPerByte);
24594ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    addl(dst, Operand(src, kSmiShift / kBitsPerByte));
24604ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  } else {
24614ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
24624ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    SmiToInteger32(kScratchRegister, src);
24634ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    addl(dst, kScratchRegister);
24644ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
24657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org}
24667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
24677979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
2468dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid MacroAssembler::Push(Smi* source) {
2469dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  intptr_t smi = reinterpret_cast<intptr_t>(source);
2470dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (is_int32(smi)) {
2471763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(Immediate(static_cast<int32_t>(smi)));
2472dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  } else {
2473dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    Register constant = GetSmiConstant(source);
2474763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(constant);
2475dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  }
2476dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org}
2477dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
2478dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
24792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) {
24802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSERT(!src.is(scratch));
248143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, src);
2482662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // High bits.
24832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
24842f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shlp(src, Immediate(kSmiShift));
2485763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(src);
2486662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Low bits.
24872f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shlp(scratch, Immediate(kSmiShift));
2488763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(scratch);
2489662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
2490662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
2491662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
24922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) {
24932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSERT(!dst.is(scratch));
2494763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(scratch);
2495662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Low bits.
24962f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shrp(scratch, Immediate(kSmiShift));
2497763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(dst);
24982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shrp(dst, Immediate(kSmiShift));
2499662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // High bits.
25002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
2501895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  orp(dst, scratch);
2502662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
2503662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
2504662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
2505dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid MacroAssembler::Test(const Operand& src, Smi* source) {
25064ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  if (SmiValuesAre32Bits()) {
25074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    testl(Operand(src, kIntSize), Immediate(source->value()));
25084ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  } else {
25094ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    ASSERT(SmiValuesAre31Bits());
25104ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    testl(src, Immediate(source));
25114ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
2512dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org}
2513dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
2514dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
2515dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// ----------------------------------------------------------------------------
2516dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
2517dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
2518528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LookupNumberStringCache(Register object,
2519528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                             Register result,
2520528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                             Register scratch1,
2521528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                             Register scratch2,
2522528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                             Label* not_found) {
2523528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Use of registers. Register result is used as a temporary.
2524528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Register number_string_cache = result;
2525528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Register mask = scratch1;
2526528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Register scratch = scratch2;
2527528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2528528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Load the number string cache.
2529528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
2530528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2531528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Make the hash mask from the length of the number string cache. It
2532528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // contains two elements (number and string) for each cache entry.
2533528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  SmiToInteger32(
2534528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
2535528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  shrl(mask, Immediate(1));
2536fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  subp(mask, Immediate(1));  // Make mask.
2537528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2538528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Calculate the entry in the number string cache. The hash value in the
2539528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // number string cache for smis is just the smi value, and the hash for
2540528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // doubles is the xor of the upper and lower words. See
2541528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Heap::GetNumberStringCache.
2542528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Label is_smi;
2543528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Label load_result_from_cache;
2544528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  JumpIfSmi(object, &is_smi);
2545528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CheckMap(object,
2546528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org           isolate()->factory()->heap_number_map(),
2547528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org           not_found,
2548528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org           DONT_DO_SMI_CHECK);
2549528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2550528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  STATIC_ASSERT(8 == kDoubleSize);
2551528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
2552895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  xorp(scratch, FieldOperand(object, HeapNumber::kValueOffset));
2553895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(scratch, mask);
2554528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Each entry in string cache consists of two pointer sized fields,
2555528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // but times_twice_pointer_size (multiplication by 16) scale factor
2556528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // is not supported by addrmode on x64 platform.
2557528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // So we have to premultiply entry index before lookup.
25582f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shlp(scratch, Immediate(kPointerSizeLog2 + 1));
2559528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2560528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Register index = scratch;
2561528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Register probe = mask;
256243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(probe,
2563528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org       FieldOperand(number_string_cache,
2564528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    index,
2565528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    times_1,
2566528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    FixedArray::kHeaderSize));
2567528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  JumpIfSmi(probe, not_found);
2568528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
2569528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset));
2570528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  j(parity_even, not_found);  // Bail out if NaN is involved.
2571528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  j(not_equal, not_found);  // The cache did not contain this value.
2572528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  jmp(&load_result_from_cache);
2573528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2574528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bind(&is_smi);
2575528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  SmiToInteger32(scratch, object);
2576895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(scratch, mask);
2577528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Each entry in string cache consists of two pointer sized fields,
2578528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // but times_twice_pointer_size (multiplication by 16) scale factor
2579528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // is not supported by addrmode on x64 platform.
2580528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // So we have to premultiply entry index before lookup.
25812f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shlp(scratch, Immediate(kPointerSizeLog2 + 1));
2582528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2583528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Check if the entry is the smi we are looking for.
25847a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(object,
2585528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org       FieldOperand(number_string_cache,
2586528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    index,
2587528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    times_1,
2588528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    FixedArray::kHeaderSize));
2589528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  j(not_equal, not_found);
2590528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2591528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Get the result from the cache.
2592528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bind(&load_result_from_cache);
259343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(result,
2594528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org       FieldOperand(number_string_cache,
2595528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    index,
2596528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    times_1,
2597528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                    FixedArray::kHeaderSize + kPointerSize));
2598528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  IncrementCounter(isolate()->counters()->number_to_string_native(), 1);
2599528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
2600528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2601528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
260283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotString(Register object,
260383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Register object_map,
260483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Label* not_string,
260583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Label::Distance near_jump) {
260683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition is_smi = CheckSmi(object);
260783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(is_smi, not_string, near_jump);
260883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map);
260983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(above_equal, not_string, near_jump);
261083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
261183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
261283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
261383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotBothSequentialAsciiStrings(
261483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register first_object,
261583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register second_object,
261683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register scratch1,
261783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register scratch2,
261883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label* on_fail,
261983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label::Distance near_jump) {
262083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Check that both objects are not smis.
262183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Condition either_smi = CheckEitherSmi(first_object, second_object);
262283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(either_smi, on_fail, near_jump);
262383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
262483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Load instance type for both strings.
262543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset));
262643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset));
262783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset));
262883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset));
262983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
26302efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Check that both are flat ASCII strings.
263183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(kNotStringTag != 0);
263283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  const int kFlatAsciiStringMask =
263346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
2634c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  const int kFlatAsciiStringTag =
2635c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      kStringTag | kOneByteStringTag | kSeqStringTag;
263683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
263783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  andl(scratch1, Immediate(kFlatAsciiStringMask));
263883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  andl(scratch2, Immediate(kFlatAsciiStringMask));
263983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Interleave the bits to check both scratch1 and scratch2 in one test.
264046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
2641895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(scratch1, Operand(scratch1, scratch2, times_8, 0));
264283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  cmpl(scratch1,
264346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org       Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
264483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_equal, on_fail, near_jump);
264583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
264683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
264783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
264883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(
264983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register instance_type,
265083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register scratch,
265183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label* failure,
265283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label::Distance near_jump) {
265383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (!scratch.is(instance_type)) {
265483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    movl(scratch, instance_type);
265583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
265683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
265783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  const int kFlatAsciiStringMask =
265883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
265983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
266083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  andl(scratch, Immediate(kFlatAsciiStringMask));
2661e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag));
266283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_equal, failure, near_jump);
266383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
266483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
266583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
266683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii(
266783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register first_object_instance_type,
266883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register second_object_instance_type,
266983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register scratch1,
267083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Register scratch2,
267183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label* on_fail,
267283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label::Distance near_jump) {
267383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Load instance type for both strings.
267443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch1, first_object_instance_type);
267543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch2, second_object_instance_type);
267683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
26772efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Check that both are flat ASCII strings.
267883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(kNotStringTag != 0);
267946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  const int kFlatAsciiStringMask =
268046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
2681c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  const int kFlatAsciiStringTag =
2682c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      kStringTag | kOneByteStringTag | kSeqStringTag;
268383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
268483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  andl(scratch1, Immediate(kFlatAsciiStringMask));
268583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  andl(scratch2, Immediate(kFlatAsciiStringMask));
268683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Interleave the bits to check both scratch1 and scratch2 in one test.
268746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
2688895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(scratch1, Operand(scratch1, scratch2, times_8, 0));
268983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  cmpl(scratch1,
269046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org       Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
269183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_equal, on_fail, near_jump);
269283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
269383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
269483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
26951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class T>
26961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstatic void JumpIfNotUniqueNameHelper(MacroAssembler* masm,
26971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                      T operand_or_register,
26981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                      Label* not_unique_name,
26991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                      Label::Distance distance) {
2700ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
2701ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Label succeed;
2702ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  masm->testb(operand_or_register,
2703ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org              Immediate(kIsNotStringMask | kIsNotInternalizedMask));
2704ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  masm->j(zero, &succeed, Label::kNear);
2705ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  masm->cmpb(operand_or_register, Immediate(static_cast<uint8_t>(SYMBOL_TYPE)));
2706ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  masm->j(not_equal, not_unique_name, distance);
2707ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
2708ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  masm->bind(&succeed);
27091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
27101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
27111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
27121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Operand operand,
27131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                         Label* not_unique_name,
27141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                         Label::Distance distance) {
27151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance);
27161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
27171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
27181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
27191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Register reg,
27201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                         Label* not_unique_name,
27211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                         Label::Distance distance) {
27221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance);
27231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
27241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
27257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
27264a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid MacroAssembler::Move(Register dst, Register src) {
27274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  if (!dst.is(src)) {
272843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, src);
27294a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  }
27304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
27314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
27324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
27335aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Move(Register dst, Handle<Object> source) {
273479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
27355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  if (source->IsSmi()) {
27369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    Move(dst, Smi::cast(*source));
27375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  } else {
2738c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    MoveHeapObject(dst, source);
27395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
27405aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
27415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
27425aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
27435aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Move(const Operand& dst, Handle<Object> source) {
274479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
274568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  if (source->IsSmi()) {
27469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    Move(dst, Smi::cast(*source));
274768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  } else {
2748c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    MoveHeapObject(kScratchRegister, source);
274943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, kScratchRegister);
275068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
27515aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
27525aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
27535aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
27545aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) {
275579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
27569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (source->IsSmi()) {
2757badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    Cmp(dst, Smi::cast(*source));
27589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  } else {
2759c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    MoveHeapObject(kScratchRegister, source);
27607a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(dst, kScratchRegister);
27619d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
27625aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
27635aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
27645aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
27653e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) {
276679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
276768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  if (source->IsSmi()) {
2768badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    Cmp(dst, Smi::cast(*source));
276968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  } else {
2770c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    MoveHeapObject(kScratchRegister, source);
27717a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(dst, kScratchRegister);
277268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
27733e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
27743e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
27753e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
27765aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Push(Handle<Object> source) {
277779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
277868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  if (source->IsSmi()) {
27799d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    Push(Smi::cast(*source));
278068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  } else {
2781c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    MoveHeapObject(kScratchRegister, source);
2782763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(kScratchRegister);
278368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
27845aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
27855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
27865aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
2787c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid MacroAssembler::MoveHeapObject(Register result,
2788c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org                                    Handle<Object> object) {
278979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference using_raw_address;
2790c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  ASSERT(object->IsHeapObject());
279164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (isolate()->heap()->InNewSpace(*object)) {
279241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Handle<Cell> cell = isolate()->factory()->NewCell(object);
27939cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    Move(result, cell, RelocInfo::CELL);
279443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(result, Operand(result, 0));
279564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  } else {
27969cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    Move(result, object, RelocInfo::EMBEDDED_OBJECT);
279764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
279864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
279964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
280064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
280141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) {
280264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (dst.is(rax)) {
280379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    AllowDeferredHandleDereference embedding_raw_address;
280441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    load_rax(cell.location(), RelocInfo::CELL);
280564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  } else {
28069cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    Move(dst, cell, RelocInfo::CELL);
280743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, Operand(dst, 0));
280864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
280964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
281064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
281164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
281213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::Drop(int stack_elements) {
281313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  if (stack_elements > 0) {
2814fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(rsp, Immediate(stack_elements * kPointerSize));
281513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
281613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
281713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
281813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
2819a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid MacroAssembler::DropUnderReturnAddress(int stack_elements,
2820a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                            Register scratch) {
2821a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ASSERT(stack_elements > 0);
2822a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (kPointerSize == kInt64Size && stack_elements == 1) {
2823a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    popq(MemOperand(rsp, 0));
2824a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return;
2825a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
2826a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
2827a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  PopReturnAddressTo(scratch);
2828a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Drop(stack_elements);
2829a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  PushReturnAddressFrom(scratch);
2830a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org}
2831a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
2832a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
2833763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Push(Register src) {
2834763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2835763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    pushq(src);
2836763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
2837763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // x32 uses 64-bit push for rbp in the prologue.
2838763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    ASSERT(src.code() != rbp.code());
2839763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    leal(rsp, Operand(rsp, -4));
2840763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(Operand(rsp, 0), src);
2841763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
2842763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
2843763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2844763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2845763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Push(const Operand& src) {
2846763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2847763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    pushq(src);
2848763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
2849763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(kScratchRegister, src);
2850763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    leal(rsp, Operand(rsp, -4));
2851763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(Operand(rsp, 0), kScratchRegister);
2852763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
2853763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
2854763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2855763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2856a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid MacroAssembler::PushQuad(const Operand& src) {
2857a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2858a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    pushq(src);
2859a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  } else {
2860a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    movp(kScratchRegister, src);
2861a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    pushq(kScratchRegister);
2862a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
2863a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org}
2864a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
2865a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
2866763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Push(Immediate value) {
2867763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2868763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    pushq(value);
2869763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
2870763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    leal(rsp, Operand(rsp, -4));
2871763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(Operand(rsp, 0), value);
2872763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
2873763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
2874763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2875763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2876763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::PushImm32(int32_t imm32) {
2877763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2878763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    pushq_imm32(imm32);
2879763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
2880763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    leal(rsp, Operand(rsp, -4));
2881763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(Operand(rsp, 0), Immediate(imm32));
2882763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
2883763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
2884763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2885763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2886763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Pop(Register dst) {
2887763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2888763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    popq(dst);
2889763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
2890763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // x32 uses 64-bit pop for rbp in the epilogue.
2891763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    ASSERT(dst.code() != rbp.code());
2892763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(dst, Operand(rsp, 0));
2893763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    leal(rsp, Operand(rsp, 4));
2894763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
2895763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
2896763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2897763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2898763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Pop(const Operand& dst) {
2899763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2900763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    popq(dst);
2901763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
2902763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Register scratch = dst.AddressUsesRegister(kScratchRegister)
2903763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org        ? kSmiConstantRegister : kScratchRegister;
2904763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(scratch, Operand(rsp, 0));
2905763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    movp(dst, scratch);
2906763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    leal(rsp, Operand(rsp, 4));
2907763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    if (scratch.is(kSmiConstantRegister)) {
2908763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      // Restore kSmiConstantRegister.
2909fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      movp(kSmiConstantRegister,
2910fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org           reinterpret_cast<void*>(Smi::FromInt(kSmiConstantRegisterValue)),
2911763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org           Assembler::RelocInfoNone());
2912763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
2913763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
2914763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
2915763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2916763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
2917a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid MacroAssembler::PopQuad(const Operand& dst) {
2918a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (kPointerSize == kInt64Size) {
2919a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    popq(dst);
2920a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  } else {
2921a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    popq(kScratchRegister);
2922a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    movp(dst, kScratchRegister);
2923a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
2924a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org}
2925a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
2926a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
292704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.orgvoid MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst,
292804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org                                                        Register base,
292904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org                                                        int offset) {
293004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  ASSERT(offset > SharedFunctionInfo::kLengthOffset &&
293104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org         offset <= SharedFunctionInfo::kSize &&
293204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org         (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
293304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (kPointerSize == kInt64Size) {
293404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movsxlq(dst, FieldOperand(base, offset));
293504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  } else {
293604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    movp(dst, FieldOperand(base, offset));
293704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    SmiToInteger32(dst, dst);
293804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
293904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org}
294004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org
294104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org
294204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.orgvoid MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base,
294304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org                                                           int offset,
294404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org                                                           int bits) {
294504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  ASSERT(offset > SharedFunctionInfo::kLengthOffset &&
294604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org         offset <= SharedFunctionInfo::kSize &&
294704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org         (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
294804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  if (kPointerSize == kInt32Size) {
294904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    // On x32, this field is represented by SMI.
295004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    bits += kSmiShift;
295104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  }
2952394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int byte_offset = bits / kBitsPerByte;
2953394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int bit_in_byte = bits & (kBitsPerByte - 1);
295404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte));
2955394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
2956394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
2957394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
2958eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Jump(ExternalReference ext) {
2959ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(kScratchRegister, ext);
2960eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  jmp(kScratchRegister);
2961eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
2962eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
2963eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
2964f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MacroAssembler::Jump(const Operand& op) {
2965f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (kPointerSize == kInt64Size) {
2966f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    jmp(op);
2967f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  } else {
2968f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    movp(kScratchRegister, op);
2969f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    jmp(kScratchRegister);
2970f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
2971f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
2972f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
2973f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
2974eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) {
29759cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  Move(kScratchRegister, destination, rmode);
2976eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  jmp(kScratchRegister);
2977eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
2978eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
2979eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
29805aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
2981c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // TODO(X64): Inline this
2982c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  jmp(code_object, rmode);
29835aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
29845aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
29855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
2986ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint MacroAssembler::CallSize(ExternalReference ext) {
2987ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes).
2988594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return LoadAddressSize(ext) +
2989594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org         Assembler::kCallScratchRegisterInstructionLength;
2990ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
2991ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
2992ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
2993eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Call(ExternalReference ext) {
2994eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG
2995ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int end_position = pc_offset() + CallSize(ext);
2996eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif
2997ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(kScratchRegister, ext);
2998eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  call(kScratchRegister);
2999eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG
3000ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CHECK_EQ(end_position, pc_offset());
3001eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif
3002eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3003eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3004eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3005f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MacroAssembler::Call(const Operand& op) {
3006f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (kPointerSize == kInt64Size) {
3007f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    call(op);
3008f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  } else {
3009f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    movp(kScratchRegister, op);
3010f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    call(kScratchRegister);
3011f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
3012f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
3013f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3014f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3015eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
3016eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG
3017af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  int end_position = pc_offset() + CallSize(destination);
3018eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif
30199cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  Move(kScratchRegister, destination, rmode);
3020eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  call(kScratchRegister);
3021eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG
3022ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CHECK_EQ(pc_offset(), end_position);
3023eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif
3024eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3025eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3026eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
30278e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid MacroAssembler::Call(Handle<Code> code_object,
30288e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                          RelocInfo::Mode rmode,
3029471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                          TypeFeedbackId ast_id) {
3030eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG
3031ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int end_position = pc_offset() + CallSize(code_object);
3032eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif
3033c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  ASSERT(RelocInfo::IsCodeTarget(rmode) ||
3034c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      rmode == RelocInfo::CODE_AGE_SEQUENCE);
30358e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  call(code_object, rmode, ast_id);
3036eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG
3037ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CHECK_EQ(end_position, pc_offset());
3038eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif
30395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org}
30405aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
30415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
30420a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid MacroAssembler::Pushad() {
3043763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(rax);
3044763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(rcx);
3045763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(rdx);
3046763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(rbx);
30470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Not pushing rsp or rbp.
3048763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(rsi);
3049763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(rdi);
3050763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(r8);
3051763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(r9);
30520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // r10 is kScratchRegister.
3053763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(r11);
3054b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // r12 is kSmiConstantRegister.
30550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // r13 is kRootRegister.
3056763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(r14);
3057763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(r15);
305849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  STATIC_ASSERT(11 == kNumSafepointSavedRegisters);
305949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Use lea for symmetry with Popad.
30603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  int sp_delta =
30613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
3062895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(rsp, Operand(rsp, -sp_delta));
30630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
30640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
30650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
30660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid MacroAssembler::Popad() {
306749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Popad must not change the flags, so use lea instead of addq.
30683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  int sp_delta =
30693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
3070895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(rsp, Operand(rsp, sp_delta));
3071763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(r15);
3072763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(r14);
3073763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(r11);
3074763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(r9);
3075763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(r8);
3076763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rdi);
3077763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rsi);
3078763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rbx);
3079763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rdx);
3080763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rcx);
3081763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rax);
30820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
30830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
30840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
30850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::Dropad() {
3086fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize));
30870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org}
30880ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
30890ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
30900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org// Order general registers are pushed by Pushad:
3091b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
30921456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int
30931456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
30940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    0,
30950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    1,
30960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    2,
30970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    3,
30980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    -1,
30990ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    -1,
31000ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    4,
31010ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    5,
31020ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    6,
31030ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    7,
31040ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    -1,
31050ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    8,
31060ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    -1,
3107b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    -1,
3108b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    9,
3109b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    10
31100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org};
31110ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
31120ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
311346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst,
311446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                                  const Immediate& imm) {
311543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(SafepointRegisterSlot(dst), imm);
311646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
311746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
311846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
31193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
312043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(SafepointRegisterSlot(dst), src);
31213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
31223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
31233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
31245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
312543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(dst, SafepointRegisterSlot(src));
31265d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org}
31275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
31285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
31293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
31303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
31313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
31323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
31333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
313478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid MacroAssembler::PushTryHandler(StackHandler::Kind kind,
313504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                                    int handler_index) {
3136eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Adjust this code if not the case.
3137d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize +
3138d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                                                kFPOnStackSize);
313904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
314004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize);
314104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize);
314204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize);
314304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
314404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
314504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // We will build up the handler from the bottom by pushing on the stack.
314678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // First push the frame pointer and context.
314778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  if (kind == StackHandler::JS_ENTRY) {
314804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    // The frame pointer does not point to a JS frame so we save NULL for
314904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    // rbp. We expect the code throwing an exception to check rbp before
315004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    // dereferencing it to restore the context.
3151763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    pushq(Immediate(0));  // NULL frame pointer.
31524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    Push(Smi::FromInt(0));  // No context.
315378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  } else {
3154763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    pushq(rbp);
3155763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(rsi);
3156e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
315704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
315804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Push the state and the code object.
315978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  unsigned state =
316078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      StackHandler::IndexField::encode(handler_index) |
316178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      StackHandler::KindField::encode(kind);
3162763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(Immediate(state));
316304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  Push(CodeObject());
316404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
316504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Link the current handler as the next handler.
316604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
3167763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(ExternalOperand(handler_address));
316804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Set this new handler as the current one.
316943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(ExternalOperand(handler_address), rsp);
3170e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org}
3171e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
3172e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
317313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::PopTryHandler() {
317404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
317504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
3176763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(ExternalOperand(handler_address));
3177fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
317813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
317913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
318013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
318104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.orgvoid MacroAssembler::JumpToHandlerEntry() {
318204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Compute the handler entry address and jump to it.  The handler table is
318304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // a fixed array of (smi-tagged) code offsets.
318404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // rax = exception, rdi = code object, rdx = state.
318543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset));
31862f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shrp(rdx, Immediate(StackHandler::kKindWidth));
318743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rdx,
31881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org       FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize));
318904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  SmiToInteger64(rdx, rdx);
3190895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize));
319104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  jmp(rdi);
319204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org}
319304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
319404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
319549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgvoid MacroAssembler::Throw(Register value) {
31964acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Adjust this code if not the case.
3197d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize +
3198d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                                                kFPOnStackSize);
319904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
320004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize);
320104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize);
320204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize);
320304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
320404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
320504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // The exception is expected in rax.
320649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (!value.is(rax)) {
320743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(rax, value);
320849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
320904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Drop the stack pointer to the top of the top handler.
321083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
321143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rsp, ExternalOperand(handler_address));
321204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Restore the next handler.
3213763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(ExternalOperand(handler_address));
321404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
321504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Remove the code object and state, compute the handler address in rdi.
3216763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rdi);  // Code object.
3217763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rdx);  // Offset and state.
321804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
321904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Restore the context and frame pointer.
3220763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rsi);  // Context.
3221763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  popq(rbp);  // Frame pointer.
322249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
32234acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // If the handler is a JS frame, restore the context to the frame.
322404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either
322504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // rbp or rsi.
322683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label skip;
32277a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(rsi, rsi);
322804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  j(zero, &skip, Label::kNear);
322943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
323049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  bind(&skip);
32314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
323204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  JumpToHandlerEntry();
323349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org}
323449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
323549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
323665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.orgvoid MacroAssembler::ThrowUncatchable(Register value) {
32374acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Adjust this code if not the case.
3238d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize +
3239d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                                                kFPOnStackSize);
324004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
324104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize);
324204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize);
324304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize);
324404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
324549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
3246c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // The exception is expected in rax.
324765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  if (!value.is(rax)) {
324843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(rax, value);
324949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
3250c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // Drop the stack pointer to the top of the top stack handler.
3251c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
3252c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Load(rsp, handler_address);
325349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
3254c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // Unwind the handlers until the top ENTRY handler is found.
3255c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Label fetch_next, check_kind;
3256c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  jmp(&check_kind, Label::kNear);
3257c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  bind(&fetch_next);
325843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rsp, Operand(rsp, StackHandlerConstants::kNextOffset));
3259c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
3260c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  bind(&check_kind);
326178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  STATIC_ASSERT(StackHandler::JS_ENTRY == 0);
326204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  testl(Operand(rsp, StackHandlerConstants::kStateOffset),
326304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org        Immediate(StackHandler::KindField::kMask));
326404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  j(not_zero, &fetch_next);
3265c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
3266c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // Set the top handler address to next handler past the top ENTRY handler.
3267763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(ExternalOperand(handler_address));
3268c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
326904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Remove the code object and state, compute the handler address in rdi.
3270763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rdi);  // Code object.
3271763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rdx);  // Offset and state.
327204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
327304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Clear the context pointer and frame pointer (0 was saved in the handler).
3274763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(rsi);
3275763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  popq(rbp);
327649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
327704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  JumpToHandlerEntry();
327849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org}
327949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
328049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
3281eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Ret() {
3282eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ret(0);
3283eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3284eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3285eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3286d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) {
3287d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  if (is_uint16(bytes_dropped)) {
3288d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    ret(bytes_dropped);
3289d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  } else {
3290594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    PopReturnAddressTo(scratch);
3291fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(rsp, Immediate(bytes_dropped));
3292594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    PushReturnAddressFrom(scratch);
3293d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    ret(0);
3294d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  }
3295d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com}
3296d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
3297d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
32983e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid MacroAssembler::FCmp() {
32993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  fucomip();
330040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  fstp(0);
33013e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
33023e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
33033e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
3304eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::CmpObjectType(Register heap_object,
3305eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                                   InstanceType type,
3306eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                                   Register map) {
330743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(map, FieldOperand(heap_object, HeapObject::kMapOffset));
3308eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  CmpInstanceType(map, type);
3309eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3310eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3311eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3312eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
3313eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  cmpb(FieldOperand(map, Map::kInstanceTypeOffset),
3314eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org       Immediate(static_cast<int8_t>(type)));
3315eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3316eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3317eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3318d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comvoid MacroAssembler::CheckFastElements(Register map,
3319d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                                       Label* fail,
3320d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                                       Label::Distance distance) {
3321830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3322830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3323830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_ELEMENTS == 2);
3324830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
3325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  cmpb(FieldOperand(map, Map::kBitField2Offset),
3326830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org       Immediate(Map::kMaximumBitField2FastHoleyElementValue));
3327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(above, fail, distance);
3328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckFastObjectElements(Register map,
3332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                             Label* fail,
3333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                             Label::Distance distance) {
3334830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3335830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3336830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_ELEMENTS == 2);
3337830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
3338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  cmpb(FieldOperand(map, Map::kBitField2Offset),
3339830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org       Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
3340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(below_equal, fail, distance);
3341d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  cmpb(FieldOperand(map, Map::kBitField2Offset),
3342830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org       Immediate(Map::kMaximumBitField2FastHoleyElementValue));
3343d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  j(above, fail, distance);
3344d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com}
3345d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
3346d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
3347830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid MacroAssembler::CheckFastSmiElements(Register map,
3348830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                                          Label* fail,
3349830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                                          Label::Distance distance) {
3350830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3351830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  cmpb(FieldOperand(map, Map::kBitField2Offset),
3353830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org       Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
3354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(above, fail, distance);
3355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::StoreNumberToDoubleElements(
3359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register maybe_number,
3360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register elements,
3361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Register index,
3362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    XMMRegister xmm_scratch,
3363fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Label* fail,
3364fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    int elements_offset) {
3365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label smi_value, is_nan, maybe_nan, not_nan, have_double_value, done;
3366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  JumpIfSmi(maybe_number, &smi_value, Label::kNear);
3368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  CheckMap(maybe_number,
3370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           isolate()->factory()->heap_number_map(),
3371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           fail,
3372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           DONT_DO_SMI_CHECK);
3373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Double value, canonicalize NaN.
3375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32);
3376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  cmpl(FieldOperand(maybe_number, offset),
3377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       Immediate(kNaNOrInfinityLowerBoundUpper32));
3378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(greater_equal, &maybe_nan, Label::kNear);
3379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&not_nan);
3381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  movsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset));
3382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&have_double_value);
3383fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  movsd(FieldOperand(elements, index, times_8,
3384fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     FixedDoubleArray::kHeaderSize - elements_offset),
3385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        xmm_scratch);
3386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  jmp(&done);
3387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&maybe_nan);
3389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
3390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // it's an Infinity, and the non-NaN code path applies.
3391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(greater, &is_nan, Label::kNear);
3392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  cmpl(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0));
3393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(zero, &not_nan);
3394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&is_nan);
3395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Convert all NaNs to the same canonical NaN value when they are stored in
3396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the double array.
3397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Set(kScratchRegister, BitCast<uint64_t>(
3398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
3399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  movq(xmm_scratch, kScratchRegister);
3400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  jmp(&have_double_value, Label::kNear);
3401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&smi_value);
3403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Value is a smi. convert to a double and store.
3404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Preserve original value.
3405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SmiToInteger32(kScratchRegister, maybe_number);
3406528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Cvtlsi2sd(xmm_scratch, kScratchRegister);
3407fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  movsd(FieldOperand(elements, index, times_8,
3408fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     FixedDoubleArray::kHeaderSize - elements_offset),
3409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        xmm_scratch);
3410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&done);
3411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3414935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) {
3415f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
3416f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
3417f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
3418f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
34195c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CheckMap(Register obj,
34205c838251403b0be9a882540f1922577abba4c872ager@chromium.org                              Handle<Map> map,
34215c838251403b0be9a882540f1922577abba4c872ager@chromium.org                              Label* fail,
3422a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                              SmiCheckType smi_check_type) {
3423c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  if (smi_check_type == DO_SMI_CHECK) {
34245c838251403b0be9a882540f1922577abba4c872ager@chromium.org    JumpIfSmi(obj, fail);
34255c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
3426f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
3427935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  CompareMap(obj, map);
34285c838251403b0be9a882540f1922577abba4c872ager@chromium.org  j(not_equal, fail);
34295c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
34305c838251403b0be9a882540f1922577abba4c872ager@chromium.org
34315c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3432c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampUint8(Register reg) {
3433c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Label done;
3434c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  testl(reg, Immediate(0xFFFFFF00));
3435c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  j(zero, &done, Label::kNear);
3436c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  setcc(negative, reg);  // 1 if negative, 0 if positive.
3437c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  decb(reg);  // 0 if negative, 255 if positive.
3438c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  bind(&done);
3439c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
3440c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
3441c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
3442c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
3443c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org                                        XMMRegister temp_xmm_reg,
344489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                                        Register result_reg) {
3445c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Label done;
344689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  Label conv_failure;
3447c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  xorps(temp_xmm_reg, temp_xmm_reg);
344846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  cvtsd2si(result_reg, input_reg);
3449c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  testl(result_reg, Immediate(0xFFFFFF00));
3450c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  j(zero, &done, Label::kNear);
3451a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  cmpl(result_reg, Immediate(1));
3452a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  j(overflow, &conv_failure, Label::kNear);
345389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  movl(result_reg, Immediate(0));
3454a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  setcc(sign, result_reg);
345589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  subl(result_reg, Immediate(1));
345689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  andl(result_reg, Immediate(255));
345789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  jmp(&done, Label::kNear);
345889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  bind(&conv_failure);
345989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  Set(result_reg, 0);
346089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  ucomisd(input_reg, temp_xmm_reg);
346189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  j(below, &done, Label::kNear);
3462c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Set(result_reg, 255);
3463c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  bind(&done);
3464c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
3465c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
3466c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
346746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::LoadUint32(XMMRegister dst,
34687e6132b924829c353864933f29124419916db550machenbach@chromium.org                                Register src) {
34692f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  if (FLAG_debug_code) {
34702f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    cmpq(src, Immediate(0xffffffff));
3471594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared);
34722f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  }
34732f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  cvtqsi2sd(dst, src);
347446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
347546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
347646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
3477c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::SlowTruncateToI(Register result_reg,
3478c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                                     Register input_reg,
3479c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                                     int offset) {
3480f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true);
3481f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  call(stub.GetCode(), RelocInfo::CODE_TARGET);
3482c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org}
3483c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3484c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3485c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg,
3486c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                                           Register input_reg) {
3487c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Label done;
3488c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3489c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  cvttsd2siq(result_reg, xmm0);
3490a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  cmpq(result_reg, Immediate(1));
3491a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  j(no_overflow, &done, Label::kNear);
3492c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3493c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Slow case.
3494c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  if (input_reg.is(result_reg)) {
3495fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(rsp, Immediate(kDoubleSize));
3496c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    movsd(MemOperand(rsp, 0), xmm0);
3497c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    SlowTruncateToI(result_reg, rsp, 0);
3498fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(rsp, Immediate(kDoubleSize));
3499c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  } else {
3500c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    SlowTruncateToI(result_reg, input_reg);
3501c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  }
3502c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3503c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  bind(&done);
35042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Keep our invariant that the upper 32 bits are zero.
35052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  movl(result_reg, result_reg);
3506c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org}
3507c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3508c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3509c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TruncateDoubleToI(Register result_reg,
3510c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                                       XMMRegister input_reg) {
3511c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Label done;
3512c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  cvttsd2siq(result_reg, input_reg);
3513a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  cmpq(result_reg, Immediate(1));
3514a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  j(no_overflow, &done, Label::kNear);
3515c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3516fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  subp(rsp, Immediate(kDoubleSize));
3517c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  movsd(MemOperand(rsp, 0), input_reg);
3518c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  SlowTruncateToI(result_reg, rsp, 0);
3519fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(rsp, Immediate(kDoubleSize));
3520c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3521c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  bind(&done);
35222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Keep our invariant that the upper 32 bits are zero.
35232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  movl(result_reg, result_reg);
3524c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org}
3525c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3526c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3527c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::DoubleToI(Register result_reg,
3528c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               XMMRegister input_reg,
3529c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               XMMRegister scratch,
3530c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               MinusZeroMode minus_zero_mode,
3531c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               Label* conversion_failed,
3532c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               Label::Distance dst) {
3533c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  cvttsd2si(result_reg, input_reg);
3534528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Cvtlsi2sd(xmm0, result_reg);
3535c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  ucomisd(xmm0, input_reg);
3536c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  j(not_equal, conversion_failed, dst);
3537c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  j(parity_even, conversion_failed, dst);  // NaN.
3538c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
3539c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    Label done;
3540c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    // The integer converted back is equal to the original. We
3541c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    // only have to test if we got -0 as an input.
3542c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    testl(result_reg, result_reg);
3543c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    j(not_zero, &done, Label::kNear);
3544c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    movmskpd(result_reg, input_reg);
3545c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    // Bit 0 contains the sign of the double in input_reg.
3546c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    // If input was positive, we are ok and return 0, otherwise
3547c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    // jump to conversion_failed.
3548c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    andl(result_reg, Immediate(1));
3549c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    j(not_zero, conversion_failed, dst);
3550c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    bind(&done);
3551c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  }
3552c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org}
3553c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3554c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3555c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TaggedToI(Register result_reg,
3556c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               Register input_reg,
3557c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               XMMRegister temp,
3558c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               MinusZeroMode minus_zero_mode,
3559c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               Label* lost_precision,
3560c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org                               Label::Distance dst) {
3561c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Label done;
3562c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  ASSERT(!temp.is(xmm0));
3563c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3564c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Heap number map check.
3565c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
3566c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org              Heap::kHeapNumberMapRootIndex);
3567c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  j(not_equal, lost_precision, dst);
3568c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3569c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3570c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  cvttsd2si(result_reg, xmm0);
3571528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Cvtlsi2sd(temp, result_reg);
3572c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  ucomisd(xmm0, temp);
3573c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  RecordComment("Deferred TaggedToI: lost precision");
3574c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  j(not_equal, lost_precision, dst);
3575c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  RecordComment("Deferred TaggedToI: NaN");
3576c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  j(parity_even, lost_precision, dst);  // NaN.
3577c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
3578c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    testl(result_reg, result_reg);
3579c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    j(not_zero, &done, Label::kNear);
3580c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    movmskpd(result_reg, xmm0);
3581c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    andl(result_reg, Immediate(1));
3582c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    j(not_zero, lost_precision, dst);
3583c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  }
3584c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  bind(&done);
3585c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org}
3586c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3587c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
358840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::LoadInstanceDescriptors(Register map,
358940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                             Register descriptors) {
359043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
359140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org}
359240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
359340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
359406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
35953c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  movl(dst, FieldOperand(map, Map::kBitField3Offset));
359606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
359706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org}
359806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
359906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
3600355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid MacroAssembler::EnumLength(Register dst, Register map) {
3601355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
36023c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  movl(dst, FieldOperand(map, Map::kBitField3Offset));
36033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  andl(dst, Immediate(Map::EnumLengthBits::kMask));
36043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Integer32ToSmi(dst, dst);
3605355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org}
3606355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3607355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3608ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgvoid MacroAssembler::DispatchMap(Register obj,
36092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                                 Register unused,
3610ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                                 Handle<Map> map,
3611ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                                 Handle<Code> success,
3612ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                                 SmiCheckType smi_check_type) {
3613ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  Label fail;
3614ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  if (smi_check_type == DO_SMI_CHECK) {
3615ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    JumpIfSmi(obj, &fail);
3616ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  }
3617ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
3618ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  j(equal, success, RelocInfo::CODE_TARGET);
3619ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
3620ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  bind(&fail);
3621ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org}
3622ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
3623ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
3624c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNumber(Register object) {
3625c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (emit_debug_code()) {
3626c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Label ok;
3627c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Condition is_smi = CheckSmi(object);
3628c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    j(is_smi, &ok, Label::kNear);
3629c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Cmp(FieldOperand(object, HeapObject::kMapOffset),
3630c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org        isolate()->factory()->heap_number_map());
3631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(equal, kOperandIsNotANumber);
3632c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    bind(&ok);
3633c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
36345c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
36355c838251403b0be9a882540f1922577abba4c872ager@chromium.org
36365c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3637c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNotSmi(Register object) {
3638c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (emit_debug_code()) {
3639c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Condition is_smi = CheckSmi(object);
3640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(NegateCondition(is_smi), kOperandIsASmi);
3641c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
3642ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org}
3643ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
3644ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
3645c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(Register object) {
3646c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (emit_debug_code()) {
3647c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Condition is_smi = CheckSmi(object);
3648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(is_smi, kOperandIsNotASmi);
3649c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
3650badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org}
3651badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
3652badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
3653c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(const Operand& object) {
3654c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (emit_debug_code()) {
3655c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Condition is_smi = CheckSmi(object);
3656594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(is_smi, kOperandIsNotASmi);
3657c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
365825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
365925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
366025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
3661c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertZeroExtended(Register int32_register) {
3662c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (emit_debug_code()) {
3663c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    ASSERT(!int32_register.is(kScratchRegister));
3664e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    movq(kScratchRegister, V8_INT64_C(0x0000000100000000));
3665c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    cmpq(kScratchRegister, int32_register);
3666594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(above_equal, k32BitValueInRegisterIsNotZeroExtended);
3667c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
3668f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
3669f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
3670f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
3671c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertString(Register object) {
3672c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (emit_debug_code()) {
3673c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    testb(object, Immediate(kSmiTagMask));
3674594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(not_equal, kOperandIsASmiAndNotAString);
3675763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(object);
367643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(object, FieldOperand(object, HeapObject::kMapOffset));
3677c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    CmpInstanceType(object, FIRST_NONSTRING_TYPE);
3678763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Pop(object);
3679594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(below, kOperandIsNotAString);
3680c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
368149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org}
368249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
368349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
3684750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid MacroAssembler::AssertName(Register object) {
3685750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (emit_debug_code()) {
3686750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    testb(object, Immediate(kSmiTagMask));
3687594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(not_equal, kOperandIsASmiAndNotAName);
3688763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(object);
368943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(object, FieldOperand(object, HeapObject::kMapOffset));
3690750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CmpInstanceType(object, LAST_NAME_TYPE);
3691763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Pop(object);
3692594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(below_equal, kOperandIsNotAName);
3693750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
3694750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
3695750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
3696750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
36972904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) {
36982904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (emit_debug_code()) {
36992904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Label done_checking;
37002904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    AssertNotSmi(object);
37012904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Cmp(object, isolate()->factory()->undefined_value());
37022904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    j(equal, &done_checking);
37032904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Cmp(FieldOperand(object, 0), isolate()->factory()->allocation_site_map());
37042904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Assert(equal, kExpectedUndefinedOrCell);
37052904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    bind(&done_checking);
37062904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
37072904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org}
37082904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
37092904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
3710c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertRootValue(Register src,
3711c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                                     Heap::RootListIndex root_value_index,
3712594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                     BailoutReason reason) {
3713c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  if (emit_debug_code()) {
3714c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    ASSERT(!src.is(kScratchRegister));
3715c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    LoadRoot(kScratchRegister, root_value_index);
37167a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(src, kScratchRegister);
3717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(equal, reason);
3718c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  }
37195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
37205ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
37215ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
37225ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
3723b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgCondition MacroAssembler::IsObjectStringType(Register heap_object,
3724b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                             Register map,
3725b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                             Register instance_type) {
372643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(map, FieldOperand(heap_object, HeapObject::kMapOffset));
3727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
372880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  STATIC_ASSERT(kNotStringTag != 0);
3729b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  testb(instance_type, Immediate(kIsNotStringMask));
3730b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return zero;
3731b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
3732b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
3733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
3734750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgCondition MacroAssembler::IsObjectNameType(Register heap_object,
3735750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                           Register map,
3736750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                           Register instance_type) {
373743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(map, FieldOperand(heap_object, HeapObject::kMapOffset));
3738750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
3739750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE)));
3740750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return below_equal;
3741750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
3742750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
3743750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
374486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgvoid MacroAssembler::TryGetFunctionPrototype(Register function,
374586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org                                             Register result,
3746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                             Label* miss,
3747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                             bool miss_on_bound_function) {
374886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Check that the receiver isn't a smi.
374986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  testl(function, Immediate(kSmiTagMask));
375086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  j(zero, miss);
375186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
375286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Check that the function really is a function.
375386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  CmpObjectType(function, JS_FUNCTION_TYPE, result);
375486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  j(not_equal, miss);
375586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
3756394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (miss_on_bound_function) {
375743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(kScratchRegister,
3758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com         FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
3759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // It's not smi-tagged (stored in the top half of a smi-tagged 8-byte
3760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // field).
376104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org    TestBitSharedFunctionInfoSpecialField(kScratchRegister,
376204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org        SharedFunctionInfo::kCompilerHintsOffset,
376304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org        SharedFunctionInfo::kBoundFunction);
3764394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    j(not_zero, miss);
3765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
3766394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
376786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Make sure that the function has an instance prototype.
376883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label non_instance;
376986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  testb(FieldOperand(result, Map::kBitFieldOffset),
377086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        Immediate(1 << Map::kHasNonInstancePrototype));
377183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_zero, &non_instance, Label::kNear);
377286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
377386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Get the prototype or initial map from the function.
377443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(result,
377586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org       FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
377686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
377786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // If the prototype or initial map is the hole, don't return it and
377886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // simply miss the cache instead. This will allow us to allocate a
377986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // prototype object on-demand in the runtime system.
378018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  CompareRoot(result, Heap::kTheHoleValueRootIndex);
378186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  j(equal, miss);
378286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
378386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // If the function does not have an initial map, we're done.
378483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label done;
378586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  CmpObjectType(result, MAP_TYPE, kScratchRegister);
378683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  j(not_equal, &done, Label::kNear);
378786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
378886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Get the prototype from the initial map.
378943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(result, FieldOperand(result, Map::kPrototypeOffset));
379083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  jmp(&done, Label::kNear);
379186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
379286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Non-instance prototype: Fetch prototype from constructor field
379386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // in initial map.
379486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  bind(&non_instance);
379543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(result, FieldOperand(result, Map::kConstructorOffset));
379686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
379786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // All done.
379886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  bind(&done);
379986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org}
380086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
3801eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3802eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) {
3803eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (FLAG_native_code_counters && counter->Enabled()) {
3804ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Operand counter_operand = ExternalOperand(ExternalReference(counter));
3805a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    movl(counter_operand, Immediate(value));
3806eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
3807eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3808eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3809eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3810eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) {
3811eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(value > 0);
3812eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (FLAG_native_code_counters && counter->Enabled()) {
3813ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Operand counter_operand = ExternalOperand(ExternalReference(counter));
3814eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    if (value == 1) {
3815ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      incl(counter_operand);
3816eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    } else {
3817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      addl(counter_operand, Immediate(value));
3818eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
3819eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
3820eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3821eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3822eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3823eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) {
3824eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(value > 0);
3825eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (FLAG_native_code_counters && counter->Enabled()) {
3826ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Operand counter_operand = ExternalOperand(ExternalReference(counter));
3827eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    if (value == 1) {
3828ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      decl(counter_operand);
3829eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    } else {
3830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      subl(counter_operand, Immediate(value));
3831eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
3832eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
3833eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3834eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3835eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
38365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::DebugBreak() {
38375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  Set(rax, 0);  // No arguments.
3838ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate()));
3839f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CEntryStub ces(isolate(), 1);
3840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(AllowThisStubCall(&ces));
3841f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
38423e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
38433e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
38443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
3845eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::InvokeCode(Register code,
3846eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                                const ParameterCount& expected,
3847eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                                const ParameterCount& actual,
38483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                                InvokeFlag flag,
3849e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                const CallWrapper& call_wrapper) {
3850c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // You can't call a function without a valid frame.
3851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(flag == JUMP_FUNCTION || has_frame());
3852c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
385383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label done;
38542efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  bool definitely_mismatches = false;
38553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  InvokePrologue(expected,
38563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                 actual,
38573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                 Handle<Code>::null(),
38583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                 code,
38593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                 &done,
38602efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                 &definitely_mismatches,
38613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                 flag,
386240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                 Label::kNear,
3863e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                 call_wrapper);
38642efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (!definitely_mismatches) {
38652efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    if (flag == CALL_FUNCTION) {
38662efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      call_wrapper.BeforeCall(CallSize(code));
38672efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      call(code);
38682efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      call_wrapper.AfterCall();
38692efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    } else {
38702efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      ASSERT(flag == JUMP_FUNCTION);
38712efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      jmp(code);
38722efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    }
38732efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    bind(&done);
3874eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
3875eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3876eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3877eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3878eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::InvokeFunction(Register function,
3879eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                                    const ParameterCount& actual,
38803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                                    InvokeFlag flag,
3881e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                    const CallWrapper& call_wrapper) {
3882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // You can't call a function without a valid frame.
3883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(flag == JUMP_FUNCTION || has_frame());
3884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3885eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(function.is(rdi));
388643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
388743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
388804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org  LoadSharedFunctionInfoSpecialField(rbx, rdx,
388904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org      SharedFunctionInfo::kFormalParameterCountOffset);
38905aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Advances rdx to the end of the Code object header, to the start of
3891eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // the executable code.
389243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
3893eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3894eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ParameterCount expected(rbx);
3895e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  InvokeCode(rdx, expected, actual, flag, call_wrapper);
3896eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
3897eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
3898eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
38998a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Register function,
390032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                                    const ParameterCount& expected,
39015c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                    const ParameterCount& actual,
39023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                                    InvokeFlag flag,
3903e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                    const CallWrapper& call_wrapper) {
3904c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // You can't call a function without a valid frame.
3905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(flag == JUMP_FUNCTION || has_frame());
3906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
39078a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  ASSERT(function.is(rdi));
390843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
39098a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  // Advances rdx to the end of the Code object header, to the start of
39108a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  // the executable code.
391143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
39128a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
3913e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  InvokeCode(rdx, expected, actual, flag, call_wrapper);
39145c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
39155c838251403b0be9a882540f1922577abba4c872ager@chromium.org
39165c838251403b0be9a882540f1922577abba4c872ager@chromium.org
39178a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function,
39188a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                    const ParameterCount& expected,
39198a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                    const ParameterCount& actual,
39208a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                    InvokeFlag flag,
3921e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                    const CallWrapper& call_wrapper) {
39228a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  Move(rdi, function);
3923e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  InvokeFunction(rdi, expected, actual, flag, call_wrapper);
39248a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org}
39258a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
39268a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
392783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::InvokePrologue(const ParameterCount& expected,
392883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    const ParameterCount& actual,
392983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Handle<Code> code_constant,
393083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Register code_register,
393183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Label* done,
39322efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                    bool* definitely_mismatches,
393383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    InvokeFlag flag,
393440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                    Label::Distance near_jump,
3935e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                    const CallWrapper& call_wrapper) {
393683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  bool definitely_matches = false;
39372efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  *definitely_mismatches = false;
393883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label invoke;
393983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (expected.is_immediate()) {
394083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(actual.is_immediate());
394183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (expected.immediate() == actual.immediate()) {
394283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      definitely_matches = true;
394383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
394483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Set(rax, actual.immediate());
394583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      if (expected.immediate() ==
394683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
394783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        // Don't worry about adapting arguments for built-ins that
394883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        // don't want that done. Skip adaption code by making it look
394983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        // like we have a match between expected and actual number of
395083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        // arguments.
395183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        definitely_matches = true;
395283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      } else {
39532efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        *definitely_mismatches = true;
395483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        Set(rbx, expected.immediate());
395583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      }
395683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
395783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
395883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (actual.is_immediate()) {
395983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      // Expected is in register, actual is immediate. This is the
396083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      // case when we invoke function values without going through the
396183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      // IC mechanism.
39627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org      cmpp(expected.reg(), Immediate(actual.immediate()));
396383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      j(equal, &invoke, Label::kNear);
396483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      ASSERT(expected.reg().is(rbx));
396583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Set(rax, actual.immediate());
396683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else if (!expected.reg().is(actual.reg())) {
396783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      // Both expected and actual are in (different) registers. This
396883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      // is the case when we invoke functions using call and apply.
39697a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org      cmpp(expected.reg(), actual.reg());
397083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      j(equal, &invoke, Label::kNear);
397183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      ASSERT(actual.reg().is(rax));
397283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      ASSERT(expected.reg().is(rbx));
397383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
397483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
397583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
397683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (!definitely_matches) {
397783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
397883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (!code_constant.is_null()) {
39799cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      Move(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
3980fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      addp(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
398183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else if (!code_register.is(rdx)) {
398243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(rdx, code_register);
398383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
398483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
398583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (flag == CALL_FUNCTION) {
398683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      call_wrapper.BeforeCall(CallSize(adaptor));
398783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Call(adaptor, RelocInfo::CODE_TARGET);
398883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      call_wrapper.AfterCall();
39892efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      if (!*definitely_mismatches) {
39902efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        jmp(done, near_jump);
39912efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      }
399283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
399383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Jump(adaptor, RelocInfo::CODE_TARGET);
399483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
399583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    bind(&invoke);
399683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
399783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
399883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
399983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
4000285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::StubPrologue() {
4001763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    pushq(rbp);  // Caller's frame pointer.
400243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(rbp, rsp);
4003763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(rsi);  // Callee's context.
4004c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    Push(Smi::FromInt(StackFrame::STUB));
4005285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org}
4006285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org
4007285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org
4008285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::Prologue(bool code_pre_aging) {
4009285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org  PredictableCodeSizeScope predictible_code_size_scope(this,
4010285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org      kNoCodeAgeSequenceLength);
4011285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org  if (code_pre_aging) {
4012285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org      // Pre-age the code.
4013285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org    Call(isolate()->builtins()->MarkCodeAsExecutedOnce(),
4014285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org         RelocInfo::CODE_AGE_SEQUENCE);
4015285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org    Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength);
4016c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  } else {
4017285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org    pushq(rbp);  // Caller's frame pointer.
4018285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org    movp(rbp, rsp);
4019285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org    Push(rsi);  // Callee's context.
4020285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org    Push(rdi);  // Callee's JS function.
4021c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  }
4022c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org}
4023c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
4024c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
4025eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::EnterFrame(StackFrame::Type type) {
4026763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  pushq(rbp);
402743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rbp, rsp);
4028763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(rsi);  // Context.
40299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  Push(Smi::FromInt(type));
40309cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
4031763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(kScratchRegister);
4032badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
40339cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    Move(kScratchRegister,
4034160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org         isolate()->factory()->undefined_value(),
4035eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org         RelocInfo::EMBEDDED_OBJECT);
40367a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(Operand(rsp, 0), kScratchRegister);
4037594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(not_equal, kCodeObjectNotProperlyPatched);
4038eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
4039eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
4040eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4041eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4042eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::LeaveFrame(StackFrame::Type type) {
4043badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
40449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    Move(kScratchRegister, Smi::FromInt(type));
40457a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister);
4046594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(equal, kStackFrameTypesMustMatch);
4047eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
404843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rsp, rbp);
4049763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  popq(rbp);
4050eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
4051eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4052eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4053d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::EnterExitFramePrologue(bool save_rax) {
4054f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up the frame structure on the stack.
405586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // All constants are relative to the frame pointer of the exit frame.
4056d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  ASSERT(ExitFrameConstants::kCallerSPDisplacement ==
4057d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org         kFPOnStackSize + kPCOnStackSize);
4058d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  ASSERT(ExitFrameConstants::kCallerPCOffset == kFPOnStackSize);
4059d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize);
4060763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  pushq(rbp);
406143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rbp, rsp);
4062eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4063d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Reserve room for entry stack pointer and push the code object.
40649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
4065763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(Immediate(0));  // Saved entry sp, patched before call.
40669cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
4067763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(kScratchRegister);  // Accessed from EditFrame::code_slot.
4068eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4069eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Save the frame pointer and the context in top.
4070e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  if (save_rax) {
407143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(r14, rax);  // Backup rax in callee-save register.
4072e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  }
4073eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
407483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp);
407583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi);
4076e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
4077eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
40784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
40790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
40800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org                                            bool save_doubles) {
4081a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef _WIN64
40820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  const int kShadowSpace = 4;
40830ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  arg_stack_space += kShadowSpace;
4084a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif
40850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // Optionally save all XMM registers.
40860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (save_doubles) {
4087c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    int space = XMMRegister::kMaxNumAllocatableRegisters * kDoubleSize +
408843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org        arg_stack_space * kRegisterSize;
4089fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(rsp, Immediate(space));
40900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    int offset = -2 * kPointerSize;
4091a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
40920ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org      XMMRegister reg = XMMRegister::FromAllocationIndex(i);
40930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org      movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
40940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    }
40950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  } else if (arg_stack_space > 0) {
4096fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(rsp, Immediate(arg_stack_space * kRegisterSize));
40974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  }
4098a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
4099eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Get the required frame alignment for the OS.
4100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  const int kFrameAlignment = OS::ActivationFrameAlignment();
4101eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (kFrameAlignment > 0) {
4102eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    ASSERT(IsPowerOf2(kFrameAlignment));
4103a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    ASSERT(is_int8(kFrameAlignment));
4104895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    andp(rsp, Immediate(-kFrameAlignment));
4105eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
4106eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4107eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Patch the saved entry sp.
410843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
4109eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
4110eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4111eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
41120ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) {
4113d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  EnterExitFramePrologue(true);
4114e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
4115f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame,
4116e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  // so it must be retained across the C-call.
4117e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
4118895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(r15, Operand(rbp, r14, times_pointer_size, offset));
4119e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
41200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  EnterExitFrameEpilogue(arg_stack_space, save_doubles);
4121e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
4122e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
4123e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
41244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
4125d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  EnterExitFramePrologue(false);
41260ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  EnterExitFrameEpilogue(arg_stack_space, false);
4127e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
4128e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
4129e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
41300ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::LeaveExitFrame(bool save_doubles) {
4131eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Registers:
4132b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // r15 : argv
41330ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (save_doubles) {
41340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    int offset = -2 * kPointerSize;
4135a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
41360ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org      XMMRegister reg = XMMRegister::FromAllocationIndex(i);
41370ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org      movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
41380ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org    }
41390ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  }
4140eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Get the return address from the stack and restore the frame pointer.
414143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rcx, Operand(rbp, kFPOnStackSize));
414243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rbp, Operand(rbp, 0 * kPointerSize));
4143eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
41440ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // Drop everything up to and including the arguments and the receiver
4145a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // from the caller stack.
4146895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(rsp, Operand(r15, 1 * kPointerSize));
4147eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4148594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  PushReturnAddressFrom(rcx);
41494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4150528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  LeaveExitFrameEpilogue(true);
41514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
41524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
41534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4154528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) {
415543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rsp, rbp);
4156763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  popq(rbp);
41574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4158528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  LeaveExitFrameEpilogue(restore_context);
41594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
41604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
41614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4162528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
4163eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Restore current context from top and clear it in debug mode.
416483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  ExternalReference context_address(Isolate::kContextAddress, isolate());
4165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Operand context_operand = ExternalOperand(context_address);
4166528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (restore_context) {
416743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(rsi, context_operand);
4168528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
4169eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG
417043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(context_operand, Immediate(0));
4171eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif
4172eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4173eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Clear the top frame.
417483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress,
4175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                       isolate());
4176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address);
417743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(c_entry_fp_operand, Immediate(0));
4178eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
4179eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4180eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4181e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
4182e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org                                            Register scratch,
4183e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org                                            Label* miss) {
4184e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  Label same_contexts;
4185e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
4186e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  ASSERT(!holder_reg.is(scratch));
4187e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  ASSERT(!scratch.is(kScratchRegister));
4188e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // Load current lexical context from the stack frame.
418943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, Operand(rbp, StandardFrameConstants::kContextOffset));
4190e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
4191e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // When generating debug code, make sure the lexical context is set.
4192badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
41937a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(scratch, Immediate(0));
4194594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext);
4195e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  }
419646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Load the native context of the current context.
419746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  int offset =
419846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
419943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, FieldOperand(scratch, offset));
420043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
4201e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
420246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Check the context is a native context.
4203badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
4204e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    Cmp(FieldOperand(scratch, HeapObject::kMapOffset),
420546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate()->factory()->native_context_map());
4206594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext);
4207e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  }
4208e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
4209e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // Check if both contexts are the same.
42107a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
4211e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  j(equal, &same_contexts);
4212e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
4213e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // Compare security tokens.
4214e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // Check that the security token in the calling global object is
4215e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // compatible with the security token in the receiving global
4216e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // object.
4217e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
421846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Check the context is a native context.
4219badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
4220e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    // Preserve original value of holder_reg.
4221763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(holder_reg);
422243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(holder_reg,
422346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org         FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
422418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    CompareRoot(holder_reg, Heap::kNullValueRootIndex);
4225594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(not_equal, kJSGlobalProxyContextShouldNotBeNull);
4226e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
422746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // Read the first word and compare to native_context_map(),
422843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
422946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex);
4230594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext);
4231763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Pop(holder_reg);
4232e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  }
4233e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
423443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(kScratchRegister,
423546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org       FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
42369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  int token_offset =
42379d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize;
423843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, FieldOperand(scratch, token_offset));
42397a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(scratch, FieldOperand(kScratchRegister, token_offset));
4240e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  j(not_equal, miss);
4241e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
4242e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  bind(&same_contexts);
4243e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org}
4244e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
4245e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
4246ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// Compute the hash code from the untagged key.  This must be kept in sync with
4247ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// ComputeIntegerHash in utils.h and KeyedLoadGenericElementStub in
4248ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// code-stub-hydrogen.cc
4249f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) {
4250f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // First of all we assign the hash seed to scratch.
4251f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  LoadRoot(scratch, Heap::kHashSeedRootIndex);
4252f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  SmiToInteger32(scratch, scratch);
4253f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4254f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Xor original key with a seed.
4255f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  xorl(r0, scratch);
4256f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4257f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Compute the hash code from the untagged key.  This must be kept in sync
4258f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // with ComputeIntegerHash in utils.h.
4259f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  //
4260f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // hash = ~hash + (hash << 15);
4261f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  movl(scratch, r0);
4262f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  notl(r0);
4263f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  shll(scratch, Immediate(15));
4264f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  addl(r0, scratch);
4265f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // hash = hash ^ (hash >> 12);
4266f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  movl(scratch, r0);
4267f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  shrl(scratch, Immediate(12));
4268f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  xorl(r0, scratch);
4269f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // hash = hash + (hash << 2);
4270f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  leal(r0, Operand(r0, r0, times_4, 0));
4271f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // hash = hash ^ (hash >> 4);
4272f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  movl(scratch, r0);
4273f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  shrl(scratch, Immediate(4));
4274f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  xorl(r0, scratch);
4275f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // hash = hash * 2057;
4276f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  imull(r0, r0, Immediate(2057));
4277f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // hash = hash ^ (hash >> 16);
4278f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  movl(scratch, r0);
4279f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  shrl(scratch, Immediate(16));
4280f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  xorl(r0, scratch);
4281f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
4282f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4283f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4284f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
42856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid MacroAssembler::LoadFromNumberDictionary(Label* miss,
42866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                              Register elements,
42876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                              Register key,
42886db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                              Register r0,
42896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                              Register r1,
42906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                              Register r2,
42916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                              Register result) {
42926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Register use:
42936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //
42946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // elements - holds the slow-case elements of the receiver on entry.
42956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //            Unchanged unless 'result' is the same register.
42966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //
42976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // key      - holds the smi key on entry.
42986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //            Unchanged unless 'result' is the same register.
42996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //
43006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Scratch registers:
43016db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //
43026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // r0 - holds the untagged key on entry and holds the hash once computed.
43036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //
43046db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // r1 - used to hold the capacity mask of the dictionary
43056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //
43066db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // r2 - used for the index into the dictionary.
43076db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //
43086db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // result - holds the result on exit if the load succeeded.
43096db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //          Allowed to be the same as 'key' or 'result'.
43106db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //          Unchanged on bailout so 'key' or 'result' can be used
43116db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  //          in further computation.
43126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  Label done;
43146db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
4315f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  GetNumberHash(r0, r1);
43166db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43176db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Compute capacity mask.
4318f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  SmiToInteger32(r1, FieldOperand(elements,
4319f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                  SeededNumberDictionary::kCapacityOffset));
43206db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  decl(r1);
43216db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43226db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Generate an unrolled loop that performs a few probes before giving up.
4323ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  for (int i = 0; i < kNumberDictionaryProbes; i++) {
43246db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    // Use r2 for index calculations and keep the hash intact in r0.
432543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(r2, r0);
43266db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    // Compute the masked index: (hash + i + i * i) & mask.
43276db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    if (i > 0) {
4328f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
43296db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    }
4330895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    andp(r2, r1);
43316db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    // Scale the index by multiplying by the entry size.
4333f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    ASSERT(SeededNumberDictionary::kEntrySize == 3);
4334895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    leap(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3
43356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    // Check if the key matches.
43377a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(key, FieldOperand(elements,
43386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                           r2,
43396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                           times_pointer_size,
4340f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                           SeededNumberDictionary::kElementsStartOffset));
4341ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (i != (kNumberDictionaryProbes - 1)) {
43426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org      j(equal, &done);
43436db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    } else {
43446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org      j(not_equal, miss);
43456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    }
43466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  }
43476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43486db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  bind(&done);
43496db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Check that the value is a normal propety.
43506db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  const int kDetailsOffset =
4351f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
43526db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  ASSERT_EQ(NORMAL, 0);
43536db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
435483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org       Smi::FromInt(PropertyDetails::TypeField::kMask));
43556db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  j(not_zero, miss);
43566db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43576db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Get the value at the masked, scaled index.
43586db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  const int kValueOffset =
4359f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      SeededNumberDictionary::kElementsStartOffset + kPointerSize;
436043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
43616db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org}
43626db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
43636db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
4364a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid MacroAssembler::LoadAllocationTopHelper(Register result,
4365a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                                             Register scratch,
4366a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                                             AllocationFlags flags) {
43672bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  ExternalReference allocation_top =
43682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      AllocationUtils::GetAllocationTopReference(isolate(), flags);
436918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
437018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Just return if allocation top is already known.
4371a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  if ((flags & RESULT_CONTAINS_TOP) != 0) {
437218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    // No use of scratch if allocation top is provided.
4373ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org    ASSERT(!scratch.is_valid());
4374a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef DEBUG
4375a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // Assert that result actually contains top on entry.
43762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Operand top_operand = ExternalOperand(allocation_top);
43777a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    cmpp(result, top_operand);
4378594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(equal, kUnexpectedAllocationTop);
4379a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif
438018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    return;
438118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
438218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
4383ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // Move address of new object to result. Use scratch register if available,
4384ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // and keep address in scratch until call to UpdateAllocationTopHelper.
4385ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  if (scratch.is_valid()) {
43862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    LoadAddress(scratch, allocation_top);
438743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(result, Operand(scratch, 0));
4388ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  } else {
43892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Load(result, allocation_top);
439018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
439118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
439218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
439318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
439438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid MacroAssembler::MakeSureDoubleAlignedHelper(Register result,
439538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                                 Register scratch,
439638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                                 Label* gc_required,
439738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                                 AllocationFlags flags) {
439838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  if (kPointerSize == kDoubleSize) {
439938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    if (FLAG_debug_code) {
440038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      testl(result, Immediate(kDoubleAlignmentMask));
440138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      Check(zero, kAllocationIsNotDoubleAligned);
440238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    }
440338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  } else {
440438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // Align the next allocation. Storing the filler map without checking top
440538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // is safe in new-space because the limit of the heap is aligned there.
440638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    ASSERT(kPointerSize * 2 == kDoubleSize);
440738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
440838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
440938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // Make sure scratch is not clobbered by this function as it might be
441038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // used in UpdateAllocationTopHelper later.
441138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    ASSERT(!scratch.is(kScratchRegister));
441238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    Label aligned;
441338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    testl(result, Immediate(kDoubleAlignmentMask));
441438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    j(zero, &aligned, Label::kNear);
441538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
441638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      ExternalReference allocation_limit =
441738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org          AllocationUtils::GetAllocationLimitReference(isolate(), flags);
441838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      cmpp(result, ExternalOperand(allocation_limit));
441938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      j(above_equal, gc_required);
442038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    }
442138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex);
442238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    movp(Operand(result, 0), kScratchRegister);
442338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    addp(result, Immediate(kDoubleSize / 2));
442438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    bind(&aligned);
442538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  }
442638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org}
442738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
442838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
442918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end,
44302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                                               Register scratch,
44312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                                               AllocationFlags flags) {
4432badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
44337a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    testp(result_end, Immediate(kObjectAlignmentMask));
4434594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(zero, kUnalignedAllocationInNewSpace);
4435ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  }
4436ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
44372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  ExternalReference allocation_top =
44382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      AllocationUtils::GetAllocationTopReference(isolate(), flags);
443918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
444018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Update new top.
4441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (scratch.is_valid()) {
4442ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // Scratch already contains address of allocation top.
444343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(Operand(scratch, 0), result_end);
444418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  } else {
44452bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Store(allocation_top, result_end);
444618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
444718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
444818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
444918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
44502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid MacroAssembler::Allocate(int object_size,
44512bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                              Register result,
44522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                              Register result_end,
44532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                              Register scratch,
44542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                              Label* gc_required,
44552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                              AllocationFlags flags) {
44564cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
4457ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  ASSERT(object_size <= Page::kMaxRegularHeapObjectSize);
4458b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (!FLAG_inline_new) {
4459badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    if (emit_debug_code()) {
4460303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      // Trash the registers to simulate an allocation failure.
4461303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      movl(result, Immediate(0x7091));
4462303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (result_end.is_valid()) {
4463303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        movl(result_end, Immediate(0x7191));
4464303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
4465303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (scratch.is_valid()) {
4466303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        movl(scratch, Immediate(0x7291));
4467303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
4468303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
4469303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    jmp(gc_required);
4470303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    return;
4471303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
447218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  ASSERT(!result.is(result_end));
447318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
447418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Load address of new object into result.
4475beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  LoadAllocationTopHelper(result, scratch, flags);
447618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
447738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  if ((flags & DOUBLE_ALIGNMENT) != 0) {
447838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags);
44794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
44804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
448118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Calculate new top and bail out if new space is exhausted.
44822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  ExternalReference allocation_limit =
44832bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
4484ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
4485ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  Register top_reg = result_end.is_valid() ? result_end : result;
4486ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
4487d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  if (!top_reg.is(result)) {
448843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(top_reg, result);
4489ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  }
4490fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(top_reg, Immediate(object_size));
4491d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  j(carry, gc_required);
44922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Operand limit_operand = ExternalOperand(allocation_limit);
44937a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(top_reg, limit_operand);
449418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  j(above, gc_required);
449518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
449618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Update allocation top.
44972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  UpdateAllocationTopHelper(top_reg, scratch, flags);
4498a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
44994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool tag_result = (flags & TAG_OBJECT) != 0;
4500ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  if (top_reg.is(result)) {
45014cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    if (tag_result) {
4502fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      subp(result, Immediate(object_size - kHeapObjectTag));
4503ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org    } else {
4504fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      subp(result, Immediate(object_size));
4505ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org    }
45064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  } else if (tag_result) {
4507ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org    // Tag the result if requested.
45084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    ASSERT(kHeapObjectTag == 1);
45097a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    incp(result);
4510a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  }
451118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
451218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
451318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
4514f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(int header_size,
4515f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              ScaleFactor element_size,
4516f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Register element_count,
4517f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Register result,
4518f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Register result_end,
4519f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Register scratch,
4520f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Label* gc_required,
4521f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              AllocationFlags flags) {
45224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT((flags & SIZE_IN_WORDS) == 0);
4523895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(result_end, Operand(element_count, element_size, header_size));
4524e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Allocate(result_end, result, result_end, scratch, gc_required, flags);
4525a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org}
452618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
452718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
4528f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(Register object_size,
4529f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Register result,
4530f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Register result_end,
4531f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Register scratch,
4532f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              Label* gc_required,
4533f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                              AllocationFlags flags) {
4534e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  ASSERT((flags & SIZE_IN_WORDS) == 0);
4535b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (!FLAG_inline_new) {
4536badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    if (emit_debug_code()) {
4537303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      // Trash the registers to simulate an allocation failure.
4538303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      movl(result, Immediate(0x7091));
4539303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      movl(result_end, Immediate(0x7191));
4540303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (scratch.is_valid()) {
4541303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        movl(scratch, Immediate(0x7291));
4542303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
4543303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      // object_size is left unchanged by this function.
4544303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
4545303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    jmp(gc_required);
4546303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    return;
4547303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
4548303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  ASSERT(!result.is(result_end));
4549303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
455018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Load address of new object into result.
4551beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  LoadAllocationTopHelper(result, scratch, flags);
455218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
455338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  if ((flags & DOUBLE_ALIGNMENT) != 0) {
455438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags);
4555e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
4556e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
455718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Calculate new top and bail out if new space is exhausted.
4558f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ExternalReference allocation_limit =
4559f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
456018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  if (!object_size.is(result_end)) {
456143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(result_end, object_size);
456218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
4563fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(result_end, result);
4564d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  j(carry, gc_required);
4565f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Operand limit_operand = ExternalOperand(allocation_limit);
45667a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(result_end, limit_operand);
456718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  j(above, gc_required);
456818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
456918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Update allocation top.
45702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  UpdateAllocationTopHelper(result_end, scratch, flags);
4571a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
4572a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Tag the result if requested.
4573a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  if ((flags & TAG_OBJECT) != 0) {
4574fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(result, Immediate(kHeapObjectTag));
4575a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  }
457618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
457718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
457818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
457918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UndoAllocationInNewSpace(Register object) {
458018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  ExternalReference new_space_allocation_top =
4581ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ExternalReference::new_space_allocation_top_address(isolate());
458218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
458318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Make sure the object has no tag before resetting top.
4584895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(object, Immediate(~kHeapObjectTagMask));
4585ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Operand top_operand = ExternalOperand(new_space_allocation_top);
458618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef DEBUG
45877a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(object, top_operand);
4588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Check(below, kUndoAllocationOfNonAllocatedMemory);
458918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif
459043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(top_operand, object);
459118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
459218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
459318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
45943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgvoid MacroAssembler::AllocateHeapNumber(Register result,
45953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org                                        Register scratch,
45963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org                                        Label* gc_required) {
45973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Allocate heap number in new space.
45982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT);
45993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
46003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Set the map.
46013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex);
460243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
46033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
46043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
46053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
460613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateTwoByteString(Register result,
460713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                           Register length,
460813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                           Register scratch1,
460913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                           Register scratch2,
461013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                           Register scratch3,
461113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                           Label* gc_required) {
461213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Calculate the number of bytes needed for the characters in the string while
461313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // observing object alignment.
4614ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  const int kHeaderAlignment = SeqTwoByteString::kHeaderSize &
4615ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org                               kObjectAlignmentMask;
461613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  ASSERT(kShortSize == 2);
461713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // scratch1 = length * 2 + kObjectAlignmentMask.
4618895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask +
4619ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org                kHeaderAlignment));
4620895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(scratch1, Immediate(~kObjectAlignmentMask));
4621ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  if (kHeaderAlignment > 0) {
4622fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(scratch1, Immediate(kHeaderAlignment));
4623ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  }
462413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
462513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Allocate two byte string in new space.
4626f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Allocate(SeqTwoByteString::kHeaderSize,
4627f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           times_1,
4628f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           scratch1,
4629f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           result,
4630f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           scratch2,
4631f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           scratch3,
4632f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           gc_required,
4633f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           TAG_OBJECT);
463413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
463513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Set the map, length and hash field.
463613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  LoadRoot(kScratchRegister, Heap::kStringMapRootIndex);
463743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
4638ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  Integer32ToSmi(scratch1, length);
463943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, String::kLengthOffset), scratch1);
464043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, String::kHashFieldOffset),
464113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org       Immediate(String::kEmptyHashField));
464213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
464313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
464413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
464513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiString(Register result,
464613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                         Register length,
464713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                         Register scratch1,
464813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                         Register scratch2,
464913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                         Register scratch3,
465013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                         Label* gc_required) {
465113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Calculate the number of bytes needed for the characters in the string while
465213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // observing object alignment.
4653fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  const int kHeaderAlignment = SeqOneByteString::kHeaderSize &
4654ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org                               kObjectAlignmentMask;
465513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  movl(scratch1, length);
465613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  ASSERT(kCharSize == 1);
4657fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment));
4658895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(scratch1, Immediate(~kObjectAlignmentMask));
4659ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  if (kHeaderAlignment > 0) {
4660fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    subp(scratch1, Immediate(kHeaderAlignment));
4661ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  }
466213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
46632efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Allocate ASCII string in new space.
4664f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Allocate(SeqOneByteString::kHeaderSize,
4665f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           times_1,
4666f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           scratch1,
4667f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           result,
4668f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           scratch2,
4669f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           scratch3,
4670f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           gc_required,
4671f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org           TAG_OBJECT);
467213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
467313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Set the map, length and hash field.
467413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex);
467543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
4676ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  Integer32ToSmi(scratch1, length);
467743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, String::kLengthOffset), scratch1);
467843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, String::kHashFieldOffset),
467913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org       Immediate(String::kEmptyHashField));
468013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
468113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
468213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
46831805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteConsString(Register result,
468413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                        Register scratch1,
468513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                        Register scratch2,
468613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                        Label* gc_required) {
468713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Allocate heap number in new space.
46882bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
46892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org           TAG_OBJECT);
469013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
469113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Set the map. The other fields are left uninitialized.
469213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex);
469343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
469413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
469513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
469613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
469713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiConsString(Register result,
469813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                             Register scratch1,
469913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                             Register scratch2,
470013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                                             Label* gc_required) {
470157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Allocate(ConsString::kSize,
470257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org           result,
470357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org           scratch1,
470457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org           scratch2,
470557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org           gc_required,
47067e6132b924829c353864933f29124419916db550machenbach@chromium.org           TAG_OBJECT);
470713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
470813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Set the map. The other fields are left uninitialized.
470913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex);
471043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
471113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
471213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
471313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
47141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteSlicedString(Register result,
47151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                          Register scratch1,
47161805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                          Register scratch2,
47171805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                          Label* gc_required) {
47181805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Allocate heap number in new space.
47192bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
47202bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org           TAG_OBJECT);
47211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
47221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Set the map. The other fields are left uninitialized.
47231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex);
472443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
47251805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
47261805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
47271805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
47281805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateAsciiSlicedString(Register result,
47291805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                               Register scratch1,
47301805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                               Register scratch2,
47311805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                               Label* gc_required) {
47321805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Allocate heap number in new space.
47332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
47342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org           TAG_OBJECT);
47351805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
47361805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Set the map. The other fields are left uninitialized.
47371805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  LoadRoot(kScratchRegister, Heap::kSlicedAsciiStringMapRootIndex);
473843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
47391805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
47401805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
47411805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
47427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// Copy memory, byte-by-byte, from source to destination.  Not optimized for
47437979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// long or aligned copies.  The contents of scratch and length are destroyed.
47447979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// Destination is incremented by length, source, length and scratch are
47457979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// clobbered.
47467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// A simpler loop is faster on small copies, but slower on large ones.
47477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// The cld() instruction must have been emitted, to set the direction flag(),
47487979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// before calling this function.
47497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgvoid MacroAssembler::CopyBytes(Register destination,
47507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                               Register source,
47517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                               Register length,
47527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                               int min_length,
47537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                               Register scratch) {
47547979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  ASSERT(min_length >= 0);
4755000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (emit_debug_code()) {
47567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    cmpl(length, Immediate(min_length));
4757594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Assert(greater_equal, kInvalidMinLength);
47587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  }
47590cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  Label short_loop, len8, len16, len24, done, short_string;
47607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
47610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  const int kLongStringLimit = 4 * kPointerSize;
47627979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  if (min_length <= kLongStringLimit) {
47630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    cmpl(length, Immediate(kPointerSize));
47640cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    j(below, &short_string, Label::kNear);
47657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  }
47667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
47677979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  ASSERT(source.is(rsi));
47687979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  ASSERT(destination.is(rdi));
47697979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  ASSERT(length.is(rcx));
47707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
47710cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (min_length <= kLongStringLimit) {
47720cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    cmpl(length, Immediate(2 * kPointerSize));
47730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    j(below_equal, &len8, Label::kNear);
47740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    cmpl(length, Immediate(3 * kPointerSize));
47750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    j(below_equal, &len16, Label::kNear);
47760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    cmpl(length, Immediate(4 * kPointerSize));
47770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    j(below_equal, &len24, Label::kNear);
47780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
47790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
47807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // Because source is 8-byte aligned in our uses of this function,
47817979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // we keep source aligned for the rep movs operation by copying the odd bytes
47827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // at the end of the ranges.
478343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, length);
478493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  shrl(length, Immediate(kPointerSizeLog2));
4785895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  repmovsp();
47867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // Move remaining bytes of length.
478793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  andl(scratch, Immediate(kPointerSize - 1));
478843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(length, Operand(source, scratch, times_1, -kPointerSize));
478943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(destination, scratch, times_1, -kPointerSize), length);
4790fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(destination, scratch);
47917979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
47927979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  if (min_length <= kLongStringLimit) {
47930cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    jmp(&done, Label::kNear);
47940cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    bind(&len24);
479543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(scratch, Operand(source, 2 * kPointerSize));
479643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(Operand(destination, 2 * kPointerSize), scratch);
47970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    bind(&len16);
479843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(scratch, Operand(source, kPointerSize));
479943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(Operand(destination, kPointerSize), scratch);
48000cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    bind(&len8);
480143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(scratch, Operand(source, 0));
480243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(Operand(destination, 0), scratch);
48030cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    // Move remaining bytes of length.
480443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(scratch, Operand(source, length, times_1, -kPointerSize));
480543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(Operand(destination, length, times_1, -kPointerSize), scratch);
4806fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(destination, length);
48070cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    jmp(&done, Label::kNear);
48087979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
48097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    bind(&short_string);
48107979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    if (min_length == 0) {
48117979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      testl(length, length);
48120cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      j(zero, &done, Label::kNear);
48137979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    }
48147979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
48157979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    bind(&short_loop);
48160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    movb(scratch, Operand(source, 0));
48170cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    movb(Operand(destination, 0), scratch);
48187a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    incp(source);
48197a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    incp(destination);
48200cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    decl(length);
48210cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    j(not_zero, &short_loop);
48227979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  }
48230cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
48240cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  bind(&done);
48257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org}
48267979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
48277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
4828c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
4829c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                Register end_offset,
4830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                Register filler) {
4831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label loop, entry;
4832c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  jmp(&entry);
4833c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&loop);
483443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(start_offset, 0), filler);
4835fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(start_offset, Immediate(kPointerSize));
4836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&entry);
48377a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(start_offset, end_offset);
4838c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(less, &loop);
4839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4842ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) {
4843ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  if (context_chain_length > 0) {
4844ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    // Move up the chain of contexts to the context containing the slot.
484543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
4846ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    for (int i = 1; i < context_chain_length; i++) {
484743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org      movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
4848ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    }
48495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  } else {
48505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // Slot is in the current function context.  Move it into the
48515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // destination register in case we store into it (the write barrier
48525d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // cannot be allowed to destroy the context in rsi).
485343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(dst, rsi);
48545d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
48555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
48564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // We should not have found a with context by walking the context
48574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // chain (i.e., the static scope chain and runtime context chain do
48584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // not agree).  A variable occurring in such a scope should have
48594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // slot type LOOKUP and not CONTEXT.
4860badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
48613cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    CompareRoot(FieldOperand(dst, HeapObject::kMapOffset),
48623cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                Heap::kWithContextMapRootIndex);
4863594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Check(not_equal, kVariableResolvedToWithContext);
4864ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  }
4865ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org}
4866ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
4867fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
48681145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadTransitionedArrayMapConditional(
48691145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    ElementsKind expected_kind,
48701145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    ElementsKind transitioned_kind,
48711145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    Register map_in_out,
48721145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    Register scratch,
48731145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org    Label* no_map_match) {
48741145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Load the global or builtins object from the current context.
487543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch,
487646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org       Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
487743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
48781145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
48791145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Check that the function's map is the same as the expected cached map.
488043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, Operand(scratch,
4881830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                        Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
4882830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
4883830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  int offset = expected_kind * kPointerSize +
4884830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      FixedArrayBase::kHeaderSize;
48857a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(map_in_out, FieldOperand(scratch, offset));
48861145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  j(not_equal, no_map_match);
48871145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
48881145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Use the transitioned cached map.
4889830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  offset = transitioned_kind * kPointerSize +
4890830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      FixedArrayBase::kHeaderSize;
489143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(map_in_out, FieldOperand(scratch, offset));
48921145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org}
48931145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
48941145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
4895ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef _WIN64
4896ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const int kRegisterPassedArguments = 4;
4897ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#else
4898ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const int kRegisterPassedArguments = 6;
4899ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif
490030ce411529579186181838984710b0b0980857aaricow@chromium.org
49015f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid MacroAssembler::LoadGlobalFunction(int index, Register function) {
49025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Load the global or builtins object from the current context.
490343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(function,
490446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org       Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
490546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Load the native context from the global or builtins object.
490643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(function, FieldOperand(function, GlobalObject::kNativeContextOffset));
490746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Load the function from the native context.
490843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(function, Operand(function, Context::SlotOffset(index)));
49095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
49105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
49115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
49125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
49135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                                                  Register map) {
49145f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Load the initial map.  The global functions all have initial maps.
491543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
4916badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
49175f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    Label ok, fail;
4918c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK);
49195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    jmp(&ok);
49205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    bind(&fail);
4921594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Abort(kGlobalFunctionsMustHaveInitialMap);
49225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    bind(&ok);
49235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
49245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
49255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
49265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4927b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) {
492830ce411529579186181838984710b0b0980857aaricow@chromium.org  // On Windows 64 stack slots are reserved by the caller for all arguments
492930ce411529579186181838984710b0b0980857aaricow@chromium.org  // including the ones passed in registers, and space is always allocated for
493030ce411529579186181838984710b0b0980857aaricow@chromium.org  // the four register arguments even if the function takes fewer than four
493130ce411529579186181838984710b0b0980857aaricow@chromium.org  // arguments.
493230ce411529579186181838984710b0b0980857aaricow@chromium.org  // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers
493330ce411529579186181838984710b0b0980857aaricow@chromium.org  // and the caller does not reserve stack slots for them.
4934b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(num_arguments >= 0);
4935b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef _WIN64
4936ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  const int kMinimumStackSlots = kRegisterPassedArguments;
493730ce411529579186181838984710b0b0980857aaricow@chromium.org  if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots;
493830ce411529579186181838984710b0b0980857aaricow@chromium.org  return num_arguments;
4939b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#else
494030ce411529579186181838984710b0b0980857aaricow@chromium.org  if (num_arguments < kRegisterPassedArguments) return 0;
494130ce411529579186181838984710b0b0980857aaricow@chromium.org  return num_arguments - kRegisterPassedArguments;
4942b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif
4943b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
4944b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
494530ce411529579186181838984710b0b0980857aaricow@chromium.org
49469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string,
49479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                               Register index,
49489af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                               Register value,
49499af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                               uint32_t encoding_mask) {
49509af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  Label is_object;
49519af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  JumpIfNotSmi(string, &is_object);
495205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org  Abort(kNonObject);
49539af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  bind(&is_object);
49549af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
4955763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Push(value);
495643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(value, FieldOperand(string, HeapObject::kMapOffset));
4957895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  movzxbp(value, FieldOperand(value, Map::kInstanceTypeOffset));
49589af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
49599af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask));
49607a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(value, Immediate(encoding_mask));
4961763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  Pop(value);
496205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org  Check(equal, kUnexpectedStringType);
49639af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
49649af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // The index is assumed to be untagged coming in, tag it to compare with the
49659af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // string length without using a temp register, it is restored at the end of
49669af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // this function.
49679af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  Integer32ToSmi(index, index);
49689af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  SmiCompare(index, FieldOperand(string, String::kLengthOffset));
496905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org  Check(less, kIndexIsTooLarge);
49709af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
49719af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  SmiCompare(index, Smi::FromInt(0));
497205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org  Check(greater_equal, kIndexIsNegative);
49739af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
49749af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // Restore the index
49759af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  SmiToInteger32(index, index);
49769af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org}
49779af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
49789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
4979b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::PrepareCallCFunction(int num_arguments) {
4980b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int frame_alignment = OS::ActivationFrameAlignment();
4981b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(frame_alignment != 0);
4982b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(num_arguments >= 0);
4983ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
4984b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Make stack end at alignment and allocate space for arguments and old rsp.
498543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(kScratchRegister, rsp);
4986b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(IsPowerOf2(frame_alignment));
4987b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int argument_slots_on_stack =
4988b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      ArgumentStackSlotsForCFunctionCall(num_arguments);
4989fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize));
4990895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(rsp, Immediate(-frame_alignment));
499143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister);
4992b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
4993b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4994b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4995b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::CallCFunction(ExternalReference function,
4996b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                   int num_arguments) {
4997ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LoadAddress(rax, function);
4998b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  CallCFunction(rax, num_arguments);
4999b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5000b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5001b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5002b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::CallCFunction(Register function, int num_arguments) {
5003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(has_frame());
5004c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Check stack alignment.
5005badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  if (emit_debug_code()) {
5006c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    CheckStackAlignment();
5007c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
5008c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
5009b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  call(function);
5010b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(OS::ActivationFrameAlignment() != 0);
5011b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(num_arguments >= 0);
5012b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int argument_slots_on_stack =
5013b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      ArgumentStackSlotsForCFunctionCall(num_arguments);
501443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize));
5015b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5016b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5017ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
5018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4) {
5019c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (r1.is(r2)) return true;
5020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (r1.is(r3)) return true;
5021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (r1.is(r4)) return true;
5022c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (r2.is(r3)) return true;
5023c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (r2.is(r4)) return true;
5024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (r3.is(r4)) return true;
5025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return false;
5026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
50294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCodePatcher::CodePatcher(byte* address, int size)
5030c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    : address_(address),
5031c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      size_(size),
5032212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      masm_(NULL, address, size + Assembler::kGap) {
50334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Create a new macro assembler pointing to the address of the code to patch.
50344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // The size is adjusted with kGap on order for the assembler to generate size
50354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // bytes of instructions without failing with buffer size constraints.
50364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
50374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
50384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
50394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
50404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCodePatcher::~CodePatcher() {
50414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Indicate that code has changed.
50424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  CPU::FlushICache(address_, size_);
50434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
50444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Check that the code was patched as expected.
50454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  ASSERT(masm_.pc_ == address_ + size_);
50464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
50474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
50484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5050c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckPageFlag(
5051c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register object,
5052c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register scratch,
5053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int mask,
5054c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Condition cc,
5055c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label* condition_met,
5056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label::Distance condition_met_distance) {
5057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(cc == zero || cc == not_zero);
5058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (scratch.is(object)) {
5059895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    andp(scratch, Immediate(~Page::kPageAlignmentMask));
5060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
506143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    movp(scratch, Immediate(~Page::kPageAlignmentMask));
5062895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    andp(scratch, object);
5063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
5064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (mask < (1 << kBitsPerByte)) {
5065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    testb(Operand(scratch, MemoryChunk::kFlagsOffset),
5066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          Immediate(static_cast<uint8_t>(mask)));
5067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
5068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask));
5069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
5070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(cc, condition_met, condition_met_distance);
5071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5074f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid MacroAssembler::CheckMapDeprecated(Handle<Map> map,
5075f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                                        Register scratch,
5076f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                                        Label* if_deprecated) {
5077f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (map->CanBeDeprecated()) {
5078f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    Move(scratch, map);
50793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    movl(scratch, FieldOperand(scratch, Map::kBitField3Offset));
50803c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    andl(scratch, Immediate(Map::Deprecated::kMask));
5081f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    j(not_zero, if_deprecated);
5082f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
5083f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
5084f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
5085f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
5086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfBlack(Register object,
5087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 Register bitmap_scratch,
5088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 Register mask_scratch,
5089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 Label* on_black,
5090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 Label::Distance on_black_distance) {
5091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!AreAliased(object, bitmap_scratch, mask_scratch, rcx));
5092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  GetMarkBits(object, bitmap_scratch, mask_scratch);
5093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0);
5095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The mask_scratch register contains a 1 at the position of the first bit
5096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // and a 0 at all other positions, including the position of the second bit.
509743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rcx, mask_scratch);
5098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Make rcx into a mask that covers both marking bits using the operation
5099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // rcx = mask | (mask << 1).
5100895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(rcx, Operand(mask_scratch, mask_scratch, times_2, 0));
5101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Note that we are using a 4-byte aligned 8-byte load.
5102895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize));
51037a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(mask_scratch, rcx);
5104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(equal, on_black, on_black_distance);
5105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Detect some, but not all, common pointer-free objects.  This is used by the
5109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// incremental write barrier which doesn't care about oddballs (they are always
5110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// marked black immediately so this code is not hit).
5111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfDataObject(
5112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register value,
5113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register scratch,
5114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label* not_data_object,
5115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label::Distance not_data_object_distance) {
5116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label is_data_object;
511743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch, FieldOperand(value, HeapObject::kMapOffset));
5118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
5119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(equal, &is_data_object, Label::kNear);
5120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
5121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
5122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // If it's a string and it's not a cons string then it's an object containing
5123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // no GC pointers.
5124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  testb(FieldOperand(scratch, Map::kInstanceTypeOffset),
5125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Immediate(kIsIndirectStringMask | kIsNotStringMask));
5126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(not_zero, not_data_object, not_data_object_distance);
5127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&is_data_object);
5128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::GetMarkBits(Register addr_reg,
5132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 Register bitmap_reg,
5133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 Register mask_reg) {
5134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx));
513543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(bitmap_reg, addr_reg);
5136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Sign extended 32 bit immediate.
5137895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask));
513843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rcx, addr_reg);
5139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int shift =
5140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2;
5141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  shrl(rcx, Immediate(shift));
5142895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(rcx,
5143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       Immediate((Page::kPageAlignmentMask >> shift) &
5144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 ~(Bitmap::kBytesPerCell - 1)));
5145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5146fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(bitmap_reg, rcx);
514743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rcx, addr_reg);
5148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  shrl(rcx, Immediate(kPointerSizeLog2));
5149895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
5150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  movl(mask_reg, Immediate(1));
51512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shlp_cl(mask_reg);
5152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::EnsureNotWhite(
5156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register value,
5157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register bitmap_scratch,
5158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register mask_scratch,
5159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label* value_is_white_and_not_data,
5160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label::Distance distance) {
5161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, rcx));
5162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  GetMarkBits(value, bitmap_scratch, mask_scratch);
5163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // If the value is black or grey we don't need to do anything.
5165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0);
5166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0);
5167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0);
5168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
5169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label done;
5171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Since both black and grey have a 1 in the first position and white does
5173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // not have a 1 there we only need to check one bit.
51747a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
5175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(not_zero, &done, Label::kNear);
5176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5177000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (emit_debug_code()) {
5178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check for impossible bit pattern.
5179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label ok;
5180763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Push(mask_scratch);
5181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // shl.  May overflow making the check conservative.
5182fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    addp(mask_scratch, mask_scratch);
51837a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org    testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
5184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    j(zero, &ok, Label::kNear);
5185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int3();
5186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bind(&ok);
5187763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Pop(mask_scratch);
5188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
5189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Value is white.  We check whether it is data that doesn't need scanning.
5191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Currently only checks for HeapNumber and non-cons strings.
5192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register map = rcx;  // Holds map while checking type.
5193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register length = rcx;  // Holds length of object after checking type.
5194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label not_heap_number;
5195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label is_data_object;
5196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check for heap-number
519843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(map, FieldOperand(value, HeapObject::kMapOffset));
5199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  CompareRoot(map, Heap::kHeapNumberMapRootIndex);
5200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(not_equal, &not_heap_number, Label::kNear);
520143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(length, Immediate(HeapNumber::kSize));
5202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  jmp(&is_data_object, Label::kNear);
5203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&not_heap_number);
5205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check for strings.
5206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
5207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
5208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // If it's a string and it's not a cons string then it's an object containing
5209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // no GC pointers.
5210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register instance_type = rcx;
5211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
5212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  testb(instance_type, Immediate(kIsIndirectStringMask | kIsNotStringMask));
5213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(not_zero, value_is_white_and_not_data);
5214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // It's a non-indirect (non-cons and non-slice) string.
5215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // If it's external, the length is just ExternalString::kSize.
5216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Otherwise it's String::kHeaderSize + string->length() * (1 or 2).
5217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label not_external;
5218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // External strings are the only ones with the kExternalStringTag bit
5219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // set.
5220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT_EQ(0, kSeqStringTag & kExternalStringTag);
5221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT_EQ(0, kConsStringTag & kExternalStringTag);
5222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  testb(instance_type, Immediate(kExternalStringTag));
5223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  j(zero, &not_external, Label::kNear);
522443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(length, Immediate(ExternalString::kSize));
5225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  jmp(&is_data_object, Label::kNear);
5226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&not_external);
5228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Sequential string, either ASCII or UC16.
5229e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(kOneByteStringTag == 0x04);
5230895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(length, Immediate(kStringEncodingMask));
5231895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  xorp(length, Immediate(kStringEncodingMask));
5232fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(length, Immediate(0x04));
5233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2.
5234fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  imulp(length, FieldOperand(value, String::kLengthOffset));
52352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
5236fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask));
5237895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(length, Immediate(~kObjectAlignmentMask));
5238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&is_data_object);
5240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Value is a data object, and it is white.  Mark it black.  Since we know
5241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // that the object is white we can make it black by flipping one bit.
5242895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  orp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
5243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5244895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  andp(bitmap_scratch, Immediate(~Page::kPageAlignmentMask));
5245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length);
5246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bind(&done);
5248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
5249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5250be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5251be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
5252355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Label next, start;
5253be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Register empty_fixed_array_value = r8;
5254be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
525543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rcx, rax);
5256be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5257355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Check if the enum length field is properly initialized, indicating that
5258355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // there is an enum cache.
525943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
5260657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
5261355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  EnumLength(rdx, rbx);
5262af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel));
5263de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org  j(equal, call_runtime);
5264de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org
5265355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  jmp(&start);
5266355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
5267355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bind(&next);
5268355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
526943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
5270be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5271be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // For all objects but the receiver, check that the cache is empty.
5272355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  EnumLength(rdx, rbx);
5273355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Cmp(rdx, Smi::FromInt(0));
5274355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  j(not_equal, call_runtime);
5275355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
5276355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bind(&start);
5277355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
5278355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Check that there are no elements. Register rcx contains the current JS
5279355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // object we've reached through the prototype chain.
52806d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Label no_elements;
52817a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(empty_fixed_array_value,
5282355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org       FieldOperand(rcx, JSObject::kElementsOffset));
52836d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  j(equal, &no_elements);
52846d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
52856d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  // Second chance, the object may be using the empty slow element dictionary.
52866d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex);
52877a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset));
5288be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  j(not_equal, call_runtime);
5289be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
52906d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  bind(&no_elements);
529143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset));
52927a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(rcx, null_value);
5293be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  j(not_equal, &next);
5294be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org}
5295be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5296ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MacroAssembler::TestJSArrayForAllocationMemento(
529759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Register receiver_reg,
5298b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Register scratch_reg,
5299b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Label* no_memento_found) {
530059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ExternalReference new_space_start =
530159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      ExternalReference::new_space_start(isolate());
530259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ExternalReference new_space_allocation_top =
530359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      ExternalReference::new_space_allocation_top_address(isolate());
530459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
5305895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  leap(scratch_reg, Operand(receiver_reg,
5306ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
5307e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Move(kScratchRegister, new_space_start);
53087a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(scratch_reg, kScratchRegister);
5309b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  j(less, no_memento_found);
53107a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(scratch_reg, ExternalOperand(new_space_allocation_top));
5311b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  j(greater, no_memento_found);
5312ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize),
5313ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org              Heap::kAllocationMementoMapRootIndex);
531459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
531559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
5316be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5317e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid MacroAssembler::JumpIfDictionaryInPrototypeChain(
5318e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Register object,
5319e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Register scratch0,
5320e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Register scratch1,
5321e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Label* found) {
5322e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  ASSERT(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister)));
5323e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  ASSERT(!scratch1.is(scratch0));
5324e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Register current = scratch0;
5325e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Label loop_again;
5326e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
532743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(current, object);
5328e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
5329e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Loop based on the map going up the prototype chain.
5330e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  bind(&loop_again);
533143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(current, FieldOperand(current, HeapObject::kMapOffset));
533243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(scratch1, FieldOperand(current, Map::kBitField2Offset));
5333d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DecodeField<Map::ElementsKindBits>(scratch1);
53347a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS));
5335e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  j(equal, found);
533643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  movp(current, FieldOperand(current, Map::kPrototypeOffset));
5337e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  CompareRoot(current, Heap::kNullValueRootIndex);
5338e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  j(not_equal, &loop_again);
5339e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}
5340e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
5341e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
5342763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) {
5343bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  ASSERT(!dividend.is(rax));
5344bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  ASSERT(!dividend.is(rdx));
5345bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  MultiplierAndShift ms(divisor);
5346bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  movl(rax, Immediate(ms.multiplier()));
5347bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  imull(dividend);
5348bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  if (divisor > 0 && ms.multiplier() < 0) addl(rdx, dividend);
5349bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  if (divisor < 0 && ms.multiplier() > 0) subl(rdx, dividend);
5350bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift()));
5351763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  movl(rax, dividend);
5352763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  shrl(rax, Immediate(31));
5353763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  addl(rdx, rax);
5354bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
5355bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
5356bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
535771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} }  // namespace v8::internal
53589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
53599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_X64
5360