19a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Copyright (c) 1994-2006 Sun Microsystems Inc.
29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// All Rights Reserved.
39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// modification, are permitted provided that the following conditions
69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// are met:
79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// - Redistributions of source code must retain the above copyright notice,
99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// this list of conditions and the following disclaimer.
109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// - Redistribution in binary form must reproduce the above copyright
129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// notice, this list of conditions and the following disclaimer in the
139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// documentation and/or other materials provided with the
149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// distribution.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// - Neither the name of Sun Microsystems or the names of contributors may
179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// be used to endorse or promote products derived from this software without
189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// specific prior written permission.
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OF THE POSSIBILITY OF SUCH DAMAGE.
329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
33b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// The original source code covered by the above license above has been
34b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// modified significantly by Google Inc.
35b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM
409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm/assembler-arm-inl.h"
4221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h"
435de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/cpu.h"
44196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h"
45196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h"
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// Get the CPU features enabled by the build. For cross compilation the
51b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS
52fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// can be defined to enable ARMv7 and VFPv3 instructions when building the
53fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// snapshot.
54b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgstatic unsigned CpuFeaturesImpliedByCompiler() {
55b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  unsigned answer = 0;
565d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#ifdef CAN_USE_ARMV7_INSTRUCTIONS
57874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_armv7) answer |= 1u << ARMv7;
58b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#endif  // CAN_USE_ARMV7_INSTRUCTIONS
59b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#ifdef CAN_USE_VFP3_INSTRUCTIONS
60874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7;
61b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#endif  // CAN_USE_VFP3_INSTRUCTIONS
62003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#ifdef CAN_USE_VFP32DREGS
63874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS;
64003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#endif  // CAN_USE_VFP32DREGS
65a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org#ifdef CAN_USE_NEON
66874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_neon) answer |= 1u << NEON;
67a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org#endif  // CAN_USE_VFP32DREGS
68e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if ((answer & (1u << ARMv7)) && FLAG_enable_unaligned_accesses) {
6989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    answer |= 1u << UNALIGNED_ACCESSES;
7089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
71fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
725d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  return answer;
735d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
745d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
755d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
76874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.orgvoid CpuFeatures::ProbeImpl(bool cross_compile) {
77874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  supported_ |= CpuFeaturesImpliedByCompiler();
78874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  cache_line_size_ = 64;
79e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
80874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  // Only use statically determined features for cross compile (snapshot).
81874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (cross_compile) return;
82fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
835d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#ifndef __arm__
84874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  // For the simulator build, use whatever the flags specify.
855c838251403b0be9a882540f1922577abba4c872ager@chromium.org  if (FLAG_enable_armv7) {
86874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    supported_ |= 1u << ARMv7;
87874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (FLAG_enable_vfp3) supported_ |= 1u << VFP3;
88874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (FLAG_enable_neon) supported_ |= 1u << NEON | 1u << VFP32DREGS;
8970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org    if (FLAG_enable_sudiv) supported_ |= 1u << SUDIV;
90874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
91874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS;
92e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
9370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org  if (FLAG_enable_mls) supported_ |= 1u << MLS;
94874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
95e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
96b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#else  // __arm__
97874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  // Probe for additional features at runtime.
985de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::CPU cpu;
99874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_vfp3 && cpu.has_vfp3()) {
100a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    // This implementation also sets the VFP flags if runtime
101e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
102a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    // 0406B, page A1-6.
103874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    supported_ |= 1u << VFP3 | 1u << ARMv7;
104169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
105169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
106874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON;
107874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV;
10870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org  if (FLAG_enable_mls && cpu.has_thumb2()) supported_ |= 1u << MLS;
10933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
110874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (cpu.architecture() >= 7) {
111874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (FLAG_enable_armv7) supported_ |= 1u << ARMv7;
112874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
113874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    // Use movw/movt for QUALCOMM ARMv7 cores.
1145de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) {
115874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org      supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
116874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    }
11789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
11889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
1191e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines.
1205de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  if (cpu.implementer() == base::CPU::ARM &&
1215de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org      (cpu.part() == base::CPU::ARM_CORTEX_A5 ||
1225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org       cpu.part() == base::CPU::ARM_CORTEX_A9)) {
123169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    cache_line_size_ = 32;
124169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
125169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
126874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS;
127c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#endif
128b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7));
130e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
133e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid CpuFeatures::PrintTarget() {
134e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_arch = NULL;
135975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  const char* arm_target_type = "";
136975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  const char* arm_no_probe = "";
137e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_fpu = "";
138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_thumb = "";
139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_float_abi = NULL;
140e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
141975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#if !defined __arm__
142975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  arm_target_type = " simulator";
143975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#endif
144975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
145975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#if defined ARM_TEST_NO_FEATURE_PROBE
146975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  arm_no_probe = " noprobe";
147975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#endif
148975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
149e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if defined CAN_USE_ARMV7_INSTRUCTIONS
150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_arch = "arm v7";
151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else
152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_arch = "arm v6";
153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif
154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
155975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#if defined CAN_USE_NEON
156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " neon";
157975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#elif defined CAN_USE_VFP3_INSTRUCTIONS
158e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#  if defined CAN_USE_VFP32DREGS
159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp3";
160e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#  else
161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp3-d16";
162e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#  endif
163975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#else
164e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp2";
165975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#endif
166975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
167975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#ifdef __arm__
1685de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  arm_float_abi = base::OS::ArmUsingHardFloat() ? "hard" : "softfp";
169975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#elif USE_EABI_HARDFLOAT
170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_float_abi = "hard";
171975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#else
172e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_float_abi = "softfp";
173975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#endif
174e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
175975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#if defined __arm__ && (defined __thumb__) || (defined __thumb2__)
176975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  arm_thumb = " thumb";
177975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#endif
178e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
179975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  printf("target%s%s %s%s%s %s\n",
180975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org         arm_target_type, arm_no_probe, arm_arch, arm_fpu, arm_thumb,
181975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org         arm_float_abi);
182e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
183e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
184e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
185e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid CpuFeatures::PrintFeatures() {
186e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  printf(
187169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    "ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d UNALIGNED_ACCESSES=%d "
188e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    "MOVW_MOVT_IMMEDIATE_LOADS=%d",
189e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(ARMv7),
190e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(VFP3),
191e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(VFP32DREGS),
192169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    CpuFeatures::IsSupported(NEON),
193e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(SUDIV),
194e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
195e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
196e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef __arm__
1975de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  bool eabi_hardfloat = base::OS::ArmUsingHardFloat();
198e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif USE_EABI_HARDFLOAT
199e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool eabi_hardfloat = true;
200e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else
201e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool eabi_hardfloat = false;
202e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif
203e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat);
204c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
205c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
206c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
208874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org// Implementation of DwVfpRegister
209874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
210874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.orgconst char* DwVfpRegister::AllocationIndexToString(int index) {
211e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= 0 && index < NumAllocatableRegisters());
212e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
213874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org         kNumReservedRegisters - 1);
214874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters;
215874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  return VFPRegisters::Name(index, true);
216874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org}
217874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
218874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
219874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org// -----------------------------------------------------------------------------
22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of RelocInfo
22143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst int RelocInfo::kApplyMask = 0;
22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2259dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool RelocInfo::IsCodedSpecially() {
226763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // The deserializer needs to know whether a pointer is specially coded.  Being
227763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // specially coded on ARM means that it is a movw/movt instruction, or is an
228763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // out of line constant pool entry.  These only occur if
229763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // FLAG_enable_ool_constant_pool is true.
230763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  return FLAG_enable_ool_constant_pool;
2319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
2329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
2339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
234bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgbool RelocInfo::IsInConstantPool() {
235d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return Assembler::is_constant_pool_load(pc_);
236bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
237bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
238bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
239245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) {
24043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch the code at the current address with the supplied instructions.
2414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Instr* pc = reinterpret_cast<Instr*>(pc_);
2424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Instr* instr = reinterpret_cast<Instr*>(instructions);
2434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  for (int i = 0; i < instruction_count; i++) {
2444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    *(pc + i) = *(instr + i);
2454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
2464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
2474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Indicate that code has changed.
2485de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  CpuFeatures::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Patch the code at the current PC with a call to the target address.
253245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Additional guard instructions can be added if required.
254245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch the code at the current address with a call to the target.
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNIMPLEMENTED();
25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Operand and MemOperand
26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// See assembler-arm-inl.h for inlined constructors
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Handle<Object> handle) {
26579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference using_raw_address;
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = no_reg;
26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Verify all Objects referred by code are NOT in new space.
26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* obj = *handle;
26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (obj->IsHeapObject()) {
270e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    imm32_ = reinterpret_cast<intptr_t>(handle.location());
272236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    rmode_ = RelocInfo::EMBEDDED_OBJECT;
27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // no relocation needed
27532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    imm32_ = reinterpret_cast<intptr_t>(obj);
27659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    rmode_ = RelocInfo::NONE32;
27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint5(shift_imm));
283a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rs_ = no_reg;
28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = shift_op;
28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_imm_ = shift_imm & 31;
288a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
289a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  if ((shift_op == ROR) && (shift_imm == 0)) {
290a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    // ROR #0 is functionally equivalent to LSL #0 and this allow us to encode
291a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    // RRX as ROR #0 (See below).
292a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    shift_op = LSL;
293a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  } else if (shift_op == RRX) {
29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // encoded as ROR with shift_imm == 0
295e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(shift_imm == 0);
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    shift_op_ = ROR;
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    shift_imm_ = 0;
29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Register rm, ShiftOp shift_op, Register rs) {
303e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(shift_op != RRX);
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rs_ = no_reg;
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = shift_op;
30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rs_ = rs;
30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenMemOperand::MemOperand(Register rn, int32_t offset, AddrMode am) {
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rn_ = rn;
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = no_reg;
31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  offset_ = offset;
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  am_ = am;
31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
318e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenMemOperand::MemOperand(Register rn, Register rm, AddrMode am) {
32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rn_ = rn;
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = LSL;
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_imm_ = 0;
32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  am_ = am;
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenMemOperand::MemOperand(Register rn, Register rm,
32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                       ShiftOp shift_op, int shift_imm, AddrMode am) {
330e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint5(shift_imm));
33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rn_ = rn;
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = shift_op;
33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_imm_ = shift_imm & 31;
33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  am_ = am;
33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
339169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgNeonMemOperand::NeonMemOperand(Register rn, AddrMode am, int align) {
340e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((am == Offset) || (am == PostIndex));
341169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rn_ = rn;
342169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rm_ = (am == Offset) ? pc : sp;
343169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  SetAlignment(align);
344169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
345169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
346169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
347169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgNeonMemOperand::NeonMemOperand(Register rn, Register rm, int align) {
348169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rn_ = rn;
349169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rm_ = rm;
350169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  SetAlignment(align);
351169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
352169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
353169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
354169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid NeonMemOperand::SetAlignment(int align) {
355169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  switch (align) {
356169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 0:
357169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 0;
358169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
359169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 64:
360169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 1;
361169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
362169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 128:
363169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 2;
364169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
365169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 256:
366169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 3;
367169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
368169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    default:
369169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      UNREACHABLE();
370169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 0;
371169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
372169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
373169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
374169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
375169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
376169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgNeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) {
377169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  base_ = base;
378169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  switch (registers_count) {
379169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 1:
380169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_1;
381169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
382169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 2:
383169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_2;
384169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
385169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 3:
386169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_3;
387169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
388169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 4:
389169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_4;
390169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
391169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    default:
392169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      UNREACHABLE();
393169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_1;
394169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
395169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
396169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
397169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
398169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
400378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Specific instructions, constants, and masks.
40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
40331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// register r is not encoded.
404378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kPushRegPattern =
4051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | 4 | NegPreIndex | kRegister_sp_Code * B16;
40631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
40731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// register r is not encoded.
408378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kPopRegPattern =
4091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | L | 4 | PostIndex | kRegister_sp_Code * B16;
410cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org// ldr rd, [pc, #offset]
411975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgconst Instr kLdrPCImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
412975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgconst Instr kLdrPCImmedPattern = 5 * B24 | L | kRegister_pc_Code * B16;
413763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org// ldr rd, [pp, #offset]
414975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgconst Instr kLdrPpImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
415975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgconst Instr kLdrPpImmedPattern = 5 * B24 | L | kRegister_r8_Code * B16;
416d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org// ldr rd, [pp, rn]
417d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgconst Instr kLdrPpRegMask = 15 * B24 | 7 * B20 | 15 * B16;
418d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgconst Instr kLdrPpRegPattern = 7 * B24 | L | kRegister_r8_Code * B16;
4194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org// vldr dd, [pc, #offset]
4204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgconst Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
4214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgconst Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8;
422763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org// vldr dd, [pp, #offset]
423763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgconst Instr kVldrDPpMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
424763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgconst Instr kVldrDPpPattern = 13 * B24 | L | kRegister_r8_Code * B16 | 11 * B8;
425cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org// blxcc rm
426cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgconst Instr kBlxRegMask =
427cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
428cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgconst Instr kBlxRegPattern =
429378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | BLX;
43088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.orgconst Instr kBlxIp = al | kBlxRegPattern | ip.code();
4312c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kMovMvnMask = 0x6d * B21 | 0xf * B16;
4322c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kMovMvnPattern = 0xd * B21;
4332c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kMovMvnFlip = B22;
4345ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovLeaveCCMask = 0xdff * B16;
4355ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovLeaveCCPattern = 0x1a0 * B16;
436d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgconst Instr kMovwPattern = 0x30 * B20;
437d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgconst Instr kMovtPattern = 0x34 * B20;
4385ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovwLeaveCCFlip = 0x5 * B21;
439a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgconst Instr kMovImmedMask = 0x7f * B21;
440a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgconst Instr kMovImmedPattern = 0x1d * B21;
441a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgconst Instr kOrrImmedMask = 0x7f * B21;
442a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgconst Instr kOrrImmedPattern = 0x1c * B21;
4432c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12;
4442c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kCmpCmnPattern = 0x15 * B20;
4452c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kCmpCmnFlip = B21;
4462c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kAddSubFlip = 0x6 * B21;
4472c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kAndBicFlip = 0xe * B21;
4482c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
4499dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com// A mask for the Rd register for push, pop, ldr, str instructions.
450378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrRegFpOffsetPattern =
4511456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | L | Offset | kRegister_fp_Code * B16;
452378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kStrRegFpOffsetPattern =
4531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | Offset | kRegister_fp_Code * B16;
454378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrRegFpNegOffsetPattern =
4551456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | L | NegOffset | kRegister_fp_Code * B16;
456378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kStrRegFpNegOffsetPattern =
4571456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | NegOffset | kRegister_fp_Code * B16;
458378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrStrInstrTypeMask = 0xffff0000;
459378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
46031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
4618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
4628e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    : AssemblerBase(isolate, buffer, buffer_size),
463471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      recorded_ast_id_(TypeFeedbackId::None()),
464763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      constant_pool_builder_(),
465e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      positions_recorder_(this) {
4668e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
467ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  num_pending_32_bit_reloc_info_ = 0;
4684cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  num_pending_64_bit_reloc_info_ = 0;
46943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  next_buffer_check_ = 0;
470013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  const_pool_blocked_nesting_ = 0;
47143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  no_const_pool_before_ = 0;
472ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  first_const_pool_32_use_ = -1;
473ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  first_const_pool_64_use_ = -1;
47443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  last_bound_pos_ = 0;
47597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  constant_pool_available_ = !FLAG_enable_ool_constant_pool;
476717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  ClearRecordedAstId();
47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenAssembler::~Assembler() {
481e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(const_pool_blocked_nesting_ == 0);
48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::GetCode(CodeDesc* desc) {
486763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (!FLAG_enable_ool_constant_pool) {
487763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Emit constant pool if necessary.
488763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    CheckConstPool(true, false);
489e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(num_pending_32_bit_reloc_info_ == 0);
490e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(num_pending_64_bit_reloc_info_ == 0);
491763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
492f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up code descriptor.
49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->buffer = buffer_;
49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->buffer_size = buffer_size_;
49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->instr_size = pc_offset();
49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
4979af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  desc->origin = this;
49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
49943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::Align(int m) {
50221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
50343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while ((pc_offset() & (m - 1)) != 0) {
50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    nop();
50543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
50643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
50743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5095ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid Assembler::CodeTargetAlign() {
5105ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Preferred alignment of jump targets on some ARM chips.
5115ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  Align(8);
5125ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
5135ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
5145ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
515496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgCondition Assembler::GetCondition(Instr instr) {
516496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return Instruction::ConditionField(instr);
517496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
518496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
519496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
520013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgbool Assembler::IsBranch(Instr instr) {
521013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  return (instr & (B27 | B25)) == (B27 | B25);
522013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
523013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
524013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
525013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgint Assembler::GetBranchOffset(Instr instr) {
526e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsBranch(instr));
527013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Take the jump offset in the lower 24 bits, sign extend it and multiply it
528013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // with 4 to get the offset in bytes.
529378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return ((instr & kImm24Mask) << 8) >> 6;
530013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
531013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
532013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
533013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgbool Assembler::IsLdrRegisterImmediate(Instr instr) {
534013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  return (instr & (B27 | B26 | B25 | B22 | B20)) == (B26 | B20);
535013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
536013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
537013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
5384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgbool Assembler::IsVldrDRegisterImmediate(Instr instr) {
5394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return (instr & (15 * B24 | 3 * B20 | 15 * B8)) == (13 * B24 | B20 | 11 * B8);
5404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
5414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
5424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
543013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgint Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
544e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsLdrRegisterImmediate(instr));
545013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  bool positive = (instr & B23) == B23;
546378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  int offset = instr & kOff12Mask;  // Zero extended offset.
547013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  return positive ? offset : -offset;
548013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
549013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
550013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
5514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgint Assembler::GetVldrDRegisterImmediateOffset(Instr instr) {
552e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsVldrDRegisterImmediate(instr));
5534cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool positive = (instr & B23) == B23;
5544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int offset = instr & kOff8Mask;  // Zero extended offset.
5554cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  offset <<= 2;
5564cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return positive ? offset : -offset;
5574cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
5584cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
5594cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
560013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgInstr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
561e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsLdrRegisterImmediate(instr));
562013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  bool positive = offset >= 0;
563013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  if (!positive) offset = -offset;
564e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint12(offset));
565013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Set bit indicating whether the offset should be added.
566013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  instr = (instr & ~B23) | (positive ? B23 : 0);
567013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Set the actual offset.
568378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return (instr & ~kOff12Mask) | offset;
569013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
570013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
571013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
5724cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgInstr Assembler::SetVldrDRegisterImmediateOffset(Instr instr, int offset) {
573e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsVldrDRegisterImmediate(instr));
574e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((offset & ~3) == offset);  // Must be 64-bit aligned.
5754cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool positive = offset >= 0;
5764cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (!positive) offset = -offset;
577e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint10(offset));
5784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Set bit indicating whether the offset should be added.
5794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  instr = (instr & ~B23) | (positive ? B23 : 0);
5804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Set the actual offset. Its bottom 2 bits are zero.
5814cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return (instr & ~kOff8Mask) | (offset >> 2);
5824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
5834cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
5844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
585ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgbool Assembler::IsStrRegisterImmediate(Instr instr) {
586ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  return (instr & (B27 | B26 | B25 | B22 | B20)) == B26;
587ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
588ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
589ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
590ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgInstr Assembler::SetStrRegisterImmediateOffset(Instr instr, int offset) {
591e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsStrRegisterImmediate(instr));
592ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  bool positive = offset >= 0;
593ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  if (!positive) offset = -offset;
594e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint12(offset));
595ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  // Set bit indicating whether the offset should be added.
596ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  instr = (instr & ~B23) | (positive ? B23 : 0);
597ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  // Set the actual offset.
598378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return (instr & ~kOff12Mask) | offset;
599ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
600ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
601ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
602ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgbool Assembler::IsAddRegisterImmediate(Instr instr) {
603ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  return (instr & (B27 | B26 | B25 | B24 | B23 | B22 | B21)) == (B25 | B23);
604ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
605ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
606ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
607ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgInstr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) {
608e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsAddRegisterImmediate(instr));
609e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset >= 0);
610e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint12(offset));
611ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  // Set the offset.
612378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return (instr & ~kOff12Mask) | offset;
613ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
614ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
615ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
6169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comRegister Assembler::GetRd(Instr instr) {
6179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  Register reg;
618378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  reg.code_ = Instruction::RdValue(instr);
6199dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return reg;
6209dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6219dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6229dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
623496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgRegister Assembler::GetRn(Instr instr) {
624496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  Register reg;
625496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  reg.code_ = Instruction::RnValue(instr);
626496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return reg;
627496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
628496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
629496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
630496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgRegister Assembler::GetRm(Instr instr) {
631496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  Register reg;
632496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  reg.code_ = Instruction::RmValue(instr);
633496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return reg;
634496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
635496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
636496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
637975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgInstr Assembler::GetConsantPoolLoadPattern() {
638975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
639975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    return kLdrPpImmedPattern;
640975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  } else {
641975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    return kLdrPCImmedPattern;
642975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  }
643975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org}
644975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
645975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
646d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgInstr Assembler::GetConsantPoolLoadMask() {
647d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
648d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return kLdrPpImmedMask;
649d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  } else {
650d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return kLdrPCImmedMask;
651d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
652d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
653d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
654d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
6559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsPush(Instr instr) {
6569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & ~kRdMask) == kPushRegPattern);
6579dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsPop(Instr instr) {
6619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & ~kRdMask) == kPopRegPattern);
6629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsStrRegFpOffset(Instr instr) {
6669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kStrRegFpOffsetPattern);
6679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6699dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsLdrRegFpOffset(Instr instr) {
6719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpOffsetPattern);
6729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsStrRegFpNegOffset(Instr instr) {
6769dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kStrRegFpNegOffsetPattern);
6779dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsLdrRegFpNegOffset(Instr instr) {
6819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpNegOffsetPattern);
6829dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
685beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.orgbool Assembler::IsLdrPcImmediateOffset(Instr instr) {
686beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // Check the instruction is indeed a
687beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // ldr<cond> <Rd>, [pc +/- offset_12].
688975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  return (instr & kLdrPCImmedMask) == kLdrPCImmedPattern;
6894cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
6904cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
6914cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
692763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgbool Assembler::IsLdrPpImmediateOffset(Instr instr) {
693763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Check the instruction is indeed a
694763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // ldr<cond> <Rd>, [pp +/- offset_12].
695975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  return (instr & kLdrPpImmedMask) == kLdrPpImmedPattern;
696763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
697763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
698763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
699d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgbool Assembler::IsLdrPpRegOffset(Instr instr) {
700d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Check the instruction is indeed a
701d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // ldr<cond> <Rd>, [pp, +/- <Rm>].
702d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return (instr & kLdrPpRegMask) == kLdrPpRegPattern;
703d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
704d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
705d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
706d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgInstr Assembler::GetLdrPpRegOffsetPattern() { return kLdrPpRegPattern; }
707d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
708d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
7094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgbool Assembler::IsVldrDPcImmediateOffset(Instr instr) {
7104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Check the instruction is indeed a
7114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // vldr<cond> <Dd>, [pc +/- offset_10].
7124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return (instr & kVldrDPCMask) == kVldrDPCPattern;
713beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org}
714beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
715beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
716763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgbool Assembler::IsVldrDPpImmediateOffset(Instr instr) {
717763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Check the instruction is indeed a
718763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // vldr<cond> <Dd>, [pp +/- offset_10].
719763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  return (instr & kVldrDPpMask) == kVldrDPpPattern;
720763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
721763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
722763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
723975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgbool Assembler::IsBlxReg(Instr instr) {
724975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  // Check the instruction is indeed a
725975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  // blxcc <Rm>
726975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  return (instr & kBlxRegMask) == kBlxRegPattern;
727975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org}
728975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
729975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
730975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgbool Assembler::IsBlxIp(Instr instr) {
731975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  // Check the instruction is indeed a
732975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  // blx ip
733975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  return instr == kBlxIp;
734975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org}
735975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
736975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
737496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgbool Assembler::IsTstImmediate(Instr instr) {
738496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
739496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      (I | TST | S);
740496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
741496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
742496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
743496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgbool Assembler::IsCmpRegister(Instr instr) {
744496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask | B4)) ==
745496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      (CMP | S);
746496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
747496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
748496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
749496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgbool Assembler::IsCmpImmediate(Instr instr) {
750496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
751496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      (I | CMP | S);
752496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
753496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
754496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
755496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgRegister Assembler::GetCmpImmediateRegister(Instr instr) {
756e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCmpImmediate(instr));
757496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return GetRn(instr);
758496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
759496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
760496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
761496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgint Assembler::GetCmpImmediateRawImmediate(Instr instr) {
762e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsCmpImmediate(instr));
763496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return instr & kOff12Mask;
764496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
765496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
766e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Labels refer to positions in the (to be) generated code.
76843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// There are bound, linked, and unused labels.
76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Bound labels refer to known positions in the already
77143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// generated code. pos() is the position the label refers to.
77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Linked labels refer to unknown positions in the code
77443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to be generated; pos() is the position of the last
77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// instruction using the label.
776d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org//
777d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// The linked labels form a link chain by making the branch offset
778d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// in the instruction steam to point to the previous branch
779d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// instruction using the same label.
780d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org//
781d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// The link chain is terminated by a branch offset pointing to the
782d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// same position.
78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.orgint Assembler::target_at(int pos) {
78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Instr instr = instr_at(pos);
7874a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  if (is_uint24(instr)) {
7884a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // Emitted link to a label, not part of a branch.
7894a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    return instr;
79018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
791e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
792378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  int imm26 = ((instr & kImm24Mask) << 8) >> 6;
793378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
794378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      ((instr & B24) != 0)) {
79543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // blx uses bit 24 to encode bit 2 of imm26
79643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    imm26 += 2;
797013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  }
79818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  return pos + kPcLoadDelta + imm26;
79943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
80043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::target_at_put(int pos, int target_pos) {
80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Instr instr = instr_at(pos);
8044a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  if (is_uint24(instr)) {
805e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(target_pos == pos || target_pos >= 0);
8064a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // Emitted link to a label, not part of a branch.
8074a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // Load the position of the label relative to the generated code object
8084a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // pointer in a register.
8094a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
8104a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // Here are the instructions we need to emit:
8114a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //   For ARMv7: target24 => target16_1:target16_0
8124a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      movw dst, #target16_0
8134a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      movt dst, #target16_1
8144a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //   For ARMv6: target24 => target8_2:target8_1:target8_0
8154a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      mov dst, #target8_0
8164a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      orr dst, dst, #target8_1 << 8
8174a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      orr dst, dst, #target8_2 << 16
8184a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
8194a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // We extract the destination register from the emitted nop instruction.
8204a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    Register dst = Register::from_code(
8214a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        Instruction::RmValue(instr_at(pos + kInstrSize)));
822e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsNop(instr_at(pos + kInstrSize), dst.code()));
8234a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
824e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_uint24(target24));
8254a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    if (is_uint8(target24)) {
8264a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      // If the target fits in a byte then only patch with a mov
8274a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      // instruction.
8284a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
8294a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                          1,
8304a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                          CodePatcher::DONT_FLUSH);
8314a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      patcher.masm()->mov(dst, Operand(target24));
8324a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    } else {
8334a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      uint16_t target16_0 = target24 & kImm16Mask;
8344a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      uint16_t target16_1 = target24 >> 16;
8354a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      if (CpuFeatures::IsSupported(ARMv7)) {
8364a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        // Patch with movw/movt.
8374a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        if (target16_1 == 0) {
8384a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
8394a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              1,
8404a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              CodePatcher::DONT_FLUSH);
8414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->movw(dst, target16_0);
8424a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        } else {
8434a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
8444a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              2,
8454a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              CodePatcher::DONT_FLUSH);
8464a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->movw(dst, target16_0);
8474a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->movt(dst, target16_1);
8484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        }
8494a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      } else {
8504a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        // Patch with a sequence of mov/orr/orr instructions.
8514a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        uint8_t target8_0 = target16_0 & kImm8Mask;
8524a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        uint8_t target8_1 = target16_0 >> 8;
8534a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        uint8_t target8_2 = target16_1 & kImm8Mask;
8544a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        if (target8_2 == 0) {
8554a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
8564a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              2,
8574a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              CodePatcher::DONT_FLUSH);
8584a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->mov(dst, Operand(target8_0));
8594a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
8604a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        } else {
8614a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
8624a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              3,
8634a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                              CodePatcher::DONT_FLUSH);
8644a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->mov(dst, Operand(target8_0));
8654a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
8664a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          patcher.masm()->orr(dst, dst, Operand(target8_2 << 16));
8674a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        }
8684a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      }
8694a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    }
87018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    return;
87118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
87218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  int imm26 = target_pos - (pos + kPcLoadDelta);
873e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
874378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (Instruction::ConditionField(instr) == kSpecialCondition) {
87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // blx uses bit 24 to encode bit 2 of imm26
876e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((imm26 & 1) == 0);
877378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
879e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((imm26 & 3) == 0);
880378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    instr &= ~kImm24Mask;
88143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = imm26 >> 2;
883e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_int24(imm24));
884378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  instr_at_put(pos, instr | (imm24 & kImm24Mask));
88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::print(Label* L) {
88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (L->is_unused()) {
89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("unused label\n");
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (L->is_bound()) {
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("bound label to %d\n", L->pos());
89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (L->is_linked()) {
89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Label l = *L;
89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("unbound label");
89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (l.is_linked()) {
89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("@ %d ", l.pos());
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Instr instr = instr_at(l.pos());
899378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if ((instr & ~kImm24Mask) == 0) {
90018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        PrintF("value\n");
90143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
902e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx
903378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        Condition cond = Instruction::ConditionField(instr);
90418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        const char* b;
90518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        const char* c;
906378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        if (cond == kSpecialCondition) {
90718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          b = "blx";
90818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          c = "";
90918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        } else {
91018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          if ((instr & B24) != 0)
91118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            b = "bl";
91218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          else
91318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            b = "b";
91418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
91518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          switch (cond) {
91618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case eq: c = "eq"; break;
91718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case ne: c = "ne"; break;
91818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case hs: c = "hs"; break;
91918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case lo: c = "lo"; break;
92018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case mi: c = "mi"; break;
92118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case pl: c = "pl"; break;
92218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case vs: c = "vs"; break;
92318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case vc: c = "vc"; break;
92418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case hi: c = "hi"; break;
92518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case ls: c = "ls"; break;
92618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case ge: c = "ge"; break;
92718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case lt: c = "lt"; break;
92818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case gt: c = "gt"; break;
92918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case le: c = "le"; break;
93018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case al: c = ""; break;
93118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            default:
93218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org              c = "";
93318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org              UNREACHABLE();
93418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          }
93543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
93618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        PrintF("%s%s\n", b, c);
93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      next(&l);
93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
94343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
94443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bind_to(Label* L, int pos) {
947e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
94843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (L->is_linked()) {
94943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int fixup_pos = L->pos();
95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    next(L);  // call next before overwriting link with target at fixup_pos
95143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    target_at_put(fixup_pos, pos);
95243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
95343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  L->bind_to(pos);
95443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Keep track of the last bound label so we don't eliminate any instructions
95641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // before a bound label.
95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (pos > last_bound_pos_)
95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    last_bound_pos_ = pos;
95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
96043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bind(Label* L) {
963e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!L->is_bound());  // label can only be bound once
96443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bind_to(L, pc_offset());
96543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::next(Label* L) {
969e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(L->is_linked());
97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int link = target_at(L->pos());
971d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (link == L->pos()) {
972d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // Branch target points to the same instuction. This is the end of the link
973d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // chain.
97443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    L->Unuse();
97580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  } else {
976e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(link >= 0);
97780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    L->link_to(link);
97843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
97943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
98043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
98143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9825c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Low-level code emission routines depending on the addressing mode.
9832c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org// If this returns true then you have to use the rotate_imm and immed_8
9842c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org// that it returns, because it may have already changed the instruction
9852c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org// to match them!
98617aac87e074aee1bc2470cf0ed56556f4f2de420machenbach@chromium.orgstatic bool fits_shifter(uint32_t imm32,
98717aac87e074aee1bc2470cf0ed56556f4f2de420machenbach@chromium.org                         uint32_t* rotate_imm,
98817aac87e074aee1bc2470cf0ed56556f4f2de420machenbach@chromium.org                         uint32_t* immed_8,
98917aac87e074aee1bc2470cf0ed56556f4f2de420machenbach@chromium.org                         Instr* instr) {
9905c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // imm32 must be unsigned.
99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int rot = 0; rot < 16; rot++) {
99243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t imm8 = (imm32 << 2*rot) | (imm32 >> (32 - 2*rot));
99343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if ((imm8 <= 0xff)) {
99417aac87e074aee1bc2470cf0ed56556f4f2de420machenbach@chromium.org      *rotate_imm = rot;
99517aac87e074aee1bc2470cf0ed56556f4f2de420machenbach@chromium.org      *immed_8 = imm8;
99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return true;
99743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
99843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
9992c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  // If the opcode is one with a complementary version and the complementary
10002c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  // immediate fits, change the opcode.
10012c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  if (instr != NULL) {
10022c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    if ((*instr & kMovMvnMask) == kMovMvnPattern) {
10032c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
10042c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        *instr ^= kMovMvnFlip;
10052c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        return true;
10065ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org      } else if ((*instr & kMovLeaveCCMask) == kMovLeaveCCPattern) {
1007c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        if (CpuFeatures::IsSupported(ARMv7)) {
10085ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org          if (imm32 < 0x10000) {
10095ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org            *instr ^= kMovwLeaveCCFlip;
1010d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org            *instr |= Assembler::EncodeMovwImmediate(imm32);
101117aac87e074aee1bc2470cf0ed56556f4f2de420machenbach@chromium.org            *rotate_imm = *immed_8 = 0;  // Not used for movw.
10125ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org            return true;
10135ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org          }
10145ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org        }
10152c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      }
10162c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    } else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) {
1017657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
10182c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        *instr ^= kCmpCmnFlip;
10192c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        return true;
10202c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      }
10212c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    } else {
10222c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      Instr alu_insn = (*instr & kALUMask);
1023378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if (alu_insn == ADD ||
1024378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org          alu_insn == SUB) {
1025657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
10262c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          *instr ^= kAddSubFlip;
10272c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          return true;
10282c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        }
1029378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      } else if (alu_insn == AND ||
1030378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                 alu_insn == BIC) {
10312c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
10322c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          *instr ^= kAndBicFlip;
10332c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          return true;
10342c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        }
10352c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      }
103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
104043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10422abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// We have to use the temporary register for things that can be relocated even
10432abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// if they can be encoded in the ARM's 12 bits of immediate-offset instruction
10442abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// space.  There is no guarantee that the relocated location can be similarly
10452abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// encoded.
1046874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.orgbool Operand::must_output_reloc_info(const Assembler* assembler) const {
1047f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
1048471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (assembler != NULL && assembler->predictable_code_size()) return true;
1049874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    return assembler->serializer_enabled();
10504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  } else if (RelocInfo::IsNone(rmode_)) {
10512abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    return false;
10522abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
10532abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  return true;
10542abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
10552abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
10562abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
1057874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.orgstatic bool use_mov_immediate_load(const Operand& x,
1058486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                   const Assembler* assembler) {
1059d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (assembler != NULL && !assembler->is_constant_pool_available()) {
1060763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    return true;
1061763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
1062486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org             (assembler == NULL || !assembler->predictable_code_size())) {
1063486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // Prefer movw / movt to constant pool if it is more efficient on the CPU.
106489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    return true;
1065874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  } else if (x.must_output_reloc_info(assembler)) {
1066486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // Prefer constant pool if data is likely to be patched.
106789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    return false;
1068486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  } else {
1069486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // Otherwise, use immediate load if movw / movt is available.
1070486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return CpuFeatures::IsSupported(ARMv7);
107189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
107289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
107389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
107489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
1075d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgint Operand::instructions_required(const Assembler* assembler,
1076d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                                   Instr instr) const {
1077d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (rm_.is_valid()) return 1;
10782c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  uint32_t dummy1, dummy2;
1079874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (must_output_reloc_info(assembler) ||
1080b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
1081b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // The immediate operand cannot be encoded as a shifter operand, or use of
1082d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    // constant pool is required.  First account for the instructions required
1083d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    // for the constant pool or immediate load
1084d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    int instructions;
1085d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    if (use_mov_immediate_load(*this, assembler)) {
1086a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      // A movw / movt or mov / orr immediate load.
1087a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      instructions = CpuFeatures::IsSupported(ARMv7) ? 2 : 4;
1088d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else if (assembler != NULL && assembler->use_extended_constant_pool()) {
1089a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      // An extended constant pool load.
1090a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      instructions = CpuFeatures::IsSupported(ARMv7) ? 3 : 5;
1091b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    } else {
1092a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      // A small constant pool load.
1093a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      instructions = 1;
10945d6930502bea0aeb6fdbc4cf04cf87c908ce0127machenbach@chromium.org    }
1095d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
1096d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    if ((instr & ~kCondMask) != 13 * B21) {  // mov, S not set
1097d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // For a mov or mvn instruction which doesn't set the condition
1098d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // code, the constant pool or immediate load is enough, otherwise we need
1099d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // to account for the actual instruction being requested.
1100d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      instructions += 1;
1101d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
1102d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return instructions;
1103b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  } else {
1104b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // No use of constant pool and the immediate operand can be encoded as a
1105b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // shifter operand.
1106d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return 1;
1107b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  }
11082c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org}
11092c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
11102c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
1111486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgvoid Assembler::move_32_bit_immediate(Register rd,
1112486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                      const Operand& x,
1113486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                      Condition cond) {
1114763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  RelocInfo rinfo(pc_, x.rmode_, x.imm32_, NULL);
1115a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  uint32_t imm32 = static_cast<uint32_t>(x.imm32_);
1116874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (x.must_output_reloc_info(this)) {
1117763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    RecordRelocInfo(rinfo);
1118763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
1119763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
1120874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  if (use_mov_immediate_load(x, this)) {
1121763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    Register target = rd.code() == pc.code() ? ip : rd;
1122a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    if (CpuFeatures::IsSupported(ARMv7)) {
1123a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (!FLAG_enable_ool_constant_pool && x.must_output_reloc_info(this)) {
1124a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        // Make sure the movw/movt doesn't get separated.
1125a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        BlockConstPoolFor(2);
1126a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      }
1127a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      movw(target, imm32 & 0xffff, cond);
1128a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      movt(target, imm32 >> 16, cond);
1129a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    } else {
1130a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK(FLAG_enable_ool_constant_pool);
1131a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      mov(target, Operand(imm32 & kImm8Mask), LeaveCC, cond);
1132a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      orr(target, target, Operand(imm32 & (kImm8Mask << 8)), LeaveCC, cond);
1133a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      orr(target, target, Operand(imm32 & (kImm8Mask << 16)), LeaveCC, cond);
1134a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      orr(target, target, Operand(imm32 & (kImm8Mask << 24)), LeaveCC, cond);
113589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    }
1136763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    if (target.code() != rd.code()) {
1137763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      mov(rd, target, LeaveCC, cond);
1138763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
1139763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
1140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_constant_pool_available());
1141d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
1142d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    if (section == ConstantPoolArray::EXTENDED_SECTION) {
1143e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(FLAG_enable_ool_constant_pool);
1144d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      Register target = rd.code() == pc.code() ? ip : rd;
1145d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // Emit instructions to load constant pool offset.
1146a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (CpuFeatures::IsSupported(ARMv7)) {
1147a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        movw(target, 0, cond);
1148a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        movt(target, 0, cond);
1149a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      } else {
1150a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        mov(target, Operand(0), LeaveCC, cond);
1151a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        orr(target, target, Operand(0), LeaveCC, cond);
1152a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        orr(target, target, Operand(0), LeaveCC, cond);
1153a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        orr(target, target, Operand(0), LeaveCC, cond);
1154a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      }
1155d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // Load from constant pool at offset.
1156d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      ldr(rd, MemOperand(pp, target), cond);
1157d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else {
1158e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(section == ConstantPoolArray::SMALL_SECTION);
1159d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      ldr(rd, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0), cond);
1160d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
116189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
116289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
116389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
116489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod1(Instr instr,
116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         Register rn,
116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         Register rd,
116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         const Operand& x) {
116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CheckBuffer();
1170e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!x.rm_.is_valid()) {
11725c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate.
117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t rotate_imm;
117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t immed_8;
1175874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (x.must_output_reloc_info(this) ||
117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // The immediate operand cannot be encoded as a shifter operand, so load
117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // it first to register ip and change the original instruction to use ip.
117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // However, if the original instruction is a 'mov rd, x' (not setting the
11805c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // condition code), then replace it with a 'ldr rd, [pc]'.
1181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      CHECK(!rn.is(ip));  // rn should never be ip, or will be trashed
1182378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      Condition cond = Instruction::ConditionField(instr);
1183378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
1184486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        move_32_bit_immediate(rd, x, cond);
118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
1186486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        mov(ip, x, LeaveCC, cond);
118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        addrmod1(instr, rn, rd, Operand(ip));
118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= I | rotate_imm*B8 | immed_8;
119243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (!x.rs_.is_valid()) {
11935c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate shift.
119443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
119543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
11965c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Register shift.
1197e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
119843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= x.rs_.code()*B8 | x.shift_op_ | B4 | x.rm_.code();
119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | rn.code()*B16 | rd.code()*B12);
1201ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  if (rn.is(pc) || x.rm_.is(pc)) {
12025c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Block constant pool emission for one instruction after reading pc.
12037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    BlockConstPoolFor(1);
1204ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  }
120543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
120643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
1209e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((instr & ~(kCondMask | B | L)) == B26);
121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int am = x.am_;
121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!x.rm_.is_valid()) {
12125c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate offset.
121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int offset_12 = x.offset_;
121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (offset_12 < 0) {
121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      offset_12 = -offset_12;
121643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      am ^= U;
121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!is_uint12(offset_12)) {
12195c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // Immediate offset cannot be encoded, load it first to register ip
12205c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // rn (and rd in a load) should never be ip, or will be trashed.
1221e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
1222378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_));
122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(offset_12 >= 0);  // no masking needed
122743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= offset_12;
122843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
12295c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Register offset (shift_imm_ and shift_op_ are 0) or scaled
123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // register offset the constructors make sure than both shift_imm_
12315c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // and shift_op_ are initialized.
1232e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!x.rm_.is(pc));
123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
123443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1235e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
123743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
123843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
1241e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
1242e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(x.rn_.is_valid());
124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int am = x.am_;
124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!x.rm_.is_valid()) {
12455c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate offset.
124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int offset_8 = x.offset_;
124743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (offset_8 < 0) {
124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      offset_8 = -offset_8;
124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      am ^= U;
125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!is_uint8(offset_8)) {
12525c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // Immediate offset cannot be encoded, load it first to register ip
12535c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // rn (and rd in a load) should never be ip, or will be trashed.
1254e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
1255378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
125643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
125743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
125843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1259e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(offset_8 >= 0);  // no masking needed
126043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf);
126143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (x.shift_imm_ != 0) {
12625c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Scaled register offset not supported, load index first
12635c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // rn (and rd in a load) should never be ip, or will be trashed.
1264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
126543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
1266378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        Instruction::ConditionField(instr));
126743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
126843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
126943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
12705c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Register offset.
1271e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= x.rm_.code();
127343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1274e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
127543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
127643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
127743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod4(Instr instr, Register rn, RegList rl) {
1280e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((instr & ~(kCondMask | P | U | W | L)) == B27);
1281e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rl != 0);
1282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!rn.is(pc));
128343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | rn.code()*B16 | rl);
128443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
128543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
12885c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unindexed addressing is not encoded by this function.
1289e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ((B27 | B26),
1290378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            (instr & ~(kCondMask | kCoprocessorMask | P | U | N | W | L)));
1291e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(x.rn_.is_valid() && !x.rm_.is_valid());
129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int am = x.am_;
129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int offset_8 = x.offset_;
1294e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((offset_8 & 3) == 0);  // offset must be an aligned word offset
129543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  offset_8 >>= 2;
129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (offset_8 < 0) {
129743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    offset_8 = -offset_8;
129843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    am ^= U;
129943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint8(offset_8));  // unsigned word offset must fit in a byte
1301e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
130243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13035c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Post-indexed addressing requires W == 1; different than in addrmod2/3.
130443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if ((am & P) == 0)
130543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    am |= W;
130643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1307e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset_8 >= 0);  // no masking needed
130843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
130943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
131043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1312769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.comint Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int target_pos;
131443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (L->is_bound()) {
131543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    target_pos = L->pos();
131643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
131741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    if (L->is_linked()) {
1318d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      // Point to previous instruction that uses the link.
1319d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      target_pos = L->pos();
132041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    } else {
1321d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      // First entry of the link chain points to itself.
1322d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      target_pos = pc_offset();
132341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    }
132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    L->link_to(pc_offset());
132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Block the emission of the constant pool, since the branch instruction must
13285c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // be emitted at the pc offset recorded by the label.
13297b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  BlockConstPoolFor(1);
133018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  return target_pos - (pc_offset() + kPcLoadDelta);
133118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
13345c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Branch instructions.
133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::b(int branch_offset, Condition cond) {
1336e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((branch_offset & 3) == 0);
133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = branch_offset >> 2;
1338e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_int24(imm24));
1339378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B27 | B25 | (imm24 & kImm24Mask));
134043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1341c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  if (cond == al) {
13425c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Dead code is a good location to emit the constant pool.
134343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CheckConstPool(false, false);
1344c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
134543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bl(int branch_offset, Condition cond) {
1349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  positions_recorder()->WriteRecordedPositions();
1350e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((branch_offset & 3) == 0);
135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = branch_offset >> 2;
1352e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_int24(imm24));
1353378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
135743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::blx(int branch_offset) {  // v5 and above
1358f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
1359e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((branch_offset & 1) == 0);
136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int h = ((branch_offset & 2) >> 1)*B24;
136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = branch_offset >> 2;
1362e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_int24(imm24));
1363378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
136443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
136543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
136643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
136743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::blx(Register target, Condition cond) {  // v5 and above
1368f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
1369e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!target.is(pc));
1370378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
137143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
137243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bx(Register target, Condition cond) {  // v5 and above, plus v4t
1375f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
1376e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!target.is(pc));  // use of pc is actually allowed, but discouraged
1377378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
137843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
137943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13815c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Data-processing instructions.
13825c838251403b0be9a882540f1922577abba4c872ager@chromium.org
138343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::and_(Register dst, Register src1, const Operand& src2,
138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     SBit s, Condition cond) {
1385378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | AND | s, src1, dst, src2);
138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::eor(Register dst, Register src1, const Operand& src2,
139043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1391378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | EOR | s, src1, dst, src2);
139243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
139343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
139543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::sub(Register dst, Register src1, const Operand& src2,
139643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1397378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | SUB | s, src1, dst, src2);
139843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::rsb(Register dst, Register src1, const Operand& src2,
140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1403378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | RSB | s, src1, dst, src2);
140443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
140543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::add(Register dst, Register src1, const Operand& src2,
140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1409378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | ADD | s, src1, dst, src2);
141043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::adc(Register dst, Register src1, const Operand& src2,
141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1415378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | ADC | s, src1, dst, src2);
141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::sbc(Register dst, Register src1, const Operand& src2,
142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1421378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | SBC | s, src1, dst, src2);
142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
142343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
142443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
142543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::rsc(Register dst, Register src1, const Operand& src2,
142643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1427378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | RSC | s, src1, dst, src2);
142843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
142943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
143043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
143143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::tst(Register src1, const Operand& src2, Condition cond) {
1432378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | TST | S, src1, r0, src2);
143343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
143443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
143543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
143643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::teq(Register src1, const Operand& src2, Condition cond) {
1437378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | TEQ | S, src1, r0, src2);
143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
144143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
1442378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | CMP | S, src1, r0, src2);
144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1446496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgvoid Assembler::cmp_raw_immediate(
1447496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    Register src, int raw_immediate, Condition cond) {
1448e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint12(raw_immediate));
1449496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  emit(cond | I | CMP | S | src.code() << 16 | raw_immediate);
1450496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
1451496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
1452496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cmn(Register src1, const Operand& src2, Condition cond) {
1454378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | CMN | S, src1, r0, src2);
145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::orr(Register dst, Register src1, const Operand& src2,
145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1460378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | ORR | s, src1, dst, src2);
146143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
146243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
1465defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (dst.is(pc)) {
1466f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    positions_recorder()->WriteRecordedPositions();
1467defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
1468013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Don't allow nop instructions in the form mov rn, rn to be generated using
1469beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // the mov instruction. They must be generated using nop(int/NopMarkerTypes)
1470beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // or MarkCode(int/NopMarkerTypes) pseudo instructions.
1471e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
1472378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | MOV | s, r0, dst, src);
147343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
147443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
147543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14764a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.orgvoid Assembler::mov_label_offset(Register dst, Label* label) {
14774a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  if (label->is_bound()) {
14784a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    mov(dst, Operand(label->pos() + (Code::kHeaderSize - kHeapObjectTag)));
14794a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  } else {
14804a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // Emit the link to the label in the code stream followed by extra nop
14814a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // instructions.
14824a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // If the label is not linked, then start a new link chain by linking it to
14834a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // itself, emitting pc_offset().
14844a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    int link = label->is_linked() ? label->pos() : pc_offset();
14854a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    label->link_to(pc_offset());
14864a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
14874a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // When the label is bound, these instructions will be patched with a
14884a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // sequence of movw/movt or mov/orr/orr instructions. They will load the
14894a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // destination register with the position of the label from the beginning
14904a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // of the code.
14914a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //
14924a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // The link will be extracted from the first instruction and the destination
14934a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // register from the second.
14944a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //   For ARMv7:
14954a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      link
14964a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      mov dst, dst
14974a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //   For ARMv6:
14984a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      link
14994a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      mov dst, dst
15004a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //      mov dst, dst
15014a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    //
15024a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // When the label gets bound: target_at extracts the link and target_at_put
15034a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // patches the instructions.
1504e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_uint24(link));
15054a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    BlockConstPoolScope block_const_pool(this);
15064a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    emit(link);
15074a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    nop(dst.code());
15084a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    if (!CpuFeatures::IsSupported(ARMv7)) {
15094a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      nop(dst.code());
15104a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    }
15114a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
15124a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org}
15134a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
15144a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
15155ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
1516e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(ARMv7));
15175de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  emit(cond | 0x30*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
15185ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
15195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
15205ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
15215ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
1522e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(ARMv7));
15235ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
15245ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
15255ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
15265ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
152743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bic(Register dst, Register src1, const Operand& src2,
152843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1529378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | BIC | s, src1, dst, src2);
153043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
153143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
1534378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | MVN | s, r0, dst, src);
153543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
153643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15385c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Multiply instructions.
153943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
154043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1541e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
154243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
154343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
154733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgvoid Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
154833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                    Condition cond) {
1549e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
1550e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsEnabled(MLS));
155133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
155233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org       src2.code()*B8 | B7 | B4 | src1.code());
155333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org}
155433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
155533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
155633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgvoid Assembler::sdiv(Register dst, Register src1, Register src2,
155733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                     Condition cond) {
1558e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1559e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsEnabled(SUDIV));
156033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  emit(cond | B26 | B25| B24 | B20 | dst.code()*B16 | 0xf * B12 |
156133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org       src2.code()*B8 | B4 | src1.code());
156233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org}
156333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
156433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
15657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid Assembler::udiv(Register dst, Register src1, Register src2,
15667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                     Condition cond) {
1567e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1568e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsEnabled(SUDIV));
15697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  emit(cond | B26 | B25 | B24 | B21 | B20 | dst.code() * B16 | 0xf * B12 |
15707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org       src2.code() * B8 | B4 | src1.code());
15717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
15727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
15737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
157443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mul(Register dst, Register src1, Register src2,
157543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1576e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
157786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // dst goes in bits 16-19 for this instruction!
157843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
157943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
158043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
158143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::smlal(Register dstL,
158343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
158443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
1588e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1589e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(dstH));
159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::smull(Register dstL,
159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
1601e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1602e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(dstH));
160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
160543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
160643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
160743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
160843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::umlal(Register dstL,
160943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
161043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
1614e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1615e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(dstH));
161643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
161743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
161843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
161943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
162043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
162143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::umull(Register dstL,
162243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
162343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
162443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
162543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
162643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
1627e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1628e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dstL.is(dstH));
162986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16345c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Miscellaneous arithmetic instructions.
163543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::clz(Register dst, Register src, Condition cond) {
163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // v5 and above.
1637e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src.is(pc));
163843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
1639378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org       15*B8 | CLZ | src.code());
164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
164143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
164243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1643ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org// Saturating instructions.
1644ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1645ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org// Unsigned saturate.
1646ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.orgvoid Assembler::usat(Register dst,
1647ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org                     int satpos,
1648ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org                     const Operand& src,
1649ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org                     Condition cond) {
1650ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // v6 and above.
1651e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(ARMv7));
1652e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src.rm_.is(pc));
1653e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((satpos >= 0) && (satpos <= 31));
1654e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
1655e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src.rs_.is(no_reg));
1656ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1657ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  int sh = 0;
1658ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  if (src.shift_op_ == ASR) {
1659ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org      sh = 1;
1660ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  }
1661ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1662ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 |
1663ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org       src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code());
1664ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org}
1665ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1666ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
166730ce411529579186181838984710b0b0980857aaricow@chromium.org// Bitfield manipulation instructions.
166830ce411529579186181838984710b0b0980857aaricow@chromium.org
166930ce411529579186181838984710b0b0980857aaricow@chromium.org// Unsigned bit field extract.
167030ce411529579186181838984710b0b0980857aaricow@chromium.org// Extracts #width adjacent bits from position #lsb in a register, and
167130ce411529579186181838984710b0b0980857aaricow@chromium.org// writes them to the low bits of a destination register.
167230ce411529579186181838984710b0b0980857aaricow@chromium.org//   ubfx dst, src, #lsb, #width
167330ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::ubfx(Register dst,
167430ce411529579186181838984710b0b0980857aaricow@chromium.org                     Register src,
167530ce411529579186181838984710b0b0980857aaricow@chromium.org                     int lsb,
167630ce411529579186181838984710b0b0980857aaricow@chromium.org                     int width,
167730ce411529579186181838984710b0b0980857aaricow@chromium.org                     Condition cond) {
167830ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1679e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(ARMv7));
1680e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src.is(pc));
1681e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((lsb >= 0) && (lsb <= 31));
1682e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((width >= 1) && (width <= (32 - lsb)));
168330ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 |
168430ce411529579186181838984710b0b0980857aaricow@chromium.org       lsb*B7 | B6 | B4 | src.code());
168530ce411529579186181838984710b0b0980857aaricow@chromium.org}
168630ce411529579186181838984710b0b0980857aaricow@chromium.org
168730ce411529579186181838984710b0b0980857aaricow@chromium.org
168830ce411529579186181838984710b0b0980857aaricow@chromium.org// Signed bit field extract.
168930ce411529579186181838984710b0b0980857aaricow@chromium.org// Extracts #width adjacent bits from position #lsb in a register, and
169030ce411529579186181838984710b0b0980857aaricow@chromium.org// writes them to the low bits of a destination register. The extracted
169130ce411529579186181838984710b0b0980857aaricow@chromium.org// value is sign extended to fill the destination register.
169230ce411529579186181838984710b0b0980857aaricow@chromium.org//   sbfx dst, src, #lsb, #width
169330ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::sbfx(Register dst,
169430ce411529579186181838984710b0b0980857aaricow@chromium.org                     Register src,
169530ce411529579186181838984710b0b0980857aaricow@chromium.org                     int lsb,
169630ce411529579186181838984710b0b0980857aaricow@chromium.org                     int width,
169730ce411529579186181838984710b0b0980857aaricow@chromium.org                     Condition cond) {
169830ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1699e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(ARMv7));
1700e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src.is(pc));
1701e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((lsb >= 0) && (lsb <= 31));
1702e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((width >= 1) && (width <= (32 - lsb)));
170330ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 |
170430ce411529579186181838984710b0b0980857aaricow@chromium.org       lsb*B7 | B6 | B4 | src.code());
170530ce411529579186181838984710b0b0980857aaricow@chromium.org}
170630ce411529579186181838984710b0b0980857aaricow@chromium.org
170730ce411529579186181838984710b0b0980857aaricow@chromium.org
170830ce411529579186181838984710b0b0980857aaricow@chromium.org// Bit field clear.
170930ce411529579186181838984710b0b0980857aaricow@chromium.org// Sets #width adjacent bits at position #lsb in the destination register
171030ce411529579186181838984710b0b0980857aaricow@chromium.org// to zero, preserving the value of the other bits.
171130ce411529579186181838984710b0b0980857aaricow@chromium.org//   bfc dst, #lsb, #width
171230ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::bfc(Register dst, int lsb, int width, Condition cond) {
171330ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1714e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(ARMv7));
1715e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
1716e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((lsb >= 0) && (lsb <= 31));
1717e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((width >= 1) && (width <= (32 - lsb)));
171830ce411529579186181838984710b0b0980857aaricow@chromium.org  int msb = lsb + width - 1;
171930ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf);
172030ce411529579186181838984710b0b0980857aaricow@chromium.org}
172130ce411529579186181838984710b0b0980857aaricow@chromium.org
172230ce411529579186181838984710b0b0980857aaricow@chromium.org
172330ce411529579186181838984710b0b0980857aaricow@chromium.org// Bit field insert.
172430ce411529579186181838984710b0b0980857aaricow@chromium.org// Inserts #width adjacent bits from the low bits of the source register
172530ce411529579186181838984710b0b0980857aaricow@chromium.org// into position #lsb of the destination register.
172630ce411529579186181838984710b0b0980857aaricow@chromium.org//   bfi dst, src, #lsb, #width
172730ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::bfi(Register dst,
172830ce411529579186181838984710b0b0980857aaricow@chromium.org                    Register src,
172930ce411529579186181838984710b0b0980857aaricow@chromium.org                    int lsb,
173030ce411529579186181838984710b0b0980857aaricow@chromium.org                    int width,
173130ce411529579186181838984710b0b0980857aaricow@chromium.org                    Condition cond) {
173230ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1733e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(ARMv7));
1734e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc) && !src.is(pc));
1735e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((lsb >= 0) && (lsb <= 31));
1736e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((width >= 1) && (width <= (32 - lsb)));
173730ce411529579186181838984710b0b0980857aaricow@chromium.org  int msb = lsb + width - 1;
173830ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
173930ce411529579186181838984710b0b0980857aaricow@chromium.org       src.code());
174030ce411529579186181838984710b0b0980857aaricow@chromium.org}
174130ce411529579186181838984710b0b0980857aaricow@chromium.org
174230ce411529579186181838984710b0b0980857aaricow@chromium.org
1743169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::pkhbt(Register dst,
1744169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Register src1,
1745169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      const Operand& src2,
1746169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Condition cond ) {
1747169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1748169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1749169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | imm5(11-7) | 0(6) | 01(5-4) | Rm(3-0)
1750e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
1751e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src1.is(pc));
1752e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src2.rm().is(pc));
1753e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src2.rm().is(no_reg));
1754e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src2.rs().is(no_reg));
1755e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
1756e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src2.shift_op() == LSL);
1757169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1758169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       src2.shift_imm_*B7 | B4 | src2.rm().code());
1759169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1760169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1761169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1762169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::pkhtb(Register dst,
1763169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Register src1,
1764169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      const Operand& src2,
1765169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Condition cond) {
1766169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1767169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1768169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | imm5(11-7) | 1(6) | 01(5-4) | Rm(3-0)
1769e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
1770e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src1.is(pc));
1771e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src2.rm().is(pc));
1772e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src2.rm().is(no_reg));
1773e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src2.rs().is(no_reg));
1774e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
1775e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src2.shift_op() == ASR);
1776169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int asr = (src2.shift_imm_ == 32) ? 0 : src2.shift_imm_;
1777169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1778169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       asr*B7 | B6 | B4 | src2.rm().code());
1779169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1780169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1781169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1782169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::uxtb(Register dst,
1783169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const Operand& src,
1784169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     Condition cond) {
1785169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.274.
1786169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101110(27-20) | 1111(19-16) |
1787169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1788e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
1789e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src.rm().is(pc));
1790e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src.rm().is(no_reg));
1791e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src.rs().is(no_reg));
1792e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src.shift_imm_ == 0) ||
1793169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 8) ||
1794169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 16) ||
1795169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 24));
1796a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  // Operand maps ROR #0 to LSL #0.
1797e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src.shift_op() == ROR) ||
1798a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org         ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
1799169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
1800169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1801169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1802169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1803169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1804169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::uxtab(Register dst,
1805169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Register src1,
1806169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      const Operand& src2,
1807169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Condition cond) {
1808169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.271.
1809169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101110(27-20) | Rn(19-16) |
1810169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1811e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
1812e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src1.is(pc));
1813e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src2.rm().is(pc));
1814e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src2.rm().is(no_reg));
1815e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src2.rs().is(no_reg));
1816e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src2.shift_imm_ == 0) ||
1817169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src2.shift_imm_ == 8) ||
1818169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src2.shift_imm_ == 16) ||
1819169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src2.shift_imm_ == 24));
1820a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  // Operand maps ROR #0 to LSL #0.
1821e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src2.shift_op() == ROR) ||
1822a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org         ((src2.shift_op() == LSL) && (src2.shift_imm_ == 0)));
1823169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
1824169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       ((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
1825169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1826169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1827169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1828169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::uxtb16(Register dst,
1829169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                       const Operand& src,
1830169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                       Condition cond) {
1831169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.275.
1832169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101100(27-20) | 1111(19-16) |
1833169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1834e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
1835e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src.rm().is(pc));
1836e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src.rm().is(no_reg));
1837e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src.rs().is(no_reg));
1838e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src.shift_imm_ == 0) ||
1839169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 8) ||
1840169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 16) ||
1841169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 24));
1842a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  // Operand maps ROR #0 to LSL #0.
1843e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((src.shift_op() == ROR) ||
1844a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org         ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
1845169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
1846169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1847169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1848169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1849169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
18505c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Status register access instructions.
185143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mrs(Register dst, SRegister s, Condition cond) {
1852e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
185343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B24 | s | 15*B16 | dst.code()*B12);
185443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
185543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
185643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
185743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::msr(SRegisterFieldMask fields, const Operand& src,
185843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
1859e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fields >= B16 && fields < B20);  // at least one field set
186043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Instr instr;
186143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!src.rm_.is_valid()) {
18625c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate.
186343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t rotate_imm;
186443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t immed_8;
1865874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (src.must_output_reloc_info(this) ||
186643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
18675c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // Immediate operand cannot be encoded, load it first to register ip.
1868486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      move_32_bit_immediate(ip, src);
186943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      msr(fields, Operand(ip), cond);
187043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
187143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
187243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr = I | rotate_imm*B8 | immed_8;
187343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
1874e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src.rs_.is_valid() && src.shift_imm_ == 0);  // only rm allowed
187543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr = src.rm_.code();
187643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
187743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | instr | B24 | B21 | fields | 15*B12);
187843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
187943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
188043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18815c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Load/Store instructions.
188243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
1883defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (dst.is(pc)) {
1884f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    positions_recorder()->WriteRecordedPositions();
1885defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
188643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26 | L, dst, src);
188743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
188943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::str(Register src, const MemOperand& dst, Condition cond) {
189143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26, src, dst);
189243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
189343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) {
189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26 | B | L, dst, src);
189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::strb(Register src, const MemOperand& dst, Condition cond) {
190143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26 | B, src, dst);
190243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
190343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrh(Register dst, const MemOperand& src, Condition cond) {
190643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | L | B7 | H | B4, dst, src);
190743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
190843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::strh(Register src, const MemOperand& dst, Condition cond) {
191143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | B7 | H | B4, src, dst);
191243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
191343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrsb(Register dst, const MemOperand& src, Condition cond) {
191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | L | B7 | S6 | B4, dst, src);
191743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
191843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
192043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
192143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | L | B7 | S6 | H | B4, dst, src);
192243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
192343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
192443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19259155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgvoid Assembler::ldrd(Register dst1, Register dst2,
19269155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org                     const MemOperand& src, Condition cond) {
1927e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsEnabled(ARMv7));
1928e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src.rm().is(no_reg));
1929e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst1.is(lr));  // r14.
1930e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0, dst1.code() % 2);
1931e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(dst1.code() + 1, dst2.code());
19329155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  addrmod3(cond | B7 | B6 | B4, dst1, src);
1933720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org}
1934720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
1935720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
19369155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgvoid Assembler::strd(Register src1, Register src2,
19379155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org                     const MemOperand& dst, Condition cond) {
1938e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(dst.rm().is(no_reg));
1939e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src1.is(lr));  // r14.
1940e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0, src1.code() % 2);
1941e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(src1.code() + 1, src2.code());
1942e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsEnabled(ARMv7));
19439155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
1944720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org}
1945720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
1946e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1947169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Preload instructions.
1948169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::pld(const MemOperand& address) {
1949169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.128.
1950169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 0111(27-24) | U(23) | R(22) | 01(21-20) | Rn(19-16) |
1951169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(15-12) | imm5(11-07) | type(6-5) | 0(4)| Rm(3-0) |
1952e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(address.rm().is(no_reg));
1953e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(address.am() == Offset);
1954169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int U = B23;
1955169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int offset = address.offset();
1956169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (offset < 0) {
1957169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    offset = -offset;
1958169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    U = 0;
1959169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
1960e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset < 4096);
1961169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(kSpecialCondition | B26 | B24 | U | B22 | B20 | address.rn().code()*B16 |
1962169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       0xf*B12 | offset);
1963169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1964169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1965169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
19665c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Load/Store multiple instructions.
196743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldm(BlockAddrMode am,
196843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register base,
196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    RegList dst,
197043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
19715c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // ABI stack constraint: ldmxx base, {..sp..}  base != sp  is not restartable.
1972e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(base.is(sp) || (dst & sp.bit()) == 0);
197343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
197443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod4(cond | B27 | am | L, base, dst);
197543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19765c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Emit the constant pool after a function return implemented by ldm ..{..pc}.
197743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (cond == al && (dst & pc.bit()) != 0) {
197843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // There is a slight chance that the ldm instruction was actually a call,
197943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // in which case it would be wrong to return into the constant pool; we
198043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // recognize this case by checking if the emission of the pool was blocked
198143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // at the pc of the ldm instruction by a mov lr, pc instruction; if this is
198243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // the case, we emit a jump over the pool.
198343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CheckConstPool(true, no_const_pool_before_ == pc_offset() - kInstrSize);
198443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
198543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
198643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
198743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
198843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::stm(BlockAddrMode am,
198943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register base,
199043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    RegList src,
199143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
199243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod4(cond | B27 | am, base, src);
199343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
199443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
199543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19965c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Exception-generating instructions and debugging support.
1997e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// Stops with a non-negative code less than kNumOfWatchedStops support
1998e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// enabling/disabling and a counter feature. See simulator-arm.h .
1999e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgvoid Assembler::stop(const char* msg, Condition cond, int32_t code) {
20005d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#ifndef __arm__
2001e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(code >= kDefaultStopCode);
20027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  {
20037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // The Simulator will handle the stop instruction and get the message
20047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // address. It expects to find the address just after the svc instruction.
20057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    BlockConstPoolScope block_const_pool(this);
20067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (code >= 0) {
20077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      svc(kStopCode + code, cond);
20087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    } else {
20097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      svc(kStopCode + kMaxStopCode, cond);
20107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
20117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    emit(reinterpret_cast<Instr>(msg));
2012e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
20135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#else  // def __arm__
20140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  if (cond != al) {
20150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    Label skip;
20160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    b(&skip, NegateCondition(cond));
20170a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    bkpt(0);
20180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    bind(&skip);
20190a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  } else {
20200a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    bkpt(0);
20210a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
20225d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#endif  // def __arm__
202343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
202443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
202543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
202643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bkpt(uint32_t imm16) {  // v5 and above
2027e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(imm16));
2028378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
202943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
203043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
203143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2032e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgvoid Assembler::svc(uint32_t imm24, Condition cond) {
2033e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint24(imm24));
203443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | 15*B24 | imm24);
203543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
203643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
203743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20385c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Coprocessor instructions.
203943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cdp(Coprocessor coproc,
204043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_1,
204143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crd,
204243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crn,
204343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crm,
204443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_2,
204543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
2046e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint4(opcode_1) && is_uint3(opcode_2));
204743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 |
204843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code());
204943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
205043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
205143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
205243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cdp2(Coprocessor coproc,
205343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_1,
205443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crd,
205543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crn,
205643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crm,
205743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_2) {  // v5 and above
2058378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  cdp(coproc, opcode_1, crd, crn, crm, opcode_2, kSpecialCondition);
205943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
206043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
206143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
206243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mcr(Coprocessor coproc,
206343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_1,
206443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register rd,
206543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crn,
206643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crm,
206743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_2,
206843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
2069e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
207043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 |
207143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
207243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
207343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
207443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
207543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mcr2(Coprocessor coproc,
207643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_1,
207743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     Register rd,
207843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crn,
207943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crm,
208043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_2) {  // v5 and above
2081378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  mcr(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
208243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
208343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
208443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
208543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mrc(Coprocessor coproc,
208643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_1,
208743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register rd,
208843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crn,
208943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crm,
209043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_2,
209143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
2092e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
209343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 |
209443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
209543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
209643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
209743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
209843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mrc2(Coprocessor coproc,
209943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_1,
210043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     Register rd,
210143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crn,
210243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crm,
210343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_2) {  // v5 and above
2104378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  mrc(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
210543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
210643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
210743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
210843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc(Coprocessor coproc,
210943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crd,
211043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    const MemOperand& src,
211143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    LFlag l,
211243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
211343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src);
211443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
211543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
211643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
211743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc(Coprocessor coproc,
211843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crd,
211943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register rn,
212043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int option,
212143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    LFlag l,
212243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
21235c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unindexed addressing.
2124e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint8(option));
212543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |
212643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       coproc*B8 | (option & 255));
212743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
212843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
212943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
213043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc2(Coprocessor coproc,
213143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crd,
213243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     const MemOperand& src,
213343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     LFlag l) {  // v5 and above
2134378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ldc(coproc, crd, src, l, kSpecialCondition);
213543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
213643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
213743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
213843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc2(Coprocessor coproc,
213943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crd,
214043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     Register rn,
214143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int option,
214243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     LFlag l) {  // v5 and above
2143378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ldc(coproc, crd, rn, option, l, kSpecialCondition);
214443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
214543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
214643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2147c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// Support for VFP.
2148d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
2149b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Assembler::vldr(const DwVfpRegister dst,
2150b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Register base,
2151b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     int offset,
2152b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Condition cond) {
2153b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Ddst = MEM(Rbase + offset).
2154003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-924.
2155003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) |
2156003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 1011(11-8) | offset
2157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2162003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2163003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
21643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
2165e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset >= 0);
21663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
2167003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 |
21683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         0xB*B8 | ((offset / 4) & 255));
21693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
21703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
21713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
2172e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!base.is(ip));
21733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
21743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
21753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
21763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
21773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
2178003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8);
21793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
21803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
21813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
21823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
21833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vldr(const DwVfpRegister dst,
21843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
21853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
2186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(operand.am_ == Offset);
21877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (operand.rm().is_valid()) {
21887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    add(ip, operand.rn(),
21897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
21907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vldr(dst, ip, 0, cond);
21917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
21927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vldr(dst, operand.rn(), operand.offset(), cond);
21937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2194b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
2195b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
2196b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
21975d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vldr(const SwVfpRegister dst,
21985d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     const Register base,
21995d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     int offset,
22005d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     const Condition cond) {
22015d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Sdst = MEM(Rbase + offset).
22025d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Instruction details available in ARM DDI 0406A, A8-628.
2203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) |
22045d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Vdst(15-12) | 1010(11-8) | offset
2205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2210d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sd, d;
2211d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  dst.split_code(&sd, &d);
2212e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset >= 0);
22133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
22143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
2215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 |
22165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org       0xA*B8 | ((offset / 4) & 255));
22173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
22183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
22193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
2220e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!base.is(ip));
22213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
22223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
22233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
22243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
22253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
22263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    emit(cond | d*B22 | 0xD1*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
22273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
22283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
22293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
22303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
22313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vldr(const SwVfpRegister dst,
22323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
22333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
2234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(operand.am_ == Offset);
22357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (operand.rm().is_valid()) {
22367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    add(ip, operand.rn(),
22377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
22387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vldr(dst, ip, 0, cond);
22397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
22407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vldr(dst, operand.rn(), operand.offset(), cond);
22417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
22425d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
22435d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
22445d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
2245b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Assembler::vstr(const DwVfpRegister src,
2246b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Register base,
2247b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     int offset,
2248b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Condition cond) {
2249b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // MEM(Rbase + offset) = Dsrc.
2250003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1082.
2251003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) |
2252003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 1011(11-8) | (offset/4)
2253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset >= 0);
2259003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2260003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vd, &d);
2261003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
22623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
2263003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | u*B23 | d*B22 | base.code()*B16 | vd*B12 | 0xB*B8 |
2264003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org         ((offset / 4) & 255));
22653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
22663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
22673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
2268e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!base.is(ip));
22693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
22703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
22713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
22723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
22733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
2274003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8);
22753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
22763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
22773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
22783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
22793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vstr(const DwVfpRegister src,
22803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
22813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
2282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(operand.am_ == Offset);
22837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (operand.rm().is_valid()) {
22847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    add(ip, operand.rn(),
22857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
22867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vstr(src, ip, 0, cond);
22877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
22887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vstr(src, operand.rn(), operand.offset(), cond);
22897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2290b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
2291b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
2292b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
22930b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid Assembler::vstr(const SwVfpRegister src,
22940b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                     const Register base,
22950b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                     int offset,
22960b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                     const Condition cond) {
22970b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // MEM(Rbase + offset) = SSrc.
22980b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Instruction details available in ARM DDI 0406A, A8-786.
2299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) |
23000b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Vdst(15-12) | 1010(11-8) | (offset/4)
2301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2302a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2306d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sd, d;
2307d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  src.split_code(&sd, &d);
2308e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset >= 0);
23093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
23103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 |
23113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         0xA*B8 | ((offset / 4) & 255));
23123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
23133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
23143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
2315e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!base.is(ip));
23163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
23173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
23183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
23193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
23203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
23213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    emit(cond | d*B22 | 0xD0*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
23223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
23233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
23243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
23253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
23263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vstr(const SwVfpRegister src,
23273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
23283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
2329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(operand.am_ == Offset);
23307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (operand.rm().is_valid()) {
23317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    add(ip, operand.rn(),
23327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
23337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vstr(src, ip, 0, cond);
23347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
23357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    vstr(src, operand.rn(), operand.offset(), cond);
23367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
23370b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org}
23380b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
23390b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
234074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vldm(BlockAddrMode am,
234174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
234274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister first,
234374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister last,
234474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
2345003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-922.
234674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
2347003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // first(15-12) | 1011(11-8) | (count * 2)
2348e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(first.code(), last.code());
2349e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(am == ia || am == ia_w || am == db_w);
2350e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!base.is(pc));
235174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
235274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
235374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
235474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
2355e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(count <= 16);
235674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
235774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xB*B8 | count*2);
235874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
235974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
236074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
236174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vstm(BlockAddrMode am,
236274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
236374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister first,
236474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister last,
236574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
2366003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1080.
236774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
236874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // first(15-12) | 1011(11-8) | (count * 2)
2369e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(first.code(), last.code());
2370e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(am == ia || am == ia_w || am == db_w);
2371e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!base.is(pc));
237274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
237374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
237474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
237574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
2376e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(count <= 16);
237774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
237874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xB*B8 | count*2);
237974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
238074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
238174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vldm(BlockAddrMode am,
238274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
238374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister first,
238474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister last,
238574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
238674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // Instruction details available in ARM DDI 0406A, A8-626.
238774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
238874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // first(15-12) | 1010(11-8) | (count/2)
2389e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(first.code(), last.code());
2390e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(am == ia || am == ia_w || am == db_w);
2391e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!base.is(pc));
239274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
239374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
239474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
239574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
239674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
239774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xA*B8 | count);
239874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
239974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
240074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
240174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vstm(BlockAddrMode am,
240274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
240374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister first,
240474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister last,
240574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
240674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // Instruction details available in ARM DDI 0406A, A8-784.
240774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
240874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // first(15-12) | 1011(11-8) | (count/2)
2409e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(first.code(), last.code());
2410e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(am == ia || am == ia_w || am == db_w);
2411e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!base.is(pc));
241274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
241374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
241474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
241574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
241674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
241774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xA*B8 | count);
241874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
241974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
2420e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
24216a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgstatic void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
24226a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  uint64_t i;
2423d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  memcpy(&i, &d, 8);
24246a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24256a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *lo = i & 0xffffffff;
24266a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *hi = i >> 32;
24276a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
24286a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2429e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
24306a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org// Only works for little endian floating point formats.
24316a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org// We don't support VFP on the mixed endian floating point platform.
24326a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgstatic bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
2433e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(VFP3));
24346a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24356a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // VMOV can accept an immediate of the form:
24366a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
24376a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7
24386a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
24396a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // The immediate is encoded using an 8-bit quantity, comprised of two
24406a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // 4-bit fields. For an 8-bit immediate of the form:
24416a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
24426a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  [abcdefgh]
24436a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
24446a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // where a is the MSB and h is the LSB, an immediate 64-bit double can be
24456a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // created of the form:
24466a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
24476a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  [aBbbbbbb,bbcdefgh,00000000,00000000,
24486a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //      00000000,00000000,00000000,00000000]
24496a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
24506a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // where B = ~b.
24516a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
24526a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24536a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  uint32_t lo, hi;
24546a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  DoubleAsTwoUInt32(d, &lo, &hi);
24556a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24566a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // The most obvious constraint is the long block of zeroes.
24576a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  if ((lo != 0) || ((hi & 0xffff) != 0)) {
24586a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    return false;
24596a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
24606a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24616a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Bits 62:55 must be all clear or all set.
24626a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  if (((hi & 0x3fc00000) != 0) && ((hi & 0x3fc00000) != 0x3fc00000)) {
24636a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    return false;
24646a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
24656a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24666a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Bit 63 must be NOT bit 62.
24676a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  if (((hi ^ (hi << 1)) & (0x40000000)) == 0) {
24686a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    return false;
24696a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
24706a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24716a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Create the encoded immediate in the form:
24726a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  [00000000,0000abcd,00000000,0000efgh]
24736a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *encoding  = (hi >> 16) & 0xf;      // Low nybble.
24746a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *encoding |= (hi >> 4) & 0x70000;   // Low three bits of the high nybble.
24756a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *encoding |= (hi >> 12) & 0x80000;  // Top bit of the high nybble.
24766a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24776a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  return true;
24786a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
24796a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24806a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24816a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
24826a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                     double imm,
248371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org                     const Register scratch) {
24846a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  uint32_t enc;
2485b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) {
24866a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    // The double can be encoded in the instruction.
2487003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    //
2488003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // Dd = immediate
2489003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // Instruction details available in ARM DDI 0406C.b, A8-936.
2490003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) |
2491003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0)
2492003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    int vd, d;
2493003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    dst.split_code(&vd, &d);
249471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org    emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc);
2495d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  } else if (FLAG_enable_vldr_imm && is_constant_pool_available()) {
24964cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // TODO(jfb) Temporarily turned off until we have constant blinding or
24974cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           some equivalent mitigation: an attacker can otherwise control
24984cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           generated data which also happens to be executable, a Very Bad
24994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           Thing indeed.
25004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           Blinding gets tricky because we don't have xor, we probably
25014cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           need to add/subtract without losing precision, which requires a
25024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           cookie value that Lithium is probably better positioned to
25034cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           choose.
25044cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           We could also add a few peepholes here like detecting 0.0 and
25054cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           -0.0 and doing a vmov from the sequestered d14, forcing denorms
25064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           to zero (we set flush-to-zero), and normalizing NaN values.
25074cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           We could also detect redundant values.
25084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           The code could also randomize the order of values, though
25094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           that's tricky because vldr has a limited reach. Furthermore
25104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           it breaks load locality.
2511763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    RelocInfo rinfo(pc_, imm);
2512d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
2513d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    if (section == ConstantPoolArray::EXTENDED_SECTION) {
2514e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(FLAG_enable_ool_constant_pool);
2515d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // Emit instructions to load constant pool offset.
2516d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      movw(ip, 0);
2517d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      movt(ip, 0);
2518d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // Load from constant pool at offset.
2519d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      vldr(dst, MemOperand(pp, ip));
2520d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else {
2521e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(section == ConstantPoolArray::SMALL_SECTION);
2522d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      vldr(dst, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0));
2523d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
25246a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  } else {
25254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // Synthesise the double from ARM immediates.
25266a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    uint32_t lo, hi;
25276a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    DoubleAsTwoUInt32(imm, &lo, &hi);
25286a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
252933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (scratch.is(no_reg)) {
2530003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      if (dst.code() < 16) {
2531fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code());
2532003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // Move the low part of the double into the lower of the corresponsing S
2533003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // registers of D register dst.
2534003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(lo));
2535fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        vmov(loc.low(), ip);
2536003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2537003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // Move the high part of the double into the higher of the
2538003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // corresponsing S registers of D register dst.
2539003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(hi));
2540fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        vmov(loc.high(), ip);
2541003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      } else {
2542003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // D16-D31 does not have S registers, so move the low and high parts
2543003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // directly to the D register using vmov.32.
2544003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // Note: This may be slower, so we only do this when we have to.
2545003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(lo));
254671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org        vmov(dst, VmovIndexLo, ip);
2547003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(hi));
254871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org        vmov(dst, VmovIndexHi, ip);
2549003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      }
255033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    } else {
255133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      // Move the low and high parts of the double to a D register in one
255233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      // instruction.
2553003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      mov(ip, Operand(lo));
255433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      mov(scratch, Operand(hi));
255571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org      vmov(dst, ip, scratch);
25566a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    }
25576a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
25586a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
25596a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
25606a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
25616a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgvoid Assembler::vmov(const SwVfpRegister dst,
25626a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                     const SwVfpRegister src,
25636a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                     const Condition cond) {
25646a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Sd = Sm
25656a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Instruction details available in ARM DDI 0406B, A8-642.
2566d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sd, d, sm, m;
2567d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  dst.split_code(&sd, &d);
2568d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  src.split_code(&sm, &m);
2569d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm);
25706a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
25716a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
25726a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
257313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
257469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org                     const DwVfpRegister src,
257569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org                     const Condition cond) {
257669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // Dd = Dm
2577003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-938.
2578003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2579003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2580003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2581003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2582003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2583003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2584003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 |
2585003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       vm);
2586003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
2587003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2588003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2589003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
25906ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org                     const VmovIndex index,
2591003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org                     const Register src,
2592003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org                     const Condition cond) {
2593003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Dd[index] = Rt
2594003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-940.
2595003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) |
2596003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
2597e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index.index == 0 || index.index == 1);
2598003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2599003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
26006ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 |
26016ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org       d*B7 | B4);
260269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
260369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
260469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
2605fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid Assembler::vmov(const Register dst,
2606fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                     const VmovIndex index,
2607fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                     const DwVfpRegister src,
2608fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                     const Condition cond) {
2609fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Dd[index] = Rt
2610fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.342.
2611fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // cond(31-28) | 1110(27-24) | U=0(23) | opc1=0index(22-21) | 1(20) |
2612fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Vn(19-16) | Rt(15-12) | 1011(11-8) | N(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
2613e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index.index == 0 || index.index == 1);
2614fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int vn, n;
2615fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  src.split_code(&vn, &n);
2616fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  emit(cond | 0xE*B24 | index.index*B21 | B20 | vn*B16 | dst.code()*B12 |
2617fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org       0xB*B8 | n*B7 | B4);
2618fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
2619fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
2620fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
262169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
262213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Register src1,
262313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Register src2,
262413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
2625c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dm = <Rt,Rt2>.
2626003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-948.
2627c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
2628c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2629e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src1.is(pc) && !src2.is(pc));
2630003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2631003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vm, &m);
2632c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  emit(cond | 0xC*B24 | B22 | src2.code()*B16 |
2633003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2634c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2635c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2636c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
263713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const Register dst1,
263813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Register dst2,
263913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src,
264013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
2641c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // <Rt,Rt2> = Dm.
2642003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-948.
2643c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
2644c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2645e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst1.is(pc) && !dst2.is(pc));
2646003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2647003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2648c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 |
2649003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2650c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2651c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2652c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
265313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const SwVfpRegister dst,
2654c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Register src,
2655c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Condition cond) {
2656c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Sn = Rt.
2657c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-642.
2658c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) |
2659c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2660e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src.is(pc));
2661d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sn, n;
2662d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  dst.split_code(&sn, &n);
2663d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
2664c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2665c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2666c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
266713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const Register dst,
266813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const SwVfpRegister src,
2669c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Condition cond) {
2670c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt = Sn.
2671c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-642.
2672c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) |
2673c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!dst.is(pc));
2675d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sn, n;
2676d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  src.split_code(&sn, &n);
2677d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
2678c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2679c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2680c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
26815d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// Type of data to read from or write to VFP register.
26825d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// Used as specifier in generic vcvt instruction.
26835d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgenum VFPType { S32, U32, F32, F64 };
26845d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26855d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26865d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic bool IsSignedVFPType(VFPType type) {
26875d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  switch (type) {
26885d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case S32:
26895d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return true;
26905d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case U32:
26915d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
26925d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    default:
26935d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      UNREACHABLE();
26945d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
26955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
26965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
26975d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26985d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26995d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic bool IsIntegerVFPType(VFPType type) {
27005d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  switch (type) {
27015d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case S32:
27025d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case U32:
27035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return true;
27045d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F32:
27055d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F64:
27065d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
27075d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    default:
27085d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      UNREACHABLE();
27095d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
27105d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
27115d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
27125d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27145d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic bool IsDoubleVFPType(VFPType type) {
27155d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  switch (type) {
27165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F32:
27175d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
27185d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F64:
27195d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return true;
27205d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    default:
27215d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      UNREACHABLE();
27225d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
27235d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
27245d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
27255d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27265d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
2727d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org// Split five bit reg_code based on size of reg_type.
2728d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org//  32-bit register codes are Vm:M
2729d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org//  64-bit register codes are M:Vm
2730d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org// where Vm is four bits, and M is a single bit.
2731d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgstatic void SplitRegCode(VFPType reg_type,
27325d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                         int reg_code,
27335d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                         int* vm,
27345d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                         int* m) {
2735e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((reg_code >= 0) && (reg_code <= 31));
2736d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
2737d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    // 32 bit type.
27385d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *m  = reg_code & 0x1;
27395d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *vm = reg_code >> 1;
27405d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  } else {
2741d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    // 64 bit type.
27425d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *m  = (reg_code & 0x10) >> 4;
27435d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *vm = reg_code & 0x0F;
27445d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
27455d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
27465d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27475d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27485d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// Encode vcvt.src_type.dst_type instruction.
27495d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic Instr EncodeVCVT(const VFPType dst_type,
27505d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const int dst_code,
27515d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const VFPType src_type,
27525d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const int src_code,
275383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                        VFPConversionMode mode,
27545d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const Condition cond) {
2755e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src_type != dst_type);
2756d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int D, Vd, M, Vm;
2757d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  SplitRegCode(src_type, src_code, &Vm, &M);
2758d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  SplitRegCode(dst_type, dst_code, &Vd, &D);
2759d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
27605d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) {
27615d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Conversion between IEEE floating point and 32-bit integer.
27625d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Instruction details available in ARM DDI 0406B, A8.6.295.
27635d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 1(19) | opc2(18-16) |
27645d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2765e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
27665d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
2767d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    int sz, opc2, op;
27685d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27695d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    if (IsIntegerVFPType(dst_type)) {
27705d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4;
27715d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
277201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org      op = mode;
27735d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    } else {
2774e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(IsIntegerVFPType(src_type));
27755d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      opc2 = 0x0;
27765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
27775d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
27785d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    }
27795d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27805d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | B19 | opc2*B16 |
27815d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            Vd*B12 | 0x5*B9 | sz*B8 | op*B7 | B6 | M*B5 | Vm);
27825d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  } else {
27835d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Conversion between IEEE double and single precision.
27845d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Instruction details available in ARM DDI 0406B, A8.6.298.
27855d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0111(19-16) |
27865d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Vd(15-12) | 101(11-9) | sz(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2787d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    int sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
27885d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 |
27895d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm);
27905d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
27915d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
27925d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27935d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
27945d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f64_s32(const DwVfpRegister dst,
27955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
279683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
27975d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
279801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond));
2799c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2800c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2801c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
28025d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f32_s32(const SwVfpRegister dst,
28035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
280483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
28055d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
280601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond));
28075d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
28085d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28095d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28105d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f64_u32(const DwVfpRegister dst,
28115d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
281283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
28135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
281401fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond));
28155d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
28165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28175d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28185d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_s32_f64(const SwVfpRegister dst,
28195d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const DwVfpRegister src,
282083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
28215d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
282201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond));
28235d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
28245d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28255d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28265d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_u32_f64(const SwVfpRegister dst,
28275d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const DwVfpRegister src,
282883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
28295d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
283001fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond));
28315d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
28325d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28335d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28345d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f64_f32(const DwVfpRegister dst,
28355d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
283683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
28375d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
283801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond));
28395d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
28405d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28415d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
28425d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f32_f64(const SwVfpRegister dst,
28435d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const DwVfpRegister src,
284483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
28455d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
284601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond));
2847c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2848c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2849c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2850bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgvoid Assembler::vcvt_f64_s32(const DwVfpRegister dst,
2851bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                             int fraction_bits,
2852bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                             const Condition cond) {
2853bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-874.
2854bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 1010(19-16) | Vd(15-12) |
2855bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // 101(11-9) | sf=1(8) | sx=1(7) | 1(6) | i(5) | 0(4) | imm4(3-0)
2856e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fraction_bits > 0 && fraction_bits <= 32);
2857e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(VFP3));
2858bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  int vd, d;
2859bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  dst.split_code(&vd, &d);
28608f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int imm5 = 32 - fraction_bits;
28618f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int i = imm5 & 1;
28628f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int imm4 = (imm5 >> 1) & 0xf;
2863bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 |
2864bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org       vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4);
2865bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org}
2866bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2867bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2868badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid Assembler::vneg(const DwVfpRegister dst,
2869badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org                     const DwVfpRegister src,
2870badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org                     const Condition cond) {
2871003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-968.
2872003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) |
2873003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2874003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2875003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2876003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2877003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2878003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2879003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 |
2880003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
2881badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org}
2882badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
2883badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
28847a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.orgvoid Assembler::vabs(const DwVfpRegister dst,
28857a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org                     const DwVfpRegister src,
28867a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org                     const Condition cond) {
2887003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-524.
2888003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2889003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2890003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2891003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2892003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2893003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2894003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 |
2895003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
28967a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org}
28977a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org
28987a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org
289913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vadd(const DwVfpRegister dst,
290013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
290113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
290213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
290313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vadd(Dn, Dm) double precision floating point addition.
2904c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2905003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-830.
2906003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2907003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2908003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2909003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2910003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2911003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2912003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2913003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2914003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2915003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       n*B7 | m*B5 | vm);
2916c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2917c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2918c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
291913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vsub(const DwVfpRegister dst,
292013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
292113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
292213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
292313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vsub(Dn, Dm) double precision floating point subtraction.
2924c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2925003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1086.
2926003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2927003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2928003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2929003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2930003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2931003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2932003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2933003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2934003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2935003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       n*B7 | B6 | m*B5 | vm);
2936c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2937c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2938c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
293913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmul(const DwVfpRegister dst,
294013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
294113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
294213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
294313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vmul(Dn, Dm) double precision floating point multiplication.
2944c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2945003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-960.
2946003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) |
2947003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2948003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2949003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2950003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2951003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2952003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2953003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2954003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2955003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       n*B7 | m*B5 | vm);
2956c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2957c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2958c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2959fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Assembler::vmla(const DwVfpRegister dst,
2960fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     const DwVfpRegister src1,
2961fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     const DwVfpRegister src2,
2962fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     const Condition cond) {
2963003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-932.
2964003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) |
2965003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0)
2966003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2967003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2968003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2969003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2970003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2971003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2972003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
2973003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       vm);
2974fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
2975fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
2976fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
29778432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgvoid Assembler::vmls(const DwVfpRegister dst,
29788432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                     const DwVfpRegister src1,
29798432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                     const DwVfpRegister src2,
29808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                     const Condition cond) {
29818432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-932.
29828432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) |
29838432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=1(6) | M(5) | 0(4) | Vm(3-0)
29848432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int vd, d;
29858432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  dst.split_code(&vd, &d);
29868432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int vn, n;
29878432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  src1.split_code(&vn, &n);
29888432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int vm, m;
29898432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  src2.split_code(&vm, &m);
29908432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | B6 |
29918432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org       m*B5 | vm);
29928432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org}
29938432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
29948432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
299513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vdiv(const DwVfpRegister dst,
299613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
299713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
299813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
299913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vdiv(Dn, Dm) double precision floating point division.
3000c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
3001003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-882.
3002003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) |
3003003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
3004003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
3005003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
3006003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
3007003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
3008003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
3009003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
3010003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
3011003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       vm);
3012c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
3013c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
3014c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
301513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vcmp(const DwVfpRegister src1,
301613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
3017c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Condition cond) {
3018c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // vcmp(Dd, Dm) double precision floating point comparison.
3019003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-864.
3020003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) |
3021003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
3022003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
3023003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vd, &d);
3024003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
3025003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
3026003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 |
3027003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
3028c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
3029c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
3030c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
3031ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgvoid Assembler::vcmp(const DwVfpRegister src1,
3032ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                     const double src2,
3033ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                     const Condition cond) {
3034003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // vcmp(Dd, #0.0) double precision floating point comparison.
3035003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-864.
3036003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) |
3037003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0)
3038e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src2 == 0.0);
3039003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
3040003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vd, &d);
3041003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6);
3042ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org}
3043ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
3044ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
304501fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.orgvoid Assembler::vmsr(Register dst, Condition cond) {
304601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-652.
304701fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) |
304801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
304901fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(cond | 0xE*B24 | 0xE*B20 |  B16 |
305001fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org       dst.code()*B12 | 0xA*B8 | B4);
305101fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org}
305201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
305301fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
3054c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Assembler::vmrs(Register dst, Condition cond) {
3055c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-652.
3056c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) |
3057c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
3058c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  emit(cond | 0xE*B24 | 0xF*B20 |  B16 |
3059c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org       dst.code()*B12 | 0xA*B8 | B4);
3060c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
3061c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
3062c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
306332d961d4454609ab4251a760fc46b19f661da90clrn@chromium.orgvoid Assembler::vsqrt(const DwVfpRegister dst,
306432d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                      const DwVfpRegister src,
306532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                      const Condition cond) {
3066003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1058.
3067003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) |
3068003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0)
3069003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
3070003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
3071003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
3072003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
3073003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 |
3074003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
307532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org}
307632d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
307732d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
3078169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Support for NEON.
3079169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
3080169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::vld1(NeonSize size,
3081169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonListOperand& dst,
3082169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonMemOperand& src) {
3083169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.320.
3084169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) |
3085169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
3086e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(NEON));
3087169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vd, d;
3088169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  dst.base().split_code(&vd, &d);
3089169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 |
3090169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       dst.type()*B8 | size*B6 | src.align()*B4 | src.rm().code());
3091169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
3092169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
3093169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
3094169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::vst1(NeonSize size,
3095169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonListOperand& src,
3096169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonMemOperand& dst) {
3097169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.404.
3098169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) |
3099169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
3100e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(NEON));
3101169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vd, d;
3102169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  src.base().split_code(&vd, &d);
3103169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 |
3104169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       size*B6 | dst.align()*B4 | dst.rm().code());
3105169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
3106169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
3107169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
3108169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) {
3109169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.346.
3110169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) |
3111169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0)
3112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(CpuFeatures::IsSupported(NEON));
3113169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vd, d;
3114169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  dst.split_code(&vd, &d);
3115169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vm, m;
3116169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  src.split_code(&vm, &m);
3117169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(0xFU*B28 | B25 | (dt & NeonDataTypeUMask) | B23 | d*B22 |
3118169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        (dt & NeonDataTypeSizeMask)*B19 | vd*B12 | 0xA*B8 | m*B5 | B4 | vm);
3119169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
3120169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
3121169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
31225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Pseudo instructions.
3123013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgvoid Assembler::nop(int type) {
312489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes
312589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // some of the CPU's pipeline and has to issue. Older ARM chips simply used
312689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
312789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
312889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // a type.
3129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
3130013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  emit(al | 13*B21 | type*B12 | type);
3131013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
3132013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3133013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
313489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgbool Assembler::IsMovT(Instr instr) {
313589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
313689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             ((kNumRegisters-1)*B12) |            // mask out register
313789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             EncodeMovwImmediate(0xFFFF));        // mask out immediate value
3138d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return instr == kMovtPattern;
313989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
314089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
314189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
314289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgbool Assembler::IsMovW(Instr instr) {
314389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
314489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             ((kNumRegisters-1)*B12) |            // mask out destination
314589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             EncodeMovwImmediate(0xFFFF));        // mask out immediate value
3146d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return instr == kMovwPattern;
3147d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
3148d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3149d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3150d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgInstr Assembler::GetMovTPattern() { return kMovtPattern; }
3151d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3152d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3153d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgInstr Assembler::GetMovWPattern() { return kMovwPattern; }
3154d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3155d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3156d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgInstr Assembler::EncodeMovwImmediate(uint32_t immediate) {
3157e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(immediate < 0x10000);
3158d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
3159d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
3160d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3161d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
3162d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgInstr Assembler::PatchMovwImmediate(Instr instruction, uint32_t immediate) {
3163d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  instruction &= ~EncodeMovwImmediate(0xffff);
3164d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return instruction | EncodeMovwImmediate(immediate);
316589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
316689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
316789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
3168a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgint Assembler::DecodeShiftImm(Instr instr) {
3169a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  int rotate = Instruction::RotateValue(instr) * 2;
3170a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  int immed8 = Instruction::Immed8Value(instr);
3171a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return (immed8 >> rotate) | (immed8 << (32 - rotate));
3172a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
3173a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3174a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3175a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgInstr Assembler::PatchShiftImm(Instr instr, int immed) {
3176a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  uint32_t rotate_imm = 0;
3177a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  uint32_t immed_8 = 0;
3178a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  bool immed_fits = fits_shifter(immed, &rotate_imm, &immed_8, NULL);
3179a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DCHECK(immed_fits);
3180a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  USE(immed_fits);
3181a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return (instr & ~kOff12Mask) | (rotate_imm << 8) | immed_8;
3182a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
3183a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3184a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3185beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.orgbool Assembler::IsNop(Instr instr, int type) {
3186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
3187496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // Check for mov rx, rx where x = type.
3188beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  return instr == (al | 13*B21 | type*B12 | type);
3189beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org}
3190beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
3191beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
3192a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgbool Assembler::IsMovImmed(Instr instr) {
3193a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return (instr & kMovImmedMask) == kMovImmedPattern;
3194a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
3195a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3196a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3197a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgbool Assembler::IsOrrImmed(Instr instr) {
3198a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return (instr & kOrrImmedMask) == kOrrImmedPattern;
3199a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
3200a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3201a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
32027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// static
3203c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgbool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) {
3204c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  uint32_t dummy1;
3205c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  uint32_t dummy2;
3206c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  return fits_shifter(imm32, &dummy1, &dummy2, NULL);
3207c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
3208c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
3209c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
32109ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool Assembler::ImmediateFitsAddrMode2Instruction(int32_t imm32) {
32119ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  return is_uint12(abs(imm32));
32129ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org}
32139ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
32149ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
32155c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Debugging.
32164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid Assembler::RecordJSReturn() {
3217f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
32184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  CheckBuffer();
32194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  RecordRelocInfo(RelocInfo::JS_RETURN);
32204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
32214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
32224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
32232356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgvoid Assembler::RecordDebugBreakSlot() {
3224f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
32252356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  CheckBuffer();
32262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
32272356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org}
32282356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
32292356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
323043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::RecordComment(const char* msg) {
3231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_code_comments) {
323243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CheckBuffer();
3233236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
323443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
323543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
323643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
323743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid Assembler::RecordConstPool(int size) {
32395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // We only need this for debugger support, to correctly compute offsets in the
32405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // code.
32415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
32425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
32435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
3244e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
324543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::GrowBuffer() {
324643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!own_buffer_) FATAL("external code buffer is too small");
324743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32485c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Compute new buffer size.
324943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CodeDesc desc;  // the new buffer
32509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  if (buffer_size_ < 1 * MB) {
325143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    desc.buffer_size = 2*buffer_size_;
325243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
325343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    desc.buffer_size = buffer_size_ + 1*MB;
325443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
325543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CHECK_GT(desc.buffer_size, 0);  // no overflow
325643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3257f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up new buffer.
325843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc.buffer = NewArray<byte>(desc.buffer_size);
325943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
326043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc.instr_size = pc_offset();
326143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
326243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32635c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Copy the data.
326443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pc_delta = desc.buffer - buffer_;
326543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
3266d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemMove(desc.buffer, buffer_, desc.instr_size);
3267d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemMove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
3268d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org          desc.reloc_size);
326943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32705c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Switch buffers.
327143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(buffer_);
327243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  buffer_ = desc.buffer;
327343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  buffer_size_ = desc.buffer_size;
327443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  pc_ += pc_delta;
327543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
327643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                               reloc_info_writer.last_pc() + pc_delta);
327743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32785c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // None of our relocation types are pc relative pointing outside the code
327943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // buffer nor pc absolute pointing inside the code buffer, so there is no need
32805c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // to relocate any emitted relocation entries.
328143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32825c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Relocate pending relocation entries.
3283ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
3284ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
3285e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
3286236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org           rinfo.rmode() != RelocInfo::POSITION);
32874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    if (rinfo.rmode() != RelocInfo::JS_RETURN) {
32884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org      rinfo.set_pc(rinfo.pc() + pc_delta);
32894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    }
329043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3291ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
3292ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
3293e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(rinfo.rmode() == RelocInfo::NONE64);
3294ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    rinfo.set_pc(rinfo.pc() + pc_delta);
3295ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
3296763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  constant_pool_builder_.Relocate(pc_delta);
329743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
329843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
329943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Assembler::db(uint8_t data) {
33010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // No relocation info should be pending while using db. db is used
33020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // to write pure data with no pointers and the constant pool should
33030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // be emitted before using db.
3304e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(num_pending_32_bit_reloc_info_ == 0);
3305e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(num_pending_64_bit_reloc_info_ == 0);
3306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckBuffer();
3307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  *reinterpret_cast<uint8_t*>(pc_) = data;
3308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  pc_ += sizeof(uint8_t);
3309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3311a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Assembler::dd(uint32_t data) {
33130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // No relocation info should be pending while using dd. dd is used
33140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // to write pure data with no pointers and the constant pool should
33150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // be emitted before using dd.
3316e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(num_pending_32_bit_reloc_info_ == 0);
3317e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(num_pending_64_bit_reloc_info_ == 0);
3318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckBuffer();
3319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  *reinterpret_cast<uint32_t*>(pc_) = data;
3320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  pc_ += sizeof(uint32_t);
3321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3324057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid Assembler::emit_code_stub_address(Code* stub) {
3325057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  CheckBuffer();
3326057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  *reinterpret_cast<uint32_t*>(pc_) =
3327057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      reinterpret_cast<uint32_t>(stub->instruction_start());
3328057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  pc_ += sizeof(uint32_t);
3329057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
3330057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
3331057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
3332763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RelocInfo rinfo(pc_, rmode, data, NULL);
3334763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  RecordRelocInfo(rinfo);
3335763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3336763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3337763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3338763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
33394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (!RelocInfo::IsNone(rinfo.rmode())) {
33409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    // Don't record external references unless the heap will be serialized.
3341874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE &&
3342874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org        !serializer_enabled() && !emit_debug_code()) {
3343874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org      return;
33449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
3345e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
3346763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) {
3347763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      RelocInfo reloc_info_with_ast_id(rinfo.pc(),
3348763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org                                       rinfo.rmode(),
3349471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                       RecordedAstId().ToInt(),
3350471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                       NULL);
3351717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org      ClearRecordedAstId();
33528e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      reloc_info_writer.Write(&reloc_info_with_ast_id);
33538e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    } else {
33548e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      reloc_info_writer.Write(&rinfo);
33558e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
335643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
335743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
335843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3359e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3360d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgConstantPoolArray::LayoutSection Assembler::ConstantPoolAddEntry(
3361d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    const RelocInfo& rinfo) {
3362763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
3363d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return constant_pool_builder_.AddEntry(this, rinfo);
3364ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  } else {
3365763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    if (rinfo.rmode() == RelocInfo::NONE64) {
3366e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo);
3367763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      if (num_pending_64_bit_reloc_info_ == 0) {
3368763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org        first_const_pool_64_use_ = pc_offset();
3369763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      }
3370763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      pending_64_bit_reloc_info_[num_pending_64_bit_reloc_info_++] = rinfo;
3371763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    } else {
3372e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo);
3373763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      if (num_pending_32_bit_reloc_info_ == 0) {
3374763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org        first_const_pool_32_use_ = pc_offset();
3375763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      }
3376763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      pending_32_bit_reloc_info_[num_pending_32_bit_reloc_info_++] = rinfo;
3377ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
3378763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Make sure the constant pool is not emitted in place of the next
3379763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // instruction for which we just recorded relocation info.
3380763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    BlockConstPoolFor(1);
3381d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return ConstantPoolArray::SMALL_SECTION;
33824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
33834cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
33844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
338543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvoid Assembler::BlockConstPoolFor(int instructions) {
3387763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
3388763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Should be a no-op if using an out-of-line constant pool.
3389e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(num_pending_32_bit_reloc_info_ == 0);
3390e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(num_pending_64_bit_reloc_info_ == 0);
3391763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    return;
3392763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3393763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
33947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int pc_limit = pc_offset() + instructions * kInstrSize;
33957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (no_const_pool_before_ < pc_limit) {
3396ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    // Max pool start (if we need a jump and an alignment).
3397ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org#ifdef DEBUG
3398ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int start = pc_limit + kInstrSize + 2 * kPointerSize;
3399e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((num_pending_32_bit_reloc_info_ == 0) ||
3400ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org           (start - first_const_pool_32_use_ +
3401ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org            num_pending_64_bit_reloc_info_ * kDoubleSize < kMaxDistToIntPool));
3402e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((num_pending_64_bit_reloc_info_ == 0) ||
3403ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org           (start - first_const_pool_64_use_ < kMaxDistToFPPool));
3404ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org#endif
34057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    no_const_pool_before_ = pc_limit;
340643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
340743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (next_buffer_check_ < no_const_pool_before_) {
34097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    next_buffer_check_ = no_const_pool_before_;
34107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
34117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
341243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
341343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvoid Assembler::CheckConstPool(bool force_emit, bool require_jump) {
3415763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
3416763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Should be a no-op if using an out-of-line constant pool.
3417e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(num_pending_32_bit_reloc_info_ == 0);
3418e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(num_pending_64_bit_reloc_info_ == 0);
3419763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    return;
3420763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3421763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
34227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Some short sequence of instruction mustn't be broken up by constant pool
34237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // emission, such sequences are protected by calls to BlockConstPoolFor and
34247b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // BlockConstPoolScope.
34257b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (is_const_pool_blocked()) {
34265c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Something is wrong if emission is forced and blocked at the same time.
3427e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!force_emit);
342843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
342943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
343043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // There is nothing to do if there are no pending constant pool entries.
3432ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if ((num_pending_32_bit_reloc_info_ == 0) &&
3433ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      (num_pending_64_bit_reloc_info_ == 0)) {
34347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Calculate the offset of the next check.
34357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    next_buffer_check_ = pc_offset() + kCheckPoolInterval;
34367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return;
34377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
34387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
343943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check that the code buffer is large enough before emitting the constant
34407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // pool (include the jump over the pool and the constant pool marker and
34417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // the gap to the relocation information).
34427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int jump_instr = require_jump ? kInstrSize : 0;
34434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int size_up_to_marker = jump_instr + kInstrSize;
3444ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int size_after_marker = num_pending_32_bit_reloc_info_ * kPointerSize;
34454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool has_fp_values = (num_pending_64_bit_reloc_info_ > 0);
3446ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  bool require_64_bit_align = false;
3447ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (has_fp_values) {
3448ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    require_64_bit_align = (((uintptr_t)pc_ + size_up_to_marker) & 0x7);
3449ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (require_64_bit_align) {
3450ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      size_after_marker += kInstrSize;
3451ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
3452ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    size_after_marker += num_pending_64_bit_reloc_info_ * kDoubleSize;
3453ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
34544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
34554cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int size = size_up_to_marker + size_after_marker;
34564cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
34574cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // We emit a constant pool when:
34584cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //  * requested to do so by parameter force_emit (e.g. after each function).
34594cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //  * the distance from the first instruction accessing the constant pool to
34604cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    any of the constant pool entries will exceed its limit the next
34614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    time the pool is checked. This is overly restrictive, but we don't emit
34624cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    constant pool entries in-order so it's conservatively correct.
34634cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //  * the instruction doesn't require a jump after itself to jump over the
34644cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    constant pool, and we're getting close to running out of range.
34654cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (!force_emit) {
3466e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
3467ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    bool need_emit = false;
34684cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    if (has_fp_values) {
3469ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      int dist64 = pc_offset() +
3470ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                   size -
3471ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                   num_pending_32_bit_reloc_info_ * kPointerSize -
3472ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                   first_const_pool_64_use_;
3473ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) ||
3474ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) {
3475ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        need_emit = true;
34764cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
34774cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
3478ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int dist32 =
3479ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      pc_offset() + size - first_const_pool_32_use_;
3480ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) ||
3481ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) {
3482ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      need_emit = true;
3483ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
3484ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (!need_emit) return;
34854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
34864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
34875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  int needed_space = size + kGap;
34887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  while (buffer_space() <= needed_space) GrowBuffer();
34897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
34907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  {
34917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Block recursive calls to CheckConstPool.
34927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    BlockConstPoolScope block_const_pool(this);
34935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    RecordComment("[ Constant Pool");
34945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    RecordConstPool(size);
34957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
34967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Emit jump over constant pool if necessary.
34977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    Label after_pool;
34987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (require_jump) {
34997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      b(&after_pool);
350043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
350143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
350272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    // Put down constant pool marker "Undefined instruction".
35034cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // The data size helps disassembly know what to print.
3504906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    emit(kConstantPoolMarker |
3505906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org         EncodeConstantPoolLength(size_after_marker / kPointerSize));
35067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
35074cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    if (require_64_bit_align) {
35084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      emit(kConstantPoolMarker);
35094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
35104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
35114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // Emit 64-bit constant pool entries first: their range is smaller than
35124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // 32-bit entries.
3513ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
3514ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
35154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
3516e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!((uintptr_t)pc_ & 0x7));  // Check 64-bit alignment.
35174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
35184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      Instr instr = instr_at(rinfo.pc());
35194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
3520e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK((IsVldrDPcImmediateOffset(instr) &&
35214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org              GetVldrDRegisterImmediateOffset(instr) == 0));
35224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
35234cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      int delta = pc_ - rinfo.pc() - kPcLoadDelta;
3524e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(is_uint10(delta));
35254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
3526ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      bool found = false;
3527ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      uint64_t value = rinfo.raw_data64();
3528ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      for (int j = 0; j < i; j++) {
3529ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        RelocInfo& rinfo2 = pending_64_bit_reloc_info_[j];
3530ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        if (value == rinfo2.raw_data64()) {
3531ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          found = true;
3532e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(rinfo2.rmode() == RelocInfo::NONE64);
3533ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          Instr instr2 = instr_at(rinfo2.pc());
3534e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(IsVldrDPcImmediateOffset(instr2));
3535ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          delta = GetVldrDRegisterImmediateOffset(instr2);
3536ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          delta += rinfo2.pc() - rinfo.pc();
3537ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          break;
3538ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        }
3539ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      }
3540ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
35414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      instr_at_put(rinfo.pc(), SetVldrDRegisterImmediateOffset(instr, delta));
35424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
3543ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      if (!found) {
3544ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        uint64_t uint_data = rinfo.raw_data64();
3545ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        emit(uint_data & 0xFFFFFFFF);
3546ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        emit(uint_data >> 32);
3547ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      }
35484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
35494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
35504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // Emit 32-bit constant pool entries.
3551ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
3552ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
3553e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
35547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org             rinfo.rmode() != RelocInfo::POSITION &&
35555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org             rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
3556ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org             rinfo.rmode() != RelocInfo::CONST_POOL &&
3557ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org             rinfo.rmode() != RelocInfo::NONE64);
35584cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
35597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Instr instr = instr_at(rinfo.pc());
35604cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
35614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // 64-bit loads shouldn't get here.
3562e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!IsVldrDPcImmediateOffset(instr));
35634cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
356489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      if (IsLdrPcImmediateOffset(instr) &&
356589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          GetLdrRegisterImmediateOffset(instr) == 0) {
3566ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        int delta = pc_ - rinfo.pc() - kPcLoadDelta;
3567e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(is_uint12(delta));
3568ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        // 0 is the smallest delta:
3569ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        //   ldr rd, [pc, #0]
3570ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        //   constant pool marker
3571ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        //   data
3572ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
3573ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        bool found = false;
3574874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org        if (!serializer_enabled() && rinfo.rmode() >= RelocInfo::CELL) {
3575ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          for (int j = 0; j < i; j++) {
3576ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org            RelocInfo& rinfo2 = pending_32_bit_reloc_info_[j];
3577ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
3578ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org            if ((rinfo2.data() == rinfo.data()) &&
3579ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                (rinfo2.rmode() == rinfo.rmode())) {
3580ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org              Instr instr2 = instr_at(rinfo2.pc());
3581ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org              if (IsLdrPcImmediateOffset(instr2)) {
3582ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                delta = GetLdrRegisterImmediateOffset(instr2);
3583ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                delta += rinfo2.pc() - rinfo.pc();
3584ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                found = true;
3585ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                break;
3586ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org              }
3587ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org            }
3588ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          }
3589ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        }
3590ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
359189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta));
3592ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
3593ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        if (!found) {
3594ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          emit(rinfo.data());
3595ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        }
359689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      } else {
3597e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(IsMovW(instr));
359889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      }
35997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
360043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3601ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    num_pending_32_bit_reloc_info_ = 0;
36024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    num_pending_64_bit_reloc_info_ = 0;
3603ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    first_const_pool_32_use_ = -1;
3604ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    first_const_pool_64_use_ = -1;
36057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
36067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    RecordComment("]");
36077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
36087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (after_pool.is_linked()) {
36097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      bind(&after_pool);
36107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
361143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
361243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
361343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Since a constant pool was just emitted, move the check offset forward by
361443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the standard interval.
36157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  next_buffer_check_ = pc_offset() + kCheckPoolInterval;
361643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
361743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
361843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
36209fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!FLAG_enable_ool_constant_pool) {
36219fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return isolate->factory()->empty_constant_pool_array();
36229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
36239fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return constant_pool_builder_.New(isolate);
3624763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3625763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3626763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3627763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3628763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  constant_pool_builder_.Populate(this, constant_pool);
3629763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3630763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3631763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3632763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgConstantPoolBuilder::ConstantPoolBuilder()
3633d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    : entries_(), current_section_(ConstantPoolArray::SMALL_SECTION) {}
3634763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3635763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3636763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgbool ConstantPoolBuilder::IsEmpty() {
3637763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  return entries_.size() == 0;
3638763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3639763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3640763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3641d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgConstantPoolArray::Type ConstantPoolBuilder::GetConstantPoolType(
3642d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    RelocInfo::Mode rmode) {
3643d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (rmode == RelocInfo::NONE64) {
3644d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return ConstantPoolArray::INT64;
3645d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  } else if (!RelocInfo::IsGCRelocMode(rmode)) {
3646d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return ConstantPoolArray::INT32;
3647d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  } else if (RelocInfo::IsCodeTarget(rmode)) {
3648d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return ConstantPoolArray::CODE_PTR;
3649d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  } else {
3650e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode));
3651d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return ConstantPoolArray::HEAP_PTR;
3652d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
3653763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3654763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3655763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3656d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgConstantPoolArray::LayoutSection ConstantPoolBuilder::AddEntry(
3657d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    Assembler* assm, const RelocInfo& rinfo) {
3658763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  RelocInfo::Mode rmode = rinfo.rmode();
3659e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rmode != RelocInfo::COMMENT &&
3660763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org         rmode != RelocInfo::POSITION &&
3661763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org         rmode != RelocInfo::STATEMENT_POSITION &&
3662763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org         rmode != RelocInfo::CONST_POOL);
3663763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3664763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Try to merge entries which won't be patched.
3665763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  int merged_index = -1;
3666d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ConstantPoolArray::LayoutSection entry_section = current_section_;
3667763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (RelocInfo::IsNone(rmode) ||
3668874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org      (!assm->serializer_enabled() && (rmode >= RelocInfo::CELL))) {
3669763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    size_t i;
3670d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    std::vector<ConstantPoolEntry>::const_iterator it;
3671763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) {
3672d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      if (RelocInfo::IsEqual(rinfo, it->rinfo_)) {
3673d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        // Merge with found entry.
3674763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org        merged_index = i;
3675d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        entry_section = entries_[i].section_;
3676763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org        break;
3677763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      }
3678763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
3679763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3680e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(entry_section <= current_section_);
3681d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  entries_.push_back(ConstantPoolEntry(rinfo, entry_section, merged_index));
3682763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3683763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (merged_index == -1) {
3684763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Not merged, so update the appropriate count.
3685d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    number_of_entries_[entry_section].increment(GetConstantPoolType(rmode));
3686763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3687763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3688d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Check if we still have room for another entry in the small section
3689d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // given Arm's ldr and vldr immediate offset range.
3690d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (current_section_ == ConstantPoolArray::SMALL_SECTION &&
3691d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      !(is_uint12(ConstantPoolArray::SizeFor(*small_entries())) &&
3692d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        is_uint10(ConstantPoolArray::MaxInt64Offset(
3693d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org            small_entries()->count_of(ConstantPoolArray::INT64))))) {
3694d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    current_section_ = ConstantPoolArray::EXTENDED_SECTION;
3695763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3696d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return entry_section;
3697763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3698763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3699763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3700763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid ConstantPoolBuilder::Relocate(int pc_delta) {
3701d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
3702d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org       entry != entries_.end(); entry++) {
3703e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(entry->rinfo_.rmode() != RelocInfo::JS_RETURN);
3704d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    entry->rinfo_.set_pc(entry->rinfo_.pc() + pc_delta);
3705763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3706763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3707763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3708763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
37099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<ConstantPoolArray> ConstantPoolBuilder::New(Isolate* isolate) {
3710763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  if (IsEmpty()) {
37119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return isolate->factory()->empty_constant_pool_array();
3712d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  } else if (extended_entries()->is_empty()) {
3713d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return isolate->factory()->NewConstantPoolArray(*small_entries());
3714763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  } else {
3715e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(current_section_ == ConstantPoolArray::EXTENDED_SECTION);
3716d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return isolate->factory()->NewExtendedConstantPoolArray(
3717d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        *small_entries(), *extended_entries());
3718763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3719763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3720763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3721763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3722763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid ConstantPoolBuilder::Populate(Assembler* assm,
3723763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org                                   ConstantPoolArray* constant_pool) {
3724e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(extended_entries()->is_empty(),
3725d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org            !constant_pool->is_extended_layout());
3726e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(small_entries()->equals(ConstantPoolArray::NumberOfEntries(
3727d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      constant_pool, ConstantPoolArray::SMALL_SECTION)));
3728d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (constant_pool->is_extended_layout()) {
3729e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(extended_entries()->equals(ConstantPoolArray::NumberOfEntries(
3730d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        constant_pool, ConstantPoolArray::EXTENDED_SECTION)));
3731d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
3732d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
373312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Set up initial offsets.
373412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int offsets[ConstantPoolArray::NUMBER_OF_LAYOUT_SECTIONS]
373512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org             [ConstantPoolArray::NUMBER_OF_TYPES];
373612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  for (int section = 0; section <= constant_pool->final_section(); section++) {
373712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int section_start = (section == ConstantPoolArray::EXTENDED_SECTION)
373812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                            ? small_entries()->total_count()
373912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                            : 0;
374012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    for (int i = 0; i < ConstantPoolArray::NUMBER_OF_TYPES; i++) {
374112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ConstantPoolArray::Type type = static_cast<ConstantPoolArray::Type>(i);
374212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if (number_of_entries_[section].count_of(type) != 0) {
374312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        offsets[section][type] = constant_pool->OffsetOfElementAt(
374412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org            number_of_entries_[section].base_of(type) + section_start);
374512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
374612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
374712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
374812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
3749d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
3750d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org       entry != entries_.end(); entry++) {
3751d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    RelocInfo rinfo = entry->rinfo_;
3752d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    RelocInfo::Mode rmode = entry->rinfo_.rmode();
3753d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    ConstantPoolArray::Type type = GetConstantPoolType(rmode);
3754763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3755763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Update constant pool if necessary and get the entry's offset.
3756763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    int offset;
3757d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    if (entry->merged_index_ == -1) {
375812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      offset = offsets[entry->section_][type];
375912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      offsets[entry->section_][type] += ConstantPoolArray::entry_size(type);
3760d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      if (type == ConstantPoolArray::INT64) {
376112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        constant_pool->set_at_offset(offset, rinfo.data64());
3762d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      } else if (type == ConstantPoolArray::INT32) {
376393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        constant_pool->set_at_offset(offset,
376493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org                                     static_cast<int32_t>(rinfo.data()));
3765d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      } else if (type == ConstantPoolArray::CODE_PTR) {
376612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        constant_pool->set_at_offset(offset,
376712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                     reinterpret_cast<Address>(rinfo.data()));
3768763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      } else {
3769e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(type == ConstantPoolArray::HEAP_PTR);
377012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        constant_pool->set_at_offset(offset,
377112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                     reinterpret_cast<Object*>(rinfo.data()));
3772763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      }
377312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      offset -= kHeapObjectTag;
3774d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      entry->merged_index_ = offset;  // Stash offset for merged entries.
3775763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    } else {
3776e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(entry->merged_index_ < (entry - entries_.begin()));
3777d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      offset = entries_[entry->merged_index_].merged_index_;
3778763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
3779763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3780763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    // Patch vldr/ldr instruction with correct offset.
3781d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    Instr instr = assm->instr_at(rinfo.pc());
3782d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    if (entry->section_ == ConstantPoolArray::EXTENDED_SECTION) {
3783a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (CpuFeatures::IsSupported(ARMv7)) {
3784a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0].
3785a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        Instr next_instr = assm->instr_at(rinfo.pc() + Assembler::kInstrSize);
3786a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DCHECK((Assembler::IsMovW(instr) &&
3787a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Instruction::ImmedMovwMovtValue(instr) == 0));
3788a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DCHECK((Assembler::IsMovT(next_instr) &&
3789a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Instruction::ImmedMovwMovtValue(next_instr) == 0));
3790a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        assm->instr_at_put(
3791a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            rinfo.pc(), Assembler::PatchMovwImmediate(instr, offset & 0xffff));
3792a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        assm->instr_at_put(
3793a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            rinfo.pc() + Assembler::kInstrSize,
3794a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Assembler::PatchMovwImmediate(next_instr, offset >> 16));
3795a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      } else {
3796a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        // Instructions to patch must be 'mov rd, [#0]' and 'orr rd, rd, [#0].
3797a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        Instr instr_2 = assm->instr_at(rinfo.pc() + Assembler::kInstrSize);
3798a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        Instr instr_3 = assm->instr_at(rinfo.pc() + 2 * Assembler::kInstrSize);
3799a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        Instr instr_4 = assm->instr_at(rinfo.pc() + 3 * Assembler::kInstrSize);
3800a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DCHECK((Assembler::IsMovImmed(instr) &&
3801a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Instruction::Immed8Value(instr) == 0));
3802a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DCHECK((Assembler::IsOrrImmed(instr_2) &&
3803a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Instruction::Immed8Value(instr_2) == 0) &&
3804a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org               Assembler::GetRn(instr_2).is(Assembler::GetRd(instr_2)));
3805a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DCHECK((Assembler::IsOrrImmed(instr_3) &&
3806a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Instruction::Immed8Value(instr_3) == 0) &&
3807a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org               Assembler::GetRn(instr_3).is(Assembler::GetRd(instr_3)));
3808a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        DCHECK((Assembler::IsOrrImmed(instr_4) &&
3809a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                Instruction::Immed8Value(instr_4) == 0) &&
3810a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org               Assembler::GetRn(instr_4).is(Assembler::GetRd(instr_4)));
3811a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        assm->instr_at_put(
3812a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            rinfo.pc(), Assembler::PatchShiftImm(instr, (offset & kImm8Mask)));
3813a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        assm->instr_at_put(
3814a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            rinfo.pc() + Assembler::kInstrSize,
3815a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Assembler::PatchShiftImm(instr_2, (offset & (kImm8Mask << 8))));
3816a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        assm->instr_at_put(
3817a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            rinfo.pc() + 2 * Assembler::kInstrSize,
3818a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Assembler::PatchShiftImm(instr_3, (offset & (kImm8Mask << 16))));
3819a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        assm->instr_at_put(
3820a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            rinfo.pc() + 3 * Assembler::kInstrSize,
3821a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Assembler::PatchShiftImm(instr_4, (offset & (kImm8Mask << 24))));
3822a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      }
3823d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else if (type == ConstantPoolArray::INT64) {
3824763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      // Instruction to patch must be 'vldr rd, [pp, #0]'.
3825e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK((Assembler::IsVldrDPpImmediateOffset(instr) &&
3826763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org              Assembler::GetVldrDRegisterImmediateOffset(instr) == 0));
3827e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(is_uint10(offset));
3828d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      assm->instr_at_put(rinfo.pc(), Assembler::SetVldrDRegisterImmediateOffset(
3829d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                                         instr, offset));
3830763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    } else {
3831763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      // Instruction to patch must be 'ldr rd, [pp, #0]'.
3832e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK((Assembler::IsLdrPpImmediateOffset(instr) &&
3833763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org              Assembler::GetLdrRegisterImmediateOffset(instr) == 0));
3834e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(is_uint12(offset));
3835d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      assm->instr_at_put(
3836d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org          rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset));
3837763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
3838763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
3839763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org}
3840763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
3841763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
384243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
38439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
38449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_ARM
3845