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_
42763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
4318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include <stdio.h>
44763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org#include <vector>
45763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
46196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm/constants-arm.h"
474b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/assembler.h"
48196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h"
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
5171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CPU Registers.
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1) We would prefer to use an enum, but enum values are assignment-
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// compatible with int, which has caused code-generation bugs.
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2) We would prefer to use a class instead of a struct but we don't like
5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the register initialization to depend on the particular initialization
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// order (which appears to be different on OS X, Linux, and Windows for the
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// installed versions of C++ we tried). Using a struct permits C-style
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "initialization". Also, the Register objects cannot be const as this
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// forces initialization stubs in MSVC, making us dependent on initialization
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// order.
6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 3) By not using an enum, we are possibly preventing the compiler from
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// doing certain constant folds, which may significantly reduce the
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// code generated for some assembly instructions (because they boil down
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to a few constants). If this is a problem, we could change the code
7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// such that we use an enum in optimized mode, and the struct in debug
7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// mode. This way we get the compile-time error checking in debug mode
7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and best performance in optimized code.
735d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
74c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org// These constants are used in several locations, including static initializers
75c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_no_reg_Code = -1;
76c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r0_Code = 0;
77c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r1_Code = 1;
78c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r2_Code = 2;
79c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r3_Code = 3;
80c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r4_Code = 4;
81c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r5_Code = 5;
82c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r6_Code = 6;
83c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r7_Code = 7;
84c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r8_Code = 8;
85c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r9_Code = 9;
86c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_r10_Code = 10;
87c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_fp_Code = 11;
88c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_ip_Code = 12;
89c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_sp_Code = 13;
90c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_lr_Code = 14;
91c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgconst int kRegister_pc_Code = 15;
92c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Core register
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstruct Register {
95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kNumRegisters = 16;
963d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  static const int kMaxNumAllocatableRegisters =
97c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      FLAG_enable_ool_constant_pool ? 8 : 9;
983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  static const int kSizeInBytes = 4;
99a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
100a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  inline static int NumAllocatableRegisters();
101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static int ToAllocationIndex(Register reg) {
103e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(reg.code() < kMaxNumAllocatableRegisters);
104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return reg.code();
105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static Register FromAllocationIndex(int index) {
108e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return from_code(index);
110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const char* AllocationIndexToString(int index) {
113e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    const char* const names[] = {
115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r0",
116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r1",
117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r2",
118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r3",
119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r4",
120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r5",
121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r6",
122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "r7",
123c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      "r8",
124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    };
125c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    if (FLAG_enable_ool_constant_pool && (index >= 7)) {
126c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      return names[index + 1];
127c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    }
128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return names[index];
129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static Register from_code(int code) {
132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Register r = { code };
133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return r;
134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
1374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(Register reg) const { return code_ == reg.code_; }
1384a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return code_;
14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
143e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
14443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return 1 << code_;
14543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  void set_code(int code) {
1489dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    code_ = code;
149e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
1509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
1519dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
1525c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unfortunately we can't make this private in a struct.
15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int code_;
15443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
15543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1561456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register no_reg = { kRegister_no_reg_Code };
1571456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1581456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r0  = { kRegister_r0_Code };
1591456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r1  = { kRegister_r1_Code };
1601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r2  = { kRegister_r2_Code };
1611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r3  = { kRegister_r3_Code };
1621456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r4  = { kRegister_r4_Code };
1631456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r5  = { kRegister_r5_Code };
1641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r6  = { kRegister_r6_Code };
165c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org// Used as constant pool pointer register if FLAG_enable_ool_constant_pool.
1661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r7  = { kRegister_r7_Code };
1671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Used as context register.
1681456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r8  = { kRegister_r8_Code };
1691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Used as lithium codegen scratch register.
1701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r9  = { kRegister_r9_Code };
1711456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org// Used as roots register.
1721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r10 = { kRegister_r10_Code };
1731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register fp  = { kRegister_fp_Code };
1741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register ip  = { kRegister_ip_Code };
1751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register sp  = { kRegister_sp_Code };
1761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register lr  = { kRegister_lr_Code };
1771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register pc  = { kRegister_pc_Code };
1781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
17913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org// Single word VFP register.
18013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgstruct SwVfpRegister {
181e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const int kSizeInBytes = 4;
1824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is_valid() const { return 0 <= code_ && code_ < 32; }
1834a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
1844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
185e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
18613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return code_;
18713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
1884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
189e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
19013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return 1 << code_;
19113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
1924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void split_code(int* vm, int* m) const {
193e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
194d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *m = code_ & 0x1;
195d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *vm = code_ >> 1;
196d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
19713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
19813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  int code_;
19913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org};
20013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
20113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
20213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org// Double word VFP register.
20313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgstruct DwVfpRegister {
20494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  static const int kMaxNumRegisters = 32;
2053cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // A few double registers are reserved: one as a scratch register and one to
2063cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // hold 0.0, that does not fit in the immediate field of vmov instructions.
2073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  //  d14: 0.0
2083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  //  d15: scratch register.
2093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  static const int kNumReservedRegisters = 2;
21094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  static const int kMaxNumAllocatableRegisters = kMaxNumRegisters -
2113cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org      kNumReservedRegisters;
212e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const int kSizeInBytes = 8;
213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
214003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Note: the number of registers can be different at snapshot and run-time.
215003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Any code included in the snapshot must be able to run both with 16 or 32
216003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // registers.
217a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  inline static int NumRegisters();
218af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  inline static int NumReservedRegisters();
219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  inline static int NumAllocatableRegisters();
220003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
221f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  inline static int ToAllocationIndex(DwVfpRegister reg);
222a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const char* AllocationIndexToString(int index);
223003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  inline static DwVfpRegister FromAllocationIndex(int index);
224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static DwVfpRegister from_code(int code) {
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DwVfpRegister r = { code };
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return r;
228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
230003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  bool is_valid() const {
23194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    return 0 <= code_ && code_ < kMaxNumRegisters;
232003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
2334a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
2344a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
235e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
23613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return code_;
23713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
2384a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
239e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
24013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    return 1 << code_;
24113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
2424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void split_code(int* vm, int* m) const {
243e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
244d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *m = (code_ & 0x10) >> 4;
245d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    *vm = code_ & 0x0F;
246d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
24713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
24813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  int code_;
24913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org};
25013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
25113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtypedef DwVfpRegister DoubleRegister;
253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
255fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// Double word VFP register d0-15.
256fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgstruct LowDwVfpRegister {
257fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org public:
258fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  static const int kMaxNumLowRegisters = 16;
259fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  operator DwVfpRegister() const {
260fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    DwVfpRegister r = { code_ };
261fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return r;
262fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
263fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  static LowDwVfpRegister from_code(int code) {
264fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    LowDwVfpRegister r = { code };
265fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return r;
266fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
267fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
268fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool is_valid() const {
269fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return 0 <= code_ && code_ < kMaxNumLowRegisters;
270fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
271fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
272fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; }
273fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int code() const {
274e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
275fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return code_;
276fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
277fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  SwVfpRegister low() const {
278fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    SwVfpRegister reg;
279fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    reg.code_ = code_ * 2;
280fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
281e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(reg.is_valid());
282fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return reg;
283fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
284fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  SwVfpRegister high() const {
285fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    SwVfpRegister reg;
286fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    reg.code_ = (code_ * 2) + 1;
287fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
288e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(reg.is_valid());
289fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return reg;
290fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
291fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
292fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int code_;
293fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org};
294fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
295fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
296169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Quad word NEON register.
297169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgstruct QwNeonRegister {
298169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static const int kMaxNumRegisters = 16;
299169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
300169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static QwNeonRegister from_code(int code) {
301169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    QwNeonRegister r = { code };
302169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return r;
303169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
304169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
305169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  bool is_valid() const {
306169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return (0 <= code_) && (code_ < kMaxNumRegisters);
307169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
308169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  bool is(QwNeonRegister reg) const { return code_ == reg.code_; }
309169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int code() const {
310e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
311169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return code_;
312169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
313169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void split_code(int* vm, int* m) const {
314e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
315a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    int encoded_code = code_ << 1;
316a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    *m = (encoded_code & 0x10) >> 4;
317a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    *vm = encoded_code & 0x0F;
318169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
319169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
320169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int code_;
321169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
322169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
323169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
324169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgtypedef QwNeonRegister QuadRegister;
325169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
326169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
327ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Support for the VFP registers s0 to s31 (d0 to d15).
32813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org// Note that "s(N):s(N+1)" is the same as "d(N/2)".
329ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s0  = {  0 };
330ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s1  = {  1 };
331ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s2  = {  2 };
332ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s3  = {  3 };
333ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s4  = {  4 };
334ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s5  = {  5 };
335ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s6  = {  6 };
336ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s7  = {  7 };
337ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s8  = {  8 };
338ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s9  = {  9 };
339ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s10 = { 10 };
340ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s11 = { 11 };
341ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s12 = { 12 };
342ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s13 = { 13 };
343ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s14 = { 14 };
344ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s15 = { 15 };
345ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s16 = { 16 };
346ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s17 = { 17 };
347ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s18 = { 18 };
348ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s19 = { 19 };
349ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s20 = { 20 };
350ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s21 = { 21 };
351ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s22 = { 22 };
352ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s23 = { 23 };
353ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s24 = { 24 };
354ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s25 = { 25 };
355ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s26 = { 26 };
356ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s27 = { 27 };
357ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s28 = { 28 };
358ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s29 = { 29 };
359ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s30 = { 30 };
360ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst SwVfpRegister s31 = { 31 };
361ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
3629ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgconst DwVfpRegister no_dreg = { -1 };
363fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d0 = { 0 };
364fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d1 = { 1 };
365fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d2 = { 2 };
366fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d3 = { 3 };
367fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d4 = { 4 };
368fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d5 = { 5 };
369fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d6 = { 6 };
370fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d7 = { 7 };
371fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d8 = { 8 };
372fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d9 = { 9 };
373fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d10 = { 10 };
374fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d11 = { 11 };
375fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d12 = { 12 };
376fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d13 = { 13 };
377fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d14 = { 14 };
378fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgconst LowDwVfpRegister d15 = { 15 };
379003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d16 = { 16 };
380003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d17 = { 17 };
381003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d18 = { 18 };
382003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d19 = { 19 };
383003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d20 = { 20 };
384003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d21 = { 21 };
385003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d22 = { 22 };
386003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d23 = { 23 };
387003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d24 = { 24 };
388003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d25 = { 25 };
389003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d26 = { 26 };
390003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d27 = { 27 };
391003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d28 = { 28 };
392003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d29 = { 29 };
393003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d30 = { 30 };
394003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst DwVfpRegister d31 = { 31 };
39513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
396169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q0  = {  0 };
397169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q1  = {  1 };
398169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q2  = {  2 };
399169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q3  = {  3 };
400169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q4  = {  4 };
401169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q5  = {  5 };
402169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q6  = {  6 };
403169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q7  = {  7 };
404169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q8  = {  8 };
405169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q9  = {  9 };
406169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q10 = { 10 };
407169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q11 = { 11 };
408169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q12 = { 12 };
409169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q13 = { 13 };
410169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q14 = { 14 };
411169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst QwNeonRegister q15 = { 15 };
412169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
413fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
414659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// Aliases for double registers.  Defined using #define instead of
415659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// "static const DwVfpRegister&" because Clang complains otherwise when a
416659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// compilation unit that includes this header doesn't use the variables.
417659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kFirstCalleeSavedDoubleReg d8
418659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kLastCalleeSavedDoubleReg d15
419659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kDoubleRegZero d14
420659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org#define kScratchDoubleReg d15
421ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Coprocessor register
42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstruct CRegister {
4254a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is_valid() const { return 0 <= code_ && code_ < 16; }
4264a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(CRegister creg) const { return code_ == creg.code_; }
4274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
428e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
42943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return code_;
43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
432e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return 1 << code_;
43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4365c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unfortunately we can't make this private in a struct.
43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int code_;
43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
441ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister no_creg = { -1 };
442ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
443ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr0  = {  0 };
444ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr1  = {  1 };
445ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr2  = {  2 };
446ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr3  = {  3 };
447ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr4  = {  4 };
448ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr5  = {  5 };
449ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr6  = {  6 };
450ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr7  = {  7 };
451ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr8  = {  8 };
452ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr9  = {  9 };
453ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr10 = { 10 };
454ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr11 = { 11 };
455ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr12 = { 12 };
456ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr13 = { 13 };
457ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr14 = { 14 };
458ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgconst CRegister cr15 = { 15 };
45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Coprocessor number
46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum Coprocessor {
46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p0  = 0,
46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p1  = 1,
46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p2  = 2,
46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p3  = 3,
46743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p4  = 4,
46843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p5  = 5,
46943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p6  = 6,
47043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p7  = 7,
47143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p8  = 8,
47243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p9  = 9,
47343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p10 = 10,
47443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p11 = 11,
47543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p12 = 12,
47643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p13 = 13,
47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p14 = 14,
47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  p15 = 15
47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Machine instruction Operands
48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Class Operand represents a shifter operand in data processing instructions
48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Operand BASE_EMBEDDED {
48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
48843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // immediate
489236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  INLINE(explicit Operand(int32_t immediate,
49059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org         RelocInfo::Mode rmode = RelocInfo::NONE32));
491ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  INLINE(static Operand Zero()) {
492ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    return Operand(static_cast<int32_t>(0));
493ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  }
49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(explicit Operand(const ExternalReference& f));
49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Handle<Object> handle);
49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(explicit Operand(Smi* value));
49743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rm
49943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(explicit Operand(Register rm));
50043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rm <shift_op> shift_imm
50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register rm, ShiftOp shift_op, int shift_imm);
503bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static Operand SmiUntag(Register rm)) {
504bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return Operand(rm, ASR, kSmiTagSize);
505bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
506bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static Operand PointerOffsetFromSmiKey(Register key)) {
507bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
508bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize);
509bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
510bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) {
511bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2);
512bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize);
513bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
51443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // rm <shift_op> rs
51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register rm, ShiftOp shift_op, Register rs);
51743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // Return true if this is a register operand.
51931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  INLINE(bool is_reg() const);
52031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
521d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Return the number of actual instructions required to implement the given
522d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // instruction for this particular operand. This can be a single instruction,
523d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // if no load into the ip register is necessary, or anything between 2 and 4
524d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // instructions when we need to load from the constant pool (depending upon
525d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // whether the constant pool entry is in the small or extended section). If
526b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // the instruction this operand is used for is a MOV or MVN instruction the
527b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // actual instruction to use is required for this calculation. For other
528b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // instructions instr is ignored.
529d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  //
530d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // The value returned is only valid as long as no entries are added to the
531d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // constant pool between this call and the actual instruction being emitted.
532d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  int instructions_required(const Assembler* assembler, Instr instr = 0) const;
533874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  bool must_output_reloc_info(const Assembler* assembler) const;
5342c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
5352c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  inline int32_t immediate() const {
536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!rm_.is_valid());
5372c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    return imm32_;
5382c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  }
5392c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
54031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  Register rm() const { return rm_; }
541ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  Register rs() const { return rs_; }
542ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  ShiftOp shift_op() const { return shift_op_; }
54331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rm_;
54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rs_;
54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ShiftOp shift_op_;
54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg
54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int32_t imm32_;  // valid if rm_ == no_reg
550236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  RelocInfo::Mode rmode_;
55143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Class MemOperand represents a memory operand in load and store instructions
55743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass MemOperand BASE_EMBEDDED {
55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
55943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- offset]      Offset/NegOffset
56043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- offset]!     PreIndex/NegPreIndex
56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn], +/- offset     PostIndex/NegPostIndex
56243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // offset is any signed 32-bit value; offset is first loaded to register ip if
56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // it does not fit the addressing mode (12-bit unsigned and sign bit)
56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit MemOperand(Register rn, int32_t offset = 0, AddrMode am = Offset);
56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm]          Offset/NegOffset
56743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm]!         PreIndex/NegPreIndex
56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn], +/- rm         PostIndex/NegPostIndex
56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit MemOperand(Register rn, Register rm, AddrMode am = Offset);
57043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm <shift_op> shift_imm]      Offset/NegOffset
57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn +/- rm <shift_op> shift_imm]!     PreIndex/NegPreIndex
57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [rn], +/- rm <shift_op> shift_imm     PostIndex/NegPostIndex
57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit MemOperand(Register rn, Register rm,
57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      ShiftOp shift_op, int shift_imm, AddrMode am = Offset);
576bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  INLINE(static MemOperand PointerAddressFromSmiKey(Register array,
577bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                                    Register key,
578bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                                    AddrMode am = Offset)) {
579bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
580bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am);
581bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
583720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  void set_offset(int32_t offset) {
584e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(rm_.is(no_reg));
585720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org      offset_ = offset;
586720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  }
587720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
5883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  uint32_t offset() const {
589e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(rm_.is(no_reg));
590720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org      return offset_;
591720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  }
592720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
5939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  Register rn() const { return rn_; }
5949dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  Register rm() const { return rm_; }
59504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  AddrMode am() const { return am_; }
596720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
5973a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  bool OffsetIsUint12Encodable() const {
5983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_);
5993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
6003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rn_;  // base
60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Register rm_;  // register offset
60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int32_t offset_;  // valid if rm_ == no_reg
60543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ShiftOp shift_op_;
60643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg
60743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  AddrMode am_;  // bits P, U, and W
60843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
612169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
613169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Class NeonMemOperand represents a memory operand in load and
614169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// store NEON instructions
615169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgclass NeonMemOperand BASE_EMBEDDED {
616169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org public:
617169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // [rn {:align}]       Offset
618169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // [rn {:align}]!      PostIndex
619169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0);
620169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
621169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // [rn {:align}], rm   PostIndex
622169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  explicit NeonMemOperand(Register rn, Register rm, int align = 0);
623169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
624169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rn() const { return rn_; }
625169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rm() const { return rm_; }
626169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int align() const { return align_; }
627169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
628169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org private:
629169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void SetAlignment(int align);
630169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
631169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rn_;  // base
632169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Register rm_;  // register increment
633169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int align_;
634169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
635169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
636169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
637169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Class NeonListOperand represents a list of NEON registers
638169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgclass NeonListOperand BASE_EMBEDDED {
639169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org public:
640169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  explicit NeonListOperand(DoubleRegister base, int registers_count = 1);
641169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  DoubleRegister base() const { return base_; }
642169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonListType type() const { return type_; }
643169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org private:
644169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  DoubleRegister base_;
645169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonListType type_;
646169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
647169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
648763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
649763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org// Class used to build a constant pool.
650763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgclass ConstantPoolBuilder BASE_EMBEDDED {
651763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org public:
6525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  ConstantPoolBuilder();
653d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ConstantPoolArray::LayoutSection AddEntry(Assembler* assm,
654d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                                            const RelocInfo& rinfo);
655763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void Relocate(int pc_delta);
656763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  bool IsEmpty();
6579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<ConstantPoolArray> New(Isolate* isolate);
658763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void Populate(Assembler* assm, ConstantPoolArray* constant_pool);
659763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
660d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  inline ConstantPoolArray::LayoutSection current_section() const {
661d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return current_section_;
662d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
663d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
664d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  inline ConstantPoolArray::NumberOfEntries* number_of_entries(
665d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      ConstantPoolArray::LayoutSection section) {
666d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return &number_of_entries_[section];
667d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
668d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
669d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  inline ConstantPoolArray::NumberOfEntries* small_entries() {
670d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return number_of_entries(ConstantPoolArray::SMALL_SECTION);
671d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
672d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
673d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  inline ConstantPoolArray::NumberOfEntries* extended_entries() {
674d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return number_of_entries(ConstantPoolArray::EXTENDED_SECTION);
675d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
676763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
677763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org private:
678d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  struct ConstantPoolEntry {
679d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section,
680d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                      int merged_index)
681d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        : rinfo_(rinfo), section_(section), merged_index_(merged_index) {}
682d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
683d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    RelocInfo rinfo_;
684d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    ConstantPoolArray::LayoutSection section_;
685d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    int merged_index_;
686d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  };
687d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
688d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode);
689d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
690d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  std::vector<ConstantPoolEntry> entries_;
691d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ConstantPoolArray::LayoutSection current_section_;
692d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ConstantPoolArray::NumberOfEntries number_of_entries_[2];
693763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org};
694763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
6956ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgstruct VmovIndex {
6966ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  unsigned char index;
6976ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org};
6986ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgconst VmovIndex VmovIndexLo = { 0 };
6996ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgconst VmovIndex VmovIndexHi = { 1 };
700378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
701ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Assembler : public AssemblerBase {
70243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
70343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create an assembler. Instructions and relocation information are emitted
70443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // into a buffer, with the instructions starting from the beginning and the
70543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // relocation information starting from the end of the buffer. See CodeDesc
70643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for a detailed comment on the layout (globals.h).
70743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
70843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is NULL, the assembler allocates and grows its own
70943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // buffer, and buffer_size determines the initial buffer size. The buffer is
71043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // owned by the assembler and deallocated upon destruction of the assembler.
71143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
71243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is not NULL, the assembler uses the provided buffer
71343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for code generation and assumes its size to be buffer_size. If the buffer
71443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is too small, a fatal error occurs. No deallocation of the buffer is done
71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // upon destruction of the assembler.
716c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Assembler(Isolate* isolate, void* buffer, int buffer_size);
7178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  virtual ~Assembler();
71843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // GetCode emits any pending (non-emitted) code and fills the descriptor
72043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // desc. GetCode() is idempotent; it returns the same result if no other
7213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Assembler functions are invoked in between GetCode() calls.
72243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GetCode(CodeDesc* desc);
72343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label operations & relative jumps (PPUM Appendix D)
72543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
72643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Takes a branch opcode (cc) and a label (L) and generates
72743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // either a backward branch or a forward branch and links it
72843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the label fixup chain. Usage:
72943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
73043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label L;    // unbound label
73143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // forward branch to unbound label
73243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // bind label to the current pc
73343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // backward branch to bound label
73443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // illegal: a label may be bound only once
73543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note: The same Label can be used for forward and backward branches
73743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // but it may be bound only once.
73843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind(Label* L);  // binds an unbound label L to the current code position
74043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns the branch offset to the given label from the current code position
74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Links the label to the current position if it is still unbound
743769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // Manages the jump elimination optimization if the second parameter is true.
744769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  int branch_offset(Label* L, bool jump_elimination_allowed);
74543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
746d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Returns true if the given pc address is the start of a constant pool load
747d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // instruction sequence.
748d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  INLINE(static bool is_constant_pool_load(Address pc));
749d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
75043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the address in the constant pool of the code target address used by
75189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // the branch/call instruction at pc, or the object in a mov.
752975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  INLINE(static Address constant_pool_entry_address(
75397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    Address pc, ConstantPoolArray* constant_pool));
75497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/Modify the code target address in the branch/call instruction at pc.
75697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  INLINE(static Address target_address_at(Address pc,
75797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                          ConstantPoolArray* constant_pool));
75897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  INLINE(static void set_target_address_at(Address pc,
75997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                           ConstantPoolArray* constant_pool,
7606a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           Address target,
7616a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           ICacheFlushMode icache_flush_mode =
7626a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                               FLUSH_ICACHE_IF_NEEDED));
76397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  INLINE(static Address target_address_at(Address pc, Code* code)) {
76497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
76597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    return target_address_at(pc, constant_pool);
76697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
76797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  INLINE(static void set_target_address_at(Address pc,
76897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                           Code* code,
7696a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           Address target,
7706a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           ICacheFlushMode icache_flush_mode =
7716a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                               FLUSH_ICACHE_IF_NEEDED)) {
77297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
7736a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    set_target_address_at(pc, constant_pool, target, icache_flush_mode);
77497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Return the code target address at a call site from the return address
77789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // of that call in the instruction stream.
77889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  INLINE(static Address target_address_from_return_address(Address pc));
77989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
78089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Given the address of the beginning of a call, return the address
78189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // in the instruction stream that the call will return from.
78289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  INLINE(static Address return_address_from_call_start(Address pc));
78389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
7849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  // Return the code target address of the patch debug break slot
7859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  INLINE(static Address break_address_from_return_address(Address pc));
7869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
787c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This sets the branch destination (which is in the constant pool on ARM).
788c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This is for calls and branches within generated code.
78988aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  inline static void deserialization_set_special_target_at(
79097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      Address constant_pool_entry, Code* code, Address target);
7913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
7923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Here we are patching the address in the constant pool, not the actual call
7933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // instruction.  The address in the constant pool is the same size as a
7943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // pointer.
79588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  static const int kSpecialTargetSize = kPointerSize;
7963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
7974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Size of an instruction.
7984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  static const int kInstrSize = sizeof(Instr);
7994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
800911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // Distance between start of patched return sequence and the emitted address
801911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // to jump to.
8022356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Patched return sequence is:
803cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  //  ldr  ip, [pc, #0]   @ emited address and start
804cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  //  blx  ip
805cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  static const int kPatchReturnSequenceAddressOffset =  0 * kInstrSize;
80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8072356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Distance between start of patched debug break slot and the emitted address
8082356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // to jump to.
8092356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Patched debug break slot code is:
8102356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  //  ldr  ip, [pc, #0]   @ emited address and start
8112356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  //  blx  ip
8122356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kPatchDebugBreakSlotAddressOffset =  0 * kInstrSize;
8132356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
81489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
81589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
81618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Difference between address of current opcode and value read from pc
81718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // register.
81818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  static const int kPcLoadDelta = 8;
81918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
8202356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kJSReturnSequenceInstructions = 4;
8212356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kDebugBreakSlotInstructions = 3;
8222356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kDebugBreakSlotLength =
8232356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      kDebugBreakSlotInstructions * kInstrSize;
82443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
82643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generation
82743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Insert the smallest number of nop instructions
82943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // possible to align the pc offset to a multiple
83043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of m. m must be a power of 2 (>= 4).
83143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Align(int m);
8325ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Aligns code to something that's optimal for a jump target for the platform.
8335ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void CodeTargetAlign();
83443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Branch instructions
83643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void b(int branch_offset, Condition cond = al);
83743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bl(int branch_offset, Condition cond = al);
83843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void blx(int branch_offset);  // v5 and above
83943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void blx(Register target, Condition cond = al);  // v5 and above
84043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bx(Register target, Condition cond = al);  // v5 and above, plus v4t
84143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convenience branch instructions using labels
843769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void b(Label* L, Condition cond = al)  {
844769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com    b(branch_offset(L, cond == al), cond);
845769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  }
846769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void b(Condition cond, Label* L)  { b(branch_offset(L, cond == al), cond); }
847769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void bl(Label* L, Condition cond = al)  { bl(branch_offset(L, false), cond); }
848769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void bl(Condition cond, Label* L)  { bl(branch_offset(L, false), cond); }
849769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void blx(Label* L)  { blx(branch_offset(L, false)); }  // v5 and above
85043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Data-processing instructions
8525c838251403b0be9a882540f1922577abba4c872ager@chromium.org
85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(Register dst, Register src1, const Operand& src2,
85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            SBit s = LeaveCC, Condition cond = al);
85543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void eor(Register dst, Register src1, const Operand& src2,
85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(Register dst, Register src1, const Operand& src2,
86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
861b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void sub(Register dst, Register src1, Register src2,
862b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org           SBit s = LeaveCC, Condition cond = al) {
863b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    sub(dst, src1, Operand(src2), s, cond);
864b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void rsb(Register dst, Register src1, const Operand& src2,
86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
86843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void add(Register dst, Register src1, const Operand& src2,
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
87182dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org  void add(Register dst, Register src1, Register src2,
87282dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org           SBit s = LeaveCC, Condition cond = al) {
87382dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org    add(dst, src1, Operand(src2), s, cond);
87482dbbabc05f6729248cef210931fe34556fd7ca0sgjesse@chromium.org  }
87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void adc(Register dst, Register src1, const Operand& src2,
87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sbc(Register dst, Register src1, const Operand& src2,
88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
88143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void rsc(Register dst, Register src1, const Operand& src2,
88343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void tst(Register src1, const Operand& src2, Condition cond = al);
886b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void tst(Register src1, Register src2, Condition cond = al) {
887b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    tst(src1, Operand(src2), cond);
888b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void teq(Register src1, const Operand& src2, Condition cond = al);
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register src1, const Operand& src2, Condition cond = al);
893b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void cmp(Register src1, Register src2, Condition cond = al) {
894b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    cmp(src1, Operand(src2), cond);
895b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
896496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al);
89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmn(Register src1, const Operand& src2, Condition cond = al);
89943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void orr(Register dst, Register src1, const Operand& src2,
90143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
902b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void orr(Register dst, Register src1, Register src2,
903b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org           SBit s = LeaveCC, Condition cond = al) {
904b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    orr(dst, src1, Operand(src2), s, cond);
905b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
90643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, const Operand& src,
90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
909b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {
910b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    mov(dst, Operand(src), s, cond);
911b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9134a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // Load the position of the label relative to the generated code object
9144a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // pointer in a register.
9154a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  void mov_label_offset(Register dst, Label* label);
9164a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
9175ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // ARMv7 instructions for loading a 32 bit immediate in two instructions.
9185de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  // The constant for movw and movt should be in the range 0-0xffff.
9195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void movw(Register reg, uint32_t immediate, Condition cond = al);
9205ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void movt(Register reg, uint32_t immediate, Condition cond = al);
9215ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bic(Register dst, Register src1, const Operand& src2,
92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
92443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mvn(Register dst, const Operand& src,
92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
92743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Shift instructions
9297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void asr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
9317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org           Condition cond = al) {
9327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (src2.is_reg()) {
9337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      mov(dst, Operand(src1, ASR, src2.rm()), s, cond);
9347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
9357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      mov(dst, Operand(src1, ASR, src2.immediate()), s, cond);
9367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
9377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
9387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void lsl(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
9407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org           Condition cond = al) {
9417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (src2.is_reg()) {
9427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      mov(dst, Operand(src1, LSL, src2.rm()), s, cond);
9437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
9447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      mov(dst, Operand(src1, LSL, src2.immediate()), s, cond);
9457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
9467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
9477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void lsr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC,
9497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org           Condition cond = al) {
9507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (src2.is_reg()) {
9517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      mov(dst, Operand(src1, LSR, src2.rm()), s, cond);
9527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
9537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      mov(dst, Operand(src1, LSR, src2.immediate()), s, cond);
9547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
9557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
9567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Multiply instructions
95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mla(Register dst, Register src1, Register src2, Register srcA,
96043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void mls(Register dst, Register src1, Register src2, Register srcA,
96333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org           Condition cond = al);
96433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
96533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void sdiv(Register dst, Register src1, Register src2,
96633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org            Condition cond = al);
96733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
9687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void udiv(Register dst, Register src1, Register src2, Condition cond = al);
9697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mul(Register dst, Register src1, Register src2,
97143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           SBit s = LeaveCC, Condition cond = al);
97243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void smlal(Register dstL, Register dstH, Register src1, Register src2,
97443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
97543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void smull(Register dstL, Register dstH, Register src1, Register src2,
97743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
97843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void umlal(Register dstL, Register dstH, Register src1, Register src2,
98043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
98143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
98243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void umull(Register dstL, Register dstH, Register src1, Register src2,
98343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             SBit s = LeaveCC, Condition cond = al);
98443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
98543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Miscellaneous arithmetic instructions
98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
98743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void clz(Register dst, Register src, Condition cond = al);  // v5 and above
98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
989ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Saturating instructions. v6 and above.
990ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
991ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Unsigned saturate.
992ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
993ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Saturate an optionally shifted signed value to an unsigned range.
994ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
995ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   usat dst, #satpos, src
996ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   usat dst, #satpos, src, lsl #sh
997ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   usat dst, #satpos, src, asr #sh
998ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
999ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // Register dst will contain:
1000ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
1001ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   0,                 if s < 0
1002ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   (1 << satpos) - 1, if s > ((1 << satpos) - 1)
1003ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //   s,                 otherwise
1004ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  //
1005ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // where s is the contents of src after shifting (if used.)
1006ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  void usat(Register dst, int satpos, const Operand& src, Condition cond = al);
1007ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
100830ce411529579186181838984710b0b0980857aaricow@chromium.org  // Bitfield manipulation instructions. v7 and above.
100930ce411529579186181838984710b0b0980857aaricow@chromium.org
101030ce411529579186181838984710b0b0980857aaricow@chromium.org  void ubfx(Register dst, Register src, int lsb, int width,
101130ce411529579186181838984710b0b0980857aaricow@chromium.org            Condition cond = al);
101230ce411529579186181838984710b0b0980857aaricow@chromium.org
101330ce411529579186181838984710b0b0980857aaricow@chromium.org  void sbfx(Register dst, Register src, int lsb, int width,
101430ce411529579186181838984710b0b0980857aaricow@chromium.org            Condition cond = al);
101530ce411529579186181838984710b0b0980857aaricow@chromium.org
101630ce411529579186181838984710b0b0980857aaricow@chromium.org  void bfc(Register dst, int lsb, int width, Condition cond = al);
101730ce411529579186181838984710b0b0980857aaricow@chromium.org
101830ce411529579186181838984710b0b0980857aaricow@chromium.org  void bfi(Register dst, Register src, int lsb, int width,
101930ce411529579186181838984710b0b0980857aaricow@chromium.org           Condition cond = al);
102030ce411529579186181838984710b0b0980857aaricow@chromium.org
1021169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void pkhbt(Register dst, Register src1, const Operand& src2,
1022169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org             Condition cond = al);
1023169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1024169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void pkhtb(Register dst, Register src1, const Operand& src2,
1025169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org             Condition cond = al);
1026169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1027169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void uxtb(Register dst, const Operand& src, Condition cond = al);
1028169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1029169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void uxtab(Register dst, Register src1, const Operand& src2,
1030169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org             Condition cond = al);
1031169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1032169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void uxtb16(Register dst, const Operand& src, Condition cond = al);
1033169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
103443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Status register access instructions
103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mrs(Register dst, SRegister s, Condition cond = al);
103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);
103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Load/Store instructions
104043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldr(Register dst, const MemOperand& src, Condition cond = al);
104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void str(Register src, const MemOperand& dst, Condition cond = al);
104243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrb(Register dst, const MemOperand& src, Condition cond = al);
104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void strb(Register src, const MemOperand& dst, Condition cond = al);
104443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrh(Register dst, const MemOperand& src, Condition cond = al);
104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void strh(Register src, const MemOperand& dst, Condition cond = al);
104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
104743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
10489155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  void ldrd(Register dst1,
10499155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Register dst2,
10509155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            const MemOperand& src, Condition cond = al);
10519155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  void strd(Register src1,
10529155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Register src2,
10539155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            const MemOperand& dst, Condition cond = al);
105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1055169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Preload instructions
1056169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void pld(const MemOperand& address);
1057169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Load/Store multiple instructions
105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Exception-generating instructions and debugging support
1063e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void stop(const char* msg,
1064e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org            Condition cond = al,
1065e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org            int32_t code = kDefaultStopCode);
106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bkpt(uint32_t imm16);  // v5 and above
1068e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void svc(uint32_t imm24, Condition cond = al);
106943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Coprocessor instructions
107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cdp(Coprocessor coproc, int opcode_1,
107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           CRegister crd, CRegister crn, CRegister crm,
107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           int opcode_2, Condition cond = al);
107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cdp2(Coprocessor coproc, int opcode_1,
107743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            CRegister crd, CRegister crn, CRegister crm,
107843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int opcode_2);  // v5 and above
107943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mcr(Coprocessor coproc, int opcode_1,
108143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           Register rd, CRegister crn, CRegister crm,
108243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           int opcode_2 = 0, Condition cond = al);
108343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mcr2(Coprocessor coproc, int opcode_1,
108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            Register rd, CRegister crn, CRegister crm,
108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int opcode_2 = 0);  // v5 and above
108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mrc(Coprocessor coproc, int opcode_1,
108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           Register rd, CRegister crn, CRegister crm,
109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           int opcode_2 = 0, Condition cond = al);
109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
109243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mrc2(Coprocessor coproc, int opcode_1,
109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            Register rd, CRegister crn, CRegister crm,
109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            int opcode_2 = 0);  // v5 and above
109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,
109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           LFlag l = Short, Condition cond = al);
109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc(Coprocessor coproc, CRegister crd, Register base, int option,
109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           LFlag l = Short, Condition cond = al);
110043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,
110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            LFlag l = Short);  // v5 and above
110343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
110443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            LFlag l = Short);  // v5 and above
110543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1106c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Support for VFP.
1107003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // All these APIs support S0 to S31 and D0 to D31.
1108c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
1109b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void vldr(const DwVfpRegister dst,
1110b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Register base,
11113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
11123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
11133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vldr(const DwVfpRegister dst,
11143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& src,
1115b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Condition cond = al);
11165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
11175d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vldr(const SwVfpRegister dst,
11185d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            const Register base,
11193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
11203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
11213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vldr(const SwVfpRegister dst,
11223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& src,
11235d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            const Condition cond = al);
11245d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
1125b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void vstr(const DwVfpRegister src,
1126b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Register base,
11273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
11283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
11293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vstr(const DwVfpRegister src,
11303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& dst,
1131b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            const Condition cond = al);
113269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
11330b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  void vstr(const SwVfpRegister src,
11340b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org            const Register base,
11353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            int offset,
11363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const Condition cond = al);
11373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void vstr(const SwVfpRegister src,
11383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            const MemOperand& dst,
11390b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org            const Condition cond = al);
11400b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
114174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vldm(BlockAddrMode am,
114274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
114374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister first,
114474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister last,
114574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
114674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
114774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vstm(BlockAddrMode am,
114874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
114974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister first,
115074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            DwVfpRegister last,
115174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
115274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
115374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vldm(BlockAddrMode am,
115474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
115574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister first,
115674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister last,
115774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
115874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
115974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void vstm(BlockAddrMode am,
116074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Register base,
116174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister first,
116274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            SwVfpRegister last,
116374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org            Condition cond = al);
116474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
116569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  void vmov(const DwVfpRegister dst,
11666a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org            double imm,
116771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org            const Register scratch = no_reg);
11686a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  void vmov(const SwVfpRegister dst,
11696a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org            const SwVfpRegister src,
11706a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org            const Condition cond = al);
11716a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  void vmov(const DwVfpRegister dst,
117269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org            const DwVfpRegister src,
117369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org            const Condition cond = al);
117413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const DwVfpRegister dst,
11756ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org            const VmovIndex index,
1176003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org            const Register src,
1177003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org            const Condition cond = al);
1178fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void vmov(const Register dst,
1179fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            const VmovIndex index,
1180fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            const DwVfpRegister src,
1181fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            const Condition cond = al);
1182003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  void vmov(const DwVfpRegister dst,
118313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Register src1,
118413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Register src2,
118513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
118613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const Register dst1,
118713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Register dst2,
118813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src,
1189c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
119013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const SwVfpRegister dst,
1191c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Register src,
1192c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
119313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmov(const Register dst,
119413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const SwVfpRegister src,
119513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
11965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f64_s32(const DwVfpRegister dst,
11975d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
119883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
11995d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
12005d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f32_s32(const SwVfpRegister dst,
12015d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
120283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
12035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
12045d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f64_u32(const DwVfpRegister dst,
12055d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
120683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
12075d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
12085d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_s32_f64(const SwVfpRegister dst,
12095d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const DwVfpRegister src,
121083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
12115d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
12125d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_u32_f64(const SwVfpRegister dst,
12135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const DwVfpRegister src,
121483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
12155d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
12165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f64_f32(const DwVfpRegister dst,
12175d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const SwVfpRegister src,
121883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
12195d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
12205d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void vcvt_f32_f64(const SwVfpRegister dst,
12215d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const DwVfpRegister src,
122283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                    VFPConversionMode mode = kDefaultRoundToZero,
12235d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                    const Condition cond = al);
1224bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  void vcvt_f64_s32(const DwVfpRegister dst,
1225bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                    int fraction_bits,
1226bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                    const Condition cond = al);
122713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
1228badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  void vneg(const DwVfpRegister dst,
1229badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org            const DwVfpRegister src,
1230badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org            const Condition cond = al);
12317a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org  void vabs(const DwVfpRegister dst,
12327a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org            const DwVfpRegister src,
12337a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org            const Condition cond = al);
123413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vadd(const DwVfpRegister dst,
123513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
123613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
123713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
123813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vsub(const DwVfpRegister dst,
123913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
124013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
124113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
124213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vmul(const DwVfpRegister dst,
124313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
124413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
124513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
1246fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  void vmla(const DwVfpRegister dst,
1247fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            const DwVfpRegister src1,
1248fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            const DwVfpRegister src2,
1249fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            const Condition cond = al);
12508432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  void vmls(const DwVfpRegister dst,
12518432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            const DwVfpRegister src1,
12528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            const DwVfpRegister src2,
12538432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            const Condition cond = al);
125413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vdiv(const DwVfpRegister dst,
125513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src1,
125613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
125713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const Condition cond = al);
125813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void vcmp(const DwVfpRegister src1,
125913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org            const DwVfpRegister src2,
1260c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
1261ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  void vcmp(const DwVfpRegister src1,
1262ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org            const double src2,
1263ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org            const Condition cond = al);
1264c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  void vmrs(const Register dst,
1265c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            const Condition cond = al);
126601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  void vmsr(const Register dst,
126701fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org            const Condition cond = al);
126832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  void vsqrt(const DwVfpRegister dst,
126932d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org             const DwVfpRegister src,
127032d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org             const Condition cond = al);
1271c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
1272169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Support for NEON.
1273169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // All these APIs support D0 to D31 and Q0 to Q15.
1274169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1275169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void vld1(NeonSize size,
1276169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonListOperand& dst,
1277169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonMemOperand& src);
1278169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void vst1(NeonSize size,
1279169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonListOperand& src,
1280169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            const NeonMemOperand& dst);
1281169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src);
1282169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
128343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Pseudo instructions
1284beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
1285beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // Different nop operations are used by the code generator to detect certain
1286beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // states of the generated code.
1287beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  enum NopMarkerTypes {
1288beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    NON_MARKING_NOP = 0,
1289beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    DEBUG_BREAK_NOP,
1290beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    // IC markers.
1291beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    PROPERTY_ACCESS_INLINED,
1292beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    PROPERTY_ACCESS_INLINED_CONTEXT,
1293beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1294beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    // Helper values.
1295beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    LAST_CODE_MARKER,
1296beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1297beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  };
1298beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
1299beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  void nop(int type = 0);   // 0 is the default non-marking type.
130043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1301b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  void push(Register src, Condition cond = al) {
1302b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    str(src, MemOperand(sp, 4, NegPreIndex), cond);
130331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  }
130431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
1305c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  void pop(Register dst, Condition cond = al) {
1306c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    ldr(dst, MemOperand(sp, 4, PostIndex), cond);
130743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
130843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
130931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  void pop() {
131031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    add(sp, sp, Operand(kPointerSize));
131143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
131243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Jump unconditionally to given label.
131443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void jmp(Label* L) { b(L, al); }
131543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Check the code size generated from label to here.
13174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int SizeOfCodeGeneratedSince(Label* label) {
13184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return pc_offset() - label->pos();
13194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
13204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
13214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Check the number of instructions generated from label to here.
13224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int InstructionsGeneratedSince(Label* label) {
13234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return SizeOfCodeGeneratedSince(label) / kInstrSize;
13244af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1326c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Check whether an immediate fits an addressing mode 1 instruction.
13277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static bool ImmediateFitsAddrMode1Instruction(int32_t imm32);
1328c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
13299ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  // Check whether an immediate fits an addressing mode 2 instruction.
13309ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  bool ImmediateFitsAddrMode2Instruction(int32_t imm32);
13319ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
1332013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Class for scoping postponing the constant pool generation.
1333013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  class BlockConstPoolScope {
1334013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org   public:
1335013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1336013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org      assem_->StartBlockConstPool();
1337013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    }
1338013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    ~BlockConstPoolScope() {
1339013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org      assem_->EndBlockConstPool();
1340013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    }
1341013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
1342013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org   private:
1343013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    Assembler* assem_;
1344013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
1345013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
1346013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  };
1347c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugging
134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Mark address of the ExitJSFrame code.
13514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void RecordJSReturn();
13524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
13532356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Mark address of a debug break slot.
13542356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  void RecordDebugBreakSlot();
13552356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
13568e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Record the AST id of the CallIC being compiled, so that it can be placed
13578e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // in the relocation information.
1358471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void SetRecordedAstId(TypeFeedbackId ast_id) {
1359e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(recorded_ast_id_.IsNone());
1360717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    recorded_ast_id_ = ast_id;
1361717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  }
1362717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
1363471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  TypeFeedbackId RecordedAstId() {
1364e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!recorded_ast_id_.IsNone());
1365717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    return recorded_ast_id_;
1366717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  }
1367717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
1368471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
13698e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Record a comment relocation entry that can be used by a disassembler.
1371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Use --code-comments to enable.
137243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void RecordComment(const char* msg);
137343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Record the emission of a constant pool.
13755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  //
13765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The emission of constant pool depends on the size of the code generated and
13775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // the number of RelocInfo recorded.
13785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The Debug mechanism needs to map code offsets between two versions of a
13795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // function, compiled with and without debugger support (see for example
13805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Debug::PrepareForBreakPoints()).
13815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Compiling functions with debugger support generates additional code
1382d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  // (DebugCodegen::GenerateSlot()). This may affect the emission of the
1383d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  // constant pools and cause the version of the code with debugger support to
1384d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  // have constant pools generated in different places.
13855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Recording the position and size of emitted constant pools allows to
13865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // correctly compute the offset mappings between the different versions of a
13875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // function in all situations.
13885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  //
13895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The parameter indicates the size of the constant pool (in bytes), including
13905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // the marker and branch over the data.
13915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void RecordConstPool(int size);
13925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
13930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Writes a single byte or word of data in the code stream.  Used
13940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // for inline tables, e.g., jump-tables. The constant pool should be
13950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // emitted before any use of db and dd to ensure that constant pools
13960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // are not emitted as part of the tables generated.
1397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void db(uint8_t data);
1398a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void dd(uint32_t data);
1399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1400057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // Emits the address of the code stub's first instruction.
1401057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  void emit_code_stub_address(Code* stub);
1402057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
1403f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
140443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/patch instructions
1406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void instr_at_put(int pos, Instr instr) {
1408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
14104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1411013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static void instr_at_put(byte* pc, Instr instr) {
141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *reinterpret_cast<Instr*>(pc) = instr;
141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1414496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Condition GetCondition(Instr instr);
1415013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static bool IsBranch(Instr instr);
1416013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static int GetBranchOffset(Instr instr);
1417013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static bool IsLdrRegisterImmediate(Instr instr);
14184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static bool IsVldrDRegisterImmediate(Instr instr);
1419975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  static Instr GetConsantPoolLoadPattern();
1420d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  static Instr GetConsantPoolLoadMask();
1421d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  static bool IsLdrPpRegOffset(Instr instr);
1422d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  static Instr GetLdrPpRegOffsetPattern();
1423763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  static bool IsLdrPpImmediateOffset(Instr instr);
1424763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  static bool IsVldrDPpImmediateOffset(Instr instr);
1425013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static int GetLdrRegisterImmediateOffset(Instr instr);
14264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static int GetVldrDRegisterImmediateOffset(Instr instr);
1427013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
14284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
1429ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static bool IsStrRegisterImmediate(Instr instr);
1430ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
1431ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static bool IsAddRegisterImmediate(Instr instr);
1432ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
14339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static Register GetRd(Instr instr);
1434496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Register GetRn(Instr instr);
1435496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Register GetRm(Instr instr);
14369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsPush(Instr instr);
14379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsPop(Instr instr);
14389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsStrRegFpOffset(Instr instr);
14399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsLdrRegFpOffset(Instr instr);
14409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsStrRegFpNegOffset(Instr instr);
14419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  static bool IsLdrRegFpNegOffset(Instr instr);
1442beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  static bool IsLdrPcImmediateOffset(Instr instr);
14434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static bool IsVldrDPcImmediateOffset(Instr instr);
1444975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  static bool IsBlxReg(Instr instr);
1445975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  static bool IsBlxIp(Instr instr);
1446496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static bool IsTstImmediate(Instr instr);
1447496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static bool IsCmpRegister(Instr instr);
1448496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static bool IsCmpImmediate(Instr instr);
1449496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static Register GetCmpImmediateRegister(Instr instr);
1450496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static int GetCmpImmediateRawImmediate(Instr instr);
1451beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1452a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  static bool IsMovImmed(Instr instr);
1453a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  static bool IsOrrImmed(Instr instr);
145489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static bool IsMovT(Instr instr);
1455d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  static Instr GetMovTPattern();
145689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static bool IsMovW(Instr instr);
1457d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  static Instr GetMovWPattern();
1458d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  static Instr EncodeMovwImmediate(uint32_t immediate);
1459d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate);
1460a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  static int DecodeShiftImm(Instr instr);
1461a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  static Instr PatchShiftImm(Instr instr, int immed);
1462013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
146340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Constants in pools are accessed via pc relative addressing, which can
14644cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
14654cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // PC-relative loads, thereby defining a maximum distance between the
14664cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // instruction and the accessed constant.
14674cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static const int kMaxDistToIntPool = 4*KB;
14684cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static const int kMaxDistToFPPool = 1*KB;
14694cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // All relocations could be integer, it therefore acts as the limit.
1470ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize;
1471ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize;
147240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
14737b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Postpone the generation of the constant pool for the specified number of
14747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // instructions.
14757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  void BlockConstPoolFor(int instructions);
14767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
14777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Check if is time to emit a constant pool.
1478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void CheckConstPool(bool force_emit, bool require_jump);
1479013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
1480763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Allocate a constant pool of the correct size for the generated code.
14819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
1482763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
1483763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Generate the constant pool for the generated code.
1484763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void PopulateConstantPool(ConstantPoolArray* constant_pool);
1485763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
1486d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  bool is_constant_pool_available() const { return constant_pool_available_; }
148797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
1488d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  bool use_extended_constant_pool() const {
1489d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return constant_pool_builder_.current_section() ==
1490d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org           ConstantPoolArray::EXTENDED_SECTION;
1491d574d98bea4e0a0bee2d1d2d858bf6d24c873d7eyangguo@chromium.org  }
14925d6930502bea0aeb6fdbc4cf04cf87c908ce0127machenbach@chromium.org
1493d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
1494013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org protected:
14958e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Relocation for a type-recording IC has the AST id added to it.  This
14968e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // member variable is a way to pass the information from the call site to
14978e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // the relocation info.
1498471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  TypeFeedbackId recorded_ast_id_;
14998e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1500013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1501013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Decode branch instruction at pos and return branch target pos
150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int target_at(int pos);
150443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
150543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch branch instruction at pos to branch to given branch target pos
150643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void target_at_put(int pos, int target_pos);
150743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Prevent contant pool emission until EndBlockConstPool is called.
15097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Call to this function can be nested but must be followed by an equal
15107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // number of call to EndBlockConstpool.
1511c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  void StartBlockConstPool() {
15127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (const_pool_blocked_nesting_++ == 0) {
15137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Prevent constant pool checks happening by setting the next check to
15147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // the biggest possible offset.
15157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      next_buffer_check_ = kMaxInt;
15167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
1517c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
15187b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
15197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Resume constant pool emission. Need to be called as many time as
15207b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // StartBlockConstPool to have an effect.
1521c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  void EndBlockConstPool() {
15227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (--const_pool_blocked_nesting_ == 0) {
1523ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org#ifdef DEBUG
1524ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // Max pool start (if we need a jump and an alignment).
1525ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      int start = pc_offset() + kInstrSize + 2 * kPointerSize;
15267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Check the constant pool hasn't been blocked for too long.
1527e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK((num_pending_32_bit_reloc_info_ == 0) ||
1528ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org             (start + num_pending_64_bit_reloc_info_ * kDoubleSize <
1529ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org              (first_const_pool_32_use_ + kMaxDistToIntPool)));
1530e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK((num_pending_64_bit_reloc_info_ == 0) ||
1531ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org             (start < (first_const_pool_64_use_ + kMaxDistToFPPool)));
1532ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org#endif
15337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Two cases:
15347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //  * no_const_pool_before_ >= next_buffer_check_ and the emission is
15357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //    still blocked
15367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //  * no_const_pool_before_ < next_buffer_check_ and the next emit will
15377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      //    trigger a check.
15387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      next_buffer_check_ = no_const_pool_before_;
15397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
15407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
15417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
15427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  bool is_const_pool_blocked() const {
15437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return (const_pool_blocked_nesting_ > 0) ||
15447b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org           (pc_offset() < no_const_pool_before_);
1545c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
1546c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org
154797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  void set_constant_pool_available(bool available) {
154897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    constant_pool_available_ = available;
154997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
155097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
155143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
155243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int next_buffer_check_;  // pc offset of next buffer check
155343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
155443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generation
155543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The relocation writer's position is at least kGap bytes below the end of
155643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the generated instructions. This is so that multi-instruction sequences do
155743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not have to check for overflow. The same is true for writes of large
155843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // relocation info entries.
155943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kGap = 32;
156043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
156143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Constant pool generation
156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Pools are emitted in the instruction stream, preferably after unconditional
156343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // jumps or after returns from functions (in dead code locations).
156443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If a long code sequence does not contain unconditional jumps, it is
156543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // necessary to emit the constant pool before the pool gets too far from the
156643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // location it is accessed from. In this case, we emit a jump over the emitted
156743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // constant pool.
156843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Constants in the pool may be addresses of functions that gets relocated;
156943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // if so, a relocation info entry is associated to the constant pool entry.
157043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
157143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Repeated checking whether the constant pool should be emitted is rather
157243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // expensive. By default we only check again once a number of instructions
157343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // has been generated. That also means that the sizing of the buffers is not
157443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // an exact science, and that we rely on some slop to not overrun buffers.
15757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static const int kCheckPoolIntervalInst = 32;
15767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
157743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
157843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1579013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Emission of the constant pool may be blocked in some code sequences.
1580013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  int const_pool_blocked_nesting_;  // Block emission if this is not zero.
1581013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  int no_const_pool_before_;  // Block emission before this pc offset.
158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Keep track of the first instruction requiring a constant pool entry
15847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // since the previous constant pool was emitted.
1585ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int first_const_pool_32_use_;
1586ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int first_const_pool_64_use_;
158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Relocation info generation
158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Each relocation is encoded as a variable size value
159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocInfoWriter reloc_info_writer;
15927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Relocation info records are also used during code generation as temporary
159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // containers for constants and code target addresses until they are emitted
159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the constant pool. These pending relocation info records are temporarily
159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // stored in a separate buffer until a constant pool is emitted.
159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If every instruction in a long sequence is accessing the pool, we need one
159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // pending relocation entry per instruction.
15997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
1600ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // The buffers of pending relocation info.
1601ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo];
1602ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo];
1603ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // Number of pending reloc info entries in the 32 bits buffer.
1604ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int num_pending_32_bit_reloc_info_;
1605ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // Number of pending reloc info entries in the 64 bits buffer.
16064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int num_pending_64_bit_reloc_info_;
160743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1608763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  ConstantPoolBuilder constant_pool_builder_;
1609763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
161041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // The bound position, before this we cannot do instruction elimination.
161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int last_bound_pos_;
161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
161397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // Indicates whether the constant pool can be accessed, which is only possible
161497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // if the pp register points to the current code object's constant pool.
161597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  bool constant_pool_available_;
161697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
161743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code emission
161843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void CheckBuffer();
161943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GrowBuffer();
162043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(Instr x);
162143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
162289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // 32-bit immediate values
1623486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  void move_32_bit_immediate(Register rd,
1624486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                             const Operand& x,
1625486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                             Condition cond = al);
162689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
162743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Instruction generation
162843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
162943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod2(Instr instr, Register rd, const MemOperand& x);
163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod3(Instr instr, Register rd, const MemOperand& x);
163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod4(Instr instr, Register rn, RegList rl);
163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Labels
163543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void print(Label* L);
163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind_to(Label* L, int pos);
163743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void next(Label* L);
163843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  enum UseConstantPoolMode {
164089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    USE_CONSTANT_POOL,
164189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    DONT_USE_CONSTANT_POOL
164289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  };
164389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Record reloc info for current pc_
1645763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1646763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void RecordRelocInfo(const RelocInfo& rinfo);
1647d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ConstantPoolArray::LayoutSection ConstantPoolAddEntry(const RelocInfo& rinfo);
164818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
16494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  friend class RelocInfo;
16504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  friend class CodePatcher;
1651013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  friend class BlockConstPoolScope;
165297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  friend class FrameAndConstantPoolScope;
165397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  friend class ConstantPoolUnavailableScope;
1654f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1655f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder positions_recorder_;
1656f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  friend class PositionsRecorder;
1657f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  friend class EnsureSpace;
1658f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org};
1659f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1660f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1661f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.orgclass EnsureSpace BASE_EMBEDDED {
1662f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org public:
1663f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  explicit EnsureSpace(Assembler* assembler) {
1664f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    assembler->CheckBuffer();
1665f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  }
166643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
166743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1668f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
166943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
167043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16715ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_ARM_ASSEMBLER_ARM_H_
1672