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