15c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Copyright (c) 1994-2006 Sun Microsystems Inc. 25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// All Rights Reserved. 35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without 55c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are 65c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met: 75c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 85c838251403b0be9a882540f1922577abba4c872ager@chromium.org// - Redistributions of source code must retain the above copyright notice, 95c838251403b0be9a882540f1922577abba4c872ager@chromium.org// this list of conditions and the following disclaimer. 105c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 115c838251403b0be9a882540f1922577abba4c872ager@chromium.org// - Redistribution in binary form must reproduce the above copyright 125c838251403b0be9a882540f1922577abba4c872ager@chromium.org// notice, this list of conditions and the following disclaimer in the 135c838251403b0be9a882540f1922577abba4c872ager@chromium.org// documentation and/or other materials provided with the distribution. 145c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 155c838251403b0be9a882540f1922577abba4c872ager@chromium.org// - Neither the name of Sun Microsystems or the names of contributors may 165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// be used to endorse or promote products derived from this software without 175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// specific prior written permission. 185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 275c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 285c838251403b0be9a882540f1922577abba4c872ager@chromium.org// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 295c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 315c838251403b0be9a882540f1922577abba4c872ager@chromium.org// The original source code covered by the above license above has been 325c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modified significantly by Google Inc. 333233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 365c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "v8.h" 379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS 399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 405c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "mips/assembler-mips-inl.h" 415c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "serialize.h" 425c838251403b0be9a882540f1922577abba4c872ager@chromium.org 435c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 { 445c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal { 455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#ifdef DEBUG 4783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgbool CpuFeatures::initialized_ = false; 4883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#endif 4983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgunsigned CpuFeatures::supported_ = 0; 50750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgunsigned CpuFeatures::found_by_runtime_probing_only_ = 0; 5163ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.orgunsigned CpuFeatures::cross_compile_ = 0; 525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 531805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 54003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgExternalReference ExternalReference::cpu_features() { 55003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ASSERT(CpuFeatures::initialized_); 56003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return ExternalReference(&CpuFeatures::supported_); 57003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 58003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 59003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 601805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org// Get the CPU features enabled by the build. For cross compilation the 611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org// preprocessor symbols CAN_USE_FPU_INSTRUCTIONS 621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org// can be defined to enable FPU instructions when building the 631805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org// snapshot. 641805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgstatic uint64_t CpuFeaturesImpliedByCompiler() { 651805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org uint64_t answer = 0; 661805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#ifdef CAN_USE_FPU_INSTRUCTIONS 67750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org answer |= static_cast<uint64_t>(1) << FPU; 681805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#endif // def CAN_USE_FPU_INSTRUCTIONS 691805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 701805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#ifdef __mips__ 711805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // If the compiler is allowed to use FPU then we can use FPU too in our code 721805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // generation even when generating snapshots. This won't work for cross 731805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // compilation. 741805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#if(defined(__mips_hard_float) && __mips_hard_float != 0) 75750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org answer |= static_cast<uint64_t>(1) << FPU; 761805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#endif // defined(__mips_hard_float) && __mips_hard_float != 0 771805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#endif // def __mips__ 781805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 791805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org return answer; 801805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 811805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 821805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 8359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgconst char* DoubleRegister::AllocationIndexToString(int index) { 84e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 85e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const char* const names[] = { 86e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f0", 87e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f2", 88e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f4", 89e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f6", 90e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f8", 91e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f10", 92e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f12", 93e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f14", 94e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f16", 95e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f18", 96e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f20", 97e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f22", 98e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f24", 99e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "f26" 100e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org }; 101e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return names[index]; 10259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 10359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 10459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 10583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid CpuFeatures::Probe() { 106b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org unsigned standard_features = (OS::CpuFeaturesImpliedByPlatform() | 107b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org CpuFeaturesImpliedByCompiler()); 108b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org ASSERT(supported_ == 0 || supported_ == standard_features); 10983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#ifdef DEBUG 11083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org initialized_ = true; 11183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#endif 1121805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 1131805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Get the features implied by the OS and the compiler settings. This is the 1141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // minimal set of features which is also allowed for generated code in the 1151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // snapshot. 116b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org supported_ |= standard_features; 1171805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 1181805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org if (Serializer::enabled()) { 1191805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // No probing for features if we might serialize (generate snapshot). 1201805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org return; 1211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 1221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 1237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // If the compiler is allowed to use fpu then we can use fpu too in our 1247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // code generation. 1257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#if !defined(__mips__) 126e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // For the simulator build, use FPU. 127e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org supported_ |= static_cast<uint64_t>(1) << FPU; 1287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#else 1291805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Probe for additional features not already known to be available. 1301e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org CPU cpu; 1311e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (cpu.has_fpu()) { 1327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // This implementation also sets the FPU flags if 1337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // runtime detection of FPU returns true. 134750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org supported_ |= static_cast<uint64_t>(1) << FPU; 135750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << FPU; 1367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 1377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif 1387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1395c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1415c838251403b0be9a882540f1922577abba4c872ager@chromium.orgint ToNumber(Register reg) { 1425c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(reg.is_valid()); 1435c838251403b0be9a882540f1922577abba4c872ager@chromium.org const int kNumbers[] = { 1445c838251403b0be9a882540f1922577abba4c872ager@chromium.org 0, // zero_reg 1455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1, // at 1465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2, // v0 1475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3, // v1 1485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4, // a0 1495c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5, // a1 1505c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6, // a2 1515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7, // a3 1525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8, // t0 1535c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9, // t1 1545c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10, // t2 1555c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11, // t3 1565c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12, // t4 1575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13, // t5 1585c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14, // t6 1595c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15, // t7 1605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16, // s0 1615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17, // s1 1625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18, // s2 1635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19, // s3 1645c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20, // s4 1655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 21, // s5 1665c838251403b0be9a882540f1922577abba4c872ager@chromium.org 22, // s6 1675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 23, // s7 1685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 24, // t8 1695c838251403b0be9a882540f1922577abba4c872ager@chromium.org 25, // t9 1705c838251403b0be9a882540f1922577abba4c872ager@chromium.org 26, // k0 1715c838251403b0be9a882540f1922577abba4c872ager@chromium.org 27, // k1 1725c838251403b0be9a882540f1922577abba4c872ager@chromium.org 28, // gp 1735c838251403b0be9a882540f1922577abba4c872ager@chromium.org 29, // sp 1747d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 30, // fp 1755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 31, // ra 1765c838251403b0be9a882540f1922577abba4c872ager@chromium.org }; 1775c838251403b0be9a882540f1922577abba4c872ager@chromium.org return kNumbers[reg.code()]; 1785c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 1795c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1815c838251403b0be9a882540f1922577abba4c872ager@chromium.orgRegister ToRegister(int num) { 1825c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(num >= 0 && num < kNumRegisters); 1835c838251403b0be9a882540f1922577abba4c872ager@chromium.org const Register kRegisters[] = { 1845c838251403b0be9a882540f1922577abba4c872ager@chromium.org zero_reg, 1855c838251403b0be9a882540f1922577abba4c872ager@chromium.org at, 1865c838251403b0be9a882540f1922577abba4c872ager@chromium.org v0, v1, 1875c838251403b0be9a882540f1922577abba4c872ager@chromium.org a0, a1, a2, a3, 1885c838251403b0be9a882540f1922577abba4c872ager@chromium.org t0, t1, t2, t3, t4, t5, t6, t7, 1895c838251403b0be9a882540f1922577abba4c872ager@chromium.org s0, s1, s2, s3, s4, s5, s6, s7, 1905c838251403b0be9a882540f1922577abba4c872ager@chromium.org t8, t9, 1915c838251403b0be9a882540f1922577abba4c872ager@chromium.org k0, k1, 1925c838251403b0be9a882540f1922577abba4c872ager@chromium.org gp, 1935c838251403b0be9a882540f1922577abba4c872ager@chromium.org sp, 1947d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org fp, 1955c838251403b0be9a882540f1922577abba4c872ager@chromium.org ra 1965c838251403b0be9a882540f1922577abba4c872ager@chromium.org }; 1975c838251403b0be9a882540f1922577abba4c872ager@chromium.org return kRegisters[num]; 1985c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 1995c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2005c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2015c838251403b0be9a882540f1922577abba4c872ager@chromium.org// ----------------------------------------------------------------------------- 2025c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Implementation of RelocInfo. 2035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgconst int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 20534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 1 << RelocInfo::INTERNAL_REFERENCE; 2065c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool RelocInfo::IsCodedSpecially() { 2097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // The deserializer needs to know whether a pointer is specially coded. Being 2107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // specially coded on MIPS means that it is a lui/ori instruction, and that is 2117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // always the case inside code objects. 2127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return true; 2137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 2147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Patch the code at the current address with the supplied instructions. 2175c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) { 2185c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr* pc = reinterpret_cast<Instr*>(pc_); 2195c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr* instr = reinterpret_cast<Instr*>(instructions); 2205c838251403b0be9a882540f1922577abba4c872ager@chromium.org for (int i = 0; i < instruction_count; i++) { 2215c838251403b0be9a882540f1922577abba4c872ager@chromium.org *(pc + i) = *(instr + i); 2225c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 2235c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2245c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Indicate that code has changed. 2255c838251403b0be9a882540f1922577abba4c872ager@chromium.org CPU::FlushICache(pc_, instruction_count * Assembler::kInstrSize); 2265c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2285c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2295c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Patch the code at the current PC with a call to the target address. 2305c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Additional guard instructions can be added if required. 2315c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 2325c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Patch the code at the current address with a call to the target. 2335c838251403b0be9a882540f1922577abba4c872ager@chromium.org UNIMPLEMENTED_MIPS(); 2345c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2365c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2375c838251403b0be9a882540f1922577abba4c872ager@chromium.org// ----------------------------------------------------------------------------- 2385c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Implementation of Operand and MemOperand. 2395c838251403b0be9a882540f1922577abba4c872ager@chromium.org// See assembler-mips-inl.h for inlined constructors. 2405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2415c838251403b0be9a882540f1922577abba4c872ager@chromium.orgOperand::Operand(Handle<Object> handle) { 24279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 2435c838251403b0be9a882540f1922577abba4c872ager@chromium.org rm_ = no_reg; 2445c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Verify all Objects referred by code are NOT in new space. 2455c838251403b0be9a882540f1922577abba4c872ager@chromium.org Object* obj = *handle; 2465c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (obj->IsHeapObject()) { 247e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org ASSERT(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj)); 2485c838251403b0be9a882540f1922577abba4c872ager@chromium.org imm32_ = reinterpret_cast<intptr_t>(handle.location()); 2495c838251403b0be9a882540f1922577abba4c872ager@chromium.org rmode_ = RelocInfo::EMBEDDED_OBJECT; 2505c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 2515c838251403b0be9a882540f1922577abba4c872ager@chromium.org // No relocation needed. 2525c838251403b0be9a882540f1922577abba4c872ager@chromium.org imm32_ = reinterpret_cast<intptr_t>(obj); 25359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org rmode_ = RelocInfo::NONE32; 2545c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 2555c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2565c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgMemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) { 2595c838251403b0be9a882540f1922577abba4c872ager@chromium.org offset_ = offset; 2605c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2635c838251403b0be9a882540f1922577abba4c872ager@chromium.org// ----------------------------------------------------------------------------- 2647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Specific instructions, constants, and masks. 2657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgstatic const int kNegOffset = 0x00008000; 2677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 2687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// operations as post-increment of sp. 2697d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kPopInstruction = ADDIU | (kRegister_sp_Code << kRsShift) 2707d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org | (kRegister_sp_Code << kRtShift) | (kPointerSize & kImm16Mask); 2717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 2727d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kPushInstruction = ADDIU | (kRegister_sp_Code << kRsShift) 2737d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org | (kRegister_sp_Code << kRtShift) | (-kPointerSize & kImm16Mask); 2747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// sw(r, MemOperand(sp, 0)) 2757d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kPushRegPattern = SW | (kRegister_sp_Code << kRsShift) 2767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (0 & kImm16Mask); 2777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// lw(r, MemOperand(sp, 0)) 2787d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kPopRegPattern = LW | (kRegister_sp_Code << kRsShift) 2797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (0 & kImm16Mask); 2807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2817d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kLwRegFpOffsetPattern = LW | (kRegister_fp_Code << kRsShift) 2827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (0 & kImm16Mask); 2837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2847d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kSwRegFpOffsetPattern = SW | (kRegister_fp_Code << kRsShift) 2857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (0 & kImm16Mask); 2867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2877d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kLwRegFpNegOffsetPattern = LW | (kRegister_fp_Code << kRsShift) 2887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (kNegOffset & kImm16Mask); 2897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2907d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgconst Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift) 2917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (kNegOffset & kImm16Mask); 2927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// A mask for the Rt register for push, pop, lw, sw instructions. 2937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst Instr kRtMask = kRtFieldMask; 2947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst Instr kLwSwInstrTypeMask = 0xffe00000; 2957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst Instr kLwSwInstrArgumentMask = ~kLwSwInstrTypeMask; 2967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst Instr kLwSwOffsetMask = kImm16Mask; 2977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 3008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org : AssemblerBase(isolate, buffer, buffer_size), 301471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org recorded_ast_id_(TypeFeedbackId::None()), 302e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org positions_recorder_(this) { 3038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 3047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org last_trampoline_pool_end_ = 0; 3067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org no_trampoline_pool_before_ = 0; 3077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org trampoline_pool_blocked_nesting_ = 0; 3083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // We leave space (16 * kTrampolineSlotsSize) 3093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // for BlockTrampolinePoolScope buffer. 3103cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_buffer_check_ = kMaxBranchOffset - kTrampolineSlotsSize * 16; 31183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org internal_trampoline_exception_ = false; 312c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org last_bound_pos_ = 0; 31383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 3143cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org trampoline_emitted_ = false; 3153cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org unbound_labels_count_ = 0; 3163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org block_buffer_growth_ = false; 3173cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 318717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org ClearRecordedAstId(); 3195c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 3205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3215c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3225c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GetCode(CodeDesc* desc) { 3237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap. 324f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up code descriptor. 3255c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc->buffer = buffer_; 3265c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc->buffer_size = buffer_size_; 3275c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc->instr_size = pc_offset(); 3285c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 3299af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org desc->origin = this; 3305c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 3315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::Align(int m) { 3347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(m >= 4 && IsPowerOf2(m)); 3357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org while ((pc_offset() & (m - 1)) != 0) { 3367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org nop(); 3377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 3387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::CodeTargetAlign() { 3427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // No advantage to aligning branch/call targets to more than 3437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // single instruction, that I am aware of. 3447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Align(4); 3457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 34883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgRegister Assembler::GetRtReg(Instr instr) { 3497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt; 35083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org rt.code_ = (instr & kRtFieldMask) >> kRtShift; 3517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return rt; 3527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 35583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgRegister Assembler::GetRsReg(Instr instr) { 35683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register rs; 35783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org rs.code_ = (instr & kRsFieldMask) >> kRsShift; 35883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return rs; 35983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 36083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 36183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 36283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgRegister Assembler::GetRdReg(Instr instr) { 36383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register rd; 36483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org rd.code_ = (instr & kRdFieldMask) >> kRdShift; 36583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return rd; 36683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 36783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 36883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 36983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetRt(Instr instr) { 37083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return (instr & kRtFieldMask) >> kRtShift; 37183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 37283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 37383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 37483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetRtField(Instr instr) { 37583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return instr & kRtFieldMask; 37683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 37783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 37883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 37983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetRs(Instr instr) { 38083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return (instr & kRsFieldMask) >> kRsShift; 38183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 38283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 38383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 38483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetRsField(Instr instr) { 38583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return instr & kRsFieldMask; 38683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 38783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 38883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 38983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetRd(Instr instr) { 39083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return (instr & kRdFieldMask) >> kRdShift; 39183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 39283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 39383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 39483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetRdField(Instr instr) { 39583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return instr & kRdFieldMask; 39683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 39783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 39883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 39983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetSa(Instr instr) { 40083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return (instr & kSaFieldMask) >> kSaShift; 40183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 40283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 40383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 40483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetSaField(Instr instr) { 40583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return instr & kSaFieldMask; 40683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 40783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 40883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 40983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetOpcodeField(Instr instr) { 41083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return instr & kOpcodeMask; 41183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 41283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 41383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 4143cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orguint32_t Assembler::GetFunction(Instr instr) { 4153cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return (instr & kFunctionFieldMask) >> kFunctionShift; 4163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 4173cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 4183cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 4193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orguint32_t Assembler::GetFunctionField(Instr instr) { 4203cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return instr & kFunctionFieldMask; 4213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 4223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 4233cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 42483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetImmediate16(Instr instr) { 42583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return instr & kImm16Mask; 42683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 42783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 42883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 42983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orguint32_t Assembler::GetLabelConst(Instr instr) { 43083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return instr & ~kImm16Mask; 43183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 43283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 43383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 4347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsPop(Instr instr) { 4357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return (instr & ~kRtMask) == kPopRegPattern; 4367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsPush(Instr instr) { 4407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return (instr & ~kRtMask) == kPushRegPattern; 4417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsSwRegFpOffset(Instr instr) { 4457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern); 4467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsLwRegFpOffset(Instr instr) { 4507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern); 4517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsSwRegFpNegOffset(Instr instr) { 4557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & (kLwSwInstrTypeMask | kNegOffset)) == 4567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org kSwRegFpNegOffsetPattern); 4577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsLwRegFpNegOffset(Instr instr) { 4617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & (kLwSwInstrTypeMask | kNegOffset)) == 4627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org kLwRegFpNegOffsetPattern); 4637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4665c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Labels refer to positions in the (to be) generated code. 4675c838251403b0be9a882540f1922577abba4c872ager@chromium.org// There are bound, linked, and unused labels. 4685c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 4695c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Bound labels refer to known positions in the already 4705c838251403b0be9a882540f1922577abba4c872ager@chromium.org// generated code. pos() is the position the label refers to. 4715c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 4725c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Linked labels refer to unknown positions in the code 4735c838251403b0be9a882540f1922577abba4c872ager@chromium.org// to be generated; pos() is the position of the last 4745c838251403b0be9a882540f1922577abba4c872ager@chromium.org// instruction using the label. 4755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// The link chain is terminated by a value in the instruction of -1, 4777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// which is an otherwise illegal value (branch -1 is inf loop). 4787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// The instruction 16-bit offset field addresses 32-bit words, but in 4797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// code is conv to an 18-bit value addressing bytes, hence the -4 value. 4805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4815c838251403b0be9a882540f1922577abba4c872ager@chromium.orgconst int kEndOfChain = -4; 4823cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org// Determines the end of the Jump chain (a subset of the label link chain). 4833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgconst int kEndOfJumpChain = 0; 4845c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsBranch(Instr instr) { 48783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint32_t opcode = GetOpcodeField(instr); 48883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint32_t rt_field = GetRtField(instr); 48983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint32_t rs_field = GetRsField(instr); 4905c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Checks if the instruction is a branch. 4915c838251403b0be9a882540f1922577abba4c872ager@chromium.org return opcode == BEQ || 4925c838251403b0be9a882540f1922577abba4c872ager@chromium.org opcode == BNE || 4935c838251403b0be9a882540f1922577abba4c872ager@chromium.org opcode == BLEZ || 4945c838251403b0be9a882540f1922577abba4c872ager@chromium.org opcode == BGTZ || 4955c838251403b0be9a882540f1922577abba4c872ager@chromium.org opcode == BEQL || 4965c838251403b0be9a882540f1922577abba4c872ager@chromium.org opcode == BNEL || 4975c838251403b0be9a882540f1922577abba4c872ager@chromium.org opcode == BLEZL || 49883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org opcode == BGTZL || 4995c838251403b0be9a882540f1922577abba4c872ager@chromium.org (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ || 5005c838251403b0be9a882540f1922577abba4c872ager@chromium.org rt_field == BLTZAL || rt_field == BGEZAL)) || 5017bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org (opcode == COP1 && rs_field == BC1); // Coprocessor branch. 5027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 5037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 504e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 5057bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgbool Assembler::IsEmittedConstant(Instr instr) { 5067bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org uint32_t label_constant = GetLabelConst(instr); 5077bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return label_constant == 0; // Emitted label const in reg-exp engine. 5087bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 5097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 510e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 51183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgbool Assembler::IsBeq(Instr instr) { 51283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return GetOpcodeField(instr) == BEQ; 51383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 51483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 51583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 51683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgbool Assembler::IsBne(Instr instr) { 51783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return GetOpcodeField(instr) == BNE; 51883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 51983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 52083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 5213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgbool Assembler::IsJump(Instr instr) { 5223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t opcode = GetOpcodeField(instr); 5233cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t rt_field = GetRtField(instr); 5243cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t rd_field = GetRdField(instr); 5253cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t function_field = GetFunctionField(instr); 5263cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Checks if the instruction is a jump. 5273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return opcode == J || opcode == JAL || 5283cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org (opcode == SPECIAL && rt_field == 0 && 5293cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ((function_field == JALR) || (rd_field == 0 && (function_field == JR)))); 5303cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5323cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5333cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgbool Assembler::IsJ(Instr instr) { 5343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t opcode = GetOpcodeField(instr); 5353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Checks if the instruction is a jump. 5363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return opcode == J; 5373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5383cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5393cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 54034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgbool Assembler::IsJal(Instr instr) { 54134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return GetOpcodeField(instr) == JAL; 54234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 54334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 544e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 54534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgbool Assembler::IsJr(Instr instr) { 54634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR; 54734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 54834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 549e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 55034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgbool Assembler::IsJalr(Instr instr) { 55134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JALR; 55234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 55334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 55434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 5553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgbool Assembler::IsLui(Instr instr) { 5563cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t opcode = GetOpcodeField(instr); 5573cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Checks if the instruction is a load upper immediate. 5583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return opcode == LUI; 5593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5603cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5613cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5623cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgbool Assembler::IsOri(Instr instr) { 5633cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t opcode = GetOpcodeField(instr); 5643cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Checks if the instruction is a load upper immediate. 5653cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return opcode == ORI; 5663cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5673cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5683cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsNop(Instr instr, unsigned int type) { 5707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // See Assembler::nop(type). 5717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(type < 32); 57283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint32_t opcode = GetOpcodeField(instr); 57333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org uint32_t function = GetFunctionField(instr); 57483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint32_t rt = GetRt(instr); 57533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org uint32_t rd = GetRd(instr); 57683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint32_t sa = GetSa(instr); 5777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 57833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // Traditional mips nop == sll(zero_reg, zero_reg, 0) 57933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // When marking non-zero type, use sll(zero_reg, at, type) 58033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // to avoid use of mips ssnop and ehb special encodings 58133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // of the sll instruction. 5827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 58333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Register nop_rt_reg = (type == 0) ? zero_reg : at; 58433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org bool ret = (opcode == SPECIAL && function == SLL && 58533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org rd == static_cast<uint32_t>(ToNumber(zero_reg)) && 58633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) && 5877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org sa == type); 5887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ret; 5907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 5917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgint32_t Assembler::GetBranchOffset(Instr instr) { 5947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(IsBranch(instr)); 59559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return (static_cast<int16_t>(instr & kImm16Mask)) << 2; 5967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 5977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsLw(Instr instr) { 6007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & kOpcodeMask) == LW); 6017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 6027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgint16_t Assembler::GetLwOffset(Instr instr) { 6057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(IsLw(instr)); 6067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & kImm16Mask)); 6077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 6087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgInstr Assembler::SetLwOffset(Instr instr, int16_t offset) { 6117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(IsLw(instr)); 6127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // We actually create a new lw instruction based on the original one. 6147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask) 6157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (offset & kImm16Mask); 6167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return temp_instr; 6187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 6197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsSw(Instr instr) { 6227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & kOpcodeMask) == SW); 6237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 6247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgInstr Assembler::SetSwOffset(Instr instr, int16_t offset) { 6277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(IsSw(instr)); 6287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); 6297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 6307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::IsAddImmediate(Instr instr) { 6337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & kOpcodeMask) == ADDIU); 6347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 6357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 6377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgInstr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) { 6387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(IsAddImmediate(instr)); 6397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); 6405c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 6415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6425c838251403b0be9a882540f1922577abba4c872ager@chromium.org 64383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgbool Assembler::IsAndImmediate(Instr instr) { 64483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return GetOpcodeField(instr) == ANDI; 64583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 64683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 64783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 6485c838251403b0be9a882540f1922577abba4c872ager@chromium.orgint Assembler::target_at(int32_t pos) { 6495c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = instr_at(pos); 6505c838251403b0be9a882540f1922577abba4c872ager@chromium.org if ((instr & ~kImm16Mask) == 0) { 6515c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Emitted label constant, not part of a branch. 6527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (instr == 0) { 6537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return kEndOfChain; 6547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { 6557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; 6567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return (imm18 + pos); 6577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 6585c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 6593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Check we have a branch or jump instruction. 6603cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(IsBranch(instr) || IsJ(instr) || IsLui(instr)); 6615c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming 6625c838251403b0be9a882540f1922577abba4c872ager@chromium.org // the compiler uses arithmectic shifts for signed integers. 6633cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (IsBranch(instr)) { 6643cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; 6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6663cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (imm18 == kEndOfChain) { 6673cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // EndOfChain sentinel is returned directly, not relative to pc or pos. 6683cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return kEndOfChain; 6693cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 6703cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return pos + kBranchPCOffset + imm18; 6713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 6723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else if (IsLui(instr)) { 6733cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); 6743cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); 6753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(IsOri(instr_ori)); 6763cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; 6773cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); 6783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 6793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (imm == kEndOfJumpChain) { 6803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // EndOfChain sentinel is returned directly, not relative to pc or pos. 6813cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return kEndOfChain; 6823cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 6833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); 6843cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t delta = instr_address - imm; 6853cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(pos > delta); 6863cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return pos - delta; 6873cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 6887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { 6893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; 6903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (imm28 == kEndOfJumpChain) { 6913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // EndOfChain sentinel is returned directly, not relative to pc or pos. 6923cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return kEndOfChain; 6933cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 6943cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); 6953cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_address &= kImm28Mask; 6963cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t delta = instr_address - imm28; 6973cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(pos > delta); 6983cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return pos - delta; 6993cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 7007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 7015c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7025c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7045c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::target_at_put(int32_t pos, int32_t target_pos) { 7055c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = instr_at(pos); 7065c838251403b0be9a882540f1922577abba4c872ager@chromium.org if ((instr & ~kImm16Mask) == 0) { 7075c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(target_pos == kEndOfChain || target_pos >= 0); 7085c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Emitted label constant, not part of a branch. 7095c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Make label relative to Code* of generated Code object. 7105c838251403b0be9a882540f1922577abba4c872ager@chromium.org instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 7115c838251403b0be9a882540f1922577abba4c872ager@chromium.org return; 7125c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 7135c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7143cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(IsBranch(instr) || IsJ(instr) || IsLui(instr)); 7153cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (IsBranch(instr)) { 7163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t imm18 = target_pos - (pos + kBranchPCOffset); 7173cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT((imm18 & 3) == 0); 7183cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 7193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr &= ~kImm16Mask; 7203cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t imm16 = imm18 >> 2; 7213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(is_int16(imm16)); 7223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 7233cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_at_put(pos, instr | (imm16 & kImm16Mask)); 7243cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else if (IsLui(instr)) { 7253cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); 7263cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); 7273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(IsOri(instr_ori)); 72859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; 7293cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT((imm & 3) == 0); 7303cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 7313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_lui &= ~kImm16Mask; 7323cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_ori &= ~kImm16Mask; 7333cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 7343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_at_put(pos + 0 * Assembler::kInstrSize, 7353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_lui | ((imm & kHiMask) >> kLuiShift)); 7363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_at_put(pos + 1 * Assembler::kInstrSize, 7373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_ori | (imm & kImm16Mask)); 7383cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 73959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; 7403cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org imm28 &= kImm28Mask; 7413cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT((imm28 & 3) == 0); 7425c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7433cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr &= ~kImm26Mask; 7443cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t imm26 = imm28 >> 2; 7453cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(is_uint26(imm26)); 7465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7473cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_at_put(pos, instr | (imm26 & kImm26Mask)); 7483cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 7495c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7505c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7525c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::print(Label* L) { 7535c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (L->is_unused()) { 7545c838251403b0be9a882540f1922577abba4c872ager@chromium.org PrintF("unused label\n"); 7555c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else if (L->is_bound()) { 7565c838251403b0be9a882540f1922577abba4c872ager@chromium.org PrintF("bound label to %d\n", L->pos()); 7575c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else if (L->is_linked()) { 7585c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label l = *L; 7595c838251403b0be9a882540f1922577abba4c872ager@chromium.org PrintF("unbound label"); 7605c838251403b0be9a882540f1922577abba4c872ager@chromium.org while (l.is_linked()) { 7615c838251403b0be9a882540f1922577abba4c872ager@chromium.org PrintF("@ %d ", l.pos()); 7625c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = instr_at(l.pos()); 7635c838251403b0be9a882540f1922577abba4c872ager@chromium.org if ((instr & ~kImm16Mask) == 0) { 7645c838251403b0be9a882540f1922577abba4c872ager@chromium.org PrintF("value\n"); 7655c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 7665c838251403b0be9a882540f1922577abba4c872ager@chromium.org PrintF("%d\n", instr); 7675c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 7685c838251403b0be9a882540f1922577abba4c872ager@chromium.org next(&l); 7695c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 7705c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 7715c838251403b0be9a882540f1922577abba4c872ager@chromium.org PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 7725c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 7735c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7765c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bind_to(Label* L, int pos) { 7777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(0 <= pos && pos <= pc_offset()); // Must have valid binding position. 7783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t trampoline_pos = kInvalidSlotPos; 7793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (L->is_linked() && !trampoline_emitted_) { 7803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org unbound_labels_count_--; 7813cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_buffer_check_ += kTrampolineSlotsSize; 7823cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 7833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 7845c838251403b0be9a882540f1922577abba4c872ager@chromium.org while (L->is_linked()) { 7855c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t fixup_pos = L->pos(); 7867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t dist = pos - fixup_pos; 7877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org next(L); // Call next before overwriting link with target at fixup_pos. 7883cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr = instr_at(fixup_pos); 7893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (IsBranch(instr)) { 7903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (dist > kMaxBranchOffset) { 7913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (trampoline_pos == kInvalidSlotPos) { 7923cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org trampoline_pos = get_trampoline_entry(fixup_pos); 7933cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org CHECK(trampoline_pos != kInvalidSlotPos); 79483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 7957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT((trampoline_pos - fixup_pos) <= kMaxBranchOffset); 7967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org target_at_put(fixup_pos, trampoline_pos); 7977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org fixup_pos = trampoline_pos; 7987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org dist = pos - fixup_pos; 7993cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 8003cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org target_at_put(fixup_pos, pos); 8013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 8027bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ASSERT(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr)); 8033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org target_at_put(fixup_pos, pos); 8043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 8055c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 8065c838251403b0be9a882540f1922577abba4c872ager@chromium.org L->bind_to(pos); 8075c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8085c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Keep track of the last bound label so we don't eliminate any instructions 8095c838251403b0be9a882540f1922577abba4c872ager@chromium.org // before a bound label. 8105c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (pos > last_bound_pos_) 8115c838251403b0be9a882540f1922577abba4c872ager@chromium.org last_bound_pos_ = pos; 8125c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8135c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8155c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bind(Label* L) { 8167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(!L->is_bound()); // Label can only be bound once. 8175c838251403b0be9a882540f1922577abba4c872ager@chromium.org bind_to(L, pc_offset()); 8185c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8215c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::next(Label* L) { 8225c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(L->is_linked()); 8235c838251403b0be9a882540f1922577abba4c872ager@chromium.org int link = target_at(L->pos()); 8247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (link == kEndOfChain) { 8255c838251403b0be9a882540f1922577abba4c872ager@chromium.org L->Unuse(); 82680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org } else { 82780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org ASSERT(link >= 0); 8287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org L->link_to(link); 8295c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 8305c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 832e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 8333cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgbool Assembler::is_near(Label* L) { 8343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (L->is_bound()) { 8353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return ((pc_offset() - L->pos()) < kMaxBranchOffset - 4 * kInstrSize); 8363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 8373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return false; 8383cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 8395c838251403b0be9a882540f1922577abba4c872ager@chromium.org 840e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 8415c838251403b0be9a882540f1922577abba4c872ager@chromium.org// We have to use a temporary register for things that can be relocated even 8425c838251403b0be9a882540f1922577abba4c872ager@chromium.org// if they can be encoded in the MIPS's 16 bits of immediate-offset instruction 8435c838251403b0be9a882540f1922577abba4c872ager@chromium.org// space. There is no guarantee that the relocated location can be similarly 8445c838251403b0be9a882540f1922577abba4c872ager@chromium.org// encoded. 8457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool Assembler::MustUseReg(RelocInfo::Mode rmode) { 8464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org return !RelocInfo::IsNone(rmode); 8475c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8495c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode, 8505c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rs, 8515c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rt, 8525c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rd, 8535c838251403b0be9a882540f1922577abba4c872ager@chromium.org uint16_t sa, 8545c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField func) { 8555c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa)); 8565c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) 8575c838251403b0be9a882540f1922577abba4c872ager@chromium.org | (rd.code() << kRdShift) | (sa << kSaShift) | func; 8585c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 8595c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8625c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode, 8637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rs, 8647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt, 8657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uint16_t msb, 8667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uint16_t lsb, 8677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SecondaryField func) { 8687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb)); 8697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) 8707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (msb << kRdShift) | (lsb << kSaShift) | func; 8717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org emit(instr); 8727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode, 8765c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField fmt, 8775c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister ft, 8785c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fs, 8795c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fd, 8805c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField func) { 8815c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(fd.is_valid() && fs.is_valid() && ft.is_valid()); 8827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift) 8837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (fd.code() << kFdShift) | func; 8845c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 8855c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8875c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8885c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode, 88959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister fr, 89059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister ft, 89159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister fs, 89259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister fd, 89359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org SecondaryField func) { 89459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid()); 89559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift) 89659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func; 89759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org emit(instr); 89859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 89959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 90059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 90159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode, 9025c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField fmt, 9035c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rt, 9045c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fs, 9055c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fd, 9065c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField func) { 9075c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(fd.is_valid() && fs.is_valid() && rt.is_valid()); 9085c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = opcode | fmt | (rt.code() << kRtShift) 9097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func; 9107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org emit(instr); 9117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode, 9157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SecondaryField fmt, 9167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt, 9177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FPUControlRegister fs, 9187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SecondaryField func) { 9197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(fs.is_valid() && rt.is_valid()); 9207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Instr instr = 9217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func; 9225c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 9235c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 9245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9255c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Instructions with immediate value. 9275c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Registers are in the order of the instruction encoding, from left to right. 9285c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GenInstrImmediate(Opcode opcode, 9295c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rs, 9305c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rt, 9315c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t j) { 9325c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j))); 9335c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) 9345c838251403b0be9a882540f1922577abba4c872ager@chromium.org | (j & kImm16Mask); 9355c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 9365c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 9375c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9395c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GenInstrImmediate(Opcode opcode, 9405c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rs, 9415c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField SF, 9425c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t j) { 9435c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(rs.is_valid() && (is_int16(j) || is_uint16(j))); 9445c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask); 9455c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 9465c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 9475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9495c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GenInstrImmediate(Opcode opcode, 9505c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rs, 9515c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister ft, 9525c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t j) { 9535c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); 9545c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) 9555c838251403b0be9a882540f1922577abba4c872ager@chromium.org | (j & kImm16Mask); 9565c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 9575c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 9585c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9595c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9605c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GenInstrJump(Opcode opcode, 96134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t address) { 9627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 9635c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint26(address)); 9645c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = opcode | address; 9655c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 9667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 9677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9703cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org// Returns the next free trampoline entry. 9713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgint32_t Assembler::get_trampoline_entry(int32_t pos) { 9723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t trampoline_entry = kInvalidSlotPos; 9737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9743cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (!internal_trampoline_exception_) { 9753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (trampoline_.start() > pos) { 9763cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org trampoline_entry = trampoline_.take_slot(); 9777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 9783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 9793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (kInvalidSlotPos == trampoline_entry) { 9803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org internal_trampoline_exception_ = true; 9817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 9827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 9833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return trampoline_entry; 9847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9873cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orguint32_t Assembler::jump_address(Label* L) { 9883cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t target_pos; 9897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (L->is_bound()) { 9913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org target_pos = L->pos(); 9923cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 9933cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (L->is_linked()) { 9943cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org target_pos = L->pos(); // L's link. 9953cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org L->link_to(pc_offset()); 9963cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 9973cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org L->link_to(pc_offset()); 9983cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return kEndOfJumpChain; 99983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 10007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 10013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 100259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; 10033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT((imm & 3) == 0); 10043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 10053cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return imm; 10065c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10075c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10085c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10095c838251403b0be9a882540f1922577abba4c872ager@chromium.orgint32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { 10105c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t target_pos; 10117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10125c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (L->is_bound()) { 10135c838251403b0be9a882540f1922577abba4c872ager@chromium.org target_pos = L->pos(); 10145c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 10155c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (L->is_linked()) { 10163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org target_pos = L->pos(); 10177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org L->link_to(pc_offset()); 10185c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 10197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org L->link_to(pc_offset()); 10203cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (!trampoline_emitted_) { 10213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org unbound_labels_count_++; 10223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_buffer_check_ -= kTrampolineSlotsSize; 10233cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 10247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return kEndOfChain; 10255c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 10265c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 10275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10285c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t offset = target_pos - (pc_offset() + kBranchPCOffset); 10297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT((offset & 3) == 0); 10307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(is_int16(offset >> 2)); 10317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10325c838251403b0be9a882540f1922577abba4c872ager@chromium.org return offset; 10335c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::label_at_put(Label* L, int at_offset) { 10375c838251403b0be9a882540f1922577abba4c872ager@chromium.org int target_pos; 10385c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (L->is_bound()) { 10395c838251403b0be9a882540f1922577abba4c872ager@chromium.org target_pos = L->pos(); 10407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 10415c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 10425c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (L->is_linked()) { 10437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org target_pos = L->pos(); // L's link. 10447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t imm18 = target_pos - at_offset; 10457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT((imm18 & 3) == 0); 10467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t imm16 = imm18 >> 2; 10477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(is_int16(imm16)); 10487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org instr_at_put(at_offset, (imm16 & kImm16Mask)); 10495c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 10505c838251403b0be9a882540f1922577abba4c872ager@chromium.org target_pos = kEndOfChain; 10517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org instr_at_put(at_offset, 0); 10523cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (!trampoline_emitted_) { 10533cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org unbound_labels_count_++; 10543cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_buffer_check_ -= kTrampolineSlotsSize; 10553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 10565c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 10575c838251403b0be9a882540f1922577abba4c872ager@chromium.org L->link_to(at_offset); 10585c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 10595c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10625c838251403b0be9a882540f1922577abba4c872ager@chromium.org//------- Branch and jump instructions -------- 10635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10645c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::b(int16_t offset) { 10655c838251403b0be9a882540f1922577abba4c872ager@chromium.org beq(zero_reg, zero_reg, offset); 10665c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10695c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bal(int16_t offset) { 10707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 10715c838251403b0be9a882540f1922577abba4c872ager@chromium.org bgezal(zero_reg, offset); 10725c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10735c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10755c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::beq(Register rs, Register rt, int16_t offset) { 10767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 10775c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(BEQ, rs, rt, offset); 10787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 10795c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10815c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10825c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bgez(Register rs, int16_t offset) { 10837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 10845c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(REGIMM, rs, BGEZ, offset); 10857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 10865c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10875c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10885c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10895c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bgezal(Register rs, int16_t offset) { 10907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 10917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 10925c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(REGIMM, rs, BGEZAL, offset); 10937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 10945c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10955c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10965c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10975c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bgtz(Register rs, int16_t offset) { 10987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 10995c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(BGTZ, rs, zero_reg, offset); 11007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 11015c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11025c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11045c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::blez(Register rs, int16_t offset) { 11057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 11065c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(BLEZ, rs, zero_reg, offset); 11077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 11085c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11095c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11105c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11115c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bltz(Register rs, int16_t offset) { 11127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 11135c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(REGIMM, rs, BLTZ, offset); 11147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 11155c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11185c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bltzal(Register rs, int16_t offset) { 11197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 11207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 11215c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(REGIMM, rs, BLTZAL, offset); 11227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 11235c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11255c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11265c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bne(Register rs, Register rt, int16_t offset) { 11277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 11285c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(BNE, rs, rt, offset); 11297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 11305c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11335c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::j(int32_t target) { 113434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#if DEBUG 113534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Get pc of delay slot. 113634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); 113759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org bool in_range = (ipc ^ static_cast<uint32_t>(target) >> 113859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (kImm26Bits + kImmFieldShift)) == 0; 113934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(in_range && ((target & 3) == 0)); 114034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#endif 11415c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrJump(J, target >> 2); 11425c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11435c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11445c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11455c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::jr(Register rs) { 11467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 11477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (rs.is(ra)) { 11487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 11497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 11505c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR); 11517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 11525c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11535c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11545c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11555c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::jal(int32_t target) { 115634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#ifdef DEBUG 115734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Get pc of delay slot. 115834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); 115959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org bool in_range = (ipc ^ static_cast<uint32_t>(target) >> 116059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (kImm26Bits + kImmFieldShift)) == 0; 116134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(in_range && ((target & 3) == 0)); 116234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#endif 11637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 11645c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrJump(JAL, target >> 2); 11655c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11665c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11685c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::jalr(Register rs, Register rd) { 11697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolScope block_trampoline_pool(this); 11707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 11715c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); 11727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolFor(1); // For associated delay slot. 11735c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 117634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgvoid Assembler::j_or_jr(int32_t target, Register rs) { 117734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Get pc of delay slot. 117834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); 117959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org bool in_range = (ipc ^ static_cast<uint32_t>(target) >> 118059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (kImm26Bits + kImmFieldShift)) == 0; 118134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (in_range) { 118234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org j(target); 118334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else { 118434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org jr(t9); 118534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 118634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 118734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 118834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 118934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgvoid Assembler::jal_or_jalr(int32_t target, Register rs) { 119034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Get pc of delay slot. 119134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); 119259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org bool in_range = (ipc ^ static_cast<uint32_t>(target) >> 119359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (kImm26Bits+kImmFieldShift)) == 0; 119434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (in_range) { 119534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org jal(target); 119634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else { 119734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org jalr(t9); 119834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 119934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 120034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 120134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 12025c838251403b0be9a882540f1922577abba4c872ager@chromium.org//-------Data-processing-instructions--------- 12035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12045c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Arithmetic. 12055c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12065c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::addu(Register rd, Register rs, Register rt) { 12075c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 12085c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12095c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12105c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12115c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::addiu(Register rd, Register rs, int32_t j) { 12125c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(ADDIU, rs, rd, j); 12135c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12165c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::subu(Register rd, Register rs, Register rt) { 12175c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU); 12185c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12215c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::mul(Register rd, Register rs, Register rt) { 12225c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL); 12235c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12255c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12265c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::mult(Register rs, Register rt) { 12275c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT); 12285c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12315c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::multu(Register rs, Register rt) { 12325c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU); 12335c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::div(Register rs, Register rt) { 12375c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV); 12385c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12395c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12415c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::divu(Register rs, Register rt) { 12425c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU); 12435c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12445c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12465c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Logical. 12475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12485c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::and_(Register rd, Register rs, Register rt) { 12495c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND); 12505c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12535c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::andi(Register rt, Register rs, int32_t j) { 125478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org ASSERT(is_uint16(j)); 12555c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(ANDI, rs, rt, j); 12565c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12585c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12595c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::or_(Register rd, Register rs, Register rt) { 12605c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR); 12615c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12645c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::ori(Register rt, Register rs, int32_t j) { 126578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org ASSERT(is_uint16(j)); 12665c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(ORI, rs, rt, j); 12675c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12695c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12705c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::xor_(Register rd, Register rs, Register rt) { 12715c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR); 12725c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12735c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12755c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::xori(Register rt, Register rs, int32_t j) { 127678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org ASSERT(is_uint16(j)); 12775c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(XORI, rs, rt, j); 12785c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12795c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12815c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::nor(Register rd, Register rs, Register rt) { 12825c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR); 12835c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12845c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12855c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12865c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Shifts. 12877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::sll(Register rd, 12887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt, 12897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uint16_t sa, 12907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool coming_from_nop) { 12917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Don't allow nop instructions in the form sll zero_reg, zero_reg to be 12927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // generated using the sll instruction. They must be generated using 12937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // nop(int/NopMarkerTypes) or MarkCode(int/NopMarkerTypes) pseudo 12947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // instructions. 12957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg))); 12965c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SLL); 12975c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12985c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12995c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13005c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::sllv(Register rd, Register rt, Register rs) { 13015c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV); 13025c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13045c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13055c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::srl(Register rd, Register rt, uint16_t sa) { 13065c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRL); 13075c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13085c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13095c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13105c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::srlv(Register rd, Register rt, Register rs) { 13115c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV); 13125c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13135c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13155c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::sra(Register rd, Register rt, uint16_t sa) { 13165c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRA); 13175c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13205c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::srav(Register rd, Register rt, Register rs) { 13215c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV); 13225c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13235c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::rotr(Register rd, Register rt, uint16_t sa) { 13267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Should be called via MacroAssembler::Ror. 13277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(rd.is_valid() && rt.is_valid() && is_uint5(sa)); 13283233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 13297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift) 13307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (rd.code() << kRdShift) | (sa << kSaShift) | SRL; 13317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org emit(instr); 13327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 13337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::rotrv(Register rd, Register rt, Register rs) { 13367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Should be called via MacroAssembler::Ror. 13377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(rd.is_valid() && rt.is_valid() && rs.is_valid() ); 13383233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 13397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift) 13407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV; 13417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org emit(instr); 13427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 13437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13455c838251403b0be9a882540f1922577abba4c872ager@chromium.org//------------Memory-instructions------------- 13465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Helper for base-reg + offset, when offset is larger than int16. 13487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) { 13497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(!src.rm().is(at)); 135009b3454f8cdcc19655f7e1d6362f8f0216941235palfia@homejinni.com lui(at, (src.offset_ >> kLuiShift) & kImm16Mask); 13517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset. 13527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org addu(at, at, src.rm()); // Add base register. 13537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 13547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13565c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::lb(Register rd, const MemOperand& rs) { 13577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 13587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LB, rs.rm(), rd, rs.offset_); 13597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to load. 13607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 13617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LB, at, rd, 0); // Equiv to lb(rd, MemOperand(at, 0)); 13627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 13635c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13645c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13665c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::lbu(Register rd, const MemOperand& rs) { 13677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 13687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_); 13697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to load. 13707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 13717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LBU, at, rd, 0); // Equiv to lbu(rd, MemOperand(at, 0)); 13727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 13737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 13747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::lh(Register rd, const MemOperand& rs) { 13777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 13787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LH, rs.rm(), rd, rs.offset_); 13797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to load. 13807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 13817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LH, at, rd, 0); // Equiv to lh(rd, MemOperand(at, 0)); 13827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 13837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 13847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::lhu(Register rd, const MemOperand& rs) { 13877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 13887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_); 13897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to load. 13907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 13917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LHU, at, rd, 0); // Equiv to lhu(rd, MemOperand(at, 0)); 13927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 13935c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13945c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13955c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13965c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::lw(Register rd, const MemOperand& rs) { 13977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 13987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LW, rs.rm(), rd, rs.offset_); 13997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to load. 14007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 14017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LW, at, rd, 0); // Equiv to lw(rd, MemOperand(at, 0)); 14027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 14037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 14047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::lwl(Register rd, const MemOperand& rs) { 14077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_); 14087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 14097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::lwr(Register rd, const MemOperand& rs) { 14127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_); 14135c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14165c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::sb(Register rd, const MemOperand& rs) { 14177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 14187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SB, rs.rm(), rd, rs.offset_); 14197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to store. 14207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 14217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SB, at, rd, 0); // Equiv to sb(rd, MemOperand(at, 0)); 14227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 14237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 14247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::sh(Register rd, const MemOperand& rs) { 14277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 14287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SH, rs.rm(), rd, rs.offset_); 14297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to store. 14307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 14317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SH, at, rd, 0); // Equiv to sh(rd, MemOperand(at, 0)); 14327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 14335c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::sw(Register rd, const MemOperand& rs) { 14377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (is_int16(rs.offset_)) { 14387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SW, rs.rm(), rd, rs.offset_); 14397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { // Offset > 16 bits, use multiple instructions to store. 14407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LoadRegPlusOffsetToAt(rs); 14417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SW, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); 14427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 14437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 14447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::swl(Register rd, const MemOperand& rs) { 14477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_); 14487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 14497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::swr(Register rd, const MemOperand& rs) { 14527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_); 14535c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14545c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14555c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14565c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::lui(Register rd, int32_t j) { 145778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org ASSERT(is_uint16(j)); 14585c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(LUI, zero_reg, rd, j); 14595c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14625c838251403b0be9a882540f1922577abba4c872ager@chromium.org//-------------Misc-instructions-------------- 14635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14645c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Break / Trap instructions. 1465c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.orgvoid Assembler::break_(uint32_t code, bool break_as_stop) { 14665c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT((code & ~0xfffff) == 0); 1467c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // We need to invalidate breaks that could be stops as well because the 1468c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // simulator expects a char pointer after the stop instruction. 1469c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // See constants-mips.h for explanation. 1470c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org ASSERT((break_as_stop && 1471c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org code <= kMaxStopCode && 1472c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org code > kMaxWatchpointCode) || 1473c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org (!break_as_stop && 1474c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org (code > kMaxStopCode || 1475c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org code <= kMaxWatchpointCode))); 14765c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr break_instr = SPECIAL | BREAK | (code << 6); 14775c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(break_instr); 14785c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14795c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1481c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.orgvoid Assembler::stop(const char* msg, uint32_t code) { 1482c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org ASSERT(code > kMaxWatchpointCode); 1483c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org ASSERT(code <= kMaxStopCode); 148493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_HOST_ARCH_MIPS 1485c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org break_(0x54321); 1486c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org#else // V8_HOST_ARCH_MIPS 1487c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org BlockTrampolinePoolFor(2); 1488c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // The Simulator will handle the stop instruction and get the message address. 1489c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // On MIPS stop() is just a special kind of break_(). 1490c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org break_(code, true); 1491c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org emit(reinterpret_cast<Instr>(msg)); 1492c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org#endif 1493c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org} 1494c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org 1495c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org 14965c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::tge(Register rs, Register rt, uint16_t code) { 14975c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint10(code)); 14985c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = SPECIAL | TGE | rs.code() << kRsShift 14995c838251403b0be9a882540f1922577abba4c872ager@chromium.org | rt.code() << kRtShift | code << 6; 15005c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 15015c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15025c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15045c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::tgeu(Register rs, Register rt, uint16_t code) { 15055c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint10(code)); 15065c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = SPECIAL | TGEU | rs.code() << kRsShift 15075c838251403b0be9a882540f1922577abba4c872ager@chromium.org | rt.code() << kRtShift | code << 6; 15085c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 15095c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15105c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15115c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15125c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::tlt(Register rs, Register rt, uint16_t code) { 15135c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint10(code)); 15145c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = 15155c838251403b0be9a882540f1922577abba4c872ager@chromium.org SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6; 15165c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 15175c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15205c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::tltu(Register rs, Register rt, uint16_t code) { 15215c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint10(code)); 15227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Instr instr = 15237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SPECIAL | TLTU | rs.code() << kRsShift 15245c838251403b0be9a882540f1922577abba4c872ager@chromium.org | rt.code() << kRtShift | code << 6; 15255c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 15265c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15285c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15295c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::teq(Register rs, Register rt, uint16_t code) { 15305c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint10(code)); 15315c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = 15325c838251403b0be9a882540f1922577abba4c872ager@chromium.org SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6; 15335c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 15345c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15365c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15375c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::tne(Register rs, Register rt, uint16_t code) { 15385c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint10(code)); 15395c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = 15405c838251403b0be9a882540f1922577abba4c872ager@chromium.org SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6; 15415c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 15425c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15435c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15445c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15455c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Move from HI/LO register. 15465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15475c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::mfhi(Register rd) { 15485c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI); 15495c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15505c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15525c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::mflo(Register rd) { 15535c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO); 15545c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15555c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15565c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15575c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Set on less than instructions. 15585c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::slt(Register rd, Register rs, Register rt) { 15595c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT); 15605c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15635c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::sltu(Register rd, Register rs, Register rt) { 15645c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU); 15655c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15665c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15685c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::slti(Register rt, Register rs, int32_t j) { 15695c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(SLTI, rs, rt, j); 15705c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15715c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15725c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15735c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::sltiu(Register rt, Register rs, int32_t j) { 15745c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(SLTIU, rs, rt, j); 15755c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15775c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Conditional move. 15797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::movz(Register rd, Register rs, Register rt) { 15807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ); 15817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 15827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 15837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 15847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::movn(Register rd, Register rs, Register rt) { 15857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN); 15867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 15877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 15887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 15897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::movt(Register rd, Register rs, uint16_t cc) { 15907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt; 159183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org rt.code_ = (cc & 0x0007) << 2 | 1; 15927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI); 15937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 15947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 15957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 15967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::movf(Register rd, Register rs, uint16_t cc) { 15977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt; 159883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org rt.code_ = (cc & 0x0007) << 2 | 0; 15997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI); 16007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Bit twiddling. 16047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::clz(Register rd, Register rs) { 16057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Clz instr requires same GPR number in 'rd' and 'rt' fields. 16067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ); 16077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) { 16117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Should be called via MacroAssembler::Ins. 16127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Ins instr has 'rt' field as dest, and two uint5: msb, lsb. 16133233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 16147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS); 16157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { 16197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Should be called via MacroAssembler::Ext. 16207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Ext instr has 'rt' field as dest, and two uint5: msb, lsb. 16213233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 16227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT); 16237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16265c838251403b0be9a882540f1922577abba4c872ager@chromium.org//--------Coprocessor-instructions---------------- 16275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16285c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Load, store, move. 16295c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::lwc1(FPURegister fd, const MemOperand& src) { 16305c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 16315c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 16325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16335c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16345c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::ldc1(FPURegister fd, const MemOperand& src) { 16357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit 16367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // load to two 32-bit loads. 16377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 16387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FPURegister nextfpreg; 16397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org nextfpreg.setcode(fd.code() + 1); 16407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(LWC1, src.rm(), nextfpreg, src.offset_ + 4); 16415c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 16425c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16435c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16445c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::swc1(FPURegister fd, const MemOperand& src) { 16455c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrImmediate(SWC1, src.rm(), fd, src.offset_); 16465c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 16475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16495c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::sdc1(FPURegister fd, const MemOperand& src) { 16507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit 16517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // store to two 32-bit stores. 16527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SWC1, src.rm(), fd, src.offset_); 16537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FPURegister nextfpreg; 16547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org nextfpreg.setcode(fd.code() + 1); 16557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrImmediate(SWC1, src.rm(), nextfpreg, src.offset_ + 4); 16565c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 16575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16585c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::mtc1(Register rt, FPURegister fs) { 16605c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, MTC1, rt, fs, f0); 16615c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 16625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::mfc1(Register rt, FPURegister fs) { 16657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, MFC1, rt, fs, f0); 16665c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 16675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 16697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::ctc1(Register rt, FPUControlRegister fs) { 16707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, CTC1, rt, fs); 16717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::cfc1(Register rt, FPUControlRegister fs) { 16757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, CFC1, rt, fs); 16767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1678e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 167934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgvoid Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { 168034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint64_t i; 1681e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(&i, &d, 8); 168234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 168334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *lo = i & 0xffffffff; 168434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *hi = i >> 32; 168534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 16867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1687e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 16887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Arithmetic. 16897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) { 16917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, ft, fs, fd, ADD_D); 16927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) { 16967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, ft, fs, fd, SUB_D); 16977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 16987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 16997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) { 17017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, ft, fs, fd, MUL_D); 17027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 170559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgvoid Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs, 170659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister ft) { 170759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D); 170859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 170959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 171059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 17117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) { 17127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, ft, fs, fd, DIV_D); 17137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::abs_d(FPURegister fd, FPURegister fs) { 17177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, ABS_D); 17185c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 17195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::mov_d(FPURegister fd, FPURegister fs) { 17227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, MOV_D); 17237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::neg_d(FPURegister fd, FPURegister fs) { 17277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, NEG_D); 17287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::sqrt_d(FPURegister fd, FPURegister fs) { 17327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D); 17335c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 17345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17365c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Conversions. 17375c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17385c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_w_s(FPURegister fd, FPURegister fs) { 17395c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S); 17405c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 17415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17425c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17435c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_w_d(FPURegister fd, FPURegister fs) { 17445c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D); 17455c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 17465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::trunc_w_s(FPURegister fd, FPURegister fs) { 17497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S); 17507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::trunc_w_d(FPURegister fd, FPURegister fs) { 17547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D); 17557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::round_w_s(FPURegister fd, FPURegister fs) { 17597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S); 17607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::round_w_d(FPURegister fd, FPURegister fs) { 17647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D); 17657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::floor_w_s(FPURegister fd, FPURegister fs) { 17697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S); 17707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::floor_w_d(FPURegister fd, FPURegister fs) { 17747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D); 17757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::ceil_w_s(FPURegister fd, FPURegister fs) { 17797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S); 17807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::ceil_w_d(FPURegister fd, FPURegister fs) { 17847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D); 17857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 17867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 17885c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_l_s(FPURegister fd, FPURegister fs) { 17893233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 17905c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S); 17915c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 17925c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17935c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17945c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_l_d(FPURegister fd, FPURegister fs) { 17953233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 17965c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D); 17975c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 17985c838251403b0be9a882540f1922577abba4c872ager@chromium.org 17995c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::trunc_l_s(FPURegister fd, FPURegister fs) { 18013233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 18027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S); 18037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::trunc_l_d(FPURegister fd, FPURegister fs) { 18073233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 18087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D); 18097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::round_l_s(FPURegister fd, FPURegister fs) { 18137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S); 18147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::round_l_d(FPURegister fd, FPURegister fs) { 18187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D); 18197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::floor_l_s(FPURegister fd, FPURegister fs) { 18237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S); 18247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::floor_l_d(FPURegister fd, FPURegister fs) { 18287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D); 18297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::ceil_l_s(FPURegister fd, FPURegister fs) { 18337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S); 18347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::ceil_l_d(FPURegister fd, FPURegister fs) { 18387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D); 18397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18425c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_s_w(FPURegister fd, FPURegister fs) { 18435c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W); 18445c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18475c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_s_l(FPURegister fd, FPURegister fs) { 18483233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 18495c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L); 18505c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18535c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_s_d(FPURegister fd, FPURegister fs) { 18545c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D); 18555c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18565c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18585c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_d_w(FPURegister fd, FPURegister fs) { 18595c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W); 18605c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18635c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_d_l(FPURegister fd, FPURegister fs) { 18643233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org ASSERT(kArchVariant == kMips32r2); 18655c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L); 18665c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18695c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::cvt_d_s(FPURegister fd, FPURegister fs) { 18705c838251403b0be9a882540f1922577abba4c872ager@chromium.org GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S); 18715c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18725c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18735c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18745c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Conditions. 18755c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::c(FPUCondition cond, SecondaryField fmt, 18767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FPURegister fs, FPURegister ft, uint16_t cc) { 18775c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint3(cc)); 18785c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT((fmt & ~(31 << kRsShift)) == 0); 18795c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = COP1 | fmt | ft.code() << 16 | fs.code() << kFsShift 18805c838251403b0be9a882540f1922577abba4c872ager@chromium.org | cc << 8 | 3 << 4 | cond; 18815c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 18825c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18835c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18845c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::fcmp(FPURegister src1, const double src2, 18867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FPUCondition cond) { 18877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(src2 == 0.0); 18887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org mtc1(zero_reg, f14); 18897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org cvt_d_w(f14, f14); 18907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org c(cond, D, src1, f14, 0); 18917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 18927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 18945c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bc1f(int16_t offset, uint16_t cc) { 18955c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint3(cc)); 18965c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask); 18975c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 18985c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 18995c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19005c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19015c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::bc1t(int16_t offset, uint16_t cc) { 19025c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_uint3(cc)); 19035c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask); 19045c838251403b0be9a882540f1922577abba4c872ager@chromium.org emit(instr); 19055c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 19065c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19075c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19085c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Debugging. 19095c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::RecordJSReturn() { 19107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 19115c838251403b0be9a882540f1922577abba4c872ager@chromium.org CheckBuffer(); 19125c838251403b0be9a882540f1922577abba4c872ager@chromium.org RecordRelocInfo(RelocInfo::JS_RETURN); 19135c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 19145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::RecordDebugBreakSlot() { 19177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org positions_recorder()->WriteRecordedPositions(); 19187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org CheckBuffer(); 19197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 19205c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 19215c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19225c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::RecordComment(const char* msg) { 19247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (FLAG_code_comments) { 19255c838251403b0be9a882540f1922577abba4c872ager@chromium.org CheckBuffer(); 19267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 19275c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 19285c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 19295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgint Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) { 19323cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr = instr_at(pc); 19333cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(IsJ(instr) || IsLui(instr)); 19343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (IsLui(instr)) { 19353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize); 19363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize); 19373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(IsOri(instr_ori)); 19383cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; 19393cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); 19403cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (imm == kEndOfJumpChain) { 19413cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return 0; // Number of instructions patched. 19423cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 19433cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org imm += pc_delta; 19443cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT((imm & 3) == 0); 19453cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 19463cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_lui &= ~kImm16Mask; 19473cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_ori &= ~kImm16Mask; 19483cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 19493cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_at_put(pc + 0 * Assembler::kInstrSize, 19503cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_lui | ((imm >> kLuiShift) & kImm16Mask)); 19513cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_at_put(pc + 1 * Assembler::kInstrSize, 19523cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_ori | (imm & kImm16Mask)); 19533cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return 2; // Number of instructions patched. 19543cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 19553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; 195659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { 19573cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return 0; // Number of instructions patched. 19583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 19593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org imm28 += pc_delta; 19603cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org imm28 &= kImm28Mask; 19613cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT((imm28 & 3) == 0); 19623cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 19633cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr &= ~kImm26Mask; 19643cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t imm26 = imm28 >> 2; 19653cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(is_uint26(imm26)); 19663cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 19673cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org instr_at_put(pc, instr | (imm26 & kImm26Mask)); 19683cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return 1; // Number of instructions patched. 19693cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 19703cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 19713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 19723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 19735c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::GrowBuffer() { 19745c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (!own_buffer_) FATAL("external code buffer is too small"); 19755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19765c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Compute new buffer size. 19777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org CodeDesc desc; // The new buffer. 19785c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (buffer_size_ < 4*KB) { 19795c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc.buffer_size = 4*KB; 19805c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else if (buffer_size_ < 1*MB) { 19815c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc.buffer_size = 2*buffer_size_; 19825c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 19835c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc.buffer_size = buffer_size_ + 1*MB; 19845c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 19857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org CHECK_GT(desc.buffer_size, 0); // No overflow. 19865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1987f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up new buffer. 19885c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc.buffer = NewArray<byte>(desc.buffer_size); 19895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19905c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc.instr_size = pc_offset(); 19915c838251403b0be9a882540f1922577abba4c872ager@chromium.org desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 19925c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19935c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Copy the data. 19945c838251403b0be9a882540f1922577abba4c872ager@chromium.org int pc_delta = desc.buffer - buffer_; 19955c838251403b0be9a882540f1922577abba4c872ager@chromium.org int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 1996e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemMove(desc.buffer, buffer_, desc.instr_size); 1997e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemMove(reloc_info_writer.pos() + rc_delta, 1998e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reloc_info_writer.pos(), desc.reloc_size); 19995c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20005c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Switch buffers. 20015c838251403b0be9a882540f1922577abba4c872ager@chromium.org DeleteArray(buffer_); 20025c838251403b0be9a882540f1922577abba4c872ager@chromium.org buffer_ = desc.buffer; 20035c838251403b0be9a882540f1922577abba4c872ager@chromium.org buffer_size_ = desc.buffer_size; 20045c838251403b0be9a882540f1922577abba4c872ager@chromium.org pc_ += pc_delta; 20055c838251403b0be9a882540f1922577abba4c872ager@chromium.org reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 20065c838251403b0be9a882540f1922577abba4c872ager@chromium.org reloc_info_writer.last_pc() + pc_delta); 20075c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Relocate runtime entries. 20093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org for (RelocIterator it(desc); !it.done(); it.next()) { 20103cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org RelocInfo::Mode rmode = it.rinfo()->rmode(); 20113cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (rmode == RelocInfo::INTERNAL_REFERENCE) { 20123cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org byte* p = reinterpret_cast<byte*>(it.rinfo()->pc()); 20133cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org RelocateInternalReference(p, pc_delta); 20143cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 20153cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 20165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20175c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(!overflow()); 20185c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 20195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::db(uint8_t data) { 20227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org CheckBuffer(); 20237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org *reinterpret_cast<uint8_t*>(pc_) = data; 20247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org pc_ += sizeof(uint8_t); 20257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 20267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 20277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 20287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::dd(uint32_t data) { 20297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org CheckBuffer(); 20307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org *reinterpret_cast<uint32_t*>(pc_) = data; 20317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org pc_ += sizeof(uint32_t); 2032057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org} 2033057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 2034057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 2035057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid Assembler::emit_code_stub_address(Code* stub) { 2036057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org CheckBuffer(); 2037057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org *reinterpret_cast<uint32_t*>(pc_) = 2038057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org reinterpret_cast<uint32_t>(stub->instruction_start()); 2039057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org pc_ += sizeof(uint32_t); 20407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 20417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 20427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 20435c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2044b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // We do not try to reuse pool constants. 2045b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org RelocInfo rinfo(pc_, rmode, data, NULL); 20467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) { 20475c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Adjust code for new modes. 20487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(RelocInfo::IsDebugBreakSlot(rmode) 20497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org || RelocInfo::IsJSReturn(rmode) 20505c838251403b0be9a882540f1922577abba4c872ager@chromium.org || RelocInfo::IsComment(rmode) 20515c838251403b0be9a882540f1922577abba4c872ager@chromium.org || RelocInfo::IsPosition(rmode)); 20525c838251403b0be9a882540f1922577abba4c872ager@chromium.org // These modes do not need an entry in the constant pool. 20535c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 20544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (!RelocInfo::IsNone(rinfo.rmode())) { 20555c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Don't record external references unless the heap will be serialized. 205634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 205734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#ifdef DEBUG 205834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (!Serializer::enabled()) { 205934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org Serializer::TooLateToEnableNow(); 206034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 206134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#endif 206234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (!Serializer::enabled() && !emit_debug_code()) { 206334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return; 206434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 20655c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 20667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(buffer_space() >= kMaxRelocSize); // Too late to grow buffer here. 206783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 2068471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org RelocInfo reloc_info_with_ast_id(pc_, 2069471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org rmode, 2070471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org RecordedAstId().ToInt(), 2071471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org NULL); 2072717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org ClearRecordedAstId(); 207383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org reloc_info_writer.Write(&reloc_info_with_ast_id); 207483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 207583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org reloc_info_writer.Write(&rinfo); 207683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 20775c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 20785c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 20795c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Assembler::BlockTrampolinePoolFor(int instructions) { 20827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize); 20837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 20847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 20857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 20863cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgvoid Assembler::CheckTrampolinePool() { 20877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Some small sequences of instructions must not be broken up by the 20887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // insertion of a trampoline pool; such sequences are protected by setting 20897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_, 20907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // which are both checked here. Also, recursive calls to CheckTrampolinePool 20917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // are blocked by trampoline_pool_blocked_nesting_. 20927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if ((trampoline_pool_blocked_nesting_ > 0) || 20937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org (pc_offset() < no_trampoline_pool_before_)) { 20947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Emission is currently blocked; make sure we try again as soon as 20957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // possible. 20967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (trampoline_pool_blocked_nesting_ > 0) { 20977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org next_buffer_check_ = pc_offset() + kInstrSize; 20987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } else { 20997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org next_buffer_check_ = no_trampoline_pool_before_; 21007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 21017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return; 21027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 21037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 21043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(!trampoline_emitted_); 21053cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(unbound_labels_count_ >= 0); 21063cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (unbound_labels_count_ > 0) { 21073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // First we emit jump (2 instructions), then we emit trampoline pool. 21083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org { BlockTrampolinePoolScope block_trampoline_pool(this); 21093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Label after_pool; 21107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org b(&after_pool); 21117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org nop(); 21123cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 21133cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int pool_start = pc_offset(); 21143cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org for (int i = 0; i < unbound_labels_count_; i++) { 21153cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t imm32; 21163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org imm32 = jump_address(&after_pool); 21173cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org { BlockGrowBufferScope block_buf_growth(this); 21183cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Buffer growth (and relocation) must be blocked for internal 21193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // references until associated instructions are emitted and available 21203cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // to be patched. 21213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 21223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org lui(at, (imm32 & kHiMask) >> kLuiShift); 21233cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ori(at, at, (imm32 & kImm16Mask)); 21243cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 21253cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org jr(at); 21263cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org nop(); 21273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 21283cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org bind(&after_pool); 21293cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org trampoline_ = Trampoline(pool_start, unbound_labels_count_); 21303cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 21313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org trampoline_emitted_ = true; 21323cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // As we are only going to emit trampoline once, we need to prevent any 21333cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // further emission. 21343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_buffer_check_ = kMaxInt; 21357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 21363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 21373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Number of branches to unbound label at this point is zero, so we can 21383cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // move next buffer check to maximum. 21393cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_buffer_check_ = pc_offset() + 21403cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org kMaxBranchOffset - kTrampolineSlotsSize * 16; 21417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 21427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return; 21437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 21447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 21457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 21465c838251403b0be9a882540f1922577abba4c872ager@chromium.orgAddress Assembler::target_address_at(Address pc) { 21475c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr1 = instr_at(pc); 21485c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr2 = instr_at(pc + kInstrSize); 214983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Interpret 2 instructions generated by li: lui/ori 215083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if ((GetOpcodeField(instr1) == LUI) && (GetOpcodeField(instr2) == ORI)) { 215183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Assemble the 32 bit value. 21525c838251403b0be9a882540f1922577abba4c872ager@chromium.org return reinterpret_cast<Address>( 215383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org (GetImmediate16(instr1) << 16) | GetImmediate16(instr2)); 21545c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 21555c838251403b0be9a882540f1922577abba4c872ager@chromium.org 215683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We should never get here, force a bad address if we do. 21575c838251403b0be9a882540f1922577abba4c872ager@chromium.org UNREACHABLE(); 21585c838251403b0be9a882540f1922577abba4c872ager@chromium.org return (Address)0x0; 21595c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 21605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 21615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 216288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32 216388d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap 216488d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// snapshot generated on ia32, the resulting MIPS sNaN must be quieted. 216588d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// OS::nan_value() returns a qNaN. 216628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid Assembler::QuietNaN(HeapObject* object) { 216788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org HeapNumber::cast(object)->set_value(OS::nan_value()); 216828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 216928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 217028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 217134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// On Mips, a target address is stored in a lui/ori instruction pair, each 217234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// of which load 16 bits of the 32-bit address to a register. 217334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// Patching the address must replace both instr, and flush the i-cache. 217434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// 217534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// There is an optimization below, which emits a nop when the address 217634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// fits in just 16 bits. This is unlikely to help, and should be benchmarked, 217734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// and possibly removed. 21785c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Assembler::set_target_address_at(Address pc, Address target) { 21795c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr2 = instr_at(pc + kInstrSize); 218034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t rt_code = GetRtField(instr2); 218134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t* p = reinterpret_cast<uint32_t*>(pc); 218234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t itarget = reinterpret_cast<uint32_t>(target); 218334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 21845c838251403b0be9a882540f1922577abba4c872ager@chromium.org#ifdef DEBUG 218534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Check we have the result from a li macro-instruction, using instr pair. 21865c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr1 = instr_at(pc); 218783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK((GetOpcodeField(instr1) == LUI && GetOpcodeField(instr2) == ORI)); 21885c838251403b0be9a882540f1922577abba4c872ager@chromium.org#endif 21895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 219034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Must use 2 instructions to insure patchable code => just use lui and ori. 219134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // lui rt, upper-16. 219234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // ori rt rt, lower-16. 219383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org *p = LUI | rt_code | ((itarget & kHiMask) >> kLuiShift); 219483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org *(p+1) = ORI | rt_code | (rt_code << 5) | (itarget & kImm16Mask); 21955c838251403b0be9a882540f1922577abba4c872ager@chromium.org 219634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // The following code is an optimization for the common case of Call() 219734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // or Jump() which is load to register, and jump through register: 219834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // li(t9, address); jalr(t9) (or jr(t9)). 219934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // If the destination address is in the same 256 MB page as the call, it 220034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // is faster to do a direct jal, or j, rather than jump thru register, since 220134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // that lets the cpu pipeline prefetch the target address. However each 220234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // time the address above is patched, we have to patch the direct jal/j 220334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // instruction, as well as possibly revert to jalr/jr if we now cross a 220434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // 256 MB page. Note that with the jal/j instructions, we do not need to 220534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // load the register, but that code is left, since it makes it easy to 220634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // revert this process. A further optimization could try replacing the 220734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // li sequence with nops. 220834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // This optimization can only be applied if the rt-code from instr2 is the 220934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // register used for the jalr/jr. Finally, we have to skip 'jr ra', which is 221034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // mips return. Occasionally this lands after an li(). 221134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 221234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org Instr instr3 = instr_at(pc + 2 * kInstrSize); 221334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize); 221432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org bool in_range = ((ipc ^ itarget) >> (kImm26Bits + kImmFieldShift)) == 0; 221559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org uint32_t target_field = 2216837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org static_cast<uint32_t>(itarget & kJumpAddrMask) >> kImmFieldShift; 221734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org bool patched_jump = false; 221834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 221934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#ifndef ALLOW_JAL_IN_BOUNDARY_REGION 222034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // This is a workaround to the 24k core E156 bug (affect some 34k cores also). 222134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Since the excluded space is only 64KB out of 256MB (0.02 %), we will just 222234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // apply this workaround for all cores so we don't have to identify the core. 222334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (in_range) { 222434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // The 24k core E156 bug has some very specific requirements, we only check 222534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // the most simple one: if the address of the delay slot instruction is in 222634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // the first or last 32 KB of the 256 MB segment. 222734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t segment_mask = ((256 * MB) - 1) ^ ((32 * KB) - 1); 222834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t ipc_segment_addr = ipc & segment_mask; 222934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (ipc_segment_addr == 0 || ipc_segment_addr == segment_mask) 223034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org in_range = false; 223134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 223234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#endif 223334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 223434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (IsJalr(instr3)) { 223534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Try to convert JALR to JAL. 223634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (in_range && GetRt(instr2) == GetRs(instr3)) { 223734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = JAL | target_field; 223834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org patched_jump = true; 223934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 224034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else if (IsJr(instr3)) { 224134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Try to convert JR to J, skip returns (jr ra). 224234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org bool is_ret = static_cast<int>(GetRs(instr3)) == ra.code(); 224334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (in_range && !is_ret && GetRt(instr2) == GetRs(instr3)) { 224434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = J | target_field; 224534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org patched_jump = true; 224634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 224734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else if (IsJal(instr3)) { 224834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (in_range) { 224934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // We are patching an already converted JAL. 225034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = JAL | target_field; 225134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else { 225234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Patch JAL, but out of range, revert to JALR. 225334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // JALR rs reg is the rt reg specified in the ORI instruction. 225434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t rs_field = GetRt(instr2) << kRsShift; 225534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t rd_field = ra.code() << kRdShift; // Return-address (ra) reg. 225634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = SPECIAL | rs_field | rd_field | JALR; 225734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 225834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org patched_jump = true; 225934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else if (IsJ(instr3)) { 226034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (in_range) { 226134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // We are patching an already converted J (jump). 226234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = J | target_field; 226334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else { 226434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Trying patch J, but out of range, just go back to JR. 226534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // JR 'rs' reg is the 'rt' reg specified in the ORI instruction (instr2). 226634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t rs_field = GetRt(instr2) << kRsShift; 226734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = SPECIAL | rs_field | JR; 226834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 226934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org patched_jump = true; 227034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 227134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 227234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org CPU::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t)); 22735c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 22745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2275e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 227634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgvoid Assembler::JumpLabelToJumpRegister(Address pc) { 227734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Address pc points to lui/ori instructions. 227834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Jump to label may follow at pc + 2 * kInstrSize. 227934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t* p = reinterpret_cast<uint32_t*>(pc); 228034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#ifdef DEBUG 228134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org Instr instr1 = instr_at(pc); 228234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#endif 228334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org Instr instr2 = instr_at(pc + 1 * kInstrSize); 228434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org Instr instr3 = instr_at(pc + 2 * kInstrSize); 228534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org bool patched = false; 228634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 228734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (IsJal(instr3)) { 228834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(GetOpcodeField(instr1) == LUI); 228934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(GetOpcodeField(instr2) == ORI); 229034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 229134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t rs_field = GetRt(instr2) << kRsShift; 229234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t rd_field = ra.code() << kRdShift; // Return-address (ra) reg. 229334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = SPECIAL | rs_field | rd_field | JALR; 229434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org patched = true; 229534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else if (IsJ(instr3)) { 229634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(GetOpcodeField(instr1) == LUI); 229734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(GetOpcodeField(instr2) == ORI); 229834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 229934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org uint32_t rs_field = GetRt(instr2) << kRsShift; 230034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org *(p+2) = SPECIAL | rs_field | JR; 230134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org patched = true; 230234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 230334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 230434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (patched) { 230534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org CPU::FlushICache(pc+2, sizeof(Address)); 230634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 230734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 23085c838251403b0be9a882540f1922577abba4c872ager@chromium.org 23095c838251403b0be9a882540f1922577abba4c872ager@chromium.org} } // namespace v8::internal 23105c838251403b0be9a882540f1922577abba4c872ager@chromium.org 23119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_MIPS 2312