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.
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
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.
159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
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
33b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// The original source code covered by the above license above has been
34b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// modified significantly by Google Inc.
35f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A light-weight ARM Assembler
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Generates user mode instructions for the ARM architecture up to version 5
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
405ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#ifndef V8_ARM_ASSEMBLER_ARM_H_
415ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#define V8_ARM_ASSEMBLER_ARM_H_
4218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include <stdio.h>
4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "assembler.h"
44378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org#include "constants-arm.h"
45c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#include "serialize.h"
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org// CpuFeatures keeps track of which features are supported by the target CPU.
51750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// Supported features must be enabled by a CpuFeatureScope before use.
52003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgclass CpuFeatures : public AllStatic {
53003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org public:
54003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Detect features of the target CPU. Set safe defaults if the serializer
55003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // is enabled (snapshots must be portable).
56003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  static void Probe();
57003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
58e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Display target use when compiling.
59e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static void PrintTarget();
60e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
61e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Display features.
62e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static void PrintFeatures();
63e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
64003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Check whether a feature is supported by the target CPU.
65003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  static bool IsSupported(CpuFeature f) {
66003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    ASSERT(initialized_);
6763ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    return Check(f, supported_);
68003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
69003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
70750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
71003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    ASSERT(initialized_);
7263ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    return Check(f, found_by_runtime_probing_only_);
73003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
74003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
75750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  static bool IsSafeForSnapshot(CpuFeature f) {
7663ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    return Check(f, cross_compile_) ||
7763ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org           (IsSupported(f) &&
78750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org            (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
79750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
80003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
81169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static unsigned cache_line_size() { return cache_line_size_; }
82169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
8363ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  static bool VerifyCrossCompiling() {
8463ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    return cross_compile_ == 0;
8563ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  }
8663ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org
8763ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  static bool VerifyCrossCompiling(CpuFeature f) {
8863ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    unsigned mask = flag2set(f);
8963ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    return cross_compile_ == 0 ||
9063ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org           (cross_compile_ & mask) == mask;
9163ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  }
9263ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org
93003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org private:
9463ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  static bool Check(CpuFeature f, unsigned set) {
9563ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    return (set & flag2set(f)) != 0;
9663ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  }
9763ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org
9863ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  static unsigned flag2set(CpuFeature f) {
9963ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org    return 1u << f;
10063ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  }
10163ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org
102003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#ifdef DEBUG
103003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  static bool initialized_;
104003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#endif
105003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  static unsigned supported_;
106750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  static unsigned found_by_runtime_probing_only_;
107169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static unsigned cache_line_size_;
108003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
10963ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  static unsigned cross_compile_;
11063ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org
111003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  friend class ExternalReference;
112528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  friend class PlatformFeatureScope;
113003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
114003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org};
115003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
116003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CPU Registers.
11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1) We would prefer to use an enum, but enum values are assignment-
12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// compatible with int, which has caused code-generation bugs.
12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2) We would prefer to use a class instead of a struct but we don't like
12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the register initialization to depend on the particular initialization
12443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// order (which appears to be different on OS X, Linux, and Windows for the
12543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// installed versions of C++ we tried). Using a struct permits C-style
12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "initialization". Also, the Register objects cannot be const as this
12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// forces initialization stubs in MSVC, making us dependent on initialization
12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// order.
12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 3) By not using an enum, we are possibly preventing the compiler from
13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// doing certain constant folds, which may significantly reduce the
13243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// code generated for some assembly instructions (because they boil down
13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to a few constants). If this is a problem, we could change the code
13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// such that we use an enum in optimized mode, and the struct in debug
13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// mode. This way we get the compile-time error checking in debug mode
13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and best performance in optimized code.
1375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
138c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org// These constants are used in several locations, including static initializers
139c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_no_reg_Code = -1;
140c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r0_Code = 0;
141c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r1_Code = 1;
142c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r2_Code = 2;
143c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r3_Code = 3;
144c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r4_Code = 4;
145c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r5_Code = 5;
146c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r6_Code = 6;
147c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r7_Code = 7;
148c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r8_Code = 8;
149c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r9_Code = 9;
150c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r10_Code = 10;
151c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_fp_Code = 11;
152c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_ip_Code = 12;
153c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_sp_Code = 13;
154c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_lr_Code = 14;
155c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_pc_Code = 15;
156c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
15743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Core register
15843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstruct Register {
159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kNumRegisters = 16;
1603d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  static const int kMaxNumAllocatableRegisters =
161c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      FLAG_enable_ool_constant_pool ? 8 : 9;
1623847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  static const int kSizeInBytes = 4;
163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
164a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  inline static int NumAllocatableRegisters();
165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static int ToAllocationIndex(Register reg) {
167a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(reg.code() < kMaxNumAllocatableRegisters);
168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return reg.code();
169a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static Register FromAllocationIndex(int index) {
172a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return from_code(index);
174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const char* AllocationIndexToString(int index) {
177a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    const char* const names[] = {
179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r0",
180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r1",
181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r2",
182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r3",
183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r4",
184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r5",
185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r6",
186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r7",
187c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      "r8",
188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    };
189c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    if (FLAG_enable_ool_constant_pool && (index >= 7)) {
190c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      return names[index + 1];
191c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    }
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return names[index];
193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static Register from_code(int code) {
196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Register r = { code };
197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return r;
198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
2014a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(Register reg) const { return code_ == reg.code_; }
2024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(is_valid());
20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return code_;
20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
2064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(is_valid());
20843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return 1 << code_;
20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  void set_code(int code) {
2129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    code_ = code;
2139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    ASSERT(is_valid());
2149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
2159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
2165c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unfortunately we can't make this private in a struct.
21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int code_;
21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2201456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register no_reg = { kRegister_no_reg_Code };
2211456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
2221456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r0  = { kRegister_r0_Code };
2231456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r1  = { kRegister_r1_Code };
2241456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r2  = { kRegister_r2_Code };
2251456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r3  = { kRegister_r3_Code };
2261456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r4  = { kRegister_r4_Code };
2271456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r5  = { kRegister_r5_Code };
2281456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r6  = { kRegister_r6_Code };
229c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org// Used as constant pool pointer register if FLAG_enable_ool_constant_pool.
2301456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r7  = { kRegister_r7_Code };
2311456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Used as context register.
2321456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r8  = { kRegister_r8_Code };
2331456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Used as lithium codegen scratch register.
2341456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r9  = { kRegister_r9_Code };
2351456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Used as roots register.
2361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r10 = { kRegister_r10_Code };
2371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register fp  = { kRegister_fp_Code };
2381456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register ip  = { kRegister_ip_Code };
2391456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register sp  = { kRegister_sp_Code };
2401456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register lr  = { kRegister_lr_Code };
2411456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register pc  = { kRegister_pc_Code };
2421456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
24313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org// Single word VFP register.
24413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgstruct SwVfpRegister {
245e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const int kSizeInBytes = 4;
2464a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is_valid() const { return 0 <= code_ && code_ < 32; }
2474a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
2484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
24913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    ASSERT(is_valid());
25013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return code_;
25113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
2524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
25313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    ASSERT(is_valid());
25413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return 1 << code_;
25513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
2564a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void split_code(int* vm, int* m) const {
257d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    ASSERT(is_valid());
258d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *m = code_ & 0x1;
259d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *vm = code_ >> 1;
260d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
26113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
26213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  int code_;
26313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org};
26413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
26513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
26613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org// Double word VFP register.
26713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgstruct DwVfpRegister {
26894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  static const int kMaxNumRegisters = 32;
2693cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // A few double registers are reserved: one as a scratch register and one to
2703cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // hold 0.0, that does not fit in the immediate field of vmov instructions.
2713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  //  d14: 0.0
2723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  //  d15: scratch register.
2733cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  static const int kNumReservedRegisters = 2;
27494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  static const int kMaxNumAllocatableRegisters = kMaxNumRegisters -
2753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org      kNumReservedRegisters;
276e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const int kSizeInBytes = 8;
277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
278003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Note: the number of registers can be different at snapshot and run-time.
279003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Any code included in the snapshot must be able to run both with 16 or 32
280003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // registers.
281a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  inline static int NumRegisters();
282af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  inline static int NumReservedRegisters();
283a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  inline static int NumAllocatableRegisters();
284003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
285f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  inline static int ToAllocationIndex(DwVfpRegister reg);
286a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const char* AllocationIndexToString(int index);
287003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  inline static DwVfpRegister FromAllocationIndex(int index);
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static DwVfpRegister from_code(int code) {
290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DwVfpRegister r = { code };
291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return r;
292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
294003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  bool is_valid() const {
29594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    return 0 <= code_ && code_ < kMaxNumRegisters;
296003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
2974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
2984a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
29913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    ASSERT(is_valid());
30013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return code_;
30113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
3024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
30313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    ASSERT(is_valid());
30413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return 1 << code_;
30513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
3064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void split_code(int* vm, int* m) const {
307d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    ASSERT(is_valid());
308d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *m = (code_ & 0x10) >> 4;
309d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *vm = code_ & 0x0F;
310d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
31113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
31213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  int code_;
31313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org};
31413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
31513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtypedef DwVfpRegister DoubleRegister;
317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
319fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// Double word VFP register d0-15.
320fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgstruct LowDwVfpRegister {
321fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org public:
322fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  static const int kMaxNumLowRegisters = 16;
323fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  operator DwVfpRegister() const {
324fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    DwVfpRegister r = { code_ };
325fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return r;
326fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
327fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  static LowDwVfpRegister from_code(int code) {
328fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    LowDwVfpRegister r = { code };
329fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return r;
330fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
331fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
332fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool is_valid() const {
333fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return 0 <= code_ && code_ < kMaxNumLowRegisters;
334fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
335fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
336fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; }
337fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int code() const {
338fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ASSERT(is_valid());
339fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return code_;
340fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
341fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  SwVfpRegister low() const {
342fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    SwVfpRegister reg;
343fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    reg.code_ = code_ * 2;
344fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
345fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ASSERT(reg.is_valid());
346fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return reg;
347fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
348fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  SwVfpRegister high() const {
349fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    SwVfpRegister reg;
350fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    reg.code_ = (code_ * 2) + 1;
351fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
352fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ASSERT(reg.is_valid());
353fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return reg;
354fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
355fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
356fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int code_;
357fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org};
358fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
359fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
360169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Quad word NEON register.
361169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgstruct QwNeonRegister {
362169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static const int kMaxNumRegisters = 16;
363169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
364169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static QwNeonRegister from_code(int code) {
365169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    QwNeonRegister r = { code };
366169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return r;
367169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
368169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
369169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  bool is_valid() const {
370169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return (0 <= code_) && (code_ < kMaxNumRegisters);
371169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
372169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  bool is(QwNeonRegister reg) const { return code_ == reg.code_; }
373169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int code() const {
374169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    ASSERT(is_valid());
375169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return code_;
376169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
377169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void split_code(int* vm, int* m) const {
378169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    ASSERT(is_valid());
379169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    *m = (code_ & 0x10) >> 4;
380169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    *vm = code_ & 0x0F;
381169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
382169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
383169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int code_;
384169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
385169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
386169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
387169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgtypedef QwNeonRegister QuadRegister;
388169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
389169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
390ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Support for the VFP registers s0 to s31 (d0 to d15).
39113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org// Note that "s(N):s(N+1)" is the same as "d(N/2)".
392ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s0  = {  0 };
393ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s1  = {  1 };
394ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s2  = {  2 };
395ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s3  = {  3 };
396ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s4  = {  4 };
397ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s5  = {  5 };
398ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s6  = {  6 };
399ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s7  = {  7 };
400ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s8  = {  8 };
401ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s9  = {  9 };
402ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s10 = { 10 };
403ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s11 = { 11 };
404ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s12 = { 12 };
405ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s13 = { 13 };
406ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s14 = { 14 };
407ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s15 = { 15 };
408ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s16 = { 16 };
409ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s17 = { 17 };
410ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s18 = { 18 };
411ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s19 = { 19 };
412ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s20 = { 20 };
413ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s21 = { 21 };
414ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s22 = { 22 };
415ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s23 = { 23 };
416ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s24 = { 24 };
417ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s25 = { 25 };
418ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s26 = { 26 };
419ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s27 = { 27 };
420ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s28 = { 28 };
421ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s29 = { 29 };
422ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s30 = { 30 };
423ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s31 = { 31 };
424ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
4259ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgconst DwVfpRegister no_dreg = { -1 };
426fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d0 = { 0 };
427fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d1 = { 1 };
428fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d2 = { 2 };
429fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d3 = { 3 };
430fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d4 = { 4 };
431fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d5 = { 5 };
432fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d6 = { 6 };
433fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d7 = { 7 };
434fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d8 = { 8 };
435fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d9 = { 9 };
436fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d10 = { 10 };
437fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d11 = { 11 };
438fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d12 = { 12 };
439fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d13 = { 13 };
440fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d14 = { 14 };
441fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d15 = { 15 };
442003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d16 = { 16 };
443003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d17 = { 17 };
444003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d18 = { 18 };
445003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d19 = { 19 };
446003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d20 = { 20 };
447003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d21 = { 21 };
448003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d22 = { 22 };
449003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d23 = { 23 };
450003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d24 = { 24 };
451003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d25 = { 25 };
452003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d26 = { 26 };
453003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d27 = { 27 };
454003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d28 = { 28 };
455003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d29 = { 29 };
456003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d30 = { 30 };
457003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d31 = { 31 };
45813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
459169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q0  = {  0 };
460169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q1  = {  1 };
461169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q2  = {  2 };
462169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q3  = {  3 };
463169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q4  = {  4 };
464169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q5  = {  5 };
465169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q6  = {  6 };
466169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q7  = {  7 };
467169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q8  = {  8 };
468169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q9  = {  9 };
469169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q10 = { 10 };
470169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q11 = { 11 };
471169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q12 = { 12 };
472169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q13 = { 13 };
473169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q14 = { 14 };
474169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q15 = { 15 };
475169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
476fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
477659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// Aliases for double registers.  Defined using #define instead of
478659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// "static const DwVfpRegister&" because Clang complains otherwise when a
479659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// compilation unit that includes this header doesn't use the variables.
480659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kFirstCalleeSavedDoubleReg d8
481659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kLastCalleeSavedDoubleReg d15
482659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kDoubleRegZero d14
483659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kScratchDoubleReg d15
484ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Coprocessor register
48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstruct CRegister {
4884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is_valid() const { return 0 <= code_ && code_ < 16; }
4894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(CRegister creg) const { return code_ == creg.code_; }
4904a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(is_valid());
49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return code_;
49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(is_valid());
49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return 1 << code_;
49743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4995c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unfortunately we can't make this private in a struct.
50043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int code_;
50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
504ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister no_creg = { -1 };
505ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
506ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr0  = {  0 };
507ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr1  = {  1 };
508ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr2  = {  2 };
509ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr3  = {  3 };
510ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr4  = {  4 };
511ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr5  = {  5 };
512ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr6  = {  6 };
513ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr7  = {  7 };
514ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr8  = {  8 };
515ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr9  = {  9 };
516ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr10 = { 10 };
517ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr11 = { 11 };
518ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr12 = { 12 };
519ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr13 = { 13 };
520ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr14 = { 14 };
521ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr15 = { 15 };
52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Coprocessor number
52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum Coprocessor {
52643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p0  = 0,
52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p1  = 1,
52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p2  = 2,
52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p3  = 3,
53043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p4  = 4,
53143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p5  = 5,
53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p6  = 6,
53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p7  = 7,
53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p8  = 8,
53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p9  = 9,
53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p10 = 10,
53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p11 = 11,
53843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p12 = 12,
53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p13 = 13,
54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p14 = 14,
54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p15 = 15
54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Machine instruction Operands
54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Class Operand represents a shifter operand in data processing instructions
54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Operand BASE_EMBEDDED {
55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
55143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // immediate
552236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  INLINE(explicit Operand(int32_t immediate,
55359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org         RelocInfo::Mode rmode = RelocInfo::NONE32));
554ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  INLINE(static Operand Zero()) {
555ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    return Operand(static_cast<int32_t>(0));
556ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  }
55743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(explicit Operand(const ExternalReference& f));
55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Handle<Object> handle);
55943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(explicit Operand(Smi* value));
56043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rm
56243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(explicit Operand(Register rm));
56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rm <shift_op> shift_imm
56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register rm, ShiftOp shift_op, int shift_imm);
566bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static Operand SmiUntag(Register rm)) {
567bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return Operand(rm, ASR, kSmiTagSize);
568bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
569bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static Operand PointerOffsetFromSmiKey(Register key)) {
570bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
571bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize);
572bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
573bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) {
574bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2);
575bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize);
576bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rm <shift_op> rs
57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register rm, ShiftOp shift_op, Register rs);
58043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // Return true if this is a register operand.
58231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  INLINE(bool is_reg() const);
58331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
5843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Return true if this operand fits in one instruction so that no
585b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // 2-instruction solution with a load into the ip register is necessary. If
586b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // the instruction this operand is used for is a MOV or MVN instruction the
587b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // actual instruction to use is required for this calculation. For other
588b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // instructions instr is ignored.
589471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  bool is_single_instruction(const Assembler* assembler, Instr instr = 0) const;
59089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  bool must_output_reloc_info(const Assembler* assembler) const;
5912c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
5922c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  inline int32_t immediate() const {
5932c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    ASSERT(!rm_.is_valid());
5942c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    return imm32_;
5952c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  }
5962c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
59731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  Register rm() const { return rm_; }
598ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  Register rs() const { return rs_; }
599ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  ShiftOp shift_op() const { return shift_op_; }
60031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rm_;
60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rs_;
60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ShiftOp shift_op_;
60543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg
60643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int32_t imm32_;  // valid if rm_ == no_reg
607236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  RelocInfo::Mode rmode_;
60843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Class MemOperand represents a memory operand in load and store instructions
61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass MemOperand BASE_EMBEDDED {
61543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- offset]      Offset/NegOffset
61743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- offset]!     PreIndex/NegPreIndex
61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn], +/- offset     PostIndex/NegPostIndex
61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // offset is any signed 32-bit value; offset is first loaded to register ip if
62043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // it does not fit the addressing mode (12-bit unsigned and sign bit)
62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit MemOperand(Register rn, int32_t offset = 0, AddrMode am = Offset);
62243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
62343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm]          Offset/NegOffset
62443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm]!         PreIndex/NegPreIndex
62543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn], +/- rm         PostIndex/NegPostIndex
62643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit MemOperand(Register rn, Register rm, AddrMode am = Offset);
62743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
62843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm <shift_op> shift_imm]      Offset/NegOffset
62943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm <shift_op> shift_imm]!     PreIndex/NegPreIndex
63043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn], +/- rm <shift_op> shift_imm     PostIndex/NegPostIndex
63143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit MemOperand(Register rn, Register rm,
63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      ShiftOp shift_op, int shift_imm, AddrMode am = Offset);
633bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static MemOperand PointerAddressFromSmiKey(Register array,
634bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                                    Register key,
635bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                                    AddrMode am = Offset)) {
636bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
637bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am);
638bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
63943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
640720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  void set_offset(int32_t offset) {
641720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org      ASSERT(rm_.is(no_reg));
642720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org      offset_ = offset;
643720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  }
644720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
6453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  uint32_t offset() const {
646720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org      ASSERT(rm_.is(no_reg));
647720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org      return offset_;
648720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  }
649720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
6509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  Register rn() const { return rn_; }
6519dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  Register rm() const { return rm_; }
65204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  AddrMode am() const { return am_; }
653720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
6543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  bool OffsetIsUint12Encodable() const {
6553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_);
6563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
6573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
65843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
65943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rn_;  // base
66043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rm_;  // register offset
66143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int32_t offset_;  // valid if rm_ == no_reg
66243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ShiftOp shift_op_;
66343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg
66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  AddrMode am_;  // bits P, U, and W
66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
669169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
670169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Class NeonMemOperand represents a memory operand in load and
671169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// store NEON instructions
672169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgclass NeonMemOperand BASE_EMBEDDED {
673169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org public:
674169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // [rn {:align}]       Offset
675169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // [rn {:align}]!      PostIndex
676169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0);
677169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
678169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // [rn {:align}], rm   PostIndex
679169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  explicit NeonMemOperand(Register rn, Register rm, int align = 0);
680169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
681169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rn() const { return rn_; }
682169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rm() const { return rm_; }
683169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int align() const { return align_; }
684169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
685169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org private:
686169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void SetAlignment(int align);
687169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
688169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rn_;  // base
689169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rm_;  // register increment
690169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int align_;
691169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
692169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
693169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
694169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Class NeonListOperand represents a list of NEON registers
695169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgclass NeonListOperand BASE_EMBEDDED {
696169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org public:
697169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  explicit NeonListOperand(DoubleRegister base, int registers_count = 1);
698169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  DoubleRegister base() const { return base_; }
699169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonListType type() const { return type_; }
700169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org private:
701169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  DoubleRegister base_;
702169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonListType type_;
703169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
704169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
7054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgextern const Instr kMovLrPc;
706cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgextern const Instr kLdrPCMask;
7074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgextern const Instr kLdrPCPattern;
708cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgextern const Instr kBlxRegMask;
709cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgextern const Instr kBlxRegPattern;
71088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.orgextern const Instr kBlxIp;
7114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
7122c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kMovMvnMask;
7132c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kMovMvnPattern;
7142c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kMovMvnFlip;
7152c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
7165ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgextern const Instr kMovLeaveCCMask;
7175ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgextern const Instr kMovLeaveCCPattern;
7185ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgextern const Instr kMovwMask;
7195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgextern const Instr kMovwPattern;
7205ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgextern const Instr kMovwLeaveCCFlip;
7215ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
7222c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kCmpCmnMask;
7232c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kCmpCmnPattern;
7242c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kCmpCmnFlip;
7252c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kAddSubFlip;
7262c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgextern const Instr kAndBicFlip;
7274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
7286ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgstruct VmovIndex {
7296ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  unsigned char index;
7306ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org};
7316ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgconst VmovIndex VmovIndexLo = { 0 };
7326ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgconst VmovIndex VmovIndexHi = { 1 };
733378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
734ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Assembler : public AssemblerBase {
73543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create an assembler. Instructions and relocation information are emitted
73743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // into a buffer, with the instructions starting from the beginning and the
73843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // relocation information starting from the end of the buffer. See CodeDesc
73943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for a detailed comment on the layout (globals.h).
74043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
74143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is NULL, the assembler allocates and grows its own
74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // buffer, and buffer_size determines the initial buffer size. The buffer is
74343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // owned by the assembler and deallocated upon destruction of the assembler.
74443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
74543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is not NULL, the assembler uses the provided buffer
74643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for code generation and assumes its size to be buffer_size. If the buffer
74743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is too small, a fatal error occurs. No deallocation of the buffer is done
74843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // upon destruction of the assembler.
749c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Assembler(Isolate* isolate, void* buffer, int buffer_size);
7508e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  virtual ~Assembler();
75143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // GetCode emits any pending (non-emitted) code and fills the descriptor
75343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // desc. GetCode() is idempotent; it returns the same result if no other
7543291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Assembler functions are invoked in between GetCode() calls.
75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GetCode(CodeDesc* desc);
75643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label operations & relative jumps (PPUM Appendix D)
75843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
75943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Takes a branch opcode (cc) and a label (L) and generates
76043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // either a backward branch or a forward branch and links it
76143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the label fixup chain. Usage:
76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label L;    // unbound label
76443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // forward branch to unbound label
76543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // bind label to the current pc
76643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // backward branch to bound label
76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // illegal: a label may be bound only once
76843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note: The same Label can be used for forward and backward branches
77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // but it may be bound only once.
77143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind(Label* L);  // binds an unbound label L to the current code position
77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns the branch offset to the given label from the current code position
77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Links the label to the current position if it is still unbound
776769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // Manages the jump elimination optimization if the second parameter is true.
777769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  int branch_offset(Label* L, bool jump_elimination_allowed);
77843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the address in the constant pool of the code target address used by
78089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // the branch/call instruction at pc, or the object in a mov.
78189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  INLINE(static Address target_pointer_address_at(Address pc));
78289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/Modify the code target address in the branch/call instruction at pc.
78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(static Address target_address_at(Address pc));
78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(static void set_target_address_at(Address pc, Address target));
78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Return the code target address at a call site from the return address
78889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // of that call in the instruction stream.
78989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  INLINE(static Address target_address_from_return_address(Address pc));
79089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
79189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Given the address of the beginning of a call, return the address
79289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // in the instruction stream that the call will return from.
79389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  INLINE(static Address return_address_from_call_start(Address pc));
79489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
795c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This sets the branch destination (which is in the constant pool on ARM).
796c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This is for calls and branches within generated code.
79788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  inline static void deserialization_set_special_target_at(
79888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      Address constant_pool_entry, Address target);
7993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
8003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Here we are patching the address in the constant pool, not the actual call
8013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // instruction.  The address in the constant pool is the same size as a
8023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // pointer.
80388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  static const int kSpecialTargetSize = kPointerSize;
8043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
8054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Size of an instruction.
8064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  static const int kInstrSize = sizeof(Instr);
8074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
808911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // Distance between start of patched return sequence and the emitted address
809911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // to jump to.
8102356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Patched return sequence is:
811cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  //  ldr  ip, [pc, #0]   @ emited address and start
812cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  //  blx  ip
813cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  static const int kPatchReturnSequenceAddressOffset =  0 * kInstrSize;
81443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8152356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Distance between start of patched debug break slot and the emitted address
8162356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // to jump to.
8172356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Patched debug break slot code is:
8182356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  //  ldr  ip, [pc, #0]   @ emited address and start
8192356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  //  blx  ip
8202356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kPatchDebugBreakSlotAddressOffset =  0 * kInstrSize;
8212356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
82289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
82389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
82418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Difference between address of current opcode and value read from pc
82518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // register.
82618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  static const int kPcLoadDelta = 8;
82718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
8282356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kJSReturnSequenceInstructions = 4;
8292356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kDebugBreakSlotInstructions = 3;
8302356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kDebugBreakSlotLength =
8312356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      kDebugBreakSlotInstructions * kInstrSize;
83243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
83443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generation
83543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Insert the smallest number of nop instructions
83743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // possible to align the pc offset to a multiple
83843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of m. m must be a power of 2 (>= 4).
83943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Align(int m);
8405ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Aligns code to something that's optimal for a jump target for the platform.
8415ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void CodeTargetAlign();
84243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Branch instructions
84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void b(int branch_offset, Condition cond = al);
84543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bl(int branch_offset, Condition cond = al);
84643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void blx(int branch_offset);  // v5 and above
84743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void blx(Register target, Condition cond = al);  // v5 and above
84843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bx(Register target, Condition cond = al);  // v5 and above, plus v4t
84943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convenience branch instructions using labels
851769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void b(Label* L, Condition cond = al)  {
852769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com    b(branch_offset(L, cond == al), cond);
853769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  }
854769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void b(Condition cond, Label* L)  { b(branch_offset(L, cond == al), cond); }
855769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void bl(Label* L, Condition cond = al)  { bl(branch_offset(L, false), cond); }
856769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void bl(Condition cond, Label* L)  { bl(branch_offset(L, false), cond); }
857769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void blx(Label* L)  { blx(branch_offset(L, false)); }  // v5 and above
85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Data-processing instructions
8605c838251403b0be9a882540f1922577abba4c872ager@chromium.org
86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(Register dst, Register src1, const Operand& src2,
86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            SBit s = LeaveCC, Condition cond = al);
86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void eor(Register dst, Register src1, const Operand& src2,
86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(Register dst, Register src1, const Operand& src2,
86843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
869b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void sub(Register dst, Register src1, Register src2,
870b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org           SBit s = LeaveCC, Condition cond = al) {
871b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    sub(dst, src1, Operand(src2), s, cond);
872b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
87343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void rsb(Register dst, Register src1, const Operand& src2,
87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
87643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void add(Register dst, Register src1, const Operand& src2,
87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
87982dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org  void add(Register dst, Register src1, Register src2,
88082dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org           SBit s = LeaveCC, Condition cond = al) {
88182dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org    add(dst, src1, Operand(src2), s, cond);
88282dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org  }
88343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void adc(Register dst, Register src1, const Operand& src2,
88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sbc(Register dst, Register src1, const Operand& src2,
88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void rsc(Register dst, Register src1, const Operand& src2,
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void tst(Register src1, const Operand& src2, Condition cond = al);
894b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void tst(Register src1, Register src2, Condition cond = al) {
895b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    tst(src1, Operand(src2), cond);
896b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void teq(Register src1, const Operand& src2, Condition cond = al);
89943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register src1, const Operand& src2, Condition cond = al);
901b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void cmp(Register src1, Register src2, Condition cond = al) {
902b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    cmp(src1, Operand(src2), cond);
903b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
904496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al);
90543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmn(Register src1, const Operand& src2, Condition cond = al);
90743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void orr(Register dst, Register src1, const Operand& src2,
90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
910b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void orr(Register dst, Register src1, Register src2,
911b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org           SBit s = LeaveCC, Condition cond = al) {
912b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    orr(dst, src1, Operand(src2), s, cond);
913b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
91443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, const Operand& src,
91643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
917b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {
918b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    mov(dst, Operand(src), s, cond);
919b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
92043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9214a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // Load the position of the label relative to the generated code object
9224a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // pointer in a register.
9234a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  void mov_label_offset(Register dst, Label* label);
9244a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
9255ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // ARMv7 instructions for loading a 32 bit immediate in two instructions.
9265ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // This may actually emit a different mov instruction, but on an ARMv7 it
9275ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // is guaranteed to only emit one instruction.
9285ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void movw(Register reg, uint32_t immediate, Condition cond = al);
9295ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // The constant for movt should be in the range 0-0xffff.
9305ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void movt(Register reg, uint32_t immediate, Condition cond = al);
9315ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
93243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bic(Register dst, Register src1, const Operand& src2,
93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
93443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mvn(Register dst, const Operand& src,
93643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Multiply instructions
93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mla(Register dst, Register src1, Register src2, Register srcA,
94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void mls(Register dst, Register src1, Register src2, Register srcA,
94433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org           Condition cond = al);
94533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
94633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void sdiv(Register dst, Register src1, Register src2,
94733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org            Condition cond = al);
94833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
94943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mul(Register dst, Register src1, Register src2,
95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
95143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void smlal(Register dstL, Register dstH, Register src1, Register src2,
95343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
95443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void smull(Register dstL, Register dstH, Register src1, Register src2,
95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void umlal(Register dstL, Register dstH, Register src1, Register src2,
95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
96043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void umull(Register dstL, Register dstH, Register src1, Register src2,
96243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
96343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Miscellaneous arithmetic instructions
96543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void clz(Register dst, Register src, Condition cond = al);  // v5 and above
96743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
968ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Saturating instructions. v6 and above.
969ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
970ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Unsigned saturate.
971ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
972ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Saturate an optionally shifted signed value to an unsigned range.
973ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
974ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   usat dst, #satpos, src
975ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   usat dst, #satpos, src, lsl #sh
976ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   usat dst, #satpos, src, asr #sh
977ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
978ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Register dst will contain:
979ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
980ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   0,                 if s < 0
981ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   (1 << satpos) - 1, if s > ((1 << satpos) - 1)
982ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   s,                 otherwise
983ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
984ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // where s is the contents of src after shifting (if used.)
985ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  void usat(Register dst, int satpos, const Operand& src, Condition cond = al);
986ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
98730ce411529579186181838984710b0b0980857aaricow@chromium.org  // Bitfield manipulation instructions. v7 and above.
98830ce411529579186181838984710b0b0980857aaricow@chromium.org
98930ce411529579186181838984710b0b0980857aaricow@chromium.org  void ubfx(Register dst, Register src, int lsb, int width,
99030ce411529579186181838984710b0b0980857aaricow@chromium.org            Condition cond = al);
99130ce411529579186181838984710b0b0980857aaricow@chromium.org
99230ce411529579186181838984710b0b0980857aaricow@chromium.org  void sbfx(Register dst, Register src, int lsb, int width,
99330ce411529579186181838984710b0b0980857aaricow@chromium.org            Condition cond = al);
99430ce411529579186181838984710b0b0980857aaricow@chromium.org
99530ce411529579186181838984710b0b0980857aaricow@chromium.org  void bfc(Register dst, int lsb, int width, Condition cond = al);
99630ce411529579186181838984710b0b0980857aaricow@chromium.org
99730ce411529579186181838984710b0b0980857aaricow@chromium.org  void bfi(Register dst, Register src, int lsb, int width,
99830ce411529579186181838984710b0b0980857aaricow@chromium.org           Condition cond = al);
99930ce411529579186181838984710b0b0980857aaricow@chromium.org
1000169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void pkhbt(Register dst, Register src1, const Operand& src2,
1001169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org             Condition cond = al);
1002169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1003169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void pkhtb(Register dst, Register src1, const Operand& src2,
1004169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org             Condition cond = al);
1005169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1006169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void uxtb(Register dst, const Operand& src, Condition cond = al);
1007169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1008169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void uxtab(Register dst, Register src1, const Operand& src2,
1009169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org             Condition cond = al);
1010169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1011169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void uxtb16(Register dst, const Operand& src, Condition cond = al);
1012169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
101343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Status register access instructions
101443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
101543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mrs(Register dst, SRegister s, Condition cond = al);
101643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);
101743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
101843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Load/Store instructions
101943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldr(Register dst, const MemOperand& src, Condition cond = al);
102043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void str(Register src, const MemOperand& dst, Condition cond = al);
102143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrb(Register dst, const MemOperand& src, Condition cond = al);
102243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void strb(Register src, const MemOperand& dst, Condition cond = al);
102343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrh(Register dst, const MemOperand& src, Condition cond = al);
102443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void strh(Register src, const MemOperand& dst, Condition cond = al);
102543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
10279155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  void ldrd(Register dst1,
10289155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Register dst2,
10299155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            const MemOperand& src, Condition cond = al);
10309155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  void strd(Register src1,
10319155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Register src2,
10329155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            const MemOperand& dst, Condition cond = al);
103343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1034169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Preload instructions
1035169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void pld(const MemOperand& address);
1036169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Load/Store multiple instructions
103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
104043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Exception-generating instructions and debugging support
1042e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void stop(const char* msg,
1043e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org            Condition cond = al,
1044e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org            int32_t code = kDefaultStopCode);
104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bkpt(uint32_t imm16);  // v5 and above
1047e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void svc(uint32_t imm24, Condition cond = al);
104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Coprocessor instructions
105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cdp(Coprocessor coproc, int opcode_1,
105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           CRegister crd, CRegister crn, CRegister crm,
105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           int opcode_2, Condition cond = al);
105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cdp2(Coprocessor coproc, int opcode_1,
105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            CRegister crd, CRegister crn, CRegister crm,
105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int opcode_2);  // v5 and above
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mcr(Coprocessor coproc, int opcode_1,
106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           Register rd, CRegister crn, CRegister crm,
106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           int opcode_2 = 0, Condition cond = al);
106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mcr2(Coprocessor coproc, int opcode_1,
106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            Register rd, CRegister crn, CRegister crm,
106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int opcode_2 = 0);  // v5 and above
106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mrc(Coprocessor coproc, int opcode_1,
106843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           Register rd, CRegister crn, CRegister crm,
106943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           int opcode_2 = 0, Condition cond = al);
107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mrc2(Coprocessor coproc, int opcode_1,
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            Register rd, CRegister crn, CRegister crm,
107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int opcode_2 = 0);  // v5 and above
107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,
107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           LFlag l = Short, Condition cond = al);
107743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc(Coprocessor coproc, CRegister crd, Register base, int option,
107843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           LFlag l = Short, Condition cond = al);
107943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,
108143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            LFlag l = Short);  // v5 and above
108243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
108343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            LFlag l = Short);  // v5 and above
108443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1085c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Support for VFP.
1086003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // All these APIs support S0 to S31 and D0 to D31.
1087c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
1088b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void vldr(const DwVfpRegister dst,
1089b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Register base,
10903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
10913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
10923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vldr(const DwVfpRegister dst,
10933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& src,
1094b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Condition cond = al);
10955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
10965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vldr(const SwVfpRegister dst,
10975d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            const Register base,
10983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
10993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
11003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vldr(const SwVfpRegister dst,
11013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& src,
11025d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            const Condition cond = al);
11035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
1104b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void vstr(const DwVfpRegister src,
1105b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Register base,
11063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
11073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
11083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vstr(const DwVfpRegister src,
11093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& dst,
1110b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Condition cond = al);
111169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
11120b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  void vstr(const SwVfpRegister src,
11130b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org            const Register base,
11143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
11153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
11163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vstr(const SwVfpRegister src,
11173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& dst,
11180b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org            const Condition cond = al);
11190b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
112074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vldm(BlockAddrMode am,
112174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
112274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister first,
112374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister last,
112474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
112574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
112674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vstm(BlockAddrMode am,
112774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
112874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister first,
112974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister last,
113074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
113174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
113274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vldm(BlockAddrMode am,
113374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
113474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister first,
113574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister last,
113674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
113774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
113874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vstm(BlockAddrMode am,
113974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
114074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister first,
114174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister last,
114274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
114374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
114469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  void vmov(const DwVfpRegister dst,
11456a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org            double imm,
114671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org            const Register scratch = no_reg);
11476a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  void vmov(const SwVfpRegister dst,
11486a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org            const SwVfpRegister src,
11496a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org            const Condition cond = al);
11506a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  void vmov(const DwVfpRegister dst,
115169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org            const DwVfpRegister src,
115269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org            const Condition cond = al);
115313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const DwVfpRegister dst,
11546ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org            const VmovIndex index,
1155003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org            const Register src,
1156003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org            const Condition cond = al);
1157fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void vmov(const Register dst,
1158fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            const VmovIndex index,
1159fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            const DwVfpRegister src,
1160fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            const Condition cond = al);
1161003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  void vmov(const DwVfpRegister dst,
116213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Register src1,
116313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Register src2,
116413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
116513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const Register dst1,
116613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Register dst2,
116713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src,
1168c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
116913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const SwVfpRegister dst,
1170c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Register src,
1171c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
117213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const Register dst,
117313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const SwVfpRegister src,
117413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
11755d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f64_s32(const DwVfpRegister dst,
11765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
117783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
11785d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
11795d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f32_s32(const SwVfpRegister dst,
11805d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
118183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
11825d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
11835d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f64_u32(const DwVfpRegister dst,
11845d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
118583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
11865d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
11875d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_s32_f64(const SwVfpRegister dst,
11885d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const DwVfpRegister src,
118983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
11905d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
11915d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_u32_f64(const SwVfpRegister dst,
11925d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const DwVfpRegister src,
119383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
11945d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
11955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f64_f32(const DwVfpRegister dst,
11965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
119783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
11985d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
11995d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f32_f64(const SwVfpRegister dst,
12005d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const DwVfpRegister src,
120183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
12025d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
1203bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  void vcvt_f64_s32(const DwVfpRegister dst,
1204bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                    int fraction_bits,
1205bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                    const Condition cond = al);
120613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1207badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  void vneg(const DwVfpRegister dst,
1208badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org            const DwVfpRegister src,
1209badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org            const Condition cond = al);
12107a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org  void vabs(const DwVfpRegister dst,
12117a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org            const DwVfpRegister src,
12127a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org            const Condition cond = al);
121313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vadd(const DwVfpRegister dst,
121413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
121513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
121613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
121713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vsub(const DwVfpRegister dst,
121813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
121913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
122013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
122113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmul(const DwVfpRegister dst,
122213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
122313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
122413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
1225fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  void vmla(const DwVfpRegister dst,
1226fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            const DwVfpRegister src1,
1227fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            const DwVfpRegister src2,
1228fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            const Condition cond = al);
12298432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  void vmls(const DwVfpRegister dst,
12308432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            const DwVfpRegister src1,
12318432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            const DwVfpRegister src2,
12328432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            const Condition cond = al);
123313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vdiv(const DwVfpRegister dst,
123413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
123513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
123613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
123713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vcmp(const DwVfpRegister src1,
123813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
1239c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
1240ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  void vcmp(const DwVfpRegister src1,
1241ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org            const double src2,
1242ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org            const Condition cond = al);
1243c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  void vmrs(const Register dst,
1244c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
124501fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  void vmsr(const Register dst,
124601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org            const Condition cond = al);
124732d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  void vsqrt(const DwVfpRegister dst,
124832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org             const DwVfpRegister src,
124932d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org             const Condition cond = al);
1250c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
1251169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Support for NEON.
1252169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // All these APIs support D0 to D31 and Q0 to Q15.
1253169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1254169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void vld1(NeonSize size,
1255169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonListOperand& dst,
1256169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonMemOperand& src);
1257169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void vst1(NeonSize size,
1258169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonListOperand& src,
1259169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonMemOperand& dst);
1260169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src);
1261169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
126243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Pseudo instructions
1263beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
1264beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // Different nop operations are used by the code generator to detect certain
1265beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // states of the generated code.
1266beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  enum NopMarkerTypes {
1267beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    NON_MARKING_NOP = 0,
1268beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    DEBUG_BREAK_NOP,
1269beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    // IC markers.
1270beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    PROPERTY_ACCESS_INLINED,
1271beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    PROPERTY_ACCESS_INLINED_CONTEXT,
1272beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1273beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    // Helper values.
1274beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    LAST_CODE_MARKER,
1275beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1276beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  };
1277beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
1278beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  void nop(int type = 0);   // 0 is the default non-marking type.
127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1280b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  void push(Register src, Condition cond = al) {
1281b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    str(src, MemOperand(sp, 4, NegPreIndex), cond);
128231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  }
128331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
1284c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  void pop(Register dst, Condition cond = al) {
1285c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    ldr(dst, MemOperand(sp, 4, PostIndex), cond);
128643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
128743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  void pop() {
128931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    add(sp, sp, Operand(kPointerSize));
129043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
129143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Jump unconditionally to given label.
129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void jmp(Label* L) { b(L, al); }
129443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static bool use_immediate_embedded_pointer_loads(
129689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      const Assembler* assembler) {
129789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
129889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        (assembler == NULL || !assembler->predictable_code_size());
129989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
130089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
13014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Check the code size generated from label to here.
13024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int SizeOfCodeGeneratedSince(Label* label) {
13034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return pc_offset() - label->pos();
13044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
13054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
13064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Check the number of instructions generated from label to here.
13074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int InstructionsGeneratedSince(Label* label) {
13084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return SizeOfCodeGeneratedSince(label) / kInstrSize;
13094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
131043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1311c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Check whether an immediate fits an addressing mode 1 instruction.
1312c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  bool ImmediateFitsAddrMode1Instruction(int32_t imm32);
1313c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
1314013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Class for scoping postponing the constant pool generation.
1315013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  class BlockConstPoolScope {
1316013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org   public:
1317013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1318013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org      assem_->StartBlockConstPool();
1319013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    }
1320013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    ~BlockConstPoolScope() {
1321013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org      assem_->EndBlockConstPool();
1322013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    }
1323013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
1324013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org   private:
1325013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    Assembler* assem_;
1326013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
1327013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
1328013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  };
1329c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
133043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugging
133143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Mark address of the ExitJSFrame code.
13334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void RecordJSReturn();
13344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13352356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Mark address of a debug break slot.
13362356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  void RecordDebugBreakSlot();
13372356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
13388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Record the AST id of the CallIC being compiled, so that it can be placed
13398e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // in the relocation information.
1340471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void SetRecordedAstId(TypeFeedbackId ast_id) {
1341471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    ASSERT(recorded_ast_id_.IsNone());
1342717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    recorded_ast_id_ = ast_id;
1343717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  }
1344717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
1345471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  TypeFeedbackId RecordedAstId() {
1346471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    ASSERT(!recorded_ast_id_.IsNone());
1347717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    return recorded_ast_id_;
1348717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  }
1349717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
1350471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
13518e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
135243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Record a comment relocation entry that can be used by a disassembler.
1353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Use --code-comments to enable.
135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void RecordComment(const char* msg);
135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Record the emission of a constant pool.
13575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  //
13585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The emission of constant pool depends on the size of the code generated and
13595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // the number of RelocInfo recorded.
13605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The Debug mechanism needs to map code offsets between two versions of a
13615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // function, compiled with and without debugger support (see for example
13625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Debug::PrepareForBreakPoints()).
13635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Compiling functions with debugger support generates additional code
13645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // (Debug::GenerateSlot()). This may affect the emission of the constant
13655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // pools and cause the version of the code with debugger support to have
13665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // constant pools generated in different places.
13675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Recording the position and size of emitted constant pools allows to
13685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // correctly compute the offset mappings between the different versions of a
13695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // function in all situations.
13705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  //
13715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The parameter indicates the size of the constant pool (in bytes), including
13725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // the marker and branch over the data.
13735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void RecordConstPool(int size);
13745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
13750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Writes a single byte or word of data in the code stream.  Used
13760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // for inline tables, e.g., jump-tables. The constant pool should be
13770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // emitted before any use of db and dd to ensure that constant pools
13780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // are not emitted as part of the tables generated.
1379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void db(uint8_t data);
1380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void dd(uint32_t data);
1381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1382057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // Emits the address of the code stub's first instruction.
1383057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  void emit_code_stub_address(Code* stub);
1384057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
1385f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/patch instructions
1388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void instr_at_put(int pos, Instr instr) {
1390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
13924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1393013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static void instr_at_put(byte* pc, Instr instr) {
139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *reinterpret_cast<Instr*>(pc) = instr;
139543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1396496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Condition GetCondition(Instr instr);
1397013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static bool IsBranch(Instr instr);
1398013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static int GetBranchOffset(Instr instr);
1399013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static bool IsLdrRegisterImmediate(Instr instr);
14004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static bool IsVldrDRegisterImmediate(Instr instr);
1401013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static int GetLdrRegisterImmediateOffset(Instr instr);
14024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static int GetVldrDRegisterImmediateOffset(Instr instr);
1403013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
14044cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
1405ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static bool IsStrRegisterImmediate(Instr instr);
1406ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
1407ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static bool IsAddRegisterImmediate(Instr instr);
1408ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
14099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static Register GetRd(Instr instr);
1410496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Register GetRn(Instr instr);
1411496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Register GetRm(Instr instr);
14129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsPush(Instr instr);
14139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsPop(Instr instr);
14149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsStrRegFpOffset(Instr instr);
14159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsLdrRegFpOffset(Instr instr);
14169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsStrRegFpNegOffset(Instr instr);
14179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsLdrRegFpNegOffset(Instr instr);
1418beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  static bool IsLdrPcImmediateOffset(Instr instr);
14194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static bool IsVldrDPcImmediateOffset(Instr instr);
1420496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static bool IsTstImmediate(Instr instr);
1421496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static bool IsCmpRegister(Instr instr);
1422496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static bool IsCmpImmediate(Instr instr);
1423496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Register GetCmpImmediateRegister(Instr instr);
1424496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static int GetCmpImmediateRawImmediate(Instr instr);
1425beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
142689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static bool IsMovT(Instr instr);
142789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static bool IsMovW(Instr instr);
1428013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
142940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Constants in pools are accessed via pc relative addressing, which can
14304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
14314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // PC-relative loads, thereby defining a maximum distance between the
14324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // instruction and the accessed constant.
14334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static const int kMaxDistToIntPool = 4*KB;
14344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static const int kMaxDistToFPPool = 1*KB;
14354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // All relocations could be integer, it therefore acts as the limit.
1436ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize;
1437ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize;
143840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
14397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Postpone the generation of the constant pool for the specified number of
14407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // instructions.
14417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  void BlockConstPoolFor(int instructions);
14427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
14437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Check if is time to emit a constant pool.
1444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void CheckConstPool(bool force_emit, bool require_jump);
1445013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
1446013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org protected:
14478e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Relocation for a type-recording IC has the AST id added to it.  This
14488e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // member variable is a way to pass the information from the call site to
14498e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // the relocation info.
1450471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  TypeFeedbackId recorded_ast_id_;
14518e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1452013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1453013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Decode branch instruction at pos and return branch target pos
145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int target_at(int pos);
145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch branch instruction at pos to branch to given branch target pos
145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void target_at_put(int pos, int target_pos);
145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14607b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Prevent contant pool emission until EndBlockConstPool is called.
14617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Call to this function can be nested but must be followed by an equal
14627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // number of call to EndBlockConstpool.
1463c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  void StartBlockConstPool() {
14647b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (const_pool_blocked_nesting_++ == 0) {
14657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Prevent constant pool checks happening by setting the next check to
14667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // the biggest possible offset.
14677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      next_buffer_check_ = kMaxInt;
14687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
1469c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
14707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
14717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Resume constant pool emission. Need to be called as many time as
14727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // StartBlockConstPool to have an effect.
1473c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  void EndBlockConstPool() {
14747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (--const_pool_blocked_nesting_ == 0) {
1475ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org#ifdef DEBUG
1476ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // Max pool start (if we need a jump and an alignment).
1477ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      int start = pc_offset() + kInstrSize + 2 * kPointerSize;
14787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Check the constant pool hasn't been blocked for too long.
1479ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      ASSERT((num_pending_32_bit_reloc_info_ == 0) ||
1480ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org             (start + num_pending_64_bit_reloc_info_ * kDoubleSize <
1481ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org              (first_const_pool_32_use_ + kMaxDistToIntPool)));
14824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      ASSERT((num_pending_64_bit_reloc_info_ == 0) ||
1483ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org             (start < (first_const_pool_64_use_ + kMaxDistToFPPool)));
1484ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org#endif
14857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Two cases:
14867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //  * no_const_pool_before_ >= next_buffer_check_ and the emission is
14877b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //    still blocked
14887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //  * no_const_pool_before_ < next_buffer_check_ and the next emit will
14897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //    trigger a check.
14907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      next_buffer_check_ = no_const_pool_before_;
14917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
14927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
14937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
14947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  bool is_const_pool_blocked() const {
14957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return (const_pool_blocked_nesting_ > 0) ||
14967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org           (pc_offset() < no_const_pool_before_);
1497c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
1498c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org
149943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
150043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int next_buffer_check_;  // pc offset of next buffer check
150143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generation
150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The relocation writer's position is at least kGap bytes below the end of
150443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the generated instructions. This is so that multi-instruction sequences do
150543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not have to check for overflow. The same is true for writes of large
150643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // relocation info entries.
150743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kGap = 32;
150843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
150943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Constant pool generation
151043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Pools are emitted in the instruction stream, preferably after unconditional
151143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // jumps or after returns from functions (in dead code locations).
151243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If a long code sequence does not contain unconditional jumps, it is
151343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // necessary to emit the constant pool before the pool gets too far from the
151443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // location it is accessed from. In this case, we emit a jump over the emitted
151543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // constant pool.
151643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Constants in the pool may be addresses of functions that gets relocated;
151743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // if so, a relocation info entry is associated to the constant pool entry.
151843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
151943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Repeated checking whether the constant pool should be emitted is rather
152043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // expensive. By default we only check again once a number of instructions
152143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // has been generated. That also means that the sizing of the buffers is not
152243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // an exact science, and that we rely on some slop to not overrun buffers.
15237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static const int kCheckPoolIntervalInst = 32;
15247b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
152543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1527013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Emission of the constant pool may be blocked in some code sequences.
1528013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  int const_pool_blocked_nesting_;  // Block emission if this is not zero.
1529013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  int no_const_pool_before_;  // Block emission before this pc offset.
153043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Keep track of the first instruction requiring a constant pool entry
15327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // since the previous constant pool was emitted.
1533ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int first_const_pool_32_use_;
1534ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int first_const_pool_64_use_;
153543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Relocation info generation
153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Each relocation is encoded as a variable size value
153843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
153943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocInfoWriter reloc_info_writer;
15407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
154143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Relocation info records are also used during code generation as temporary
154243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // containers for constants and code target addresses until they are emitted
154343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the constant pool. These pending relocation info records are temporarily
154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // stored in a separate buffer until a constant pool is emitted.
154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If every instruction in a long sequence is accessing the pool, we need one
154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // pending relocation entry per instruction.
15477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
1548ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // The buffers of pending relocation info.
1549ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo];
1550ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo];
1551ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // Number of pending reloc info entries in the 32 bits buffer.
1552ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int num_pending_32_bit_reloc_info_;
1553ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // Number of pending reloc info entries in the 64 bits buffer.
15544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int num_pending_64_bit_reloc_info_;
155543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
155641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // The bound position, before this we cannot do instruction elimination.
155743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int last_bound_pos_;
155843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
155943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code emission
156043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void CheckBuffer();
156143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GrowBuffer();
156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(Instr x);
156343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
156489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // 32-bit immediate values
156589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  void move_32_bit_immediate(Condition cond,
156689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                             Register rd,
156789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                             SBit s,
156889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                             const Operand& x);
156989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
157043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Instruction generation
157143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
157243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod2(Instr instr, Register rd, const MemOperand& x);
157343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod3(Instr instr, Register rd, const MemOperand& x);
157443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod4(Instr instr, Register rn, RegList rl);
157543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
157643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
157743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Labels
157843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void print(Label* L);
157943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind_to(Label* L, int pos);
158043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void next(Label* L);
158143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
158289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  enum UseConstantPoolMode {
158389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    USE_CONSTANT_POOL,
158489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    DONT_USE_CONSTANT_POOL
158589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  };
158689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Record reloc info for current pc_
158889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0,
158989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                       UseConstantPoolMode mode = USE_CONSTANT_POOL);
15904cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  void RecordRelocInfo(double data);
15914cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  void RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo);
159218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
15934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  friend class RelocInfo;
15944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  friend class CodePatcher;
1595013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  friend class BlockConstPoolScope;
1596f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1597f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder positions_recorder_;
1598f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  friend class PositionsRecorder;
1599f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  friend class EnsureSpace;
1600f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org};
1601f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1602f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1603f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.orgclass EnsureSpace BASE_EMBEDDED {
1604f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org public:
1605f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  explicit EnsureSpace(Assembler* assembler) {
1606f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    assembler->CheckBuffer();
1607f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  }
160843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
160943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1610f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_ARM_ASSEMBLER_ARM_H_
1614