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
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h"
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM
409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
413a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org#include "arm/assembler-arm-inl.h"
429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "serialize.h"
4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#ifdef DEBUG
48c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgbool CpuFeatures::initialized_ = false;
49c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#endif
50c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgunsigned CpuFeatures::supported_ = 0;
51750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgunsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
52169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgunsigned CpuFeatures::cache_line_size_ = 64;
53c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
545d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
55003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgExternalReference ExternalReference::cpu_features() {
56003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  ASSERT(CpuFeatures::initialized_);
57003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  return ExternalReference(&CpuFeatures::supported_);
58003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
59003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
60e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
61fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// Get the CPU features enabled by the build. For cross compilation the
62b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS
63fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// can be defined to enable ARMv7 and VFPv3 instructions when building the
64fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// snapshot.
65b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgstatic unsigned CpuFeaturesImpliedByCompiler() {
66b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  unsigned answer = 0;
675d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#ifdef CAN_USE_ARMV7_INSTRUCTIONS
68e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (FLAG_enable_armv7) {
69e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    answer |= 1u << ARMv7;
70e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
71b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#endif  // CAN_USE_ARMV7_INSTRUCTIONS
72b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#ifdef CAN_USE_VFP3_INSTRUCTIONS
73e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (FLAG_enable_vfp3) {
74e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    answer |= 1u << VFP3 | 1u << ARMv7;
75e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
76b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#endif  // CAN_USE_VFP3_INSTRUCTIONS
77003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#ifdef CAN_USE_VFP32DREGS
78e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (FLAG_enable_32dregs) {
79e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    answer |= 1u << VFP32DREGS;
80e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
81003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#endif  // CAN_USE_VFP32DREGS
82e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if ((answer & (1u << ARMv7)) && FLAG_enable_unaligned_accesses) {
8389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    answer |= 1u << UNALIGNED_ACCESSES;
8489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
85fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
865d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  return answer;
875d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
885d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
895d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
90a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst char* DwVfpRegister::AllocationIndexToString(int index) {
91e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(index >= 0 && index < NumAllocatableRegisters());
92e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
93e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org         kNumReservedRegisters - 1);
94e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (index >= kDoubleRegZero.code())
95e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    index += kNumReservedRegisters;
96e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
97e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return VFPRegisters::Name(index, true);
98a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
99a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
100a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
101c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid CpuFeatures::Probe() {
102750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint64_t standard_features = static_cast<unsigned>(
103b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org      OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler();
104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(supported_ == 0 || supported_ == standard_features);
105c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#ifdef DEBUG
106c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  initialized_ = true;
107c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#endif
108fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
109fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // Get the features implied by the OS and the compiler settings. This is the
110fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // minimal set of features which is also alowed for generated code in the
111fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // snapshot.
112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  supported_ |= standard_features;
113fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
114fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  if (Serializer::enabled()) {
115fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org    // No probing for features if we might serialize (generate snapshot).
116e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    printf("   ");
117e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    PrintFeatures();
118fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org    return;
119fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  }
120fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
1215d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#ifndef __arm__
122a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is
123a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
1245c838251403b0be9a882540f1922577abba4c872ager@chromium.org  if (FLAG_enable_vfp3) {
125750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    supported_ |=
126750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        static_cast<uint64_t>(1) << VFP3 |
127e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        static_cast<uint64_t>(1) << ARMv7;
1285c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
129169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (FLAG_enable_neon) {
130169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    supported_ |= 1u << NEON;
131169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
1325c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled
1335c838251403b0be9a882540f1922577abba4c872ager@chromium.org  if (FLAG_enable_armv7) {
134750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    supported_ |= static_cast<uint64_t>(1) << ARMv7;
1355c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
13633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
13733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  if (FLAG_enable_sudiv) {
138750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    supported_ |= static_cast<uint64_t>(1) << SUDIV;
13933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  }
14089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
14189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  if (FLAG_enable_movw_movt) {
142750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    supported_ |= static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS;
14389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
144003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
145003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (FLAG_enable_32dregs) {
146750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    supported_ |= static_cast<uint64_t>(1) << VFP32DREGS;
147003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
148003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
149e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (FLAG_enable_unaligned_accesses) {
150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    supported_ |= static_cast<uint64_t>(1) << UNALIGNED_ACCESSES;
151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
153b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org#else  // __arm__
154fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // Probe for additional features not already known to be available.
155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!IsSupported(VFP3) && FLAG_enable_vfp3 && OS::ArmCpuHasFeature(VFP3)) {
156a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    // This implementation also sets the VFP flags if runtime
157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
158a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    // 0406B, page A1-6.
159750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    found_by_runtime_probing_only_ |=
160750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        static_cast<uint64_t>(1) << VFP3 |
161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        static_cast<uint64_t>(1) << ARMv7;
162c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
1635c838251403b0be9a882540f1922577abba4c872ager@chromium.org
164169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (!IsSupported(NEON) && FLAG_enable_neon && OS::ArmCpuHasFeature(NEON)) {
165169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    found_by_runtime_probing_only_ |= 1u << NEON;
166169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
167169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
168e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!IsSupported(ARMv7) && FLAG_enable_armv7 && OS::ArmCpuHasFeature(ARMv7)) {
169750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << ARMv7;
1705c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
171b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
172e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!IsSupported(SUDIV) && FLAG_enable_sudiv && OS::ArmCpuHasFeature(SUDIV)) {
173750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << SUDIV;
17433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  }
17533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
176e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!IsSupported(UNALIGNED_ACCESSES) && FLAG_enable_unaligned_accesses
177e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      && OS::ArmCpuHasFeature(ARMv7)) {
178750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    found_by_runtime_probing_only_ |=
179750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        static_cast<uint64_t>(1) << UNALIGNED_ACCESSES;
18089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
18189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
182169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  CpuImplementer implementer = OS::GetCpuImplementer();
183169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (implementer == QUALCOMM_IMPLEMENTER &&
184e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      FLAG_enable_movw_movt && OS::ArmCpuHasFeature(ARMv7)) {
185750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    found_by_runtime_probing_only_ |=
186750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS;
18789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
18889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
189169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  CpuPart part = OS::GetCpuPart(implementer);
190169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if ((part == CORTEX_A9) || (part == CORTEX_A5)) {
191169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    cache_line_size_ = 32;
192169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
193169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
194e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!IsSupported(VFP32DREGS) && FLAG_enable_32dregs
195e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      && OS::ArmCpuHasFeature(VFP32DREGS)) {
196750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP32DREGS;
197003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
198003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
199750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  supported_ |= found_by_runtime_probing_only_;
200c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#endif
201b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org
202e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Assert that VFP3 implies ARMv7.
203e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7));
204e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
205e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
206e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
207e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid CpuFeatures::PrintTarget() {
208e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_arch = NULL;
209e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_test = "";
210e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_fpu = "";
211e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_thumb = "";
212e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const char* arm_float_abi = NULL;
213e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
214e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if defined CAN_USE_ARMV7_INSTRUCTIONS
215e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_arch = "arm v7";
216e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else
217e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_arch = "arm v6";
218e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif
219e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
220e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef __arm__
221e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
222e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# ifdef ARM_TEST
223e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_test = " test";
224e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# endif
225e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# if defined __ARM_NEON__
226e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " neon";
227e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# elif defined CAN_USE_VFP3_INSTRUCTIONS
228e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp3";
229e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# else
230e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp2";
231e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# endif
232e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# if (defined __thumb__) || (defined __thumb2__)
233e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_thumb = " thumb";
234e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# endif
235e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_float_abi = OS::ArmUsingHardFloat() ? "hard" : "softfp";
236e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
237e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else  // __arm__
238e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
239e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_test = " simulator";
240e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# if defined CAN_USE_VFP3_INSTRUCTIONS
241e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#  if defined CAN_USE_VFP32DREGS
242e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp3";
243e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#  else
244e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp3-d16";
245e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#  endif
246e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# else
247e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_fpu = " vfp2";
248e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# endif
249e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# if USE_EABI_HARDFLOAT == 1
250e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_float_abi = "hard";
251e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# else
252e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  arm_float_abi = "softfp";
253e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org# endif
254e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
255e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif  // __arm__
256e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
257e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  printf("target%s %s%s%s %s\n",
258e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org         arm_test, arm_arch, arm_fpu, arm_thumb, arm_float_abi);
259e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
260e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
261e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
262e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid CpuFeatures::PrintFeatures() {
263e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  printf(
264169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    "ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d UNALIGNED_ACCESSES=%d "
265e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    "MOVW_MOVT_IMMEDIATE_LOADS=%d",
266e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(ARMv7),
267e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(VFP3),
268e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(VFP32DREGS),
269169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    CpuFeatures::IsSupported(NEON),
270e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(SUDIV),
271e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
272e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
273e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef __arm__
274e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool eabi_hardfloat = OS::ArmUsingHardFloat();
275e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif USE_EABI_HARDFLOAT
276e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool eabi_hardfloat = true;
277e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else
278e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool eabi_hardfloat = false;
279e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif
280e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat);
281c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
282c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
283c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of RelocInfo
28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst int RelocInfo::kApplyMask = 0;
28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool RelocInfo::IsCodedSpecially() {
2919dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // The deserializer needs to know whether a pointer is specially coded.  Being
2929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // specially coded on ARM means that it is a movw/movt instruction.  We don't
2939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // generate those yet.
2949dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return false;
2959dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
2969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
2979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
298245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) {
29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch the code at the current address with the supplied instructions.
3004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Instr* pc = reinterpret_cast<Instr*>(pc_);
3014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Instr* instr = reinterpret_cast<Instr*>(instructions);
3024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  for (int i = 0; i < instruction_count; i++) {
3034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    *(pc + i) = *(instr + i);
3044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  }
3054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
3064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Indicate that code has changed.
3074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  CPU::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Patch the code at the current PC with a call to the target address.
312245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Additional guard instructions can be added if required.
313245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch the code at the current address with a call to the target.
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNIMPLEMENTED();
31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Operand and MemOperand
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// See assembler-arm-inl.h for inlined constructors
32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Handle<Object> handle) {
32432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org#ifdef DEBUG
32532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  Isolate* isolate = Isolate::Current();
32632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org#endif
32779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference using_raw_address;
32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = no_reg;
32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Verify all Objects referred by code are NOT in new space.
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* obj = *handle;
33132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  ASSERT(!isolate->heap()->InNewSpace(obj));
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (obj->IsHeapObject()) {
33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    imm32_ = reinterpret_cast<intptr_t>(handle.location());
334236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    rmode_ = RelocInfo::EMBEDDED_OBJECT;
33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // no relocation needed
33732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    imm32_ = reinterpret_cast<intptr_t>(obj);
33859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    rmode_ = RelocInfo::NONE32;
33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint5(shift_imm));
34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(shift_op != ROR || shift_imm != 0);  // use RRX if you mean it
34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rs_ = no_reg;
34843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = shift_op;
34943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_imm_ = shift_imm & 31;
35043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (shift_op == RRX) {
35143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // encoded as ROR with shift_imm == 0
35243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(shift_imm == 0);
35343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    shift_op_ = ROR;
35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    shift_imm_ = 0;
35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOperand::Operand(Register rm, ShiftOp shift_op, Register rs) {
36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(shift_op != RRX);
36143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
36243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rs_ = no_reg;
36343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = shift_op;
36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rs_ = rs;
36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
36643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenMemOperand::MemOperand(Register rn, int32_t offset, AddrMode am) {
36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rn_ = rn;
37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = no_reg;
37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  offset_ = offset;
37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  am_ = am;
37343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
37443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
375e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
37643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenMemOperand::MemOperand(Register rn, Register rm, AddrMode am) {
37743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rn_ = rn;
37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
37943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = LSL;
38043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_imm_ = 0;
38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  am_ = am;
38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
38343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenMemOperand::MemOperand(Register rn, Register rm,
38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                       ShiftOp shift_op, int shift_imm, AddrMode am) {
38743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint5(shift_imm));
38843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rn_ = rn;
38943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  rm_ = rm;
39043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_op_ = shift_op;
39143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shift_imm_ = shift_imm & 31;
39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  am_ = am;
39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
39443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
396169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgNeonMemOperand::NeonMemOperand(Register rn, AddrMode am, int align) {
397169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT((am == Offset) || (am == PostIndex));
398169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rn_ = rn;
399169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rm_ = (am == Offset) ? pc : sp;
400169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  SetAlignment(align);
401169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
402169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
403169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
404169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgNeonMemOperand::NeonMemOperand(Register rn, Register rm, int align) {
405169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rn_ = rn;
406169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  rm_ = rm;
407169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  SetAlignment(align);
408169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
409169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
410169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
411169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid NeonMemOperand::SetAlignment(int align) {
412169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  switch (align) {
413169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 0:
414169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 0;
415169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
416169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 64:
417169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 1;
418169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
419169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 128:
420169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 2;
421169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
422169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 256:
423169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 3;
424169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
425169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    default:
426169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      UNREACHABLE();
427169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      align_ = 0;
428169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
429169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
430169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
431169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
432169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
433169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgNeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) {
434169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  base_ = base;
435169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  switch (registers_count) {
436169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 1:
437169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_1;
438169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
439169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 2:
440169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_2;
441169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
442169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 3:
443169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_3;
444169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
445169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    case 4:
446169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_4;
447169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
448169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    default:
449169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      UNREACHABLE();
450169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      type_ = nlt_1;
451169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      break;
452169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
453169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
454169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
455169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
457378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Specific instructions, constants, and masks.
45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// add(sp, sp, 4) instruction (aka Pop())
460378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kPopInstruction =
4611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | PostIndex | 4 | LeaveCC | I | kRegister_sp_Code * B16 |
4621456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        kRegister_sp_Code * B12;
46331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
46431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// register r is not encoded.
465378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kPushRegPattern =
4661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | 4 | NegPreIndex | kRegister_sp_Code * B16;
46731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
46831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// register r is not encoded.
469378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kPopRegPattern =
4701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | L | 4 | PostIndex | kRegister_sp_Code * B16;
4714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// mov lr, pc
4721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Instr kMovLrPc = al | MOV | kRegister_pc_Code | kRegister_lr_Code * B12;
473cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org// ldr rd, [pc, #offset]
4744cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgconst Instr kLdrPCMask = 15 * B24 | 7 * B20 | 15 * B16;
4754cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgconst Instr kLdrPCPattern = 5 * B24 | L | kRegister_pc_Code * B16;
4764cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org// vldr dd, [pc, #offset]
4774cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgconst Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
4784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgconst Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8;
479cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org// blxcc rm
480cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgconst Instr kBlxRegMask =
481cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
482cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.orgconst Instr kBlxRegPattern =
483378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | BLX;
48488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.orgconst Instr kBlxIp = al | kBlxRegPattern | ip.code();
4852c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kMovMvnMask = 0x6d * B21 | 0xf * B16;
4862c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kMovMvnPattern = 0xd * B21;
4872c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kMovMvnFlip = B22;
4885ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovLeaveCCMask = 0xdff * B16;
4895ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovLeaveCCPattern = 0x1a0 * B16;
4905ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovwMask = 0xff * B20;
4915ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovwPattern = 0x30 * B20;
4925ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgconst Instr kMovwLeaveCCFlip = 0x5 * B21;
4932c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12;
4942c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kCmpCmnPattern = 0x15 * B20;
4952c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kCmpCmnFlip = B21;
4962c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kAddSubFlip = 0x6 * B21;
4972c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.orgconst Instr kAndBicFlip = 0xe * B21;
4982c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
4999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com// A mask for the Rd register for push, pop, ldr, str instructions.
500378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrRegFpOffsetPattern =
5011456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | L | Offset | kRegister_fp_Code * B16;
502378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kStrRegFpOffsetPattern =
5031456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | Offset | kRegister_fp_Code * B16;
504378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrRegFpNegOffsetPattern =
5051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | L | NegOffset | kRegister_fp_Code * B16;
506378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kStrRegFpNegOffsetPattern =
5071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    al | B26 | NegOffset | kRegister_fp_Code * B16;
508378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrStrInstrTypeMask = 0xffff0000;
509378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrStrInstrArgumentMask = 0x0000ffff;
510378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgconst Instr kLdrStrOffsetMask = 0x00000fff;
511378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
51231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
5138e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
5148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    : AssemblerBase(isolate, buffer, buffer_size),
515471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      recorded_ast_id_(TypeFeedbackId::None()),
516e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      positions_recorder_(this) {
5178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
5187b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  num_pending_reloc_info_ = 0;
5194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  num_pending_64_bit_reloc_info_ = 0;
52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  next_buffer_check_ = 0;
521013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  const_pool_blocked_nesting_ = 0;
52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  no_const_pool_before_ = 0;
5237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  first_const_pool_use_ = -1;
52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  last_bound_pos_ = 0;
525717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  ClearRecordedAstId();
52643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenAssembler::~Assembler() {
530013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  ASSERT(const_pool_blocked_nesting_ == 0);
53143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::GetCode(CodeDesc* desc) {
5355c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Emit constant pool if necessary.
53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CheckConstPool(true, false);
5377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ASSERT(num_pending_reloc_info_ == 0);
5384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(num_pending_64_bit_reloc_info_ == 0);
53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
540f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up code descriptor.
54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->buffer = buffer_;
54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->buffer_size = buffer_size_;
54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->instr_size = pc_offset();
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::Align(int m) {
54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(m >= 4 && IsPowerOf2(m));
55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while ((pc_offset() & (m - 1)) != 0) {
55143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    nop();
55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5565ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid Assembler::CodeTargetAlign() {
5575ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Preferred alignment of jump targets on some ARM chips.
5585ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  Align(8);
5595ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
5605ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
5615ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
562496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgCondition Assembler::GetCondition(Instr instr) {
563496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return Instruction::ConditionField(instr);
564496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
565496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
566496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
567013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgbool Assembler::IsBranch(Instr instr) {
568013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  return (instr & (B27 | B25)) == (B27 | B25);
569013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
570013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
571013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
572013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgint Assembler::GetBranchOffset(Instr instr) {
573013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  ASSERT(IsBranch(instr));
574013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Take the jump offset in the lower 24 bits, sign extend it and multiply it
575013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // with 4 to get the offset in bytes.
576378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return ((instr & kImm24Mask) << 8) >> 6;
577013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
578013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
579013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
580013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgbool Assembler::IsLdrRegisterImmediate(Instr instr) {
581013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  return (instr & (B27 | B26 | B25 | B22 | B20)) == (B26 | B20);
582013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
583013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
584013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
5854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgbool Assembler::IsVldrDRegisterImmediate(Instr instr) {
5864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return (instr & (15 * B24 | 3 * B20 | 15 * B8)) == (13 * B24 | B20 | 11 * B8);
5874cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
5884cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
5894cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
590013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgint Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
591013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  ASSERT(IsLdrRegisterImmediate(instr));
592013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  bool positive = (instr & B23) == B23;
593378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  int offset = instr & kOff12Mask;  // Zero extended offset.
594013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  return positive ? offset : -offset;
595013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
596013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
597013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
5984cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgint Assembler::GetVldrDRegisterImmediateOffset(Instr instr) {
5994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(IsVldrDRegisterImmediate(instr));
6004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool positive = (instr & B23) == B23;
6014cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int offset = instr & kOff8Mask;  // Zero extended offset.
6024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  offset <<= 2;
6034cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return positive ? offset : -offset;
6044cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
6054cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
6064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
607013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgInstr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
608013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  ASSERT(IsLdrRegisterImmediate(instr));
609013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  bool positive = offset >= 0;
610013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  if (!positive) offset = -offset;
611013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  ASSERT(is_uint12(offset));
612013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Set bit indicating whether the offset should be added.
613013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  instr = (instr & ~B23) | (positive ? B23 : 0);
614013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Set the actual offset.
615378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return (instr & ~kOff12Mask) | offset;
616013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
617013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
618013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
6194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgInstr Assembler::SetVldrDRegisterImmediateOffset(Instr instr, int offset) {
6204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(IsVldrDRegisterImmediate(instr));
6214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT((offset & ~3) == offset);  // Must be 64-bit aligned.
6224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool positive = offset >= 0;
6234cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (!positive) offset = -offset;
6244cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(is_uint10(offset));
6254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Set bit indicating whether the offset should be added.
6264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  instr = (instr & ~B23) | (positive ? B23 : 0);
6274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Set the actual offset. Its bottom 2 bits are zero.
6284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return (instr & ~kOff8Mask) | (offset >> 2);
6294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
6304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
6314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
632ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgbool Assembler::IsStrRegisterImmediate(Instr instr) {
633ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  return (instr & (B27 | B26 | B25 | B22 | B20)) == B26;
634ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
635ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
636ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
637ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgInstr Assembler::SetStrRegisterImmediateOffset(Instr instr, int offset) {
638ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  ASSERT(IsStrRegisterImmediate(instr));
639ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  bool positive = offset >= 0;
640ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  if (!positive) offset = -offset;
641ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  ASSERT(is_uint12(offset));
642ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  // Set bit indicating whether the offset should be added.
643ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  instr = (instr & ~B23) | (positive ? B23 : 0);
644ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  // Set the actual offset.
645378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return (instr & ~kOff12Mask) | offset;
646ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
647ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
648ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
649ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgbool Assembler::IsAddRegisterImmediate(Instr instr) {
650ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  return (instr & (B27 | B26 | B25 | B24 | B23 | B22 | B21)) == (B25 | B23);
651ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
652ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
653ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
654ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.orgInstr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) {
655ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  ASSERT(IsAddRegisterImmediate(instr));
656ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  ASSERT(offset >= 0);
657ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  ASSERT(is_uint12(offset));
658ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  // Set the offset.
659378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return (instr & ~kOff12Mask) | offset;
660ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
661ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
662ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
6639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comRegister Assembler::GetRd(Instr instr) {
6649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  Register reg;
665378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  reg.code_ = Instruction::RdValue(instr);
6669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return reg;
6679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6699dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
670496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgRegister Assembler::GetRn(Instr instr) {
671496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  Register reg;
672496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  reg.code_ = Instruction::RnValue(instr);
673496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return reg;
674496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
675496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
676496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
677496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgRegister Assembler::GetRm(Instr instr) {
678496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  Register reg;
679496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  reg.code_ = Instruction::RmValue(instr);
680496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return reg;
681496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
682496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
683496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
6849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsPush(Instr instr) {
6859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & ~kRdMask) == kPushRegPattern);
6869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6899dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsPop(Instr instr) {
6909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & ~kRdMask) == kPopRegPattern);
6919dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6949dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsStrRegFpOffset(Instr instr) {
6959dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kStrRegFpOffsetPattern);
6969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
6979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6989dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsLdrRegFpOffset(Instr instr) {
7009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpOffsetPattern);
7019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
7029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsStrRegFpNegOffset(Instr instr) {
7059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kStrRegFpNegOffsetPattern);
7069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
7079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.combool Assembler::IsLdrRegFpNegOffset(Instr instr) {
7109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpNegOffsetPattern);
7119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
7129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
7139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
714beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.orgbool Assembler::IsLdrPcImmediateOffset(Instr instr) {
715beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // Check the instruction is indeed a
716beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // ldr<cond> <Rd>, [pc +/- offset_12].
7174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return (instr & kLdrPCMask) == kLdrPCPattern;
7184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
7194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
7204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
7214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgbool Assembler::IsVldrDPcImmediateOffset(Instr instr) {
7224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Check the instruction is indeed a
7234cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // vldr<cond> <Dd>, [pc +/- offset_10].
7244cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return (instr & kVldrDPCMask) == kVldrDPCPattern;
725beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org}
726beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
727beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
728496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgbool Assembler::IsTstImmediate(Instr instr) {
729496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
730496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      (I | TST | S);
731496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
732496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
733496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
734496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgbool Assembler::IsCmpRegister(Instr instr) {
735496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask | B4)) ==
736496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      (CMP | S);
737496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
738496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
739496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
740496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgbool Assembler::IsCmpImmediate(Instr instr) {
741496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
742496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      (I | CMP | S);
743496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
744496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
745496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
746496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgRegister Assembler::GetCmpImmediateRegister(Instr instr) {
747496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(IsCmpImmediate(instr));
748496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return GetRn(instr);
749496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
750496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
751496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
752496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgint Assembler::GetCmpImmediateRawImmediate(Instr instr) {
753496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(IsCmpImmediate(instr));
754496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return instr & kOff12Mask;
755496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
756496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
757e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
75843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Labels refer to positions in the (to be) generated code.
75943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// There are bound, linked, and unused labels.
76043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
76143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Bound labels refer to known positions in the already
76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// generated code. pos() is the position the label refers to.
76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
76443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Linked labels refer to unknown positions in the code
76543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to be generated; pos() is the position of the last
76643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// instruction using the label.
767d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org//
768d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// The linked labels form a link chain by making the branch offset
769d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// in the instruction steam to point to the previous branch
770d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// instruction using the same label.
771d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org//
772d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// The link chain is terminated by a branch offset pointing to the
773d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// same position.
77443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint Assembler::target_at(int pos)  {
77743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Instr instr = instr_at(pos);
778378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if ((instr & ~kImm24Mask) == 0) {
77918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    // Emitted label constant, not part of a branch.
78018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    return instr - (Code::kHeaderSize - kHeapObjectTag);
78118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
78243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
783378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  int imm26 = ((instr & kImm24Mask) << 8) >> 6;
784378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
785378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      ((instr & B24) != 0)) {
78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // blx uses bit 24 to encode bit 2 of imm26
78743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    imm26 += 2;
788013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  }
78918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  return pos + kPcLoadDelta + imm26;
79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::target_at_put(int pos, int target_pos) {
79443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Instr instr = instr_at(pos);
795378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if ((instr & ~kImm24Mask) == 0) {
796d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(target_pos == pos || target_pos >= 0);
79718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    // Emitted label constant, not part of a branch.
79818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    // Make label relative to Code* of generated Code object.
79918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
80018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    return;
80118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
80218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  int imm26 = target_pos - (pos + kPcLoadDelta);
80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
804378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (Instruction::ConditionField(instr) == kSpecialCondition) {
80543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // blx uses bit 24 to encode bit 2 of imm26
80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT((imm26 & 1) == 0);
807378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
80843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
80943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT((imm26 & 3) == 0);
810378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    instr &= ~kImm24Mask;
81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
81243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = imm26 >> 2;
81343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_int24(imm24));
814378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  instr_at_put(pos, instr | (imm24 & kImm24Mask));
81543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::print(Label* L) {
81943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (L->is_unused()) {
82043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("unused label\n");
82143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (L->is_bound()) {
82243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("bound label to %d\n", L->pos());
82343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (L->is_linked()) {
82443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Label l = *L;
82543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("unbound label");
82643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (l.is_linked()) {
82743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("@ %d ", l.pos());
82843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Instr instr = instr_at(l.pos());
829378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if ((instr & ~kImm24Mask) == 0) {
83018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        PrintF("value\n");
83143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
83218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx
833378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        Condition cond = Instruction::ConditionField(instr);
83418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        const char* b;
83518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        const char* c;
836378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        if (cond == kSpecialCondition) {
83718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          b = "blx";
83818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          c = "";
83918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        } else {
84018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          if ((instr & B24) != 0)
84118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            b = "bl";
84218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          else
84318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            b = "b";
84418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
84518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          switch (cond) {
84618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case eq: c = "eq"; break;
84718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case ne: c = "ne"; break;
84818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case hs: c = "hs"; break;
84918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case lo: c = "lo"; break;
85018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case mi: c = "mi"; break;
85118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case pl: c = "pl"; break;
85218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case vs: c = "vs"; break;
85318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case vc: c = "vc"; break;
85418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case hi: c = "hi"; break;
85518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case ls: c = "ls"; break;
85618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case ge: c = "ge"; break;
85718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case lt: c = "lt"; break;
85818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case gt: c = "gt"; break;
85918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case le: c = "le"; break;
86018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            case al: c = ""; break;
86118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org            default:
86218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org              c = "";
86318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org              UNREACHABLE();
86418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org          }
86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
86618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org        PrintF("%s%s\n", b, c);
86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
86843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      next(&l);
86943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
87243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
87343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
87443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bind_to(Label* L, int pos) {
87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(0 <= pos && pos <= pc_offset());  // must have a valid binding position
87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (L->is_linked()) {
87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int fixup_pos = L->pos();
88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    next(L);  // call next before overwriting link with target at fixup_pos
88143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    target_at_put(fixup_pos, pos);
88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
88343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  L->bind_to(pos);
88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Keep track of the last bound label so we don't eliminate any instructions
88641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // before a bound label.
88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (pos > last_bound_pos_)
88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    last_bound_pos_ = pos;
88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bind(Label* L) {
89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!L->is_bound());  // label can only be bound once
89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bind_to(L, pc_offset());
89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::next(Label* L) {
89943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(L->is_linked());
90043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int link = target_at(L->pos());
901d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (link == L->pos()) {
902d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // Branch target points to the same instuction. This is the end of the link
903d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // chain.
90443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    L->Unuse();
90580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  } else {
90680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    ASSERT(link >= 0);
90780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    L->link_to(link);
90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
91043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9125c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Low-level code emission routines depending on the addressing mode.
9132c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org// If this returns true then you have to use the rotate_imm and immed_8
9142c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org// that it returns, because it may have already changed the instruction
9152c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org// to match them!
91643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool fits_shifter(uint32_t imm32,
91743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         uint32_t* rotate_imm,
91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         uint32_t* immed_8,
91943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         Instr* instr) {
9205c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // imm32 must be unsigned.
92143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int rot = 0; rot < 16; rot++) {
92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t imm8 = (imm32 << 2*rot) | (imm32 >> (32 - 2*rot));
92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if ((imm8 <= 0xff)) {
92443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      *rotate_imm = rot;
92543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      *immed_8 = imm8;
92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return true;
92743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
9292c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  // If the opcode is one with a complementary version and the complementary
9302c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  // immediate fits, change the opcode.
9312c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  if (instr != NULL) {
9322c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    if ((*instr & kMovMvnMask) == kMovMvnPattern) {
9332c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
9342c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        *instr ^= kMovMvnFlip;
9352c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        return true;
9365ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org      } else if ((*instr & kMovLeaveCCMask) == kMovLeaveCCPattern) {
937c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        if (CpuFeatures::IsSupported(ARMv7)) {
9385ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org          if (imm32 < 0x10000) {
9395ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org            *instr ^= kMovwLeaveCCFlip;
9405ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org            *instr |= EncodeMovwImmediate(imm32);
9415ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org            *rotate_imm = *immed_8 = 0;  // Not used for movw.
9425ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org            return true;
9435ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org          }
9445ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org        }
9452c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      }
9462c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    } else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) {
947657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
9482c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        *instr ^= kCmpCmnFlip;
9492c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        return true;
9502c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      }
9512c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org    } else {
9522c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      Instr alu_insn = (*instr & kALUMask);
953378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if (alu_insn == ADD ||
954378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org          alu_insn == SUB) {
955657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8, NULL)) {
9562c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          *instr ^= kAddSubFlip;
9572c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          return true;
9582c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        }
959378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      } else if (alu_insn == AND ||
960378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                 alu_insn == BIC) {
9612c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
9622c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          *instr ^= kAndBicFlip;
9632c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org          return true;
9642c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org        }
9652c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org      }
96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
96743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
96843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
96943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9722abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// We have to use the temporary register for things that can be relocated even
9732abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// if they can be encoded in the ARM's 12 bits of immediate-offset instruction
9742abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// space.  There is no guarantee that the relocated location can be similarly
9752abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org// encoded.
97689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgbool Operand::must_output_reloc_info(const Assembler* assembler) const {
977f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
978c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#ifdef DEBUG
979c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    if (!Serializer::enabled()) {
980c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      Serializer::TooLateToEnableNow();
981c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    }
9825d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#endif  // def DEBUG
983471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (assembler != NULL && assembler->predictable_code_size()) return true;
9842abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    return Serializer::enabled();
9854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  } else if (RelocInfo::IsNone(rmode_)) {
9862abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    return false;
9872abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
9882abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  return true;
9892abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
9902abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
9912abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
99289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgstatic bool use_movw_movt(const Operand& x, const Assembler* assembler) {
99389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  if (Assembler::use_immediate_embedded_pointer_loads(assembler)) {
99489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    return true;
99589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
99689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  if (x.must_output_reloc_info(assembler)) {
99789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    return false;
99889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
99989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  return CpuFeatures::IsSupported(ARMv7);
100089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
100189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
100289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
1003471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgbool Operand::is_single_instruction(const Assembler* assembler,
1004471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                    Instr instr) const {
10052c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  if (rm_.is_valid()) return true;
10062c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  uint32_t dummy1, dummy2;
100789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  if (must_output_reloc_info(assembler) ||
1008b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
1009b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // The immediate operand cannot be encoded as a shifter operand, or use of
1010b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // constant pool is required. For a mov instruction not setting the
1011b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // condition code additional instruction conventions can be used.
1012b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
101389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      return !use_movw_movt(*this, assembler);
1014b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    } else {
1015b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      // If this is not a mov or mvn instruction there will always an additional
1016b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      // instructions - either mov or ldr. The mov might actually be two
1017b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      // instructions mov or movw followed by movt so including the actual
1018b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      // instruction two or three instructions will be generated.
1019b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      return false;
1020b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    }
1021b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  } else {
1022b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // No use of constant pool and the immediate operand can be encoded as a
1023b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    // shifter operand.
1024b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    return true;
1025b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  }
10262c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org}
10272c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
10282c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
102989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgvoid Assembler::move_32_bit_immediate(Condition cond,
103089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                                      Register rd,
103189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                                      SBit s,
103289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                                      const Operand& x) {
103389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  if (rd.code() != pc.code() && s == LeaveCC) {
103489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    if (use_movw_movt(x, this)) {
103589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      if (x.must_output_reloc_info(this)) {
103689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL);
103789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        // Make sure the movw/movt doesn't get separated.
103889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        BlockConstPoolFor(2);
103989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      }
104089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      emit(cond | 0x30*B20 | rd.code()*B12 |
104189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org           EncodeMovwImmediate(x.imm32_ & 0xffff));
104289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
104389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      return;
104489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    }
104589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
104689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
104789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
104889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  ldr(rd, MemOperand(pc, 0), cond);
104989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
105089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
105189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod1(Instr instr,
105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         Register rn,
105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         Register rd,
105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         const Operand& x) {
105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CheckBuffer();
1057378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!x.rm_.is_valid()) {
10595c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate.
106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t rotate_imm;
106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t immed_8;
106289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    if (x.must_output_reloc_info(this) ||
106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // The immediate operand cannot be encoded as a shifter operand, so load
106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // it first to register ip and change the original instruction to use ip.
106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // However, if the original instruction is a 'mov rd, x' (not setting the
10675c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // condition code), then replace it with a 'ldr rd, [pc]'.
1068a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      CHECK(!rn.is(ip));  // rn should never be ip, or will be trashed
1069378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      Condition cond = Instruction::ConditionField(instr);
1070378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
107189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        move_32_bit_immediate(cond, rd, LeaveCC, x);
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
107389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        if ((instr & kMovMvnMask) == kMovMvnPattern) {
107489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          // Moves need to use a constant pool entry.
107589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
10765ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org          ldr(ip, MemOperand(pc, 0), cond);
107789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        } else if (x.must_output_reloc_info(this)) {
107889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          // Otherwise, use most efficient form of fetching from constant pool.
107989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          move_32_bit_immediate(cond, ip, LeaveCC, x);
108089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        } else {
108189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          // If this is not a mov or mvn instruction we may still be able to
108289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          // avoid a constant pool entry by using mvn or movw.
108389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          mov(ip, x, LeaveCC, cond);
10845ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org        }
108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        addrmod1(instr, rn, rd, Operand(ip));
108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= I | rotate_imm*B8 | immed_8;
109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (!x.rs_.is_valid()) {
10915c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate shift.
109243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
10945c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Register shift.
109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= x.rs_.code()*B8 | x.shift_op_ | B4 | x.rm_.code();
109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | rn.code()*B16 | rd.code()*B12);
1099ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  if (rn.is(pc) || x.rm_.is(pc)) {
11005c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Block constant pool emission for one instruction after reading pc.
11017b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    BlockConstPoolFor(1);
1102ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  }
110343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
110443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
1107378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ASSERT((instr & ~(kCondMask | B | L)) == B26);
110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int am = x.am_;
110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!x.rm_.is_valid()) {
11105c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate offset.
111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int offset_12 = x.offset_;
111243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (offset_12 < 0) {
111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      offset_12 = -offset_12;
111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      am ^= U;
111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!is_uint12(offset_12)) {
11175c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // Immediate offset cannot be encoded, load it first to register ip
11185c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // rn (and rd in a load) should never be ip, or will be trashed.
111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
1120378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
112143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_));
112243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
112443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(offset_12 >= 0);  // no masking needed
112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= offset_12;
112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
11275c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Register offset (shift_imm_ and shift_op_ are 0) or scaled
112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // register offset the constructors make sure than both shift_imm_
11295c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // and shift_op_ are initialized.
113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(!x.rm_.is(pc));
113143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
1139378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ASSERT((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(x.rn_.is_valid());
114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int am = x.am_;
114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!x.rm_.is_valid()) {
11435c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate offset.
114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int offset_8 = x.offset_;
114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (offset_8 < 0) {
114643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      offset_8 = -offset_8;
114743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      am ^= U;
114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
114943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!is_uint8(offset_8)) {
11505c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // Immediate offset cannot be encoded, load it first to register ip
11515c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // rn (and rd in a load) should never be ip, or will be trashed.
115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
1153378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(offset_8 >= 0);  // no masking needed
115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf);
115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (x.shift_imm_ != 0) {
11605c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Scaled register offset not supported, load index first
11615c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // rn (and rd in a load) should never be ip, or will be trashed.
116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
1164378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        Instruction::ConditionField(instr));
116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
11685c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Register offset.
116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr |= x.rm_.code();
117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod4(Instr instr, Register rn, RegList rl) {
1178378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ASSERT((instr & ~(kCondMask | P | U | W | L)) == B27);
117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(rl != 0);
118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!rn.is(pc));
118143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | rn.code()*B16 | rl);
118243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
118343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
11865c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unindexed addressing is not encoded by this function.
1187b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  ASSERT_EQ((B27 | B26),
1188378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org            (instr & ~(kCondMask | kCoprocessorMask | P | U | N | W | L)));
118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(x.rn_.is_valid() && !x.rm_.is_valid());
119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int am = x.am_;
119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int offset_8 = x.offset_;
119243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((offset_8 & 3) == 0);  // offset must be an aligned word offset
119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  offset_8 >>= 2;
119443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (offset_8 < 0) {
119543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    offset_8 = -offset_8;
119643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    am ^= U;
119743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
119843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint8(offset_8));  // unsigned word offset must fit in a byte
119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12015c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Post-indexed addressing requires W == 1; different than in addrmod2/3.
120243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if ((am & P) == 0)
120343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    am |= W;
120443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(offset_8 >= 0);  // no masking needed
120643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
120743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
120843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1210769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.comint Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int target_pos;
121243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (L->is_bound()) {
121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    target_pos = L->pos();
121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
121541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    if (L->is_linked()) {
1216d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      // Point to previous instruction that uses the link.
1217d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      target_pos = L->pos();
121841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    } else {
1219d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      // First entry of the link chain points to itself.
1220d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      target_pos = pc_offset();
122141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    }
122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    L->link_to(pc_offset());
122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Block the emission of the constant pool, since the branch instruction must
12265c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // be emitted at the pc offset recorded by the label.
12277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  BlockConstPoolFor(1);
122818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  return target_pos - (pc_offset() + kPcLoadDelta);
122918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
123218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid Assembler::label_at_put(Label* L, int at_offset) {
123318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  int target_pos;
1234d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(!L->is_bound());
1235d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (L->is_linked()) {
1236d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // Point to previous instruction that uses the link.
123718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    target_pos = L->pos();
123818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  } else {
1239d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // First entry of the link chain points to itself.
1240d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    target_pos = at_offset;
124118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
1242d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  L->link_to(at_offset);
1243d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12475c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Branch instructions.
124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::b(int branch_offset, Condition cond) {
124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((branch_offset & 3) == 0);
125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = branch_offset >> 2;
125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_int24(imm24));
1252378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B27 | B25 | (imm24 & kImm24Mask));
125343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1254c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  if (cond == al) {
12555c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Dead code is a good location to emit the constant pool.
125643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CheckConstPool(false, false);
1257c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
125843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
125943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
126043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
126143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bl(int branch_offset, Condition cond) {
1262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  positions_recorder()->WriteRecordedPositions();
126343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((branch_offset & 3) == 0);
126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = branch_offset >> 2;
126543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_int24(imm24));
1266378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
126743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
126843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
126943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::blx(int branch_offset) {  // v5 and above
1271f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT((branch_offset & 1) == 0);
127343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int h = ((branch_offset & 2) >> 1)*B24;
127443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int imm24 = branch_offset >> 2;
127543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_int24(imm24));
1276378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
127743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
127843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::blx(Register target, Condition cond) {  // v5 and above
1281f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
128243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!target.is(pc));
1283378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
128443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
128543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bx(Register target, Condition cond) {  // v5 and above, plus v4t
1288f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
128943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!target.is(pc));  // use of pc is actually allowed, but discouraged
1290378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
129143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12945c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Data-processing instructions.
12955c838251403b0be9a882540f1922577abba4c872ager@chromium.org
129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::and_(Register dst, Register src1, const Operand& src2,
129743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     SBit s, Condition cond) {
1298378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | AND | s, src1, dst, src2);
129943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
130043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
130143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
130243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::eor(Register dst, Register src1, const Operand& src2,
130343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1304378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | EOR | s, src1, dst, src2);
130543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
130643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
130743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
130843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::sub(Register dst, Register src1, const Operand& src2,
130943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1310378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | SUB | s, src1, dst, src2);
131143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
131243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::rsb(Register dst, Register src1, const Operand& src2,
131543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1316378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | RSB | s, src1, dst, src2);
131743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
131843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::add(Register dst, Register src1, const Operand& src2,
132143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1322378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | ADD | s, src1, dst, src2);
132343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::adc(Register dst, Register src1, const Operand& src2,
132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1328378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | ADC | s, src1, dst, src2);
132943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
133043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::sbc(Register dst, Register src1, const Operand& src2,
133343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1334378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | SBC | s, src1, dst, src2);
133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::rsc(Register dst, Register src1, const Operand& src2,
133943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1340378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | RSC | s, src1, dst, src2);
134143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
134243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::tst(Register src1, const Operand& src2, Condition cond) {
1345378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | TST | S, src1, r0, src2);
134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::teq(Register src1, const Operand& src2, Condition cond) {
1350378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | TEQ | S, src1, r0, src2);
135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
135243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
135343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
1355378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | CMP | S, src1, r0, src2);
135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
135743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
135843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1359496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgvoid Assembler::cmp_raw_immediate(
1360496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    Register src, int raw_immediate, Condition cond) {
1361496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(is_uint12(raw_immediate));
1362496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  emit(cond | I | CMP | S | src.code() << 16 | raw_immediate);
1363496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
1364496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
1365496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
136643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cmn(Register src1, const Operand& src2, Condition cond) {
1367378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | CMN | S, src1, r0, src2);
136843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::orr(Register dst, Register src1, const Operand& src2,
137243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1373378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | ORR | s, src1, dst, src2);
137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
1378defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (dst.is(pc)) {
1379f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    positions_recorder()->WriteRecordedPositions();
1380defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
1381013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  // Don't allow nop instructions in the form mov rn, rn to be generated using
1382beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // the mov instruction. They must be generated using nop(int/NopMarkerTypes)
1383beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // or MarkCode(int/NopMarkerTypes) pseudo instructions.
1384013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
1385378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | MOV | s, r0, dst, src);
138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13895ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
13905ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  ASSERT(immediate < 0x10000);
139189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // May use movw if supported, but on unsupported platforms will try to use
139289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // equivalent rotated immed_8 value and other tricks before falling back to a
139389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // constant pool load.
13945ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  mov(reg, Operand(immediate), LeaveCC, cond);
13955ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
13965ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
13975ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
13985ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
13995ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
14005ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
14015ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
14025ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
140343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bic(Register dst, Register src1, const Operand& src2,
140443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
1405378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | BIC | s, src1, dst, src2);
140643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
140943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
1410378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  addrmod1(cond | MVN | s, r0, dst, src);
141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14145c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Multiply instructions.
141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
142333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgvoid Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
142433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                    Condition cond) {
142533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
142633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
142733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org       src2.code()*B8 | B7 | B4 | src1.code());
142833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org}
142933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
143033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
143133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgvoid Assembler::sdiv(Register dst, Register src1, Register src2,
143233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                     Condition cond) {
143333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1434837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  ASSERT(IsEnabled(SUDIV));
143533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  emit(cond | B26 | B25| B24 | B20 | dst.code()*B16 | 0xf * B12 |
143633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org       src2.code()*B8 | B4 | src1.code());
143733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org}
143833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
143933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mul(Register dst, Register src1, Register src2,
144143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    SBit s, Condition cond) {
144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
144386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // dst goes in bits 16-19 for this instruction!
144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
144743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
144843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::smlal(Register dstL,
144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
14552abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(!dstL.is(dstH));
145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::smull(Register dstL,
146243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
146343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
146443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
146543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
146643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
146743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
14682abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(!dstL.is(dstH));
146943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
147043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
147143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
147243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
147343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
147443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::umlal(Register dstL,
147543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
147643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
147743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
147843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
147943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
148043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
14812abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(!dstL.is(dstH));
148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
148343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
148443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
148543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
148643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
148743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::umull(Register dstL,
148843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register dstH,
148943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src1,
149043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Register src2,
149143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      SBit s,
149243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Condition cond) {
149343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
14942abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(!dstL.is(dstH));
149586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
149643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       src2.code()*B8 | B7 | B4 | src1.code());
149743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
149843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
149943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15005c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Miscellaneous arithmetic instructions.
150143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::clz(Register dst, Register src, Condition cond) {
150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // v5 and above.
150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dst.is(pc) && !src.is(pc));
150443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
1505378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org       15*B8 | CLZ | src.code());
150643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
150743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
150843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1509ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org// Saturating instructions.
1510ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1511ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org// Unsigned saturate.
1512ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.orgvoid Assembler::usat(Register dst,
1513ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org                     int satpos,
1514ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org                     const Operand& src,
1515ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org                     Condition cond) {
1516ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  // v6 and above.
1517c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(CpuFeatures::IsSupported(ARMv7));
1518ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  ASSERT(!dst.is(pc) && !src.rm_.is(pc));
1519ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  ASSERT((satpos >= 0) && (satpos <= 31));
1520ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  ASSERT((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
1521ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  ASSERT(src.rs_.is(no_reg));
1522ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1523ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  int sh = 0;
1524ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  if (src.shift_op_ == ASR) {
1525ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org      sh = 1;
1526ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  }
1527ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1528ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 |
1529ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org       src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code());
1530ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org}
1531ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
1532ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
153330ce411529579186181838984710b0b0980857aaricow@chromium.org// Bitfield manipulation instructions.
153430ce411529579186181838984710b0b0980857aaricow@chromium.org
153530ce411529579186181838984710b0b0980857aaricow@chromium.org// Unsigned bit field extract.
153630ce411529579186181838984710b0b0980857aaricow@chromium.org// Extracts #width adjacent bits from position #lsb in a register, and
153730ce411529579186181838984710b0b0980857aaricow@chromium.org// writes them to the low bits of a destination register.
153830ce411529579186181838984710b0b0980857aaricow@chromium.org//   ubfx dst, src, #lsb, #width
153930ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::ubfx(Register dst,
154030ce411529579186181838984710b0b0980857aaricow@chromium.org                     Register src,
154130ce411529579186181838984710b0b0980857aaricow@chromium.org                     int lsb,
154230ce411529579186181838984710b0b0980857aaricow@chromium.org                     int width,
154330ce411529579186181838984710b0b0980857aaricow@chromium.org                     Condition cond) {
154430ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1545c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(CpuFeatures::IsSupported(ARMv7));
154630ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT(!dst.is(pc) && !src.is(pc));
154730ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((lsb >= 0) && (lsb <= 31));
154830ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((width >= 1) && (width <= (32 - lsb)));
154930ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 |
155030ce411529579186181838984710b0b0980857aaricow@chromium.org       lsb*B7 | B6 | B4 | src.code());
155130ce411529579186181838984710b0b0980857aaricow@chromium.org}
155230ce411529579186181838984710b0b0980857aaricow@chromium.org
155330ce411529579186181838984710b0b0980857aaricow@chromium.org
155430ce411529579186181838984710b0b0980857aaricow@chromium.org// Signed bit field extract.
155530ce411529579186181838984710b0b0980857aaricow@chromium.org// Extracts #width adjacent bits from position #lsb in a register, and
155630ce411529579186181838984710b0b0980857aaricow@chromium.org// writes them to the low bits of a destination register. The extracted
155730ce411529579186181838984710b0b0980857aaricow@chromium.org// value is sign extended to fill the destination register.
155830ce411529579186181838984710b0b0980857aaricow@chromium.org//   sbfx dst, src, #lsb, #width
155930ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::sbfx(Register dst,
156030ce411529579186181838984710b0b0980857aaricow@chromium.org                     Register src,
156130ce411529579186181838984710b0b0980857aaricow@chromium.org                     int lsb,
156230ce411529579186181838984710b0b0980857aaricow@chromium.org                     int width,
156330ce411529579186181838984710b0b0980857aaricow@chromium.org                     Condition cond) {
156430ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1565c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(CpuFeatures::IsSupported(ARMv7));
156630ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT(!dst.is(pc) && !src.is(pc));
156730ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((lsb >= 0) && (lsb <= 31));
156830ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((width >= 1) && (width <= (32 - lsb)));
156930ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 |
157030ce411529579186181838984710b0b0980857aaricow@chromium.org       lsb*B7 | B6 | B4 | src.code());
157130ce411529579186181838984710b0b0980857aaricow@chromium.org}
157230ce411529579186181838984710b0b0980857aaricow@chromium.org
157330ce411529579186181838984710b0b0980857aaricow@chromium.org
157430ce411529579186181838984710b0b0980857aaricow@chromium.org// Bit field clear.
157530ce411529579186181838984710b0b0980857aaricow@chromium.org// Sets #width adjacent bits at position #lsb in the destination register
157630ce411529579186181838984710b0b0980857aaricow@chromium.org// to zero, preserving the value of the other bits.
157730ce411529579186181838984710b0b0980857aaricow@chromium.org//   bfc dst, #lsb, #width
157830ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::bfc(Register dst, int lsb, int width, Condition cond) {
157930ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1580c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(CpuFeatures::IsSupported(ARMv7));
158130ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT(!dst.is(pc));
158230ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((lsb >= 0) && (lsb <= 31));
158330ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((width >= 1) && (width <= (32 - lsb)));
158430ce411529579186181838984710b0b0980857aaricow@chromium.org  int msb = lsb + width - 1;
158530ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf);
158630ce411529579186181838984710b0b0980857aaricow@chromium.org}
158730ce411529579186181838984710b0b0980857aaricow@chromium.org
158830ce411529579186181838984710b0b0980857aaricow@chromium.org
158930ce411529579186181838984710b0b0980857aaricow@chromium.org// Bit field insert.
159030ce411529579186181838984710b0b0980857aaricow@chromium.org// Inserts #width adjacent bits from the low bits of the source register
159130ce411529579186181838984710b0b0980857aaricow@chromium.org// into position #lsb of the destination register.
159230ce411529579186181838984710b0b0980857aaricow@chromium.org//   bfi dst, src, #lsb, #width
159330ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid Assembler::bfi(Register dst,
159430ce411529579186181838984710b0b0980857aaricow@chromium.org                    Register src,
159530ce411529579186181838984710b0b0980857aaricow@chromium.org                    int lsb,
159630ce411529579186181838984710b0b0980857aaricow@chromium.org                    int width,
159730ce411529579186181838984710b0b0980857aaricow@chromium.org                    Condition cond) {
159830ce411529579186181838984710b0b0980857aaricow@chromium.org  // v7 and above.
1599c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(CpuFeatures::IsSupported(ARMv7));
160030ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT(!dst.is(pc) && !src.is(pc));
160130ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((lsb >= 0) && (lsb <= 31));
160230ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT((width >= 1) && (width <= (32 - lsb)));
160330ce411529579186181838984710b0b0980857aaricow@chromium.org  int msb = lsb + width - 1;
160430ce411529579186181838984710b0b0980857aaricow@chromium.org  emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
160530ce411529579186181838984710b0b0980857aaricow@chromium.org       src.code());
160630ce411529579186181838984710b0b0980857aaricow@chromium.org}
160730ce411529579186181838984710b0b0980857aaricow@chromium.org
160830ce411529579186181838984710b0b0980857aaricow@chromium.org
1609169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::pkhbt(Register dst,
1610169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Register src1,
1611169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      const Operand& src2,
1612169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Condition cond ) {
1613169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1614169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1615169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | imm5(11-7) | 0(6) | 01(5-4) | Rm(3-0)
1616169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!dst.is(pc));
1617169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src1.is(pc));
1618169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src2.rm().is(pc));
1619169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src2.rm().is(no_reg));
1620169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src2.rs().is(no_reg));
1621169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
1622169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src2.shift_op() == LSL);
1623169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1624169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       src2.shift_imm_*B7 | B4 | src2.rm().code());
1625169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1626169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1627169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1628169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::pkhtb(Register dst,
1629169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Register src1,
1630169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      const Operand& src2,
1631169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Condition cond) {
1632169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1633169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1634169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | imm5(11-7) | 1(6) | 01(5-4) | Rm(3-0)
1635169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!dst.is(pc));
1636169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src1.is(pc));
1637169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src2.rm().is(pc));
1638169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src2.rm().is(no_reg));
1639169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src2.rs().is(no_reg));
1640169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
1641169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src2.shift_op() == ASR);
1642169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int asr = (src2.shift_imm_ == 32) ? 0 : src2.shift_imm_;
1643169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1644169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       asr*B7 | B6 | B4 | src2.rm().code());
1645169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1646169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1647169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1648169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::uxtb(Register dst,
1649169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const Operand& src,
1650169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     Condition cond) {
1651169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.274.
1652169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101110(27-20) | 1111(19-16) |
1653169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1654169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!dst.is(pc));
1655169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src.rm().is(pc));
1656169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src.rm().is(no_reg));
1657169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src.rs().is(no_reg));
1658169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT((src.shift_imm_ == 0) ||
1659169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 8) ||
1660169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 16) ||
1661169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 24));
1662169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src.shift_op() == ROR);
1663169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
1664169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1665169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1666169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1667169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1668169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::uxtab(Register dst,
1669169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Register src1,
1670169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      const Operand& src2,
1671169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                      Condition cond) {
1672169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.271.
1673169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101110(27-20) | Rn(19-16) |
1674169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1675169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!dst.is(pc));
1676169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src1.is(pc));
1677169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src2.rm().is(pc));
1678169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src2.rm().is(no_reg));
1679169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src2.rs().is(no_reg));
1680169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT((src2.shift_imm_ == 0) ||
1681169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src2.shift_imm_ == 8) ||
1682169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src2.shift_imm_ == 16) ||
1683169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src2.shift_imm_ == 24));
1684169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src2.shift_op() == ROR);
1685169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
1686169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       ((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
1687169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1688169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1689169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1690169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::uxtb16(Register dst,
1691169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                       const Operand& src,
1692169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                       Condition cond) {
1693169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.275.
1694169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // cond(31-28) | 01101100(27-20) | 1111(19-16) |
1695169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1696169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!dst.is(pc));
1697169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src.rm().is(pc));
1698169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!src.rm().is(no_reg));
1699169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src.rs().is(no_reg));
1700169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT((src.shift_imm_ == 0) ||
1701169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 8) ||
1702169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 16) ||
1703169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org         (src.shift_imm_ == 24));
1704169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(src.shift_op() == ROR);
1705169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
1706169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1707169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1708169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1709169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
17105c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Status register access instructions.
171143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mrs(Register dst, SRegister s, Condition cond) {
171243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!dst.is(pc));
171343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B24 | s | 15*B16 | dst.code()*B12);
171443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
171543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
171643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
171743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::msr(SRegisterFieldMask fields, const Operand& src,
171843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
171943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(fields >= B16 && fields < B20);  // at least one field set
172043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Instr instr;
172143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!src.rm_.is_valid()) {
17225c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Immediate.
172343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t rotate_imm;
172443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    uint32_t immed_8;
172589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    if (src.must_output_reloc_info(this) ||
172643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
17275c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // Immediate operand cannot be encoded, load it first to register ip.
172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      RecordRelocInfo(src.rmode_, src.imm32_);
172943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ldr(ip, MemOperand(pc, 0), cond);
173043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      msr(fields, Operand(ip), cond);
173143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
173243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
173343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr = I | rotate_imm*B8 | immed_8;
173443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
173543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0);  // only rm allowed
173643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    instr = src.rm_.code();
173743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
173843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | instr | B24 | B21 | fields | 15*B12);
173943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
174043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
174143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17425c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Load/Store instructions.
174343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
1744defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  if (dst.is(pc)) {
1745f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org    positions_recorder()->WriteRecordedPositions();
1746defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
174743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26 | L, dst, src);
174843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
174943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
175043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
175143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::str(Register src, const MemOperand& dst, Condition cond) {
175243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26, src, dst);
175343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
175443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
175543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
175643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) {
175743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26 | B | L, dst, src);
175843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
175943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
176043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
176143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::strb(Register src, const MemOperand& dst, Condition cond) {
176243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod2(cond | B26 | B, src, dst);
176343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
176443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
176543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
176643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrh(Register dst, const MemOperand& src, Condition cond) {
176743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | L | B7 | H | B4, dst, src);
176843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
176943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
177043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
177143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::strh(Register src, const MemOperand& dst, Condition cond) {
177243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | B7 | H | B4, src, dst);
177343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
177443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
177543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
177643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrsb(Register dst, const MemOperand& src, Condition cond) {
177743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | L | B7 | S6 | B4, dst, src);
177843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
177943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
178043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
178143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
178243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod3(cond | L | B7 | S6 | H | B4, dst, src);
178343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
178443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
178543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17869155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgvoid Assembler::ldrd(Register dst1, Register dst2,
17879155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org                     const MemOperand& src, Condition cond) {
1788750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(IsEnabled(ARMv7));
1789720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  ASSERT(src.rm().is(no_reg));
17909155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  ASSERT(!dst1.is(lr));  // r14.
17919155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  ASSERT_EQ(0, dst1.code() % 2);
17929155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  ASSERT_EQ(dst1.code() + 1, dst2.code());
17939155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  addrmod3(cond | B7 | B6 | B4, dst1, src);
1794720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org}
1795720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
1796720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
17979155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgvoid Assembler::strd(Register src1, Register src2,
17989155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org                     const MemOperand& dst, Condition cond) {
1799720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  ASSERT(dst.rm().is(no_reg));
18009155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  ASSERT(!src1.is(lr));  // r14.
18019155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  ASSERT_EQ(0, src1.code() % 2);
18029155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  ASSERT_EQ(src1.code() + 1, src2.code());
1803750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(IsEnabled(ARMv7));
18049155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
1805720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org}
1806720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
1807e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1808169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Preload instructions.
1809169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::pld(const MemOperand& address) {
1810169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.128.
1811169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 0111(27-24) | U(23) | R(22) | 01(21-20) | Rn(19-16) |
1812169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(15-12) | imm5(11-07) | type(6-5) | 0(4)| Rm(3-0) |
1813169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(address.rm().is(no_reg));
1814169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(address.am() == Offset);
1815169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int U = B23;
1816169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int offset = address.offset();
1817169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (offset < 0) {
1818169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    offset = -offset;
1819169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    U = 0;
1820169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
1821169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(offset < 4096);
1822169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(kSpecialCondition | B26 | B24 | U | B22 | B20 | address.rn().code()*B16 |
1823169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       0xf*B12 | offset);
1824169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
1825169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1826169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
18275c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Load/Store multiple instructions.
182843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldm(BlockAddrMode am,
182943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register base,
183043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    RegList dst,
183143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
18325c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // ABI stack constraint: ldmxx base, {..sp..}  base != sp  is not restartable.
183343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(base.is(sp) || (dst & sp.bit()) == 0);
183443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
183543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod4(cond | B27 | am | L, base, dst);
183643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18375c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Emit the constant pool after a function return implemented by ldm ..{..pc}.
183843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (cond == al && (dst & pc.bit()) != 0) {
183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // There is a slight chance that the ldm instruction was actually a call,
184043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // in which case it would be wrong to return into the constant pool; we
184143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // recognize this case by checking if the emission of the pool was blocked
184243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // at the pc of the ldm instruction by a mov lr, pc instruction; if this is
184343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // the case, we emit a jump over the pool.
184443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CheckConstPool(true, no_const_pool_before_ == pc_offset() - kInstrSize);
184543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
184643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
184743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
184843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
184943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::stm(BlockAddrMode am,
185043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register base,
185143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    RegList src,
185243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
185343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod4(cond | B27 | am, base, src);
185443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
185543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
185643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18575c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Exception-generating instructions and debugging support.
1858e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// Stops with a non-negative code less than kNumOfWatchedStops support
1859e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// enabling/disabling and a counter feature. See simulator-arm.h .
1860e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgvoid Assembler::stop(const char* msg, Condition cond, int32_t code) {
18615d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#ifndef __arm__
1862e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  ASSERT(code >= kDefaultStopCode);
18637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  {
18647b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // The Simulator will handle the stop instruction and get the message
18657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // address. It expects to find the address just after the svc instruction.
18667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    BlockConstPoolScope block_const_pool(this);
18677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (code >= 0) {
18687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      svc(kStopCode + code, cond);
18697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    } else {
18707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      svc(kStopCode + kMaxStopCode, cond);
18717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
18727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    emit(reinterpret_cast<Instr>(msg));
1873e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
18745d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#else  // def __arm__
18750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  if (cond != al) {
18760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    Label skip;
18770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    b(&skip, NegateCondition(cond));
18780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    bkpt(0);
18790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    bind(&skip);
18800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  } else {
18810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    bkpt(0);
18820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
18835d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org#endif  // def __arm__
188443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
188543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
188643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
188743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::bkpt(uint32_t imm16) {  // v5 and above
188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint16(imm16));
1889378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
189043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
189143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1893e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgvoid Assembler::svc(uint32_t imm24, Condition cond) {
189443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint24(imm24));
189543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | 15*B24 | imm24);
189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18995c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Coprocessor instructions.
190043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cdp(Coprocessor coproc,
190143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_1,
190243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crd,
190343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crn,
190443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crm,
190543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_2,
190643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
190743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint4(opcode_1) && is_uint3(opcode_2));
190843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 |
190943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code());
191043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
191143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
191343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::cdp2(Coprocessor coproc,
191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_1,
191543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crd,
191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crn,
191743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crm,
191843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_2) {  // v5 and above
1919378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  cdp(coproc, opcode_1, crd, crn, crm, opcode_2, kSpecialCondition);
192043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
192143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
192243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
192343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mcr(Coprocessor coproc,
192443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_1,
192543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register rd,
192643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crn,
192743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crm,
192843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_2,
192943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
193043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
193143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 |
193243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
193343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
193443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
193543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
193643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mcr2(Coprocessor coproc,
193743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_1,
193843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     Register rd,
193943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crn,
194043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crm,
194143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_2) {  // v5 and above
1942378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  mcr(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
194343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
194443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
194543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
194643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mrc(Coprocessor coproc,
194743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_1,
194843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register rd,
194943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crn,
195043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crm,
195143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int opcode_2,
195243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
195443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 |
195543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
195643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
195743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
195843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
195943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::mrc2(Coprocessor coproc,
196043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_1,
196143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     Register rd,
196243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crn,
196343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crm,
196443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int opcode_2) {  // v5 and above
1965378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  mrc(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
196643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
196743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
196843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc(Coprocessor coproc,
197043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crd,
197143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    const MemOperand& src,
197243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    LFlag l,
197343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
197443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src);
197543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
197643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
197743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
197843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc(Coprocessor coproc,
197943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    CRegister crd,
198043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Register rn,
198143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    int option,
198243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    LFlag l,
198343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Condition cond) {
19845c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unindexed addressing.
198543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(is_uint8(option));
198643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |
198743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       coproc*B8 | (option & 255));
198843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
198943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
199043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
199143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc2(Coprocessor coproc,
199243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crd,
199343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     const MemOperand& src,
199443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     LFlag l) {  // v5 and above
1995378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ldc(coproc, crd, src, l, kSpecialCondition);
199643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
199743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
199843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
199943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::ldc2(Coprocessor coproc,
200043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     CRegister crd,
200143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     Register rn,
200243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     int option,
200343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                     LFlag l) {  // v5 and above
2004378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ldc(coproc, crd, rn, option, l, kSpecialCondition);
200543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
200643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
200743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2008c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// Support for VFP.
2009d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
2010b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Assembler::vldr(const DwVfpRegister dst,
2011b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Register base,
2012b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     int offset,
2013b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Condition cond) {
2014b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Ddst = MEM(Rbase + offset).
2015003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-924.
2016003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) |
2017003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 1011(11-8) | offset
2018a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2019a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2020a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2021a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2022a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2023003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2024003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
20253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20260b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  ASSERT(offset >= 0);
20273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
2028003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 |
20293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         0xB*B8 | ((offset / 4) & 255));
20303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
20313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
20323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
20333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ASSERT(!base.is(ip));
20343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
20353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
20363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
20373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
20383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
2039003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8);
20403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
20413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
20423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vldr(const DwVfpRegister dst,
20453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
20463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
20473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(!operand.rm().is_valid());
20483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(operand.am_ == Offset);
20493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  vldr(dst, operand.rn(), operand.offset(), cond);
2050b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
2051b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
2052b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
20535d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vldr(const SwVfpRegister dst,
20545d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     const Register base,
20555d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     int offset,
20565d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     const Condition cond) {
20575d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Sdst = MEM(Rbase + offset).
20585d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Instruction details available in ARM DDI 0406A, A8-628.
2059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) |
20605d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Vdst(15-12) | 1010(11-8) | offset
2061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2064a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2065a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2066d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sd, d;
2067d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  dst.split_code(&sd, &d);
20683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(offset >= 0);
20693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
2071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 |
20725d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org       0xA*B8 | ((offset / 4) & 255));
20733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
20743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
20753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
20763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ASSERT(!base.is(ip));
20773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
20783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
20793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
20803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
20813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
20823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    emit(cond | d*B22 | 0xD1*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
20833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
20843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
20853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vldr(const SwVfpRegister dst,
20883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
20893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
20903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(!operand.rm().is_valid());
20913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(operand.am_ == Offset);
20923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  vldr(dst, operand.rn(), operand.offset(), cond);
20935d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
20945d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
20955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
2096b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Assembler::vstr(const DwVfpRegister src,
2097b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Register base,
2098b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     int offset,
2099b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                     const Condition cond) {
2100b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // MEM(Rbase + offset) = Dsrc.
2101003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1082.
2102003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) |
2103003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 1011(11-8) | (offset/4)
2104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
21090b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  ASSERT(offset >= 0);
2110003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2111003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vd, &d);
2112003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
21133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
2114003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | u*B23 | d*B22 | base.code()*B16 | vd*B12 | 0xB*B8 |
2115003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org         ((offset / 4) & 255));
21163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
21173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
21183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
21193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ASSERT(!base.is(ip));
21203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
21213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
21223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
21233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
21243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
2125003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8);
21263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
21273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
21283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
21293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
21303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vstr(const DwVfpRegister src,
21313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
21323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
21333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(!operand.rm().is_valid());
21343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(operand.am_ == Offset);
21353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  vstr(src, operand.rn(), operand.offset(), cond);
2136b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
2137b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
2138b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
21390b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid Assembler::vstr(const SwVfpRegister src,
21400b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                     const Register base,
21410b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                     int offset,
21420b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org                     const Condition cond) {
21430b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // MEM(Rbase + offset) = SSrc.
21440b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Instruction details available in ARM DDI 0406A, A8-786.
2145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) |
21460b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Vdst(15-12) | 1010(11-8) | (offset/4)
2147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int u = 1;
2148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (offset < 0) {
2149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    offset = -offset;
2150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    u = 0;
2151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2152d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sd, d;
2153d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  src.split_code(&sd, &d);
21543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(offset >= 0);
21553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if ((offset % 4) == 0 && (offset / 4) < 256) {
21563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 |
21573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         0xA*B8 | ((offset / 4) & 255));
21583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
21593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Larger offsets must be handled by computing the correct address
21603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // in the ip register.
21613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ASSERT(!base.is(ip));
21623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (u == 1) {
21633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      add(ip, base, Operand(offset));
21643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
21653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      sub(ip, base, Operand(offset));
21663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
21673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    emit(cond | d*B22 | 0xD0*B20 | ip.code()*B16 | sd*B12 | 0xA*B8);
21683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
21693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
21703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
21713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
21723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid Assembler::vstr(const SwVfpRegister src,
21733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const MemOperand& operand,
21743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     const Condition cond) {
21753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(!operand.rm().is_valid());
21763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(operand.am_ == Offset);
2177c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  vstr(src, operand.rn(), operand.offset(), cond);
21780b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org}
21790b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
21800b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
218174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vldm(BlockAddrMode am,
218274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
218374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister first,
218474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister last,
218574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
2186003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-922.
218774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
2188003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // first(15-12) | 1011(11-8) | (count * 2)
218974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT_LE(first.code(), last.code());
219074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(am == ia || am == ia_w || am == db_w);
219174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(!base.is(pc));
219274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
219374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
219474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
219574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
2196304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  ASSERT(count <= 16);
219774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
219874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xB*B8 | count*2);
219974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
220074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
220174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
220274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vstm(BlockAddrMode am,
220374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
220474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister first,
220574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      DwVfpRegister last,
220674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
2207003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1080.
220874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
220974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // first(15-12) | 1011(11-8) | (count * 2)
221074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT_LE(first.code(), last.code());
221174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(am == ia || am == ia_w || am == db_w);
221274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(!base.is(pc));
221374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
221474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
221574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
221674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
2217304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  ASSERT(count <= 16);
221874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
221974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xB*B8 | count*2);
222074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
222174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
222274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vldm(BlockAddrMode am,
222374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
222474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister first,
222574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister last,
222674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
222774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // Instruction details available in ARM DDI 0406A, A8-626.
222874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
222974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // first(15-12) | 1010(11-8) | (count/2)
223074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT_LE(first.code(), last.code());
223174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(am == ia || am == ia_w || am == db_w);
223274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(!base.is(pc));
223374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
223474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
223574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
223674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
223774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
223874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xA*B8 | count);
223974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
224074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
224174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
224274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid  Assembler::vstm(BlockAddrMode am,
224374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Register base,
224474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister first,
224574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      SwVfpRegister last,
224674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org                      Condition cond) {
224774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // Instruction details available in ARM DDI 0406A, A8-784.
224874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
224974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  // first(15-12) | 1011(11-8) | (count/2)
225074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT_LE(first.code(), last.code());
225174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(am == ia || am == ia_w || am == db_w);
225274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(!base.is(pc));
225374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
225474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int sd, d;
225574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  first.split_code(&sd, &d);
225674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int count = last.code() - first.code() + 1;
225774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
225874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org       0xA*B8 | count);
225974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
226074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
2261e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
22626a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgstatic void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
22636a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  uint64_t i;
2264e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemCopy(&i, &d, 8);
22656a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22666a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *lo = i & 0xffffffff;
22676a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *hi = i >> 32;
22686a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
22696a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
2270e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
22716a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org// Only works for little endian floating point formats.
22726a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org// We don't support VFP on the mixed endian floating point platform.
22736a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgstatic bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
2274b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  ASSERT(CpuFeatures::IsSupported(VFP3));
22756a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22766a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // VMOV can accept an immediate of the form:
22776a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
22786a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7
22796a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
22806a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // The immediate is encoded using an 8-bit quantity, comprised of two
22816a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // 4-bit fields. For an 8-bit immediate of the form:
22826a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
22836a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  [abcdefgh]
22846a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
22856a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // where a is the MSB and h is the LSB, an immediate 64-bit double can be
22866a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // created of the form:
22876a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
22886a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  [aBbbbbbb,bbcdefgh,00000000,00000000,
22896a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //      00000000,00000000,00000000,00000000]
22906a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
22916a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // where B = ~b.
22926a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //
22936a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22946a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  uint32_t lo, hi;
22956a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  DoubleAsTwoUInt32(d, &lo, &hi);
22966a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
22976a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // The most obvious constraint is the long block of zeroes.
22986a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  if ((lo != 0) || ((hi & 0xffff) != 0)) {
22996a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    return false;
23006a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
23016a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23026a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Bits 62:55 must be all clear or all set.
23036a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  if (((hi & 0x3fc00000) != 0) && ((hi & 0x3fc00000) != 0x3fc00000)) {
23046a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    return false;
23056a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
23066a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23076a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Bit 63 must be NOT bit 62.
23086a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  if (((hi ^ (hi << 1)) & (0x40000000)) == 0) {
23096a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    return false;
23106a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
23116a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23126a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Create the encoded immediate in the form:
23136a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  //  [00000000,0000abcd,00000000,0000efgh]
23146a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *encoding  = (hi >> 16) & 0xf;      // Low nybble.
23156a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *encoding |= (hi >> 4) & 0x70000;   // Low three bits of the high nybble.
23166a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  *encoding |= (hi >> 12) & 0x80000;  // Top bit of the high nybble.
23176a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23186a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  return true;
23196a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
23206a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23216a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23226a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
23236a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                     double imm,
232471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org                     const Register scratch) {
23256a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  uint32_t enc;
2326b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) {
23276a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    // The double can be encoded in the instruction.
2328003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    //
2329003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // Dd = immediate
2330003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // Instruction details available in ARM DDI 0406C.b, A8-936.
2331003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) |
2332003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0)
2333003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    int vd, d;
2334003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    dst.split_code(&vd, &d);
233571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org    emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc);
23364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  } else if (FLAG_enable_vldr_imm) {
23374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // TODO(jfb) Temporarily turned off until we have constant blinding or
23384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           some equivalent mitigation: an attacker can otherwise control
23394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           generated data which also happens to be executable, a Very Bad
23404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           Thing indeed.
23414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           Blinding gets tricky because we don't have xor, we probably
23424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           need to add/subtract without losing precision, which requires a
23434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           cookie value that Lithium is probably better positioned to
23444cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           choose.
23454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           We could also add a few peepholes here like detecting 0.0 and
23464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           -0.0 and doing a vmov from the sequestered d14, forcing denorms
23474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           to zero (we set flush-to-zero), and normalizing NaN values.
23484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           We could also detect redundant values.
23494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           The code could also randomize the order of values, though
23504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           that's tricky because vldr has a limited reach. Furthermore
23514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           it breaks load locality.
23524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    RecordRelocInfo(imm);
235371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org    vldr(dst, MemOperand(pc, 0));
23546a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  } else {
23554cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // Synthesise the double from ARM immediates.
23566a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    uint32_t lo, hi;
23576a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    DoubleAsTwoUInt32(imm, &lo, &hi);
23586a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
235933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (scratch.is(no_reg)) {
2360003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      if (dst.code() < 16) {
2361fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code());
2362003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // Move the low part of the double into the lower of the corresponsing S
2363003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // registers of D register dst.
2364003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(lo));
2365fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        vmov(loc.low(), ip);
2366003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2367003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // Move the high part of the double into the higher of the
2368003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // corresponsing S registers of D register dst.
2369003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(hi));
2370fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        vmov(loc.high(), ip);
2371003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      } else {
2372003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // D16-D31 does not have S registers, so move the low and high parts
2373003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // directly to the D register using vmov.32.
2374003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        // Note: This may be slower, so we only do this when we have to.
2375003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(lo));
237671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org        vmov(dst, VmovIndexLo, ip);
2377003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        mov(ip, Operand(hi));
237871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org        vmov(dst, VmovIndexHi, ip);
2379003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      }
238033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    } else {
238133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      // Move the low and high parts of the double to a D register in one
238233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      // instruction.
2383003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      mov(ip, Operand(lo));
238433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      mov(scratch, Operand(hi));
238571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org      vmov(dst, ip, scratch);
23866a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org    }
23876a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  }
23886a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
23896a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23906a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
23916a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.orgvoid Assembler::vmov(const SwVfpRegister dst,
23926a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                     const SwVfpRegister src,
23936a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org                     const Condition cond) {
23946a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Sd = Sm
23956a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Instruction details available in ARM DDI 0406B, A8-642.
2396d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sd, d, sm, m;
2397d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  dst.split_code(&sd, &d);
2398d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  src.split_code(&sm, &m);
2399d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm);
24006a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
24016a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
24026a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
240313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
240469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org                     const DwVfpRegister src,
240569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org                     const Condition cond) {
240669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // Dd = Dm
2407003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-938.
2408003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2409003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2410003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2411003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2412003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2413003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2414003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 |
2415003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       vm);
2416003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
2417003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2418003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2419003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
24206ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org                     const VmovIndex index,
2421003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org                     const Register src,
2422003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org                     const Condition cond) {
2423003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Dd[index] = Rt
2424003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-940.
2425003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) |
2426003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
24276ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  ASSERT(index.index == 0 || index.index == 1);
2428003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2429003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
24306ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 |
24316ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org       d*B7 | B4);
243269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
243369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
243469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
2435fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid Assembler::vmov(const Register dst,
2436fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                     const VmovIndex index,
2437fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                     const DwVfpRegister src,
2438fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                     const Condition cond) {
2439fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Dd[index] = Rt
2440fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.342.
2441fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // cond(31-28) | 1110(27-24) | U=0(23) | opc1=0index(22-21) | 1(20) |
2442fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Vn(19-16) | Rt(15-12) | 1011(11-8) | N(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
2443fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  ASSERT(index.index == 0 || index.index == 1);
2444fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int vn, n;
2445fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  src.split_code(&vn, &n);
2446fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  emit(cond | 0xE*B24 | index.index*B21 | B20 | vn*B16 | dst.code()*B12 |
2447fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org       0xB*B8 | n*B7 | B4);
2448fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
2449fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
2450fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
245169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid Assembler::vmov(const DwVfpRegister dst,
245213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Register src1,
245313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Register src2,
245413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
2455c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dm = <Rt,Rt2>.
2456003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-948.
2457c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
2458c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2459c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  ASSERT(!src1.is(pc) && !src2.is(pc));
2460003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2461003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vm, &m);
2462c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  emit(cond | 0xC*B24 | B22 | src2.code()*B16 |
2463003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2464c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2465c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2466c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
246713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const Register dst1,
246813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Register dst2,
246913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src,
247013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
2471c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // <Rt,Rt2> = Dm.
2472003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-948.
2473c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
2474c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2475c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  ASSERT(!dst1.is(pc) && !dst2.is(pc));
2476003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2477003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2478c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 |
2479003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm);
2480c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2481c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2482c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
248313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const SwVfpRegister dst,
2484c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Register src,
2485c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Condition cond) {
2486c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Sn = Rt.
2487c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-642.
2488c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) |
2489c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2490c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  ASSERT(!src.is(pc));
2491d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sn, n;
2492d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  dst.split_code(&sn, &n);
2493d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
2494c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2495c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2496c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
249713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmov(const Register dst,
249813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const SwVfpRegister src,
2499c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Condition cond) {
2500c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt = Sn.
2501c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-642.
2502c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) |
2503c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2504c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  ASSERT(!dst.is(pc));
2505d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int sn, n;
2506d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  src.split_code(&sn, &n);
2507d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
2508c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2509c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2510c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
25115d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// Type of data to read from or write to VFP register.
25125d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// Used as specifier in generic vcvt instruction.
25135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgenum VFPType { S32, U32, F32, F64 };
25145d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25155d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic bool IsSignedVFPType(VFPType type) {
25175d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  switch (type) {
25185d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case S32:
25195d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return true;
25205d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case U32:
25215d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
25225d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    default:
25235d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      UNREACHABLE();
25245d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
25255d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
25265d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
25275d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25285d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25295d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic bool IsIntegerVFPType(VFPType type) {
25305d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  switch (type) {
25315d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case S32:
25325d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case U32:
25335d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return true;
25345d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F32:
25355d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F64:
25365d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
25375d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    default:
25385d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      UNREACHABLE();
25395d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
25405d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
25415d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
25425d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25435d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25445d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic bool IsDoubleVFPType(VFPType type) {
25455d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  switch (type) {
25465d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F32:
25475d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
25485d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    case F64:
25495d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return true;
25505d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    default:
25515d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      UNREACHABLE();
25525d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      return false;
25535d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
25545d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
25555d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25565d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
2557d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org// Split five bit reg_code based on size of reg_type.
2558d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org//  32-bit register codes are Vm:M
2559d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org//  64-bit register codes are M:Vm
2560d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org// where Vm is four bits, and M is a single bit.
2561d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgstatic void SplitRegCode(VFPType reg_type,
25625d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                         int reg_code,
25635d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                         int* vm,
25645d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                         int* m) {
2565d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  ASSERT((reg_code >= 0) && (reg_code <= 31));
2566d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
2567d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    // 32 bit type.
25685d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *m  = reg_code & 0x1;
25695d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *vm = reg_code >> 1;
25705d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  } else {
2571d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    // 64 bit type.
25725d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *m  = (reg_code & 0x10) >> 4;
25735d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    *vm = reg_code & 0x0F;
25745d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
25755d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
25765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25775d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25785d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// Encode vcvt.src_type.dst_type instruction.
25795d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgstatic Instr EncodeVCVT(const VFPType dst_type,
25805d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const int dst_code,
25815d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const VFPType src_type,
25825d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const int src_code,
258383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                        VFPConversionMode mode,
25845d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                        const Condition cond) {
2585d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  ASSERT(src_type != dst_type);
2586d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  int D, Vd, M, Vm;
2587d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  SplitRegCode(src_type, src_code, &Vm, &M);
2588d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  SplitRegCode(dst_type, dst_code, &Vd, &D);
2589d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
25905d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) {
25915d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Conversion between IEEE floating point and 32-bit integer.
25925d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Instruction details available in ARM DDI 0406B, A8.6.295.
25935d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 1(19) | opc2(18-16) |
25945d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
25955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
25965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
2597d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    int sz, opc2, op;
25985d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
25995d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    if (IsIntegerVFPType(dst_type)) {
26005d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4;
26015d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
260201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org      op = mode;
26035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    } else {
26045d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      ASSERT(IsIntegerVFPType(src_type));
26055d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      opc2 = 0x0;
26065d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
26075d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
26085d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    }
26095d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26105d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | B19 | opc2*B16 |
26115d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            Vd*B12 | 0x5*B9 | sz*B8 | op*B7 | B6 | M*B5 | Vm);
26125d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  } else {
26135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Conversion between IEEE double and single precision.
26145d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Instruction details available in ARM DDI 0406B, A8.6.298.
26155d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0111(19-16) |
26165d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Vd(15-12) | 101(11-9) | sz(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2617d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    int sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
26185d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 |
26195d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org            Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm);
26205d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
26215d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
26225d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26235d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26245d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f64_s32(const DwVfpRegister dst,
26255d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
262683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
26275d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
262801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond));
2629c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2630c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2631c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
26325d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f32_s32(const SwVfpRegister dst,
26335d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
263483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
26355d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
263601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond));
26375d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
26385d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26395d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26405d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f64_u32(const DwVfpRegister dst,
26415d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
264283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
26435d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
264401fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond));
26455d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
26465d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26475d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26485d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_s32_f64(const SwVfpRegister dst,
26495d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const DwVfpRegister src,
265083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
26515d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
265201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond));
26535d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
26545d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26555d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26565d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_u32_f64(const SwVfpRegister dst,
26575d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const DwVfpRegister src,
265883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
26595d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
266001fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond));
26615d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
26625d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26635d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26645d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f64_f32(const DwVfpRegister dst,
26655d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const SwVfpRegister src,
266683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
26675d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
266801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond));
26695d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org}
26705d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26715d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
26725d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.orgvoid Assembler::vcvt_f32_f64(const SwVfpRegister dst,
26735d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const DwVfpRegister src,
267483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                             VFPConversionMode mode,
26755d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                             const Condition cond) {
267601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond));
2677c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2678c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2679c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2680bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgvoid Assembler::vcvt_f64_s32(const DwVfpRegister dst,
2681bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                             int fraction_bits,
2682bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                             const Condition cond) {
2683bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-874.
2684bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 1010(19-16) | Vd(15-12) |
2685bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // 101(11-9) | sf=1(8) | sx=1(7) | 1(6) | i(5) | 0(4) | imm4(3-0)
2686bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  ASSERT(fraction_bits > 0 && fraction_bits <= 32);
2687bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  ASSERT(CpuFeatures::IsSupported(VFP3));
2688bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  int vd, d;
2689bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  dst.split_code(&vd, &d);
2690bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  int i = ((32 - fraction_bits) >> 4) & 1;
2691bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  int imm4 = (32 - fraction_bits) & 0xf;
2692bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 |
2693bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org       vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4);
2694bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org}
2695bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2696bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2697badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid Assembler::vneg(const DwVfpRegister dst,
2698badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org                     const DwVfpRegister src,
2699badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org                     const Condition cond) {
2700003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-968.
2701003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) |
2702003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2703003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2704003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2705003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2706003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2707003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2708003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 |
2709003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
2710badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org}
2711badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
2712badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
27137a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.orgvoid Assembler::vabs(const DwVfpRegister dst,
27147a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org                     const DwVfpRegister src,
27157a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org                     const Condition cond) {
2716003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-524.
2717003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) |
2718003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2719003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2720003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2721003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2722003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2723003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 |
2724003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
27257a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org}
27267a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org
27277a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org
272813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vadd(const DwVfpRegister dst,
272913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
273013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
273113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
273213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vadd(Dn, Dm) double precision floating point addition.
2733c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2734003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-830.
2735003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2736003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2737003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2738003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2739003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2740003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2741003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2742003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2743003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2744003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       n*B7 | m*B5 | vm);
2745c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2746c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2747c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
274813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vsub(const DwVfpRegister dst,
274913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
275013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
275113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
275213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vsub(Dn, Dm) double precision floating point subtraction.
2753c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2754003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1086.
2755003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) |
2756003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2757003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2758003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2759003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2760003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2761003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2762003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2763003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2764003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       n*B7 | B6 | m*B5 | vm);
2765c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2766c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2767c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
276813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vmul(const DwVfpRegister dst,
276913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
277013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
277113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
277213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vmul(Dn, Dm) double precision floating point multiplication.
2773c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2774003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-960.
2775003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) |
2776003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2777003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2778003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2779003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2780003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2781003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2782003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2783003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 |
2784003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       n*B7 | m*B5 | vm);
2785c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2786c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2787c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2788fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Assembler::vmla(const DwVfpRegister dst,
2789fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     const DwVfpRegister src1,
2790fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     const DwVfpRegister src2,
2791fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                     const Condition cond) {
2792003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-932.
2793003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) |
2794003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0)
2795003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2796003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2797003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2798003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2799003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2800003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2801003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
2802003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       vm);
2803fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
2804fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
2805fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
28068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgvoid Assembler::vmls(const DwVfpRegister dst,
28078432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                     const DwVfpRegister src1,
28088432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                     const DwVfpRegister src2,
28098432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                     const Condition cond) {
28108432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-932.
28118432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) |
28128432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=1(6) | M(5) | 0(4) | Vm(3-0)
28138432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int vd, d;
28148432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  dst.split_code(&vd, &d);
28158432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int vn, n;
28168432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  src1.split_code(&vn, &n);
28178432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int vm, m;
28188432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  src2.split_code(&vm, &m);
28198432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | B6 |
28208432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org       m*B5 | vm);
28218432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org}
28228432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
28238432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
282413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vdiv(const DwVfpRegister dst,
282513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src1,
282613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
282713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const Condition cond) {
282813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Dd = vdiv(Dn, Dm) double precision floating point division.
2829c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2830003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-882.
2831003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) |
2832003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0)
2833003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2834003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2835003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vn, n;
2836003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vn, &n);
2837003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2838003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2839003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 |
2840003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       vm);
2841c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2842c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2843c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
284413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid Assembler::vcmp(const DwVfpRegister src1,
284513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                     const DwVfpRegister src2,
2846c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     const Condition cond) {
2847c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // vcmp(Dd, Dm) double precision floating point comparison.
2848003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-864.
2849003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) |
2850003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
2851003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2852003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vd, &d);
2853003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2854003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src2.split_code(&vm, &m);
2855003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 |
2856003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
2857c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2858c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2859c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2860ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgvoid Assembler::vcmp(const DwVfpRegister src1,
2861ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                     const double src2,
2862ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org                     const Condition cond) {
2863003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // vcmp(Dd, #0.0) double precision floating point comparison.
2864003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-864.
2865003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) |
2866003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0)
2867ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  ASSERT(src2 == 0.0);
2868003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2869003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src1.split_code(&vd, &d);
2870003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6);
2871ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org}
2872ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2873ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
287401fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.orgvoid Assembler::vmsr(Register dst, Condition cond) {
287501fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-652.
287601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) |
287701fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
287801fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org  emit(cond | 0xE*B24 | 0xE*B20 |  B16 |
287901fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org       dst.code()*B12 | 0xA*B8 | B4);
288001fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org}
288101fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
288201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org
2883c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Assembler::vmrs(Register dst, Condition cond) {
2884c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Instruction details available in ARM DDI 0406A, A8-652.
2885c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) |
2886c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
2887c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  emit(cond | 0xE*B24 | 0xF*B20 |  B16 |
2888c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org       dst.code()*B12 | 0xA*B8 | B4);
2889c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2890c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2891c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
289232d961d4454609ab4251a760fc46b19f661da90clrn@chromium.orgvoid Assembler::vsqrt(const DwVfpRegister dst,
289332d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                      const DwVfpRegister src,
289432d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                      const Condition cond) {
2895003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8-1058.
2896003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) |
2897003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0)
2898003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vd, d;
2899003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  dst.split_code(&vd, &d);
2900003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  int vm, m;
2901003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  src.split_code(&vm, &m);
2902003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 |
2903003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org       m*B5 | vm);
290432d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org}
290532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
290632d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
2907169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Support for NEON.
2908169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2909169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::vld1(NeonSize size,
2910169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonListOperand& dst,
2911169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonMemOperand& src) {
2912169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.320.
2913169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) |
2914169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
2915169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(CpuFeatures::IsSupported(NEON));
2916169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vd, d;
2917169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  dst.base().split_code(&vd, &d);
2918169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 |
2919169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       dst.type()*B8 | size*B6 | src.align()*B4 | src.rm().code());
2920169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
2921169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2922169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2923169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::vst1(NeonSize size,
2924169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonListOperand& src,
2925169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                     const NeonMemOperand& dst) {
2926169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.404.
2927169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) |
2928169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
2929169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(CpuFeatures::IsSupported(NEON));
2930169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vd, d;
2931169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  src.base().split_code(&vd, &d);
2932169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 |
2933169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org       size*B6 | dst.align()*B4 | dst.rm().code());
2934169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
2935169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2936169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2937169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) {
2938169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Instruction details available in ARM DDI 0406C.b, A8.8.346.
2939169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) |
2940169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0)
2941169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(CpuFeatures::IsSupported(NEON));
2942169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vd, d;
2943169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  dst.split_code(&vd, &d);
2944169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int vm, m;
2945169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  src.split_code(&vm, &m);
2946169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  emit(0xFU*B28 | B25 | (dt & NeonDataTypeUMask) | B23 | d*B22 |
2947169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        (dt & NeonDataTypeSizeMask)*B19 | vd*B12 | 0xA*B8 | m*B5 | B4 | vm);
2948169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
2949169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2950169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
29515c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Pseudo instructions.
2952013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.orgvoid Assembler::nop(int type) {
295389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes
295489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // some of the CPU's pipeline and has to issue. Older ARM chips simply used
295589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
295689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
295789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // a type.
295889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  ASSERT(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
2959013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  emit(al | 13*B21 | type*B12 | type);
2960013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org}
2961013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
2962013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
296389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgbool Assembler::IsMovT(Instr instr) {
296489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
296589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             ((kNumRegisters-1)*B12) |            // mask out register
296689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             EncodeMovwImmediate(0xFFFF));        // mask out immediate value
296789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  return instr == 0x34*B20;
296889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
296989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
297089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
297189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgbool Assembler::IsMovW(Instr instr) {
297289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
297389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             ((kNumRegisters-1)*B12) |            // mask out destination
297489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org             EncodeMovwImmediate(0xFFFF));        // mask out immediate value
297589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  return instr == 0x30*B20;
297689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org}
297789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
297889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
2979beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.orgbool Assembler::IsNop(Instr instr, int type) {
298089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  ASSERT(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
2981496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // Check for mov rx, rx where x = type.
2982beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  return instr == (al | 13*B21 | type*B12 | type);
2983beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org}
2984beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
2985beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
2986c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgbool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) {
2987c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  uint32_t dummy1;
2988c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  uint32_t dummy2;
2989c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  return fits_shifter(imm32, &dummy1, &dummy2, NULL);
2990c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
2991c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2992c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
29935c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Debugging.
29944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid Assembler::RecordJSReturn() {
2995f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
29964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  CheckBuffer();
29974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  RecordRelocInfo(RelocInfo::JS_RETURN);
29984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}
29994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
30004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
30012356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgvoid Assembler::RecordDebugBreakSlot() {
3002f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  positions_recorder()->WriteRecordedPositions();
30032356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  CheckBuffer();
30042356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
30052356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org}
30062356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
30072356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
300843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::RecordComment(const char* msg) {
3009a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_code_comments) {
301043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CheckBuffer();
3011236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
301243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
301343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
301443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
301543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid Assembler::RecordConstPool(int size) {
30175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // We only need this for debugger support, to correctly compute offsets in the
30185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // code.
30195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
30205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
30215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org#endif
30225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
30235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
3024e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
302543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Assembler::GrowBuffer() {
302643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!own_buffer_) FATAL("external code buffer is too small");
302743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30285c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Compute new buffer size.
302943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CodeDesc desc;  // the new buffer
303043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (buffer_size_ < 4*KB) {
303143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    desc.buffer_size = 4*KB;
303243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (buffer_size_ < 1*MB) {
303343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    desc.buffer_size = 2*buffer_size_;
303443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
303543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    desc.buffer_size = buffer_size_ + 1*MB;
303643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
303743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CHECK_GT(desc.buffer_size, 0);  // no overflow
303843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3039f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up new buffer.
304043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc.buffer = NewArray<byte>(desc.buffer_size);
304143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
304243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc.instr_size = pc_offset();
304343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
304443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30455c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Copy the data.
304643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pc_delta = desc.buffer - buffer_;
304743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
3048e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemMove(desc.buffer, buffer_, desc.instr_size);
3049e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemMove(reloc_info_writer.pos() + rc_delta,
3050e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org              reloc_info_writer.pos(), desc.reloc_size);
305143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30525c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Switch buffers.
305343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(buffer_);
305443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  buffer_ = desc.buffer;
305543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  buffer_size_ = desc.buffer_size;
305643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  pc_ += pc_delta;
305743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
305843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                               reloc_info_writer.last_pc() + pc_delta);
305943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30605c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // None of our relocation types are pc relative pointing outside the code
306143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // buffer nor pc absolute pointing inside the code buffer, so there is no need
30625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // to relocate any emitted relocation entries.
306343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30645c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Relocate pending relocation entries.
30657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  for (int i = 0; i < num_pending_reloc_info_; i++) {
30667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    RelocInfo& rinfo = pending_reloc_info_[i];
3067236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
3068236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org           rinfo.rmode() != RelocInfo::POSITION);
30694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    if (rinfo.rmode() != RelocInfo::JS_RETURN) {
30704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org      rinfo.set_pc(rinfo.pc() + pc_delta);
30714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org    }
307243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
307343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
307443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
307543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Assembler::db(uint8_t data) {
30770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // No relocation info should be pending while using db. db is used
30780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // to write pure data with no pointers and the constant pool should
30790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // be emitted before using db.
30807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ASSERT(num_pending_reloc_info_ == 0);
30814cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(num_pending_64_bit_reloc_info_ == 0);
3082a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckBuffer();
3083a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  *reinterpret_cast<uint8_t*>(pc_) = data;
3084a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  pc_ += sizeof(uint8_t);
3085a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3086a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3087a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Assembler::dd(uint32_t data) {
30890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // No relocation info should be pending while using dd. dd is used
30900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // to write pure data with no pointers and the constant pool should
30910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // be emitted before using dd.
30927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ASSERT(num_pending_reloc_info_ == 0);
30934cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(num_pending_64_bit_reloc_info_ == 0);
3094a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckBuffer();
3095a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  *reinterpret_cast<uint32_t*>(pc_) = data;
3096a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  pc_ += sizeof(uint32_t);
3097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3098a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
310089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
310189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                                UseConstantPoolMode mode) {
3102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // We do not try to reuse pool constants.
3103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RelocInfo rinfo(pc_, rmode, data, NULL);
31045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (((rmode >= RelocInfo::JS_RETURN) &&
31055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org       (rmode <= RelocInfo::DEBUG_BREAK_SLOT)) ||
310689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      (rmode == RelocInfo::CONST_POOL) ||
310789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      mode == DONT_USE_CONSTANT_POOL) {
31085c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Adjust code for new modes.
31092356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    ASSERT(RelocInfo::IsDebugBreakSlot(rmode)
31102356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org           || RelocInfo::IsJSReturn(rmode)
31114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org           || RelocInfo::IsComment(rmode)
31125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org           || RelocInfo::IsPosition(rmode)
311389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org           || RelocInfo::IsConstPool(rmode)
311489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org           || mode == DONT_USE_CONSTANT_POOL);
31155c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // These modes do not need an entry in the constant pool.
311643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
31174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    RecordRelocInfoConstantPoolEntryHelper(rinfo);
311843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
31194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (!RelocInfo::IsNone(rinfo.rmode())) {
31209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    // Don't record external references unless the heap will be serialized.
3121c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
3122c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#ifdef DEBUG
3123c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      if (!Serializer::enabled()) {
3124c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        Serializer::TooLateToEnableNow();
3125c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      }
3126c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#endif
3127badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      if (!Serializer::enabled() && !emit_debug_code()) {
3128c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        return;
3129c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      }
31309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
31328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
3133471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      RelocInfo reloc_info_with_ast_id(pc_,
3134471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                       rmode,
3135471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                       RecordedAstId().ToInt(),
3136471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                       NULL);
3137717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org      ClearRecordedAstId();
31388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      reloc_info_writer.Write(&reloc_info_with_ast_id);
31398e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    } else {
31408e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      reloc_info_writer.Write(&rinfo);
31418e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
314243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
314343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
314443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3145e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
31464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgvoid Assembler::RecordRelocInfo(double data) {
31474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // We do not try to reuse pool constants.
31484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  RelocInfo rinfo(pc_, data);
31494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  RecordRelocInfoConstantPoolEntryHelper(rinfo);
31504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
31514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
31524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
31534cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgvoid Assembler::RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo) {
31544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo);
31554cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (num_pending_reloc_info_ == 0) {
31564cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    first_const_pool_use_ = pc_offset();
31574cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
31584cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  pending_reloc_info_[num_pending_reloc_info_++] = rinfo;
31594cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (rinfo.rmode() == RelocInfo::NONE64) {
31604cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    ++num_pending_64_bit_reloc_info_;
31614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
31624cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ASSERT(num_pending_64_bit_reloc_info_ <= num_pending_reloc_info_);
31634cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Make sure the constant pool is not emitted in place of the next
31644cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // instruction for which we just recorded relocation info.
31654cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  BlockConstPoolFor(1);
31664cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org}
31674cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
316843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvoid Assembler::BlockConstPoolFor(int instructions) {
31707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int pc_limit = pc_offset() + instructions * kInstrSize;
31717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (no_const_pool_before_ < pc_limit) {
31727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // If there are some pending entries, the constant pool cannot be blocked
31734cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // further than constant pool instruction's reach.
31747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    ASSERT((num_pending_reloc_info_ == 0) ||
31754cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org           (pc_limit - first_const_pool_use_ < kMaxDistToIntPool));
31764cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // TODO(jfb) Also check 64-bit entries are in range (requires splitting
31774cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    //           them up from 32-bit entries).
31787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    no_const_pool_before_ = pc_limit;
317943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
318043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31817b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (next_buffer_check_ < no_const_pool_before_) {
31827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    next_buffer_check_ = no_const_pool_before_;
31837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
31847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
318543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
318643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31877b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvoid Assembler::CheckConstPool(bool force_emit, bool require_jump) {
31887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Some short sequence of instruction mustn't be broken up by constant pool
31897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // emission, such sequences are protected by calls to BlockConstPoolFor and
31907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // BlockConstPoolScope.
31917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (is_const_pool_blocked()) {
31925c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Something is wrong if emission is forced and blocked at the same time.
319343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(!force_emit);
319443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
319543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
319643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // There is nothing to do if there are no pending constant pool entries.
31987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (num_pending_reloc_info_ == 0)  {
31994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    ASSERT(num_pending_64_bit_reloc_info_ == 0);
32007b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Calculate the offset of the next check.
32017b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    next_buffer_check_ = pc_offset() + kCheckPoolInterval;
32027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return;
32037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
32047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
320543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check that the code buffer is large enough before emitting the constant
32067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // pool (include the jump over the pool and the constant pool marker and
32077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // the gap to the relocation information).
32084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // Note 64-bit values are wider, and the first one needs to be 64-bit aligned.
32097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int jump_instr = require_jump ? kInstrSize : 0;
32104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int size_up_to_marker = jump_instr + kInstrSize;
32114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int size_after_marker = num_pending_reloc_info_ * kPointerSize;
32124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool has_fp_values = (num_pending_64_bit_reloc_info_ > 0);
32134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // 64-bit values must be 64-bit aligned.
32144cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // We'll start emitting at PC: branch+marker, then 32-bit values, then
32154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // 64-bit values which might need to be aligned.
32164cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  bool require_64_bit_align = has_fp_values &&
32174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      (((uintptr_t)pc_ + size_up_to_marker + size_after_marker) & 0x3);
32184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (require_64_bit_align) {
32194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    size_after_marker += kInstrSize;
32204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
32214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // num_pending_reloc_info_ also contains 64-bit entries, the above code
32224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // therefore already counted half of the size for 64-bit entries. Add the
32234cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // remaining size.
32244cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  STATIC_ASSERT(kPointerSize == kDoubleSize / 2);
32254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  size_after_marker += num_pending_64_bit_reloc_info_ * (kDoubleSize / 2);
32264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int size = size_up_to_marker + size_after_marker;
32284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // We emit a constant pool when:
32304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //  * requested to do so by parameter force_emit (e.g. after each function).
32314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //  * the distance from the first instruction accessing the constant pool to
32324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    any of the constant pool entries will exceed its limit the next
32334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    time the pool is checked. This is overly restrictive, but we don't emit
32344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    constant pool entries in-order so it's conservatively correct.
32354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //  * the instruction doesn't require a jump after itself to jump over the
32364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  //    constant pool, and we're getting close to running out of range.
32374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (!force_emit) {
32384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    ASSERT((first_const_pool_use_ >= 0) && (num_pending_reloc_info_ > 0));
32394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    int dist = pc_offset() + size - first_const_pool_use_;
32404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    if (has_fp_values) {
32414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if ((dist < kMaxDistToFPPool - kCheckPoolInterval) &&
32424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          (require_jump || (dist < kMaxDistToFPPool / 2))) {
32434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        return;
32444cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
32454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    } else {
32464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if ((dist < kMaxDistToIntPool - kCheckPoolInterval) &&
32474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          (require_jump || (dist < kMaxDistToIntPool / 2))) {
32484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        return;
32494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
32504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
32514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
32524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  int needed_space = size + kGap;
32547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  while (buffer_space() <= needed_space) GrowBuffer();
32557b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
32567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  {
32577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Block recursive calls to CheckConstPool.
32587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    BlockConstPoolScope block_const_pool(this);
32595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    RecordComment("[ Constant Pool");
32605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    RecordConstPool(size);
32617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
32627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Emit jump over constant pool if necessary.
32637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    Label after_pool;
32647b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (require_jump) {
32657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      b(&after_pool);
326643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
326743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
326872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    // Put down constant pool marker "Undefined instruction".
32694cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // The data size helps disassembly know what to print.
3270906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    emit(kConstantPoolMarker |
3271906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org         EncodeConstantPoolLength(size_after_marker / kPointerSize));
32727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
32734cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    if (require_64_bit_align) {
32744cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      emit(kConstantPoolMarker);
32754cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
32764cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32774cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // Emit 64-bit constant pool entries first: their range is smaller than
32784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // 32-bit entries.
32794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    for (int i = 0; i < num_pending_reloc_info_; i++) {
32804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      RelocInfo& rinfo = pending_reloc_info_[i];
32814cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if (rinfo.rmode() != RelocInfo::NONE64) {
32834cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        // 32-bit values emitted later.
32844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        continue;
32854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
32864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32874cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      ASSERT(!((uintptr_t)pc_ & 0x3));  // Check 64-bit alignment.
32884cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32894cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      Instr instr = instr_at(rinfo.pc());
32904cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
32914cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      ASSERT((IsVldrDPcImmediateOffset(instr) &&
32924cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org              GetVldrDRegisterImmediateOffset(instr) == 0));
32934cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      int delta = pc_ - rinfo.pc() - kPcLoadDelta;
32954cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      ASSERT(is_uint10(delta));
32964cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32974cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      instr_at_put(rinfo.pc(), SetVldrDRegisterImmediateOffset(instr, delta));
32984cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
32994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      const double double_data = rinfo.data64();
33004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      uint64_t uint_data = 0;
3301e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      OS::MemCopy(&uint_data, &double_data, sizeof(double_data));
33024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      emit(uint_data & 0xFFFFFFFF);
33034cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      emit(uint_data >> 32);
33044cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
33054cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
33064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // Emit 32-bit constant pool entries.
33077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    for (int i = 0; i < num_pending_reloc_info_; i++) {
33087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      RelocInfo& rinfo = pending_reloc_info_[i];
33097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
33107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org             rinfo.rmode() != RelocInfo::POSITION &&
33115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org             rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
33125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org             rinfo.rmode() != RelocInfo::CONST_POOL);
33137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
33144cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if (rinfo.rmode() == RelocInfo::NONE64) {
33154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        // 64-bit values emitted earlier.
33164cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        continue;
33174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
33184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
33197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Instr instr = instr_at(rinfo.pc());
33204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
33214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // 64-bit loads shouldn't get here.
33224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      ASSERT(!IsVldrDPcImmediateOffset(instr));
33234cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
33244cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      int delta = pc_ - rinfo.pc() - kPcLoadDelta;
33254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // 0 is the smallest delta:
33264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      //   ldr rd, [pc, #0]
33274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      //   constant pool marker
33284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      //   data
33294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
333089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      if (IsLdrPcImmediateOffset(instr) &&
333189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org          GetLdrRegisterImmediateOffset(instr) == 0) {
333289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        ASSERT(is_uint12(delta));
333389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta));
33344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        emit(rinfo.data());
333589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      } else {
333689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org        ASSERT(IsMovW(instr));
33374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        emit(rinfo.data());
333889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      }
33397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
334043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    num_pending_reloc_info_ = 0;
33424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    num_pending_64_bit_reloc_info_ = 0;
33437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    first_const_pool_use_ = -1;
33447b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
33457b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    RecordComment("]");
33467b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
33477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (after_pool.is_linked()) {
33487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      bind(&after_pool);
33497b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
335043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
335143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
335243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Since a constant pool was just emitted, move the check offset forward by
335343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the standard interval.
33547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  next_buffer_check_ = pc_offset() + kCheckPoolInterval;
335543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
335643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
335743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
335843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
33599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
33609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_ARM
3361