19a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Copyright (c) 1994-2006 Sun Microsystems Inc.
29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// All Rights Reserved.
39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// modification, are permitted provided that the following conditions
69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// are met:
79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// - Redistributions of source code must retain the above copyright notice,
99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// this list of conditions and the following disclaimer.
109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// - Redistribution in binary form must reproduce the above copyright
129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// notice, this list of conditions and the following disclaimer in the
139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// documentation and/or other materials provided with the
149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// distribution.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// - Neither the name of Sun Microsystems or the names of contributors may
179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// be used to endorse or promote products derived from this software without
189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// specific prior written permission.
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OF THE POSSIBILITY OF SUCH DAMAGE.
329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// The original source code covered by the above license above has been modified
349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// significantly by Google Inc.
35f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
375ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#ifndef V8_ARM_ASSEMBLER_ARM_INL_H_
385ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#define V8_ARM_ASSEMBLER_ARM_INL_H_
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm/assembler-arm.h"
41659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
425de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/assembler.h"
43196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.orgbool CpuFeatures::SupportsCrankshaft() { return IsSupported(VFP3); }
51874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
52874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
53a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgint Register::NumAllocatableRegisters() {
54e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return kMaxNumAllocatableRegisters;
55a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
56a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
57a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
58a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgint DwVfpRegister::NumRegisters() {
59e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return CpuFeatures::IsSupported(VFP32DREGS) ? 32 : 16;
60a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
61a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
62a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
63af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgint DwVfpRegister::NumReservedRegisters() {
64af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  return kNumReservedRegisters;
65af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org}
66af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
67af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
68a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgint DwVfpRegister::NumAllocatableRegisters() {
69e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return NumRegisters() - kNumReservedRegisters;
70a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
71a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
72a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
73f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comint DwVfpRegister::ToAllocationIndex(DwVfpRegister reg) {
74e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!reg.is(kDoubleRegZero));
75e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!reg.is(kScratchDoubleReg));
76003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (reg.code() > kDoubleRegZero.code()) {
77003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    return reg.code() - kNumReservedRegisters;
78003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
79f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  return reg.code();
80f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
81f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
82f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
83003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgDwVfpRegister DwVfpRegister::FromAllocationIndex(int index) {
84e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= 0 && index < NumAllocatableRegisters());
85e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
86003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org         kNumReservedRegisters - 1);
87003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (index >= kDoubleRegZero.code()) {
88003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    return from_code(index + kNumReservedRegisters);
89003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
90003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  return from_code(index);
91003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
92003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
93003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
946a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
95236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  if (RelocInfo::IsInternalReference(rmode_)) {
96236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // absolute code pointer inside code object moves with the code object.
97236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    int32_t* p = reinterpret_cast<int32_t*>(pc_);
98236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    *p += delta;  // relocate entry
99236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
100236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // We do not use pc relative addressing on ARM, so there is
101236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // nothing else to do.
10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenAddress RelocInfo::target_address() {
106e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
10797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  return Assembler::target_address_at(pc_, host_);
10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1113291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgAddress RelocInfo::target_address_address() {
112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
11304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                              || rmode_ == EMBEDDED_OBJECT
11404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                              || rmode_ == EXTERNAL_REFERENCE);
115763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (FLAG_enable_ool_constant_pool ||
116763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      Assembler::IsMovW(Memory::int32_at(pc_))) {
117763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // We return the PC for ool constant pool since this function is used by the
118763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // serializerer and expects the address to reside within the code object.
119763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    return reinterpret_cast<Address>(pc_);
120763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
121e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_)));
122975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    return constant_pool_entry_address();
123763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
1243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org}
1253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
1263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
127bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgAddress RelocInfo::constant_pool_entry_address() {
128e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsInConstantPool());
129975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  return Assembler::constant_pool_entry_address(pc_, host_->constant_pool());
130bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
131bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
132bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
1339155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgint RelocInfo::target_address_size() {
13488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  return kPointerSize;
1359155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
1369155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
1379155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
1386a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_target_address(Address target,
1396a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                   WriteBarrierMode write_barrier_mode,
1406a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                   ICacheFlushMode icache_flush_mode) {
141e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
1426a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
1436a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
1446a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      host() != NULL && IsCodeTarget(rmode_)) {
145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* target_code = Code::GetCodeFromTargetAddress(target);
146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        host(), this, HeapObject::cast(target_code));
148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
14943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* RelocInfo::target_object() {
153e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
15497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
155c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
156c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
157c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
158c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgHandle<Object> RelocInfo::target_object_handle(Assembler* origin) {
159e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
16089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  return Handle<Object>(reinterpret_cast<Object**>(
16197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      Assembler::target_address_at(pc_, host_)));
16243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
16343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1656a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_target_object(Object* target,
1666a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                  WriteBarrierMode write_barrier_mode,
1676a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                  ICacheFlushMode icache_flush_mode) {
168e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
16997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  Assembler::set_target_address_at(pc_, host_,
1706a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                   reinterpret_cast<Address>(target),
1716a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                   icache_flush_mode);
1726a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
173394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      host() != NULL &&
174394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      target->IsHeapObject()) {
175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    host()->GetHeap()->incremental_marking()->RecordWrite(
176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        host(), &Memory::Object_at(pc_), HeapObject::cast(target));
177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
181057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgAddress RelocInfo::target_reference() {
182e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rmode_ == EXTERNAL_REFERENCE);
18397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  return Assembler::target_address_at(pc_, host_);
18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1876e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgAddress RelocInfo::target_runtime_entry(Assembler* origin) {
188e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsRuntimeEntry(rmode_));
1896e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  return target_address();
1906e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
1916e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
1926e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
1936e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid RelocInfo::set_target_runtime_entry(Address target,
1946a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                         WriteBarrierMode write_barrier_mode,
1956a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                         ICacheFlushMode icache_flush_mode) {
196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsRuntimeEntry(rmode_));
1976a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (target_address() != target)
1986a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    set_target_address(target, write_barrier_mode, icache_flush_mode);
1996e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
2006e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
2016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
20241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgHandle<Cell> RelocInfo::target_cell_handle() {
203e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rmode_ == RelocInfo::CELL);
204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Address address = Memory::Address_at(pc_);
20541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return Handle<Cell>(reinterpret_cast<Cell**>(address));
206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
20941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgCell* RelocInfo::target_cell() {
210e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rmode_ == RelocInfo::CELL);
21141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return Cell::FromValueAddress(Memory::Address_at(pc_));
212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2156a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_target_cell(Cell* cell,
2166a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                WriteBarrierMode write_barrier_mode,
2176a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                ICacheFlushMode icache_flush_mode) {
218e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rmode_ == RelocInfo::CELL);
21941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Address address = cell->address() + Cell::kValueOffset;
220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Memory::Address_at(pc_) = address;
2216a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // TODO(1550) We are passing NULL as a slot because cell can never be on
223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // evacuation candidate.
224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    host()->GetHeap()->incremental_marking()->RecordWrite(
225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        host(), NULL, cell);
226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2305924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgstatic const int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize;
231e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
232c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
233c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
234c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  UNREACHABLE();  // This should never be reached on Arm.
235c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  return Handle<Object>();
236c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org}
237c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
238c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
239e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgCode* RelocInfo::code_age_stub() {
240e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
241e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return Code::GetCodeFromTargetAddress(
2425924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org      Memory::Address_at(pc_ +
2435924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org                         (kNoCodeAgeSequenceLength - Assembler::kInstrSize)));
244e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
245e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
246e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
2476a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_code_age_stub(Code* stub,
2486a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                  ICacheFlushMode icache_flush_mode) {
249e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
2505924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  Memory::Address_at(pc_ +
2515924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org                     (kNoCodeAgeSequenceLength - Assembler::kInstrSize)) =
252e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      stub->instruction_start();
253e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
254e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
255e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenAddress RelocInfo::call_address() {
2572356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // The 2 instructions offset assumes patched debug break slot or return
2582356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // sequence.
259e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
2602356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
2614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize);
26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid RelocInfo::set_call_address(Address target) {
266e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
267c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
2684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target;
269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (host() != NULL) {
270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* target_code = Code::GetCodeFromTargetAddress(target);
271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        host(), this, HeapObject::cast(target_code));
273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* RelocInfo::call_object() {
2784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  return *call_object_address();
27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
282c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgvoid RelocInfo::set_call_object(Object* target) {
283c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  *call_object_address() = target;
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
287c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgObject** RelocInfo::call_object_address() {
288e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
289c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
290c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize);
29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
294057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid RelocInfo::WipeOut() {
295e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsEmbeddedObject(rmode_) ||
296057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org         IsCodeTarget(rmode_) ||
297057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org         IsRuntimeEntry(rmode_) ||
298057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org         IsExternalReference(rmode_));
29997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  Assembler::set_target_address_at(pc_, host_, NULL);
300057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
301057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
302057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
3039d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.combool RelocInfo::IsPatchedReturnSequence() {
304cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  Instr current_instr = Assembler::instr_at(pc_);
305cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize);
306cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  // A patched return sequence is:
307cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  //  ldr ip, [pc, #0]
308cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  //  blx ip
309975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  return Assembler::IsLdrPcImmediateOffset(current_instr) &&
310975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org         Assembler::IsBlxReg(next_instr);
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3142356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgbool RelocInfo::IsPatchedDebugBreakSlotSequence() {
3152356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  Instr current_instr = Assembler::instr_at(pc_);
316beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP);
3172356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org}
3182356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
3192356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
320e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.orgvoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
3219155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  RelocInfo::Mode mode = rmode();
3229155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  if (mode == RelocInfo::EMBEDDED_OBJECT) {
323b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    visitor->VisitEmbeddedPointer(this);
3249155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  } else if (RelocInfo::IsCodeTarget(mode)) {
3259155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    visitor->VisitCodeTarget(this);
32641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else if (mode == RelocInfo::CELL) {
32741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    visitor->VisitCell(this);
3289155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
32904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    visitor->VisitExternalReference(this);
330e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
331e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    visitor->VisitCodeAgeSequence(this);
332ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else if (((RelocInfo::IsJSReturn(mode) &&
3332356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org              IsPatchedReturnSequence()) ||
3342356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org             (RelocInfo::IsDebugBreakSlot(mode) &&
335ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org              IsPatchedDebugBreakSlotSequence())) &&
336e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org             isolate->debug()->has_break_points()) {
3379155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    visitor->VisitDebugTarget(this);
3382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  } else if (RelocInfo::IsRuntimeEntry(mode)) {
3399155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    visitor->VisitRuntimeEntry(this);
3409155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
3419155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
3429155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
3439155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
344ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgtemplate<typename StaticVisitor>
345ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid RelocInfo::Visit(Heap* heap) {
346ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  RelocInfo::Mode mode = rmode();
347ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  if (mode == RelocInfo::EMBEDDED_OBJECT) {
348b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    StaticVisitor::VisitEmbeddedPointer(heap, this);
349ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  } else if (RelocInfo::IsCodeTarget(mode)) {
350c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    StaticVisitor::VisitCodeTarget(heap, this);
35141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else if (mode == RelocInfo::CELL) {
35241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    StaticVisitor::VisitCell(heap, this);
353ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
35404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    StaticVisitor::VisitExternalReference(this);
355e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
356e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    StaticVisitor::VisitCodeAgeSequence(heap, this);
357ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else if (heap->isolate()->debug()->has_break_points() &&
358ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org             ((RelocInfo::IsJSReturn(mode) &&
359ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org              IsPatchedReturnSequence()) ||
360ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org             (RelocInfo::IsDebugBreakSlot(mode) &&
361ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org              IsPatchedDebugBreakSlotSequence()))) {
362c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    StaticVisitor::VisitDebugTarget(heap, this);
3632bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  } else if (RelocInfo::IsRuntimeEntry(mode)) {
364ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    StaticVisitor::VisitRuntimeEntry(this);
365ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  }
366ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org}
367ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
368ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
369236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.orgOperand::Operand(int32_t immediate, RelocInfo::Mode rmode)  {
37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = no_reg;
37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  imm32_ = immediate;
37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rmode_ = rmode;
37343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
37443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(const ExternalReference& f)  {
37743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = no_reg;
37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  imm32_ = reinterpret_cast<int32_t>(f.address());
379236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
38043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Smi* value) {
38443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = no_reg;
38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  imm32_ =  reinterpret_cast<intptr_t>(value);
38659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  rmode_ = RelocInfo::NONE32;
38743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
38843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Register rm) {
39143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rs_ = no_reg;
39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = LSL;
39443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_imm_ = 0;
39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
39643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.agerbool Operand::is_reg() const {
39931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  return rm_.is_valid() &&
40031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager         rs_.is(no_reg) &&
40131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager         shift_op_ == LSL &&
40231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager         shift_imm_ == 0;
40331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager}
40431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
40531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::CheckBuffer() {
40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (buffer_space() <= kGap) {
40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    GrowBuffer();
40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
41018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  if (pc_offset() >= next_buffer_check_) {
41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CheckConstPool(false, true);
41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::emit(Instr x) {
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CheckBuffer();
41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  *reinterpret_cast<Instr*>(pc_) = x;
41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  pc_ += kInstrSize;
42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgAddress Assembler::target_address_from_return_address(Address pc) {
42489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Returns the address of the call target from the return address that will
42589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // be returned to after a call.
426a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Call sequence on V7 or later is:
42789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  //  movw  ip, #... @ call address low 16
42889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  //  movt  ip, #... @ call address high 16
42989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  //  blx   ip
43089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  //                      @ return address
431a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // For V6 when the constant pool is unavailable, it is:
432a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  mov  ip, #...     @ call address low 8
433a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  orr  ip, ip, #... @ call address 2nd 8
434a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  orr  ip, ip, #... @ call address 3rd 8
435a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  orr  ip, ip, #... @ call address high 8
436a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  blx   ip
437a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //                      @ return address
438a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // In cases that need frequent patching, the address is in the
439d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // constant pool.  It could be a small constant pool load:
440d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  //  ldr   ip, [pc / pp, #...] @ call address
441d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  //  blx   ip
442d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  //                      @ return address
443a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Or an extended constant pool load (ARMv7):
444d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  //  movw  ip, #...
445d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  //  movt  ip, #...
446d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  //  ldr   ip, [pc, ip]  @ call address
44789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  //  blx   ip
44889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  //                      @ return address
449a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Or an extended constant pool load (ARMv6):
450a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  mov  ip, #...
451a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  orr  ip, ip, #...
452a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  orr  ip, ip, #...
453a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  orr  ip, ip, #...
454a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  ldr   ip, [pc, ip]  @ call address
455a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //  blx   ip
456a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  //                      @ return address
45789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  Address candidate = pc - 2 * Assembler::kInstrSize;
45889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  Instr candidate_instr(Memory::int32_at(candidate));
459763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (IsLdrPcImmediateOffset(candidate_instr) |
460763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      IsLdrPpImmediateOffset(candidate_instr)) {
46189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    return candidate;
462d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  } else {
463a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    if (IsLdrPpRegOffset(candidate_instr)) {
464a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      candidate -= Assembler::kInstrSize;
465a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
466a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    if (CpuFeatures::IsSupported(ARMv7)) {
467a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      candidate -= 1 * Assembler::kInstrSize;
468a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsMovW(Memory::int32_at(candidate)) &&
469a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org             IsMovT(Memory::int32_at(candidate + Assembler::kInstrSize)));
470a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    } else {
471a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      candidate -= 3 * Assembler::kInstrSize;
472a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(
473a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          IsMovImmed(Memory::int32_at(candidate)) &&
474a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          IsOrrImmed(Memory::int32_at(candidate + Assembler::kInstrSize)) &&
475a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          IsOrrImmed(Memory::int32_at(candidate + 2 * Assembler::kInstrSize)) &&
476a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          IsOrrImmed(Memory::int32_at(candidate + 3 * Assembler::kInstrSize)));
477a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
478d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return candidate;
47989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
48089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
48189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
48289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
4839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgAddress Assembler::break_address_from_return_address(Address pc) {
4849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  return pc - Assembler::kPatchDebugBreakSlotReturnOffset;
4859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
4869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
4879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
48889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgAddress Assembler::return_address_from_call_start(Address pc) {
489763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) |
490763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      IsLdrPpImmediateOffset(Memory::int32_at(pc))) {
491d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    // Load from constant pool, small section.
49289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    return pc + kInstrSize * 2;
49389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  } else {
494a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    if (CpuFeatures::IsSupported(ARMv7)) {
495a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsMovW(Memory::int32_at(pc)));
496a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)));
497a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))) {
498a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        // Load from constant pool, extended section.
499a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        return pc + kInstrSize * 4;
500a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      } else {
501a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        // A movw / movt load immediate.
502a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        return pc + kInstrSize * 3;
503a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      }
504d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else {
505a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsMovImmed(Memory::int32_at(pc)));
506a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize)));
507a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)));
508a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
509a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize))) {
510a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        // Load from constant pool, extended section.
511a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        return pc + kInstrSize * 6;
512a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      } else {
513a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        // A mov / orr load immediate.
514a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        return pc + kInstrSize * 5;
515a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      }
516d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
51789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
51843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.orgvoid Assembler::deserialization_set_special_target_at(
52297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    Address constant_pool_entry, Code* code, Address target) {
523763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
524763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    set_target_address_at(constant_pool_entry, code, target);
525763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
526763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Memory::Address_at(constant_pool_entry) = target;
527763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
52888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org}
52988aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org
53088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org
531d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgbool Assembler::is_constant_pool_load(Address pc) {
532a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (CpuFeatures::IsSupported(ARMv7)) {
533a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    return !Assembler::IsMovW(Memory::int32_at(pc)) ||
534a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           (FLAG_enable_ool_constant_pool &&
535a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Assembler::IsLdrPpRegOffset(
536a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Memory::int32_at(pc + 2 * Assembler::kInstrSize)));
537a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  } else {
538a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    return !Assembler::IsMovImmed(Memory::int32_at(pc)) ||
539a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           (FLAG_enable_ool_constant_pool &&
540a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Assembler::IsLdrPpRegOffset(
541a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Memory::int32_at(pc + 4 * Assembler::kInstrSize)));
542a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
543975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org}
544975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
545975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
546975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgAddress Assembler::constant_pool_entry_address(
547975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Address pc, ConstantPoolArray* constant_pool) {
548975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
549e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(constant_pool != NULL);
550d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    int cp_offset;
551a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    if (!CpuFeatures::IsSupported(ARMv7) && IsMovImmed(Memory::int32_at(pc))) {
552a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
553a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org             IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
554a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org             IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)) &&
555a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org             IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize)));
556a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      // This is an extended constant pool lookup (ARMv6).
557a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Instr mov_instr = instr_at(pc);
558a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Instr orr_instr_1 = instr_at(pc + kInstrSize);
559a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize);
560a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize);
561a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      cp_offset = DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) |
562a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                  DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3);
563a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    } else if (IsMovW(Memory::int32_at(pc))) {
564e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)) &&
565d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org             IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize)));
566a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      // This is an extended constant pool lookup (ARMv7).
567d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      Instruction* movw_instr = Instruction::At(pc);
568d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      Instruction* movt_instr = Instruction::At(pc + kInstrSize);
569d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      cp_offset = (movt_instr->ImmedMovwMovtValue() << 16) |
570d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                  movw_instr->ImmedMovwMovtValue();
571d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else {
572d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // This is a small constant pool lookup.
573e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc)));
574d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc));
575d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
576d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return reinterpret_cast<Address>(constant_pool) + cp_offset;
577975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  } else {
578e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc)));
579975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Instr instr = Memory::int32_at(pc);
580975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta;
581975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  }
582975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org}
583975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
584975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
585975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgAddress Assembler::target_address_at(Address pc,
586975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org                                     ConstantPoolArray* constant_pool) {
587d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (is_constant_pool_load(pc)) {
588975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // This is a constant pool lookup. Return the value in the constant pool.
589975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    return Memory::Address_at(constant_pool_entry_address(pc, constant_pool));
590a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  } else if (CpuFeatures::IsSupported(ARMv7)) {
591a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    // This is an movw / movt immediate load. Return the immediate.
592e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsMovW(Memory::int32_at(pc)) &&
593975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org           IsMovT(Memory::int32_at(pc + kInstrSize)));
594975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Instruction* movw_instr = Instruction::At(pc);
595975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Instruction* movt_instr = Instruction::At(pc + kInstrSize);
596975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    return reinterpret_cast<Address>(
597975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org        (movt_instr->ImmedMovwMovtValue() << 16) |
598975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org         movw_instr->ImmedMovwMovtValue());
599a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  } else {
600a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    // This is an mov / orr immediate load. Return the immediate.
601a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
602a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
603a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
604a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
605a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Instr mov_instr = instr_at(pc);
606a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Instr orr_instr_1 = instr_at(pc + kInstrSize);
607a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize);
608a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize);
609a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Address ret = reinterpret_cast<Address>(
610a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) |
611a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3));
612a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    return ret;
613975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  }
614975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org}
615975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
616975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
61797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgvoid Assembler::set_target_address_at(Address pc,
61897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                      ConstantPoolArray* constant_pool,
6196a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                      Address target,
6206a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                      ICacheFlushMode icache_flush_mode) {
621d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (is_constant_pool_load(pc)) {
622975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // This is a constant pool lookup. Update the entry in the constant pool.
623975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target;
624975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // Intuitively, we would think it is necessary to always flush the
625975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // instruction cache after patching a target address in the code as follows:
6265de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    //   CpuFeatures::FlushICache(pc, sizeof(target));
627975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // However, on ARM, no instruction is actually patched in the case
628975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // of embedded constants of the form:
629975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // ldr   ip, [pp, #...]
630975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // since the instruction accessing this address in the constant pool remains
631975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // unchanged.
632a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  } else if (CpuFeatures::IsSupported(ARMv7)) {
633a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    // This is an movw / movt immediate load. Patch the immediate embedded in
634a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    // the instructions.
635e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsMovW(Memory::int32_at(pc)));
636e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)));
63789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
63889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    uint32_t immediate = reinterpret_cast<uint32_t>(target);
6396a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    instr_ptr[0] = PatchMovwImmediate(instr_ptr[0], immediate & 0xFFFF);
6406a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    instr_ptr[1] = PatchMovwImmediate(instr_ptr[1], immediate >> 16);
641e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsMovW(Memory::int32_at(pc)));
642e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)));
6436a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
6445de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org      CpuFeatures::FlushICache(pc, 2 * kInstrSize);
6456a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    }
646a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  } else {
647a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    // This is an mov / orr immediate load. Patch the immediate embedded in
648a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    // the instructions.
649a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
650a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
651a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
652a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
653a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
654a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    uint32_t immediate = reinterpret_cast<uint32_t>(target);
655a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    instr_ptr[0] = PatchShiftImm(instr_ptr[0], immediate & kImm8Mask);
656a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    instr_ptr[1] = PatchShiftImm(instr_ptr[1], immediate & (kImm8Mask << 8));
657a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    instr_ptr[2] = PatchShiftImm(instr_ptr[2], immediate & (kImm8Mask << 16));
658a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    instr_ptr[3] = PatchShiftImm(instr_ptr[3], immediate & (kImm8Mask << 24));
659a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
660a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
661a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
662a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
663a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
664a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      CpuFeatures::FlushICache(pc, 4 * kInstrSize);
665a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
66689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
66789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
66889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
66989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6725ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_ARM_ASSEMBLER_ARM_INL_H_
673