13100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Copyright (c) 1994-2006 Sun Microsystems Inc. 23100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// All Rights Reserved. 33100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 43100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Redistribution and use in source and binary forms, with or without 53100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modification, are permitted provided that the following conditions are 63100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// met: 73100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 83100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistributions of source code must retain the above copyright notice, 93100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// this list of conditions and the following disclaimer. 103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistribution in binary form must reproduce the above copyright 123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// notice, this list of conditions and the following disclaimer in the 133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// documentation and/or other materials provided with the distribution. 143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Neither the name of Sun Microsystems or the names of contributors may 163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// be used to endorse or promote products derived from this software without 173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// specific prior written permission. 183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// The original source code covered by the above license above has been 323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modified significantly by Google Inc. 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/mips/assembler-mips.h" 36f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_MIPS 38f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/cpu.h" 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips/assembler-mips-inl.h" 423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace v8 { 443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace internal { 453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 46589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Get the CPU features enabled by the build. For cross compilation the 47589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// preprocessor symbols CAN_USE_FPU_INSTRUCTIONS 48589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// can be defined to enable FPU instructions when building the 49589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// snapshot. 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic unsigned CpuFeaturesImpliedByCompiler() { 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned answer = 0; 52589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifdef CAN_USE_FPU_INSTRUCTIONS 53589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch answer |= 1u << FPU; 54589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif // def CAN_USE_FPU_INSTRUCTIONS 55589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 56589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // If the compiler is allowed to use FPU then we can use FPU too in our code 57589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // generation even when generating snapshots. This won't work for cross 58589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // compilation. 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(__mips__) && defined(__mips_hard_float) && __mips_hard_float != 0 60589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch answer |= 1u << FPU; 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 62589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 63589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return answer; 64589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 65589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 66589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::ProbeImpl(bool cross_compile) { 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= CpuFeaturesImpliedByCompiler(); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only use statically determined features for cross compile (snapshot). 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cross_compile) return; 72589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // If the compiler is allowed to use fpu then we can use fpu too in our 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // code generation. 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef __mips__ 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For the simulator build, use FPU. 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << FPU; 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(_MIPS_ARCH_MIPS32R6) 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // FP64 mode is implied on r6. 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << FP64FPU; 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(FPU_MODE_FP64) 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << FP64FPU; 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Probe for additional features at runtime. 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::CPU cpu; 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cpu.has_fpu()) supported_ |= 1u << FPU; 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(FPU_MODE_FPXX) 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cpu.is_fp64_mode()) supported_ |= 1u << FP64FPU; 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif defined(FPU_MODE_FP64) 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << FP64FPU; 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(_MIPS_ARCH_MIPS32RX) 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cpu.architecture() == 6) { 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << MIPSr6; 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (cpu.architecture() == 2) { 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << MIPSr1; 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << MIPSr2; 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch supported_ |= 1u << MIPSr1; 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 1063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::PrintTarget() { } 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::PrintFeatures() { } 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuint ToNumber(Register reg) { 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reg.is_valid()); 1143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu const int kNumbers[] = { 1153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 0, // zero_reg 1163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1, // at 1173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2, // v0 1183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3, // v1 1193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4, // a0 1203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5, // a1 1213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6, // a2 1223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7, // a3 1233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 8, // t0 1243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9, // t1 1253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 10, // t2 1263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 11, // t3 1273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12, // t4 1283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13, // t5 1293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 14, // t6 1303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15, // t7 1313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16, // s0 1323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17, // s1 1333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 18, // s2 1343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19, // s3 1353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20, // s4 1363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21, // s5 1373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22, // s6 1383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 23, // s7 1393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 24, // t8 1403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 25, // t9 1413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 26, // k0 1423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 27, // k1 1433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28, // gp 1443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 29, // sp 145db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch 30, // fp 1463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 31, // ra 1473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu }; 1483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return kNumbers[reg.code()]; 1493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuRegister ToRegister(int num) { 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num >= 0 && num < kNumRegisters); 1543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu const Register kRegisters[] = { 1553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu zero_reg, 1563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu at, 1573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v0, v1, 1583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu a0, a1, a2, a3, 1593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu t0, t1, t2, t3, t4, t5, t6, t7, 1603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu s0, s1, s2, s3, s4, s5, s6, s7, 1613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu t8, t9, 1623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu k0, k1, 1633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu gp, 1643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu sp, 165db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch fp, 1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ra 1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu }; 1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return kRegisters[num]; 1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 1733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Implementation of RelocInfo. 1743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 175589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochconst int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1 << RelocInfo::INTERNAL_REFERENCE | 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1 << RelocInfo::INTERNAL_REFERENCE_ENCODED; 1783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 18044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool RelocInfo::IsCodedSpecially() { 18144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The deserializer needs to know whether a pointer is specially coded. Being 18244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // specially coded on MIPS means that it is a lui/ori instruction, and that is 18344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // always the case inside code objects. 18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return true; 18544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 18644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 18744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RelocInfo::IsInConstantPool() { 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochAddress RelocInfo::wasm_memory_reference() { 193bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsWasmMemoryReference(rmode_)); 194bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Assembler::target_address_at(pc_, host_); 195bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 19713e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochAddress RelocInfo::wasm_global_reference() { 19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(IsWasmGlobalReference(rmode_)); 19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Assembler::target_address_at(pc_, host_); 20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 20113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 202bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochuint32_t RelocInfo::wasm_memory_size_reference() { 203bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsWasmMemorySizeReference(rmode_)); 204bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return reinterpret_cast<uint32_t>(Assembler::target_address_at(pc_, host_)); 205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 206bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochuint32_t RelocInfo::wasm_function_table_size_reference() { 20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(IsWasmFunctionTableSizeReference(rmode_)); 20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return reinterpret_cast<uint32_t>(Assembler::target_address_at(pc_, host_)); 21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid RelocInfo::unchecked_update_wasm_memory_reference( 21313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Address address, ICacheFlushMode flush_mode) { 21413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode); 21513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 21613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid RelocInfo::unchecked_update_wasm_size(uint32_t size, 21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ICacheFlushMode flush_mode) { 21913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, 22013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch reinterpret_cast<Address>(size), flush_mode); 221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 2243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Implementation of Operand and MemOperand. 2253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// See assembler-mips-inl.h for inlined constructors. 2263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(Handle<Object> handle) { 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference using_raw_address; 2293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rm_ = no_reg; 2303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Verify all Objects referred by code are NOT in new space. 2313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Object* obj = *handle; 2323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (obj->IsHeapObject()) { 2333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu imm32_ = reinterpret_cast<intptr_t>(handle.location()); 2343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rmode_ = RelocInfo::EMBEDDED_OBJECT; 2353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 2363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // No relocation needed. 2373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu imm32_ = reinterpret_cast<intptr_t>(obj); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::NONE32; 2393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 2403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 24244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 24344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) { 2443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu offset_ = offset; 2453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier, 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OffsetAddend offset_addend) : Operand(rm) { 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset_ = unit * multiplier + offset_addend; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 25544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Specific instructions, constants, and masks. 25644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 25744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kNegOffset = 0x00008000; 25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 25944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// operations as post-increment of sp. 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPopInstruction = ADDIU | (Register::kCode_sp << kRsShift) | 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (Register::kCode_sp << kRtShift) | 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (kPointerSize & kImm16Mask); // NOLINT 26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPushInstruction = ADDIU | (Register::kCode_sp << kRsShift) | 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (Register::kCode_sp << kRtShift) | 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (-kPointerSize & kImm16Mask); // NOLINT 26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// sw(r, MemOperand(sp, 0)) 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPushRegPattern = 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SW | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask); // NOLINT 27044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// lw(r, MemOperand(sp, 0)) 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPopRegPattern = 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LW | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask); // NOLINT 27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kLwRegFpOffsetPattern = 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask); // NOLINT 27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kSwRegFpOffsetPattern = 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask); // NOLINT 27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kLwRegFpNegOffsetPattern = LW | (Register::kCode_fp << kRsShift) | 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (kNegOffset & kImm16Mask); // NOLINT 28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kSwRegFpNegOffsetPattern = SW | (Register::kCode_fp << kRsShift) | 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (kNegOffset & kImm16Mask); // NOLINT 28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A mask for the Rt register for push, pop, lw, sw instructions. 28644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockconst Instr kRtMask = kRtFieldMask; 28744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockconst Instr kLwSwInstrTypeMask = 0xffe00000; 28844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockconst Instr kLwSwInstrArgumentMask = ~kLwSwInstrTypeMask; 28944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockconst Instr kLwSwOffsetMask = kImm16Mask; 29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : AssemblerBase(isolate, buffer, buffer_size), 293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch recorded_ast_id_(TypeFeedbackId::None()) { 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block last_trampoline_pool_end_ = 0; 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block no_trampoline_pool_before_ = 0; 29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block trampoline_pool_blocked_nesting_ = 0; 2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We leave space (16 * kTrampolineSlotsSize) 3003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // for BlockTrampolinePoolScope buffer. 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_buffer_check_ = FLAG_force_long_branches 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16; 303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch internal_trampoline_exception_ = false; 304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch last_bound_pos_ = 0; 305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trampoline_emitted_ = FLAG_force_long_branches; 3073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unbound_labels_count_ = 0; 3083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_buffer_growth_ = false; 3093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ClearRecordedAstId(); 3113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 3123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::GetCode(CodeDesc* desc) { 315109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch EmitForbiddenSlotInstruction(); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up code descriptor. 3183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc->buffer = buffer_; 3193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc->buffer_size = buffer_size_; 3203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc->instr_size = pc_offset(); 3213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->origin = this; 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->constant_pool_size = 0; 32413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch desc->unwinding_info_size = 0; 32513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch desc->unwinding_info = nullptr; 3263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 3273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 32944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::Align(int m) { 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m)); 331109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch EmitForbiddenSlotInstruction(); 33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block while ((pc_offset() & (m - 1)) != 0) { 33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block nop(); 33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 33844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::CodeTargetAlign() { 33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // No advantage to aligning branch/call targets to more than 34044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // single instruction, that I am aware of. 34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Align(4); 34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochRegister Assembler::GetRtReg(Instr instr) { 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register rt; 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rt.reg_code = (instr & kRtFieldMask) >> kRtShift; 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return rt; 34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochRegister Assembler::GetRsReg(Instr instr) { 353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register rs; 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rs.reg_code = (instr & kRsFieldMask) >> kRsShift; 355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return rs; 356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochRegister Assembler::GetRdReg(Instr instr) { 360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register rd; 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rd.reg_code = (instr & kRdFieldMask) >> kRdShift; 362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return rd; 363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetRt(Instr instr) { 367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return (instr & kRtFieldMask) >> kRtShift; 368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetRtField(Instr instr) { 372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return instr & kRtFieldMask; 373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetRs(Instr instr) { 377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return (instr & kRsFieldMask) >> kRsShift; 378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetRsField(Instr instr) { 382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return instr & kRsFieldMask; 383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetRd(Instr instr) { 387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return (instr & kRdFieldMask) >> kRdShift; 388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetRdField(Instr instr) { 392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return instr & kRdFieldMask; 393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 396257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetSa(Instr instr) { 397257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return (instr & kSaFieldMask) >> kSaShift; 398257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetSaField(Instr instr) { 402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return instr & kSaFieldMask; 403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetOpcodeField(Instr instr) { 407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return instr & kOpcodeMask; 408257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 410257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochuint32_t Assembler::GetFunction(Instr instr) { 4123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return (instr & kFunctionFieldMask) >> kFunctionShift; 4133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochuint32_t Assembler::GetFunctionField(Instr instr) { 4173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return instr & kFunctionFieldMask; 4183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetImmediate16(Instr instr) { 422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return instr & kImm16Mask; 423257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 424257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochuint32_t Assembler::GetLabelConst(Instr instr) { 427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return instr & ~kImm16Mask; 428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 43144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsPop(Instr instr) { 43244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return (instr & ~kRtMask) == kPopRegPattern; 43344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 43644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsPush(Instr instr) { 43744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return (instr & ~kRtMask) == kPushRegPattern; 43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsSwRegFpOffset(Instr instr) { 44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern); 44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 44444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsLwRegFpOffset(Instr instr) { 44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern); 44844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 45144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsSwRegFpNegOffset(Instr instr) { 45244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & (kLwSwInstrTypeMask | kNegOffset)) == 45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block kSwRegFpNegOffsetPattern); 45444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 45744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsLwRegFpNegOffset(Instr instr) { 45844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & (kLwSwInstrTypeMask | kNegOffset)) == 45944f0eee88ff00398ff7f715fab053374d808c90dSteve Block kLwRegFpNegOffsetPattern); 46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 46244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Labels refer to positions in the (to be) generated code. 4643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// There are bound, linked, and unused labels. 4653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 4663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Bound labels refer to known positions in the already 4673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// generated code. pos() is the position the label refers to. 4683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 4693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Linked labels refer to unknown positions in the code 4703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// to be generated; pos() is the position of the last 4713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// instruction using the label. 4723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// The link chain is terminated by a value in the instruction of -1, 47444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// which is an otherwise illegal value (branch -1 is inf loop). 47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// The instruction 16-bit offset field addresses 32-bit words, but in 47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// code is conv to an 18-bit value addressing bytes, hence the -4 value. 4773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuconst int kEndOfChain = -4; 4793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Determines the end of the Jump chain (a subset of the label link chain). 4803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochconst int kEndOfJumpChain = 0; 4813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 48344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsBranch(Instr instr) { 484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uint32_t rt_field = GetRtField(instr); 486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uint32_t rs_field = GetRsField(instr); 4873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Checks if the instruction is a branch. 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool isBranch = 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode == BEQ || opcode == BNE || opcode == BLEZ || opcode == BGTZ || 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode == BEQL || opcode == BNEL || opcode == BLEZL || opcode == BGTZL || 4913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ || 4923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rt_field == BLTZAL || rt_field == BGEZAL)) || 49344f0eee88ff00398ff7f715fab053374d808c90dSteve Block (opcode == COP1 && rs_field == BC1) || // Coprocessor branch. 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (opcode == COP1 && rs_field == BC1EQZ) || 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (opcode == COP1 && rs_field == BC1NEZ); 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!isBranch && IsMipsArchVariant(kMips32r6)) { 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // All the 3 variants of POP10 (BOVC, BEQC, BEQZALC) and 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // POP30 (BNVC, BNEC, BNEZALC) are branch ops. 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isBranch |= opcode == POP10 || opcode == POP30 || opcode == BC || 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode == BALC || 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (opcode == POP66 && rs_field != 0) || // BEQZC 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (opcode == POP76 && rs_field != 0); // BNEZC 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return isBranch; 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBc(Instr instr) { 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Checks if the instruction is a BC or BALC. 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return opcode == BC || opcode == BALC; 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBzc(Instr instr) { 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Checks if the instruction is BEQZC or BNEZC. 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return (opcode == POP66 && GetRsField(instr) != 0) || 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (opcode == POP76 && GetRsField(instr) != 0); 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsEmittedConstant(Instr instr) { 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t label_constant = GetLabelConst(instr); 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return label_constant == 0; // Emitted label const in reg-exp engine. 52644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 52744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Assembler::IsBeq(Instr instr) { 530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return GetOpcodeField(instr) == BEQ; 531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Assembler::IsBne(Instr instr) { 535257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return GetOpcodeField(instr) == BNE; 536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBeqzc(Instr instr) { 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return opcode == POP66 && GetRsField(instr) != 0; 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBnezc(Instr instr) { 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return opcode == POP76 && GetRsField(instr) != 0; 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBeqc(Instr instr) { 552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t rs = GetRsField(instr); 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t rt = GetRtField(instr); 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return opcode == POP10 && rs != 0 && rs < rt; // && rt != 0 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBnec(Instr instr) { 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t rs = GetRsField(instr); 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t rt = GetRtField(instr); 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return opcode == POP30 && rs != 0 && rs < rt; // && rt != 0 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool Assembler::IsJicOrJialc(Instr instr) { 5673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 5683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t rs = GetRsField(instr); 5693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return (opcode == POP66 || opcode == POP76) && rs == 0; 5703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Assembler::IsJump(Instr instr) { 5733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 5743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t rt_field = GetRtField(instr); 5753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t rd_field = GetRdField(instr); 5763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t function_field = GetFunctionField(instr); 5773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Checks if the instruction is a jump. 5783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return opcode == J || opcode == JAL || 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (opcode == SPECIAL && rt_field == 0 && 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ((function_field == JALR) || (rd_field == 0 && (function_field == JR)))); 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Assembler::IsJ(Instr instr) { 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 5853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Checks if the instruction is a jump. 5863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return opcode == J; 5873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 590589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochbool Assembler::IsJal(Instr instr) { 591589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return GetOpcodeField(instr) == JAL; 592589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 593589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 595589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochbool Assembler::IsJr(Instr instr) { 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsMipsArchVariant(kMips32r6)) { 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR; 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetOpcodeField(instr) == SPECIAL && 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetRdField(instr) == 0 && GetFunctionField(instr) == JALR; 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 602589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 603589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 605589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochbool Assembler::IsJalr(Instr instr) { 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetOpcodeField(instr) == SPECIAL && 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetRdField(instr) != 0 && GetFunctionField(instr) == JALR; 608589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 609589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 610589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 6113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Assembler::IsLui(Instr instr) { 6123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 6133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Checks if the instruction is a load upper immediate. 6143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return opcode == LUI; 6153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Assembler::IsOri(Instr instr) { 6193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 6203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Checks if the instruction is a load upper immediate. 6213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return opcode == ORI; 6223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 62544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsNop(Instr instr, unsigned int type) { 62644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // See Assembler::nop(type). 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(type < 32); 628257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t function = GetFunctionField(instr); 630257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uint32_t rt = GetRt(instr); 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t rd = GetRd(instr); 632257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uint32_t sa = GetSa(instr); 63344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Traditional mips nop == sll(zero_reg, zero_reg, 0) 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // When marking non-zero type, use sll(zero_reg, at, type) 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to avoid use of mips ssnop and ehb special encodings 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the sll instruction. 63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register nop_rt_reg = (type == 0) ? zero_reg : at; 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ret = (opcode == SPECIAL && function == SLL && 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rd == static_cast<uint32_t>(ToNumber(zero_reg)) && 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) && 64344f0eee88ff00398ff7f715fab053374d808c90dSteve Block sa == type); 64444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 64544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ret; 64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 64744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 64944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint32_t Assembler::GetBranchOffset(Instr instr) { 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsBranch(instr)); 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (static_cast<int16_t>(instr & kImm16Mask)) << 2; 65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 65344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 65444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 65544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsLw(Instr instr) { 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return (static_cast<uint32_t>(instr & kOpcodeMask) == LW); 65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 65844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 66044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint16_t Assembler::GetLwOffset(Instr instr) { 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLw(instr)); 66244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & kImm16Mask)); 66344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 66544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 66644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockInstr Assembler::SetLwOffset(Instr instr, int16_t offset) { 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLw(instr)); 66844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 66944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // We actually create a new lw instruction based on the original one. 67044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask) 67144f0eee88ff00398ff7f715fab053374d808c90dSteve Block | (offset & kImm16Mask); 67244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return temp_instr; 67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 67644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 67744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsSw(Instr instr) { 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return (static_cast<uint32_t>(instr & kOpcodeMask) == SW); 67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 68044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockInstr Assembler::SetSwOffset(Instr instr, int16_t offset) { 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsSw(instr)); 68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); 68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::IsAddImmediate(Instr instr) { 68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & kOpcodeMask) == ADDIU); 69044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 69244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 69344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockInstr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) { 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAddImmediate(instr)); 69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); 6963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 6973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Assembler::IsAndImmediate(Instr instr) { 700257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return GetOpcodeField(instr) == ANDI; 701257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 702257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic Assembler::OffsetSize OffsetSizeInBits(Instr instr) { 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsMipsArchVariant(kMips32r6)) { 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Assembler::IsBc(instr)) { 707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Assembler::OffsetSize::kOffset26; 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (Assembler::IsBzc(instr)) { 709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Assembler::OffsetSize::kOffset21; 710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Assembler::OffsetSize::kOffset16; 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic inline int32_t AddBranchOffset(int pos, Instr instr) { 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int bits = OffsetSizeInBits(instr); 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int32_t mask = (1 << bits) - 1; 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bits = 32 - bits; 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the compiler uses arithmetic shifts for signed integers. 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t imm = ((instr & mask) << bits) >> (bits - 2); 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm == kEndOfChain) { 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // EndOfChain sentinel is returned directly, not relative to pc or pos. 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return kEndOfChain; 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pos + Assembler::kBranchPCOffset + imm; 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochuint32_t Assembler::CreateTargetAddress(Instr instr_lui, Instr instr_jic) { 7343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(IsLui(instr_lui) && IsJicOrJialc(instr_jic)); 7353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int16_t jic_offset = GetImmediate16(instr_jic); 7363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int16_t lui_offset = GetImmediate16(instr_lui); 7373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (jic_offset < 0) { 7393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch lui_offset += kImm16Mask; 7403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 7413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t lui_offset_u = (static_cast<uint32_t>(lui_offset)) << kLuiShift; 7423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t jic_offset_u = static_cast<uint32_t>(jic_offset) & kImm16Mask; 7433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return lui_offset_u | jic_offset_u; 7453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 7463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Use just lui and jic instructions. Insert lower part of the target address in 7483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// jic offset part. Since jic sign-extends offset and then add it with register, 7493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// before that addition, difference between upper part of the target address and 7503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// upper part of the sign-extended offset (0xffff or 0x0000), will be inserted 7513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// in jic register with lui instruction. 7523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Assembler::UnpackTargetAddress(uint32_t address, int16_t& lui_offset, 7533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int16_t& jic_offset) { 7543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch lui_offset = (address & kHiMask) >> kLuiShift; 7553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jic_offset = address & kLoMask; 7563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (jic_offset < 0) { 7583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch lui_offset -= kImm16Mask; 7593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 7603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 7613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Assembler::UnpackTargetAddressUnsigned(uint32_t address, 7633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t& lui_offset, 7643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t& jic_offset) { 7653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int16_t lui_offset16 = (address & kHiMask) >> kLuiShift; 7663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int16_t jic_offset16 = address & kLoMask; 7673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (jic_offset16 < 0) { 7693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch lui_offset16 -= kImm16Mask; 7703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 7713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch lui_offset = static_cast<uint32_t>(lui_offset16) & kImm16Mask; 7723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jic_offset = static_cast<uint32_t>(jic_offset16) & kImm16Mask; 7733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Assembler::target_at(int pos, bool is_internal) { 7763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = instr_at(pos); 777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_internal) { 778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr == 0) { 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return kEndOfChain; 780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int delta = static_cast<int>(instr_address - instr); 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(pos > delta); 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pos - delta; 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if ((instr & ~kImm16Mask) == 0) { 7883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Emitted label constant, not part of a branch. 78944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (instr == 0) { 79044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return kEndOfChain; 79144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 79244f0eee88ff00398ff7f715fab053374d808c90dSteve Block int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; 79344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return (imm18 + pos); 79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 7953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check we have a branch or jump instruction. 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsBranch(instr) || IsLui(instr)); 7983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (IsBranch(instr)) { 799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AddBranchOffset(pos, instr); 800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 8013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instr instr1 = instr_at(pos + 0 * Assembler::kInstrSize); 8023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instr instr2 = instr_at(pos + 1 * Assembler::kInstrSize); 8033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(IsOri(instr2) || IsJicOrJialc(instr2)); 8043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int32_t imm; 8053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsJicOrJialc(instr2)) { 8063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm = CreateTargetAddress(instr1, instr2); 8073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 8083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm = (instr1 & static_cast<int32_t>(kImm16Mask)) << kLuiShift; 8093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm |= (instr2 & static_cast<int32_t>(kImm16Mask)); 8103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 8113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (imm == kEndOfJumpChain) { 8133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // EndOfChain sentinel is returned directly, not relative to pc or pos. 8143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return kEndOfChain; 8153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); 8173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int32_t delta = instr_address - imm; 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pos > delta); 8193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return pos - delta; 8203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic inline Instr SetBranchOffset(int32_t pos, int32_t target_pos, 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr) { 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t bits = OffsetSizeInBits(instr); 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t imm = target_pos - (pos + Assembler::kBranchPCOffset); 830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((imm & 3) == 0); 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch imm >>= 2; 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int32_t mask = (1 << bits) - 1; 834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr &= ~mask; 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_intn(imm, bits)); 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return instr | (imm & mask); 8383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 8393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 8403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::target_at_put(int32_t pos, int32_t target_pos, 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_internal) { 8433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = instr_at(pos); 844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_internal) { 846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; 847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr_at_put(pos, imm); 848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if ((instr & ~kImm16Mask) == 0) { 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(target_pos == kEndOfChain || target_pos >= 0); 8523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Emitted label constant, not part of a branch. 8533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Make label relative to Code* of generated Code object. 8543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 8553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return; 8563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 8573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsBranch(instr) || IsLui(instr)); 8593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (IsBranch(instr)) { 860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr = SetBranchOffset(pos, target_pos, instr); 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr_at_put(pos, instr); 862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 8633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instr instr1 = instr_at(pos + 0 * Assembler::kInstrSize); 8643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instr instr2 = instr_at(pos + 1 * Assembler::kInstrSize); 8653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(IsOri(instr2) || IsJicOrJialc(instr2)); 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((imm & 3) == 0); 8683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(IsLui(instr1) && (IsJicOrJialc(instr2) || IsOri(instr2))); 8693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr1 &= ~kImm16Mask; 8703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr2 &= ~kImm16Mask; 8713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 8723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsJicOrJialc(instr2)) { 8733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t lui_offset_u, jic_offset_u; 8743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch UnpackTargetAddressUnsigned(imm, lui_offset_u, jic_offset_u); 8753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pos + 0 * Assembler::kInstrSize, instr1 | lui_offset_u); 8763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pos + 1 * Assembler::kInstrSize, instr2 | jic_offset_u); 8773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 8783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pos + 0 * Assembler::kInstrSize, 8793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr1 | ((imm & kHiMask) >> kLuiShift)); 8803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pos + 1 * Assembler::kInstrSize, 8813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr2 | (imm & kImm16Mask)); 8823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 8833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 8853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 8863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 8873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::print(Label* L) { 8883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (L->is_unused()) { 8893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PrintF("unused label\n"); 8903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else if (L->is_bound()) { 8913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PrintF("bound label to %d\n", L->pos()); 8923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else if (L->is_linked()) { 8933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Label l = *L; 8943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PrintF("unbound label"); 8953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu while (l.is_linked()) { 8963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PrintF("@ %d ", l.pos()); 8973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = instr_at(l.pos()); 8983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if ((instr & ~kImm16Mask) == 0) { 8993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PrintF("value\n"); 9003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 9013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PrintF("%d\n", instr); 9023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 90362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch next(&l, is_internal_reference(&l)); 9043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 9053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 9063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 9073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 9083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 9093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bind_to(Label* L, int pos) { 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(0 <= pos && pos <= pc_offset()); // Must have valid binding position. 9133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int32_t trampoline_pos = kInvalidSlotPos; 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_internal = false; 9153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (L->is_linked() && !trampoline_emitted_) { 9163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unbound_labels_count_--; 91762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!is_internal_reference(L)) { 91862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch next_buffer_check_ += kTrampolineSlotsSize; 91962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 9203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu while (L->is_linked()) { 9233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t fixup_pos = L->pos(); 92444f0eee88ff00398ff7f715fab053374d808c90dSteve Block int32_t dist = pos - fixup_pos; 92562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch is_internal = is_internal_reference(L); 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next(L, is_internal); // Call next before overwriting link with target at 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // fixup_pos. 9283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Instr instr = instr_at(fixup_pos); 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_internal) { 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_at_put(fixup_pos, pos, is_internal); 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsBranch(instr)) { 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int branch_offset = BranchOffset(instr); 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dist > branch_offset) { 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (trampoline_pos == kInvalidSlotPos) { 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch trampoline_pos = get_trampoline_entry(fixup_pos); 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(trampoline_pos != kInvalidSlotPos); 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK((trampoline_pos - fixup_pos) <= branch_offset); 940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_at_put(fixup_pos, trampoline_pos, false); 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fixup_pos = trampoline_pos; 942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_at_put(fixup_pos, pos, false); 944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_at_put(fixup_pos, pos, false); 9463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 9493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu L->bind_to(pos); 9503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Keep track of the last bound label so we don't eliminate any instructions 9523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // before a bound label. 9533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (pos > last_bound_pos_) 9543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu last_bound_pos_ = pos; 9553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 9563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bind(Label* L) { 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!L->is_bound()); // Label can only be bound once. 9603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bind_to(L, pc_offset()); 9613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 9623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::next(Label* L, bool is_internal) { 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(L->is_linked()); 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int link = target_at(L->pos(), is_internal); 96744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (link == kEndOfChain) { 9683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu L->Unuse(); 96969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(link >= 0); 97144f0eee88ff00398ff7f715fab053374d808c90dSteve Block L->link_to(link); 9723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 9733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 9743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Assembler::is_near(Label* L) { 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(L->is_bound()); 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize; 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::is_near(Label* L, OffsetSize bits) { 983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (L == nullptr || !L->is_bound()) return true; 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pc_offset() - L->pos() < (1 << (bits + 2 - 1)) - 1 - 5 * kInstrSize; 985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::is_near_branch(Label* L) { 989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(L->is_bound()); 990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IsMipsArchVariant(kMips32r6) ? is_near_r6(L) : is_near_pre_r6(L); 991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Assembler::BranchOffset(Instr instr) { 995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // At pre-R6 and for other R6 branches the offset is 16 bits. 996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int bits = OffsetSize::kOffset16; 997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsMipsArchVariant(kMips32r6)) { 999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t opcode = GetOpcodeField(instr); 1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (opcode) { 1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Checks BC or BALC. 1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case BC: 1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case BALC: 1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bits = OffsetSize::kOffset26; 1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Checks BEQZC or BNEZC. 1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case POP66: 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case POP76: 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (GetRsField(instr) != 0) bits = OffsetSize::kOffset21; 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return (1 << (bits + 2 - 1)) - 1; 10183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 10193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// We have to use a temporary register for things that can be relocated even 10223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// if they can be encoded in the MIPS's 16 bits of immediate-offset instruction 10233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// space. There is no guarantee that the relocated location can be similarly 10243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// encoded. 102544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Assembler::MustUseReg(RelocInfo::Mode rmode) { 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !RelocInfo::IsNone(rmode); 10273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 10283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 10293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::GenInstrRegister(Opcode opcode, 10303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rs, 10313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rt, 10323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rd, 10333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu uint16_t sa, 10343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField func) { 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa)); 10363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) 10373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu | (rd.code() << kRdShift) | (sa << kSaShift) | func; 10383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 10393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 10403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 10413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 10423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::GenInstrRegister(Opcode opcode, 104344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register rs, 104444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register rt, 104544f0eee88ff00398ff7f715fab053374d808c90dSteve Block uint16_t msb, 104644f0eee88ff00398ff7f715fab053374d808c90dSteve Block uint16_t lsb, 104744f0eee88ff00398ff7f715fab053374d808c90dSteve Block SecondaryField func) { 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb)); 104944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) 105044f0eee88ff00398ff7f715fab053374d808c90dSteve Block | (msb << kRdShift) | (lsb << kSaShift) | func; 105144f0eee88ff00398ff7f715fab053374d808c90dSteve Block emit(instr); 105244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 105344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 105444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 105544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::GenInstrRegister(Opcode opcode, 10563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField fmt, 10573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister ft, 10583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fs, 10593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fd, 10603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField func) { 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid()); 106244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift) 106344f0eee88ff00398ff7f715fab053374d808c90dSteve Block | (fd.code() << kFdShift) | func; 10643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 10653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 10663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 10673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 10683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::GenInstrRegister(Opcode opcode, 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fr, 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister ft, 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fs, 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fd, 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField func) { 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid()); 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift) 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func; 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(instr); 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode, 10823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField fmt, 10833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rt, 10843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fs, 10853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fd, 10863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField func) { 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid()); 10883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = opcode | fmt | (rt.code() << kRtShift) 108944f0eee88ff00398ff7f715fab053374d808c90dSteve Block | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func; 109044f0eee88ff00398ff7f715fab053374d808c90dSteve Block emit(instr); 109144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 109244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 109344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 109444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::GenInstrRegister(Opcode opcode, 109544f0eee88ff00398ff7f715fab053374d808c90dSteve Block SecondaryField fmt, 109644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register rt, 109744f0eee88ff00398ff7f715fab053374d808c90dSteve Block FPUControlRegister fs, 109844f0eee88ff00398ff7f715fab053374d808c90dSteve Block SecondaryField func) { 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fs.is_valid() && rt.is_valid()); 110044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr = 110144f0eee88ff00398ff7f715fab053374d808c90dSteve Block opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func; 11023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 11033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 11043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 11053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 11063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Instructions with immediate value. 11073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Registers are in the order of the instruction encoding, from left to right. 1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, Register rt, 1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t j, 1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch) { 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j))); 11123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) 11133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu | (j & kImm16Mask); 1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(instr, is_compact_branch); 11153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 11163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 11173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, SecondaryField SF, 1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t j, 1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch) { 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j))); 11223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask); 1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(instr, is_compact_branch); 11243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 11253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 11263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, FPURegister ft, 1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t j, 1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch) { 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j))); 11313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift) 11323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu | (j & kImm16Mask); 1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(instr, is_compact_branch); 1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t offset21, 1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch) { 1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.is_valid() && (is_int21(offset21))); 1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask); 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(instr, is_compact_branch); 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, 1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t offset21) { 1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.is_valid() && (is_uint21(offset21))); 1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask); 11493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 11503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 11513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 11523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26, 1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch) { 1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_int26(offset26)); 1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instr instr = opcode | (offset26 & kImm26Mask); 1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(instr, is_compact_branch); 1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::GenInstrJump(Opcode opcode, 1162589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t address) { 116344f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint26(address)); 11653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = opcode | address; 11663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 116744f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 116844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 116944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 117044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Returns the next free trampoline entry. 11723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint32_t Assembler::get_trampoline_entry(int32_t pos) { 11733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int32_t trampoline_entry = kInvalidSlotPos; 117444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!internal_trampoline_exception_) { 11763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (trampoline_.start() > pos) { 11773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trampoline_entry = trampoline_.take_slot(); 117844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 11793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (kInvalidSlotPos == trampoline_entry) { 11813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch internal_trampoline_exception_ = true; 118244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 118344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 11843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return trampoline_entry; 118544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 118644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 118744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochuint32_t Assembler::jump_address(Label* L) { 11893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int32_t target_pos; 119044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (L->is_bound()) { 11923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch target_pos = L->pos(); 11933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 11943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (L->is_linked()) { 11953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch target_pos = L->pos(); // L's link. 11963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch L->link_to(pc_offset()); 11973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 11983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch L->link_to(pc_offset()); 11993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return kEndOfJumpChain; 1200257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 120144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 12023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((imm & 3) == 0); 12053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return imm; 12073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 12083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint32_t Assembler::branch_offset_helper(Label* L, OffsetSize bits) { 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t target_pos; 1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t pad = IsPrevInstrCompactBranch() ? kInstrSize : 0; 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (L->is_bound()) { 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_pos = L->pos(); 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (L->is_linked()) { 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_pos = L->pos(); 1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch L->link_to(pc_offset() + pad); 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch L->link_to(pc_offset() + pad); 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!trampoline_emitted_) { 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unbound_labels_count_++; 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_buffer_check_ -= kTrampolineSlotsSize; 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kEndOfChain; 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t offset = target_pos - (pc_offset() + kBranchPCOffset + pad); 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_intn(offset, bits + 2)); 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((offset & 3) == 0); 123344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return offset; 12353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 12363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::label_at_put(Label* L, int at_offset) { 12393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int target_pos; 12403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (L->is_bound()) { 12413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu target_pos = L->pos(); 124244f0eee88ff00398ff7f715fab053374d808c90dSteve Block instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 12433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 12443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (L->is_linked()) { 124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block target_pos = L->pos(); // L's link. 124644f0eee88ff00398ff7f715fab053374d808c90dSteve Block int32_t imm18 = target_pos - at_offset; 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((imm18 & 3) == 0); 124844f0eee88ff00398ff7f715fab053374d808c90dSteve Block int32_t imm16 = imm18 >> 2; 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_int16(imm16)); 125044f0eee88ff00398ff7f715fab053374d808c90dSteve Block instr_at_put(at_offset, (imm16 & kImm16Mask)); 12513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 12523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu target_pos = kEndOfChain; 125344f0eee88ff00398ff7f715fab053374d808c90dSteve Block instr_at_put(at_offset, 0); 12543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!trampoline_emitted_) { 12553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unbound_labels_count_++; 12563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next_buffer_check_ -= kTrampolineSlotsSize; 12573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 12583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 12593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu L->link_to(at_offset); 12603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 12613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 12623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//------- Branch and jump instructions -------- 12653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::b(int16_t offset) { 12673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu beq(zero_reg, zero_reg, offset); 12683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 12693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bal(int16_t offset) { 12723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bgezal(zero_reg, offset); 12733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 12743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::bc(int32_t offset) { 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BC, offset, CompactBranchType::COMPACT_BRANCH); 1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::balc(int32_t offset) { 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BALC, offset, CompactBranchType::COMPACT_BRANCH); 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::beq(Register rs, Register rt, int16_t offset) { 128944f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 12903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(BEQ, rs, rt, offset); 129144f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 12923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 12933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 12953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bgez(Register rs, int16_t offset) { 129644f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 12973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(REGIMM, rs, BGEZ, offset); 129844f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 12993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 13003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezc(Register rt, int16_t offset) { 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BLEZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH); 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgeuc(Register rs, Register rt, int16_t offset) { 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rs.is(zero_reg))); 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.code() != rt.code()); 1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BLEZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgec(Register rs, Register rt, int16_t offset) { 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rs.is(zero_reg))); 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.code() != rt.code()); 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BLEZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bgezal(Register rs, int16_t offset) { 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsMipsArchVariant(kMips32r6) || rs.is(zero_reg)); 132944f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 13303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(REGIMM, rs, BGEZAL, offset); 133144f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 13323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 13333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bgtz(Register rs, int16_t offset) { 133644f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 13373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(BGTZ, rs, zero_reg, offset); 133844f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 13393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 13403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtzc(Register rt, int16_t offset) { 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BGTZL, zero_reg, rt, offset, 1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType::COMPACT_BRANCH); 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::blez(Register rs, int16_t offset) { 135144f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 13523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(BLEZ, rs, zero_reg, offset); 135344f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 13543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 13553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blezc(Register rt, int16_t offset) { 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BLEZL, zero_reg, rt, offset, 1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType::COMPACT_BRANCH); 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzc(Register rt, int16_t offset) { 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!rt.is(zero_reg)); 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BGTZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH); 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltuc(Register rs, Register rt, int16_t offset) { 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rs.is(zero_reg))); 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.code() != rt.code()); 1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BGTZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltc(Register rs, Register rt, int16_t offset) { 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!rs.is(zero_reg)); 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!rt.is(zero_reg)); 1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rs.code() != rt.code()); 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BGTZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bltz(Register rs, int16_t offset) { 139144f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 13923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(REGIMM, rs, BLTZ, offset); 139344f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 13943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 13953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bltzal(Register rs, int16_t offset) { 1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsMipsArchVariant(kMips32r6) || rs.is(zero_reg)); 139944f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 14003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(REGIMM, rs, BLTZAL, offset); 140144f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 14023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 14033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 14043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 14053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bne(Register rs, Register rt, int16_t offset) { 140644f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 14073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(BNE, rs, rt, offset); 140844f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 14093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 14103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 14113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bovc(Register rs, Register rt, int16_t offset) { 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (rs.code() >= rt.code()) { 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnvc(Register rs, Register rt, int16_t offset) { 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (rs.code() >= rt.code()) { 1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); 1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blezalc(Register rt, int16_t offset) { 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BLEZ, zero_reg, rt, offset, 1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType::COMPACT_BRANCH); 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezalc(Register rt, int16_t offset) { 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BLEZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH); 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezall(Register rs, int16_t offset) { 1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rs.is(zero_reg))); 1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BlockTrampolinePoolScope block_trampoline_pool(this); 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrImmediate(REGIMM, rs, BGEZALL, offset); 1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BlockTrampolinePoolFor(1); // For associated delay slot. 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzalc(Register rt, int16_t offset) { 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BGTZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH); 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtzalc(Register rt, int16_t offset) { 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(BGTZ, zero_reg, rt, offset, 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType::COMPACT_BRANCH); 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqzalc(Register rt, int16_t offset) { 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(ADDI, zero_reg, rt, offset, 1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType::COMPACT_BRANCH); 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnezalc(Register rt, int16_t offset) { 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rt.is(zero_reg))); 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(DADDI, zero_reg, rt, offset, 1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType::COMPACT_BRANCH); 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqc(Register rs, Register rt, int16_t offset) { 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0); 1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (rs.code() < rt.code()) { 1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); 1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqzc(Register rs, int32_t offset) { 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rs.is(zero_reg))); 1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH); 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnec(Register rs, Register rt, int16_t offset) { 1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0); 1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (rs.code() < rt.code()) { 1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH); 1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH); 1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnezc(Register rs, int32_t offset) { 1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rs.is(zero_reg))); 1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH); 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::j(int32_t target) { 1524589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#if DEBUG 1525589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Get pc of delay slot. 1526589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); 1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool in_range = ((ipc ^ static_cast<uint32_t>(target)) >> 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (kImm26Bits + kImmFieldShift)) == 0; 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(in_range && ((target & 3) == 0)); 1530589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif 1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BlockTrampolinePoolScope block_trampoline_pool(this); 1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrJump(J, (target >> 2) & kImm26Mask); 1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BlockTrampolinePoolFor(1); // For associated delay slot. 15343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::jr(Register rs) { 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsMipsArchVariant(kMips32r6)) { 1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlockTrampolinePoolScope block_trampoline_pool(this); 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR); 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlockTrampolinePoolFor(1); // For associated delay slot. 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jalr(rs, zero_reg); 154444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 15453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::jal(int32_t target) { 1549589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifdef DEBUG 1550589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Get pc of delay slot. 1551589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); 1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool in_range = ((ipc ^ static_cast<uint32_t>(target)) >> 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (kImm26Bits + kImmFieldShift)) == 0; 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(in_range && ((target & 3) == 0)); 1555589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif 1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BlockTrampolinePoolScope block_trampoline_pool(this); 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrJump(JAL, (target >> 2) & kImm26Mask); 1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BlockTrampolinePoolFor(1); // For associated delay slot. 15593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::jalr(Register rs, Register rd) { 1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.code() != rd.code()); 156444f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolScope block_trampoline_pool(this); 15653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); 156644f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolFor(1); // For associated delay slot. 15673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::jic(Register rt, int16_t offset) { 1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(POP66, zero_reg, rt, offset); 1573589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 1574589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 1575589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::jialc(Register rt, int16_t offset) { 1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(POP76, zero_reg, rt, offset); 1579589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 1580589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 1581589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -------Data-processing-instructions--------- 15833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Arithmetic. 15853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::addu(Register rd, Register rs, Register rt) { 15873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 15883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::addiu(Register rd, Register rs, int32_t j) { 15923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(ADDIU, rs, rd, j); 15933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::subu(Register rd, Register rs, Register rt) { 15973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU); 15983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::mul(Register rd, Register rs, Register rt) { 1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsMipsArchVariant(kMips32r6)) { 1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL); 1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH); 1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mulu(Register rd, Register rs, Register rt) { 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH_U); 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::muh(Register rd, Register rs, Register rt) { 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH); 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::muhu(Register rd, Register rs, Register rt) { 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH_U); 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mod(Register rd, Register rs, Register rt) { 1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD); 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::modu(Register rd, Register rs, Register rt) { 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD_U); 16373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::mult(Register rs, Register rt) { 16413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT); 16423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::multu(Register rs, Register rt) { 16463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU); 16473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::div(Register rs, Register rt) { 16513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV); 16523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::div(Register rd, Register rs, Register rt) { 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD); 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::divu(Register rs, Register rt) { 16623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU); 16633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::divu(Register rd, Register rs, Register rt) { 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD_U); 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Logical. 16733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::and_(Register rd, Register rs, Register rt) { 16753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND); 16763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::andi(Register rt, Register rs, int32_t j) { 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(j)); 16813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(ANDI, rs, rt, j); 16823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::or_(Register rd, Register rs, Register rt) { 16863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR); 16873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::ori(Register rt, Register rs, int32_t j) { 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(j)); 16923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(ORI, rs, rt, j); 16933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 16963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::xor_(Register rd, Register rs, Register rt) { 16973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR); 16983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 16993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::xori(Register rt, Register rs, int32_t j) { 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(j)); 17033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(XORI, rs, rt, j); 17043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::nor(Register rd, Register rs, Register rt) { 17083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR); 17093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Shifts. 171344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::sll(Register rd, 171444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register rt, 171544f0eee88ff00398ff7f715fab053374d808c90dSteve Block uint16_t sa, 171644f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool coming_from_nop) { 171744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Don't allow nop instructions in the form sll zero_reg, zero_reg to be 171844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // generated using the sll instruction. They must be generated using 171944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // nop(int/NopMarkerTypes) or MarkCode(int/NopMarkerTypes) pseudo 172044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // instructions. 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg))); 1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SLL); 17233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::sllv(Register rd, Register rt, Register rs) { 17273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV); 17283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::srl(Register rd, Register rt, uint16_t sa) { 1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRL); 17333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::srlv(Register rd, Register rt, Register rs) { 17373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV); 17383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::sra(Register rd, Register rt, uint16_t sa) { 1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRA); 17433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::srav(Register rd, Register rt, Register rs) { 17473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV); 17483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 17493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 17503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 175144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::rotr(Register rd, Register rt, uint16_t sa) { 175244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Should be called via MacroAssembler::Ror. 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa)); 1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 175544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift) 175644f0eee88ff00398ff7f715fab053374d808c90dSteve Block | (rd.code() << kRdShift) | (sa << kSaShift) | SRL; 175744f0eee88ff00398ff7f715fab053374d808c90dSteve Block emit(instr); 175844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 175944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 176044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 176144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::rotrv(Register rd, Register rt, Register rs) { 176244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Should be called via MacroAssembler::Ror. 1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid()); 1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 176544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift) 176644f0eee88ff00398ff7f715fab053374d808c90dSteve Block | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV; 176744f0eee88ff00398ff7f715fab053374d808c90dSteve Block emit(instr); 176844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 176944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 177044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::lsa(Register rd, Register rt, Register rs, uint8_t sa) { 1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid()); 17733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(sa <= 3); 1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 17753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instr instr = SPECIAL | rs.code() << kRsShift | rt.code() << kRtShift | 17763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch rd.code() << kRdShift | sa << kSaShift | LSA; 1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(instr); 1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ------------Memory-instructions------------- 17823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 178344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Helper for base-reg + offset, when offset is larger than int16. 178444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) { 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.rm().is(at)); 178662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (IsMipsArchVariant(kMips32r6)) { 178762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int32_t hi = (src.offset_ >> kLuiShift) & kImm16Mask; 178862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (src.offset_ & kNegOffset) { 178962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch hi += 1; 179062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 179162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch aui(at, src.rm(), hi); 179262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch addiu(at, at, src.offset_ & kImm16Mask); 179362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 179462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch lui(at, (src.offset_ >> kLuiShift) & kImm16Mask); 179562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset. 179662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch addu(at, at, src.rm()); // Add base register. 179762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 179844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 179944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1800c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Helper for base-reg + upper part of offset, when offset is larger than int16. 1801c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Loads higher part of the offset to AT register. 1802c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Returns lower part of the offset to be used as offset 1803c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// in Load/Store instructions 1804c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint32_t Assembler::LoadRegPlusUpperOffsetPartToAt(const MemOperand& src) { 1805c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(!src.rm().is(at)); 1806c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t hi = (src.offset_ >> kLuiShift) & kImm16Mask; 1807c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // If the highest bit of the lower part of the offset is 1, this would make 1808c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // the offset in the load/store instruction negative. We need to compensate 1809c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // for this by adding 1 to the upper part of the offset. 1810c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (src.offset_ & kNegOffset) { 1811c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch hi += 1; 1812c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 181362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 181462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (IsMipsArchVariant(kMips32r6)) { 181562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch aui(at, src.rm(), hi); 181662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 181762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch lui(at, hi); 181862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch addu(at, at, src.rm()); 181962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 1820c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return (src.offset_ & kImm16Mask); 1821c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 1822c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1823c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Helper for loading base-reg + upper offset's part to AT reg when we are using 1824c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// two 32-bit loads/stores instead of one 64-bit 1825c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint32_t Assembler::LoadUpperOffsetForTwoMemoryAccesses(const MemOperand& src) { 1826c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(!src.rm().is(at)); 1827c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (is_int16((src.offset_ & kImm16Mask) + kIntSize)) { 1828c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Only if lower part of offset + kIntSize fits in 16bits 1829c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return LoadRegPlusUpperOffsetPartToAt(src); 1830c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1831c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // In case offset's lower part + kIntSize doesn't fit in 16bits, 1832c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // load reg + hole offset to AT 1833c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoadRegPlusOffsetToAt(src); 1834c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return 0; 1835c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 183644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 18373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::lb(Register rd, const MemOperand& rs) { 183844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 183944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(LB, rs.rm(), rd, rs.offset_); 184044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to load. 1841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LB, at, rd, off16); 184344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 18443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 18453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 18463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 18473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::lbu(Register rd, const MemOperand& rs) { 184844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 184944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_); 185044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to load. 1851c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1852c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LBU, at, rd, off16); 185344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 185444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 185544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 185644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 185744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::lh(Register rd, const MemOperand& rs) { 185844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 185944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(LH, rs.rm(), rd, rs.offset_); 186044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to load. 1861c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1862c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LH, at, rd, off16); 186344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 186444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 186544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 186644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 186744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::lhu(Register rd, const MemOperand& rs) { 186844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 186944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_); 187044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to load. 1871c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1872c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LHU, at, rd, off16); 187344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 18743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 18753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 18763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 18773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::lw(Register rd, const MemOperand& rs) { 187844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 187944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(LW, rs.rm(), rd, rs.offset_); 188044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to load. 1881c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1882c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LW, at, rd, off16); 188344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 188444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 188544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 188644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 188744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::lwl(Register rd, const MemOperand& rs) { 1888bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(is_int16(rs.offset_)); 1889bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || 1890bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IsMipsArchVariant(kMips32r2)); 189144f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_); 189244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 189344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 189444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 189544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::lwr(Register rd, const MemOperand& rs) { 1896bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(is_int16(rs.offset_)); 1897bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || 1898bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IsMipsArchVariant(kMips32r2)); 189944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_); 19003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 19013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::sb(Register rd, const MemOperand& rs) { 190444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 190544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(SB, rs.rm(), rd, rs.offset_); 190644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to store. 1907c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1908c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SB, at, rd, off16); 190944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 191044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 191144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 191244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 191344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::sh(Register rd, const MemOperand& rs) { 191444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 191544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(SH, rs.rm(), rd, rs.offset_); 191644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to store. 1917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SH, at, rd, off16); 191944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 19203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 19213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::sw(Register rd, const MemOperand& rs) { 192444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_int16(rs.offset_)) { 192544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(SW, rs.rm(), rd, rs.offset_); 192644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { // Offset > 16 bits, use multiple instructions to store. 1927c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs); 1928c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SW, at, rd, off16); 192944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 193044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 193144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 193244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 193344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::swl(Register rd, const MemOperand& rs) { 1934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(is_int16(rs.offset_)); 1935bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || 1936bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IsMipsArchVariant(kMips32r2)); 193744f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_); 193844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 193944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 194044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 194144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::swr(Register rd, const MemOperand& rs) { 1942bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(is_int16(rs.offset_)); 1943bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || 1944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IsMipsArchVariant(kMips32r2)); 194544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_); 19463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 19473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::lui(Register rd, int32_t j) { 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(j)); 19513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(LUI, zero_reg, rd, j); 19523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 19533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 19543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::aui(Register rt, Register rs, int32_t j) { 1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This instruction uses same opcode as 'lui'. The difference in encoding is 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 'lui' has zero reg. for rs field. 1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!(rs.is(zero_reg))); 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(j)); 1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrImmediate(LUI, rs, rt, j); 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ---------PC-Relative instructions----------- 19643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::addiupc(Register rs, int32_t imm19) { 1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.is_valid() && is_int19(imm19)); 1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask); 1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(PCREL, rs, imm21); 1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::lwpc(Register rs, int32_t offset19) { 1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.is_valid() && is_int19(offset19)); 1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask); 1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(PCREL, rs, imm21); 1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::auipc(Register rs, int16_t imm16) { 1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.is_valid()); 1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask); 1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(PCREL, rs, imm21); 1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::aluipc(Register rs, int16_t imm16) { 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rs.is_valid()); 1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask); 1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(PCREL, rs, imm21); 1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -------------Misc-instructions-------------- 1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Break / Trap instructions. 20003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Assembler::break_(uint32_t code, bool break_as_stop) { 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((code & ~0xfffff) == 0); 20023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We need to invalidate breaks that could be stops as well because the 20033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // simulator expects a char pointer after the stop instruction. 20043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // See constants-mips.h for explanation. 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((break_as_stop && 20063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code <= kMaxStopCode && 20073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code > kMaxWatchpointCode) || 20083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (!break_as_stop && 20093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (code > kMaxStopCode || 20103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code <= kMaxWatchpointCode))); 20113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr break_instr = SPECIAL | BREAK | (code << 6); 20123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(break_instr); 20133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Assembler::stop(const char* msg, uint32_t code) { 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(code > kMaxWatchpointCode); 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(code <= kMaxStopCode); 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_HOST_ARCH_MIPS 20203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_(0x54321); 20213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else // V8_HOST_ARCH_MIPS 20223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BlockTrampolinePoolFor(2); 20233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The Simulator will handle the stop instruction and get the message address. 20243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // On MIPS stop() is just a special kind of break_(). 20253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_(code, true); 2026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Do not embed the message string address! We used to do this, but that 2027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // made snapshots created from position-independent executable builds 2028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // non-deterministic. 2029f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(yangguo): remove this field entirely. 2030f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch nop(); 20313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 20323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 20333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 20343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 20353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::tge(Register rs, Register rt, uint16_t code) { 2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint10(code)); 20373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = SPECIAL | TGE | rs.code() << kRsShift 20383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu | rt.code() << kRtShift | code << 6; 20393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 20403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::tgeu(Register rs, Register rt, uint16_t code) { 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint10(code)); 20453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = SPECIAL | TGEU | rs.code() << kRsShift 20463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu | rt.code() << kRtShift | code << 6; 20473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 20483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::tlt(Register rs, Register rt, uint16_t code) { 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint10(code)); 20533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = 20543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6; 20553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 20563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::tltu(Register rs, Register rt, uint16_t code) { 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint10(code)); 206144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr = 206244f0eee88ff00398ff7f715fab053374d808c90dSteve Block SPECIAL | TLTU | rs.code() << kRsShift 20633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu | rt.code() << kRtShift | code << 6; 20643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 20653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::teq(Register rs, Register rt, uint16_t code) { 2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint10(code)); 20703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = 20713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6; 20723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 20733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::tne(Register rs, Register rt, uint16_t code) { 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint10(code)); 20783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = 20793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6; 20803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 20813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2083bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Assembler::sync() { 2084bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Instr sync_instr = SPECIAL | SYNC; 2085bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch emit(sync_instr); 2086bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 20873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Move from HI/LO register. 20893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::mfhi(Register rd) { 20913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI); 20923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::mflo(Register rd) { 20963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO); 20973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 20983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 20993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Set on less than instructions. 21013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::slt(Register rd, Register rs, Register rt) { 21023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT); 21033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 21043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::sltu(Register rd, Register rs, Register rt) { 21073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU); 21083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 21093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::slti(Register rt, Register rs, int32_t j) { 21123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(SLTI, rs, rt, j); 21133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 21143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::sltiu(Register rt, Register rs, int32_t j) { 21173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrImmediate(SLTIU, rs, rt, j); 21183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 21193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 21203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 212144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Conditional move. 212244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::movz(Register rd, Register rs, Register rt) { 212344f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ); 212444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 212544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 212644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 212744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::movn(Register rd, Register rs, Register rt) { 212844f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN); 212944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 213044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 213144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 213244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::movt(Register rd, Register rs, uint16_t cc) { 213344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register rt; 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rt.reg_code = (cc & 0x0007) << 2 | 1; 213544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI); 213644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 213744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 213844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 213944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::movf(Register rd, Register rs, uint16_t cc) { 214044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register rt; 2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rt.reg_code = (cc & 0x0007) << 2 | 0; 214244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI); 214344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 214444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 214544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz(Register rd, Register rs, Register rt) { 2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELEQZ_S); 2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 215244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Bit twiddling. 215344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::clz(Register rd, Register rs) { 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsMipsArchVariant(kMips32r6)) { 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clz instr requires same GPR number in 'rd' and 'rt' fields. 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ); 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, CLZ_R6); 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 216044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 216144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 216244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 216344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) { 216444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Should be called via MacroAssembler::Ins. 216544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Ins instr has 'rt' field as dest, and two uint5: msb, lsb. 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 216744f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS); 216844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 216944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 217044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 217144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { 217244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Should be called via MacroAssembler::Ext. 217344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Ext instr has 'rt' field as dest, and two uint5: msb, lsb. 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 217544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT); 217644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 217744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 217844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::bitswap(Register rd, Register rt) { 2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL); 2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::pref(int32_t hint, const MemOperand& rs) { 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsMipsArchVariant(kLoongson)); 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch | (rs.offset_); 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(instr); 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) { 2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_uint3(bp)); 2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint16_t sa = (ALIGN << kBp2Bits) | bp; 2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL); 2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 220113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Byte swap. 220213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::wsbh(Register rd, Register rt) { 220313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 220413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GenInstrRegister(SPECIAL3, zero_reg, rt, rd, WSBH, BSHFL); 220513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 220613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 220713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::seh(Register rd, Register rt) { 220813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 220913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEH, BSHFL); 221013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 221113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 221213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::seb(Register rd, Register rt) { 221313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 221413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEB, BSHFL); 221513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --------Coprocessor-instructions---------------- 22183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Load, store, move. 22203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::lwc1(FPURegister fd, const MemOperand& src) { 2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_int16(src.offset_)) { 2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { // Offset > 16 bits, use multiple instructions to load. 2224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src); 2225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LWC1, at, fd, off16); 2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 22273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 22283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::ldc1(FPURegister fd, const MemOperand& src) { 223144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit 223244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // load to two 32-bit loads. 2233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (IsFp32Mode()) { // fp32 mode. 2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_int16(src.offset_) && is_int16(src.offset_ + kIntSize)) { 2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(LWC1, src.rm(), fd, 2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kMantissaOffset); 2237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FPURegister nextfpreg; 2238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch nextfpreg.setcode(fd.code() + 1); 2239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch GenInstrImmediate(LWC1, src.rm(), nextfpreg, 2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kExponentOffset); 2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { // Offset > 16 bits, use multiple instructions to load. 2242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadUpperOffsetForTwoMemoryAccesses(src); 2243c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LWC1, at, fd, off16 + Register::kMantissaOffset); 2244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FPURegister nextfpreg; 2245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch nextfpreg.setcode(fd.code() + 1); 2246c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LWC1, at, nextfpreg, off16 + Register::kExponentOffset); 2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 2249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(IsFp64Mode() || IsFpxxMode()); 2250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Currently we support FPXX and FP64 on Mips32r2 and Mips32r6 2251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_int16(src.offset_) && is_int16(src.offset_ + kIntSize)) { 2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(LWC1, src.rm(), fd, 2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kMantissaOffset); 2255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch GenInstrImmediate(LW, src.rm(), at, 2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kExponentOffset); 2257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch mthc1(at, fd); 2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { // Offset > 16 bits, use multiple instructions to load. 2259c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadUpperOffsetForTwoMemoryAccesses(src); 2260c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LWC1, at, fd, off16 + Register::kMantissaOffset); 2261c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(LW, at, at, off16 + Register::kExponentOffset); 2262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch mthc1(at, fd); 2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 22653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 22663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::swc1(FPURegister fd, const MemOperand& src) { 2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_int16(src.offset_)) { 2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(SWC1, src.rm(), fd, src.offset_); 2271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { // Offset > 16 bits, use multiple instructions to load. 2272c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src); 2273c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SWC1, at, fd, off16); 2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 22753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 22763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 22783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::sdc1(FPURegister fd, const MemOperand& src) { 227944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit 228044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // store to two 32-bit stores. 2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!src.rm().is(at)); 2282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!src.rm().is(t8)); 2283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (IsFp32Mode()) { // fp32 mode. 2284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_int16(src.offset_) && is_int16(src.offset_ + kIntSize)) { 2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(SWC1, src.rm(), fd, 2286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kMantissaOffset); 2287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FPURegister nextfpreg; 2288109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch nextfpreg.setcode(fd.code() + 1); 2289109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch GenInstrImmediate(SWC1, src.rm(), nextfpreg, 2290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kExponentOffset); 2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { // Offset > 16 bits, use multiple instructions to load. 2292c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadUpperOffsetForTwoMemoryAccesses(src); 2293c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SWC1, at, fd, off16 + Register::kMantissaOffset); 2294109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FPURegister nextfpreg; 2295109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch nextfpreg.setcode(fd.code() + 1); 2296c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SWC1, at, nextfpreg, off16 + Register::kExponentOffset); 2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2298109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 2299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(IsFp64Mode() || IsFpxxMode()); 2300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Currently we support FPXX and FP64 on Mips32r2 and Mips32r6 2301109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_int16(src.offset_) && is_int16(src.offset_ + kIntSize)) { 2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrImmediate(SWC1, src.rm(), fd, 2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kMantissaOffset); 2305109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch mfhc1(at, fd); 2306109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch GenInstrImmediate(SW, src.rm(), at, 2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch src.offset_ + Register::kExponentOffset); 2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { // Offset > 16 bits, use multiple instructions to load. 2309c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t off16 = LoadUpperOffsetForTwoMemoryAccesses(src); 2310c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SWC1, at, fd, off16 + Register::kMantissaOffset); 2311109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch mfhc1(t8, fd); 2312c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GenInstrImmediate(SW, at, t8, off16 + Register::kExponentOffset); 2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 23153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 23163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 23173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 231844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::mtc1(Register rt, FPURegister fs) { 23193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, MTC1, rt, fs, f0); 23203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 23213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 23223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mthc1(Register rt, FPURegister fs) { 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(COP1, MTHC1, rt, fs, f0); 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::mfc1(Register rt, FPURegister fs) { 232944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, MFC1, rt, fs, f0); 23303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 23313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 23323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mfhc1(Register rt, FPURegister fs) { 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(COP1, MFHC1, rt, fs, f0); 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 233844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::ctc1(Register rt, FPUControlRegister fs) { 233944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, CTC1, rt, fs); 234044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 234144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 234244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 234344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::cfc1(Register rt, FPUControlRegister fs) { 234444f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, CFC1, rt, fs); 234544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 234644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2348589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { 2349589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint64_t i; 2350589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch memcpy(&i, &d, 8); 2351589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2352589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *lo = i & 0xffffffff; 2353589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *hi = i >> 32; 2354589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 235544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movn_s(FPURegister fd, FPURegister fs, Register rt) { 2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, rt, fs, fd, MOVN_C); 2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movn_d(FPURegister fd, FPURegister fs, Register rt) { 2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, D, rt, fs, fd, MOVN_C); 2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sel(SecondaryField fmt, FPURegister fd, FPURegister fs, 2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((fmt == D) || (fmt == S)); 2373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, fmt, ft, fs, fd, SEL); 2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sel_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sel(S, fd, fs, ft); 2380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sel_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sel(D, fd, fs, ft); 2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs, 2389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((fmt == D) || (fmt == S)); 2392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C); 2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez(Register rd, Register rs, Register rt) { 2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELNEZ_S); 2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez(SecondaryField fmt, FPURegister fd, FPURegister fs, 2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((fmt == D) || (fmt == S)); 2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C); 2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seleqz(D, fd, fs, ft); 2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seleqz(S, fd, fs, ft); 2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selnez(D, fd, fs, ft); 2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selnez(S, fd, fs, ft); 2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movz_s(FPURegister fd, FPURegister fs, Register rt) { 2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, rt, fs, fd, MOVZ_C); 2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movz_d(FPURegister fd, FPURegister fs, Register rt) { 2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, D, rt, fs, fd, MOVZ_C); 2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) { 2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft; 2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ft.reg_code = (cc & 0x0007) << 2 | 1; 2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, MOVF); 2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) { 2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft; 2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ft.reg_code = (cc & 0x0007) << 2 | 1; 2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, D, ft, fs, fd, MOVF); 2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) { 2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft; 2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ft.reg_code = (cc & 0x0007) << 2 | 0; 2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, MOVF); 2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movf_d(FPURegister fd, FPURegister fs, uint16_t cc) { 2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsMipsArchVariant(kMips32r6)); 2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft; 2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ft.reg_code = (cc & 0x0007) << 2 | 0; 2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, D, ft, fs, fd, MOVF); 2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 247444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Arithmetic. 247544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::add_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, ADD_S); 2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 248144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) { 248244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, ft, fs, fd, ADD_D); 248344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 248444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 248544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sub_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, SUB_S); 2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 249144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) { 249244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, ft, fs, fd, SUB_D); 249344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 249444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 249544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mul_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, MUL_S); 2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 250144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) { 250244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, ft, fs, fd, MUL_D); 250344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 250444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::madd_s(FPURegister fd, FPURegister fr, FPURegister fs, 2506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch FPURegister ft) { 2507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2)); 2508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_S); 2509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 251044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs, 2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister ft) { 2513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsMipsArchVariant(kMips32r2)); 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D); 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msub_s(FPURegister fd, FPURegister fr, FPURegister fs, 2518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch FPURegister ft) { 2519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2)); 2520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GenInstrRegister(COP1X, fr, ft, fs, fd, MSUB_S); 2521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 2523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msub_d(FPURegister fd, FPURegister fr, FPURegister fs, 2524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch FPURegister ft) { 2525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2)); 2526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GenInstrRegister(COP1X, fr, ft, fs, fd, MSUB_D); 2527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 2529f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::maddf_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, MADDF_S); 2532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 2534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::maddf_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2536f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GenInstrRegister(COP1, D, ft, fs, fd, MADDF_D); 2537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 2539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msubf_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2541f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, MSUBF_S); 2542f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 2544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msubf_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GenInstrRegister(COP1, D, ft, fs, fd, MSUBF_D); 2547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::div_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, ft, fs, fd, DIV_S); 2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 255444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) { 255544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, ft, fs, fd, DIV_D); 255644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 255744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 255844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::abs_s(FPURegister fd, FPURegister fs) { 2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, f0, fs, fd, ABS_S); 2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 256444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::abs_d(FPURegister fd, FPURegister fs) { 256544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, ABS_D); 25663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 25673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 25683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 256944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::mov_d(FPURegister fd, FPURegister fs) { 257044f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, MOV_D); 257144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 257244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 257344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mov_s(FPURegister fd, FPURegister fs) { 2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, f0, fs, fd, MOV_S); 2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::neg_s(FPURegister fd, FPURegister fs) { 2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, f0, fs, fd, NEG_S); 2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 258444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::neg_d(FPURegister fd, FPURegister fs) { 258544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, NEG_D); 258644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 258744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 258844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sqrt_s(FPURegister fd, FPURegister fs) { 2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, f0, fs, fd, SQRT_S); 2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 259444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::sqrt_d(FPURegister fd, FPURegister fs) { 259544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D); 25963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 25973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 25983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rsqrt_s(FPURegister fd, FPURegister fs) { 2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, f0, fs, fd, RSQRT_S); 2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rsqrt_d(FPURegister fd, FPURegister fs) { 2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, D, f0, fs, fd, RSQRT_D); 2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::recip_d(FPURegister fd, FPURegister fs) { 2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, D, f0, fs, fd, RECIP_D); 2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::recip_s(FPURegister fd, FPURegister fs) { 2618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, f0, fs, fd, RECIP_S); 2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 26233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Conversions. 26243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 26253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_w_s(FPURegister fd, FPURegister fs) { 26263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S); 26273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 26283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 26293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 26303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_w_d(FPURegister fd, FPURegister fs) { 26313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D); 26323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 26333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 26343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 263544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::trunc_w_s(FPURegister fd, FPURegister fs) { 263644f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S); 263744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 263844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 263944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 264044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::trunc_w_d(FPURegister fd, FPURegister fs) { 264144f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D); 264244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 264344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 264444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 264544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::round_w_s(FPURegister fd, FPURegister fs) { 264644f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S); 264744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 264844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 264944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 265044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::round_w_d(FPURegister fd, FPURegister fs) { 265144f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D); 265244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 265344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 265444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 265544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::floor_w_s(FPURegister fd, FPURegister fs) { 265644f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S); 265744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 265844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 265944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 266044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::floor_w_d(FPURegister fd, FPURegister fs) { 266144f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D); 266244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 266344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 266444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 266544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::ceil_w_s(FPURegister fd, FPURegister fs) { 266644f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S); 266744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 266844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 266944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 267044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::ceil_w_d(FPURegister fd, FPURegister fs) { 267144f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D); 267244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 267344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 267444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rint_s(FPURegister fd, FPURegister fs) { rint(S, fd, fs); } 2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rint(SecondaryField fmt, FPURegister fd, FPURegister fs) { 2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((fmt == D) || (fmt == S)); 2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, fmt, f0, fs, fd, RINT); 2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rint_d(FPURegister fd, FPURegister fs) { rint(D, fd, fs); } 2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 26883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_l_s(FPURegister fd, FPURegister fs) { 2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 26913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S); 26923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 26933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 26943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 26953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_l_d(FPURegister fd, FPURegister fs) { 2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 26983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D); 26993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 27003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 27013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 270244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::trunc_l_s(FPURegister fd, FPURegister fs) { 2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 270544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S); 270644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 270744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 270844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 270944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::trunc_l_d(FPURegister fd, FPURegister fs) { 2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 271244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D); 271344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 271444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 271544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 271644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::round_l_s(FPURegister fd, FPURegister fs) { 2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 271944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S); 272044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 272144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 272244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 272344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::round_l_d(FPURegister fd, FPURegister fs) { 2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 272644f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D); 272744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 272844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 272944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 273044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::floor_l_s(FPURegister fd, FPURegister fs) { 2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 273344f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S); 273444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 273544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 273644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 273744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::floor_l_d(FPURegister fd, FPURegister fs) { 2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 274044f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D); 274144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 274244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 274344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 274444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::ceil_l_s(FPURegister fd, FPURegister fs) { 2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 274744f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S); 274844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 274944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 275044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 275144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::ceil_l_d(FPURegister fd, FPURegister fs) { 2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 275444f0eee88ff00398ff7f715fab053374d808c90dSteve Block GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D); 275544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 275644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 275744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::class_s(FPURegister fd, FPURegister fs) { 2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, S, f0, fs, fd, CLASS_S); 2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::class_d(FPURegister fd, FPURegister fs) { 2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenInstrRegister(COP1, D, f0, fs, fd, CLASS_D); 2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::min(SecondaryField fmt, FPURegister fd, FPURegister fs, 2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((fmt == D) || (fmt == S)); 2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(COP1, fmt, ft, fs, fd, MIN); 2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister fs, 2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((fmt == D) || (fmt == S)); 2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(COP1, fmt, ft, fs, fd, MINA); 2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister fs, 2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((fmt == D) || (fmt == S)); 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(COP1, fmt, ft, fs, fd, MAX); 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister fs, 2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((fmt == D) || (fmt == S)); 2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA); 2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::min_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch min(S, fd, fs, ft); 2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::min_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch min(D, fd, fs, ft); 2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::max_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch max(S, fd, fs, ft); 2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::max_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch max(D, fd, fs, ft); 2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mina_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mina(S, fd, fs, ft); 2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mina_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mina(D, fd, fs, ft); 2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::maxa_s(FPURegister fd, FPURegister fs, FPURegister ft) { 2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch maxa(S, fd, fs, ft); 2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::maxa_d(FPURegister fd, FPURegister fs, FPURegister ft) { 2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch maxa(D, fd, fs, ft); 2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 28423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_s_w(FPURegister fd, FPURegister fs) { 28433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W); 28443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 28453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_s_l(FPURegister fd, FPURegister fs) { 2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 28503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L); 28513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 28523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_s_d(FPURegister fd, FPURegister fs) { 28553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D); 28563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 28573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_d_w(FPURegister fd, FPURegister fs) { 28603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W); 28613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 28623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_d_l(FPURegister fd, FPURegister fs) { 2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFp64Mode()); 28673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L); 28683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 28693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::cvt_d_s(FPURegister fd, FPURegister fs) { 28723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S); 28733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 28743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 28753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditions for >= MIPSr6. 2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cmp(FPUCondition cond, SecondaryField fmt, 2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fd, FPURegister fs, FPURegister ft) { 2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((fmt & ~(31 << kRsShift)) == 0); 2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr instr = COP1 | fmt | ft.code() << kFtShift | 2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fs.code() << kFsShift | fd.code() << kFdShift | (0 << 5) | cond; 2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(instr); 2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs, 2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmp(cond, W, fd, fs, ft); 2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, 2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft) { 2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmp(cond, L, fd, fs, ft); 2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1eqz(int16_t offset, FPURegister ft) { 2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask); 2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(instr); 2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1nez(int16_t offset, FPURegister ft) { 2906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsMipsArchVariant(kMips32r6)); 2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask); 2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(instr); 2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditions for < MIPSr6. 29133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::c(FPUCondition cond, SecondaryField fmt, 291444f0eee88ff00398ff7f715fab053374d808c90dSteve Block FPURegister fs, FPURegister ft, uint16_t cc) { 2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint3(cc)); 2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(fmt == S || fmt == D); 2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((fmt & ~(31 << kRsShift)) == 0); 29183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = COP1 | fmt | ft.code() << 16 | fs.code() << kFsShift 29193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu | cc << 8 | 3 << 4 | cond; 29203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 29213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 29223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 29233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::c_s(FPUCondition cond, FPURegister fs, FPURegister ft, 2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint16_t cc) { 2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch c(cond, S, fs, ft, cc); 2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::c_d(FPUCondition cond, FPURegister fs, FPURegister ft, 2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint16_t cc) { 2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch c(cond, D, fs, ft, cc); 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 293644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::fcmp(FPURegister src1, const double src2, 293744f0eee88ff00398ff7f715fab053374d808c90dSteve Block FPUCondition cond) { 2938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(src2 == 0.0); 293944f0eee88ff00398ff7f715fab053374d808c90dSteve Block mtc1(zero_reg, f14); 294044f0eee88ff00398ff7f715fab053374d808c90dSteve Block cvt_d_w(f14, f14); 294144f0eee88ff00398ff7f715fab053374d808c90dSteve Block c(cond, D, src1, f14, 0); 294244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 294344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 294444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 29453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bc1f(int16_t offset, uint16_t cc) { 2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint3(cc)); 29473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask); 29483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 29493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 29503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 29513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 29523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::bc1t(int16_t offset, uint16_t cc) { 2953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint3(cc)); 29543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask); 29553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu emit(instr); 29563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 29573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 29583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc, 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t pc_delta) { 29613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Instr instr = instr_at(pc); 29623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (RelocInfo::IsInternalReference(rmode)) { 2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t* p = reinterpret_cast<int32_t*>(pc); 2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (*p == 0) { 29663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return 0; // Number of instructions patched. 29673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *p += pc_delta; 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1; // Number of instructions patched. 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode)); 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsLui(instr)) { 29733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instr instr1 = instr_at(pc + 0 * Assembler::kInstrSize); 29743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instr instr2 = instr_at(pc + 1 * Assembler::kInstrSize); 29753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(IsOri(instr2) || IsJicOrJialc(instr2)); 29763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int32_t imm; 29773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsJicOrJialc(instr2)) { 29783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm = CreateTargetAddress(instr1, instr2); 29793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 29803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm = (instr1 & static_cast<int32_t>(kImm16Mask)) << kLuiShift; 29813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm |= (instr2 & static_cast<int32_t>(kImm16Mask)); 29823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 29833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm == kEndOfJumpChain) { 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; // Number of instructions patched. 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch imm += pc_delta; 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((imm & 3) == 0); 29893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr1 &= ~kImm16Mask; 29903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr2 &= ~kImm16Mask; 29913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 29923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsJicOrJialc(instr2)) { 29933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t lui_offset_u, jic_offset_u; 29943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Assembler::UnpackTargetAddressUnsigned(imm, lui_offset_u, jic_offset_u); 29953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pc + 0 * Assembler::kInstrSize, instr1 | lui_offset_u); 29963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pc + 1 * Assembler::kInstrSize, instr2 | jic_offset_u); 29973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 29983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pc + 0 * Assembler::kInstrSize, 29993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr1 | ((imm >> kLuiShift) & kImm16Mask)); 30003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr_at_put(pc + 1 * Assembler::kInstrSize, 30013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr2 | (imm & kImm16Mask)); 30023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 2; // Number of instructions patched. 3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 30083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 30093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 30103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 30113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 30123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::GrowBuffer() { 30133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (!own_buffer_) FATAL("external code buffer is too small"); 30143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 30153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Compute new buffer size. 301644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeDesc desc; // The new buffer. 3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer_size_ < 1 * MB) { 30183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc.buffer_size = 2*buffer_size_; 30193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 30203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc.buffer_size = buffer_size_ + 1*MB; 30213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 302244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_GT(desc.buffer_size, 0); // No overflow. 30233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 30243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up new buffer. 30253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc.buffer = NewArray<byte>(desc.buffer_size); 3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc.origin = this; 30273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 30283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc.instr_size = pc_offset(); 30293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 30303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 30313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Copy the data. 30323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int pc_delta = desc.buffer - buffer_; 30333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemMove(desc.buffer, buffer_, desc.instr_size); 3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemMove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(), 3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc.reloc_size); 30373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 30383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Switch buffers. 30393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu DeleteArray(buffer_); 30403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu buffer_ = desc.buffer; 30413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu buffer_size_ = desc.buffer_size; 30423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu pc_ += pc_delta; 30433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 30443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu reloc_info_writer.last_pc() + pc_delta); 30453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 30463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Relocate runtime entries. 30473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (RelocIterator it(desc); !it.done(); it.next()) { 30483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RelocInfo::Mode rmode = it.rinfo()->rmode(); 3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (rmode == RelocInfo::INTERNAL_REFERENCE_ENCODED || 3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rmode == RelocInfo::INTERNAL_REFERENCE) { 30513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch byte* p = reinterpret_cast<byte*>(it.rinfo()->pc()); 3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocateInternalReference(rmode, p, pc_delta); 30533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 30543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!overflow()); 30563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 30573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 30583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 305944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::db(uint8_t data) { 3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckForEmitInForbiddenSlot(); 3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmitHelper(data); 306244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 306344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 306444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 306544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::dd(uint32_t data) { 3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckForEmitInForbiddenSlot(); 3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmitHelper(data); 306844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 306944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 307044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dq(uint64_t data) { 3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckForEmitInForbiddenSlot(); 3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmitHelper(data); 3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dd(Label* label) { 3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t data; 3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckForEmitInForbiddenSlot(); 3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (label->is_bound()) { 3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data = reinterpret_cast<uint32_t>(buffer_ + label->pos()); 3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data = jump_address(label); 3084bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch unbound_labels_count_++; 3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch internal_reference_positions_.insert(label->pos()); 3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmitHelper(data); 3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 30933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We do not try to reuse pool constants. 3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo rinfo(isolate(), pc_, rmode, data, NULL); 3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (rmode >= RelocInfo::COMMENT && 30963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch rmode <= RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL) { 30973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Adjust code for new modes. 3098f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(RelocInfo::IsDebugBreakSlot(rmode) || RelocInfo::IsComment(rmode)); 30993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // These modes do not need an entry in the constant pool. 31003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!RelocInfo::IsNone(rinfo.rmode())) { 31023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Don't record external references unless the heap will be serialized. 3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rmode == RelocInfo::EXTERNAL_REFERENCE && 3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !serializer_enabled() && !emit_debug_code()) { 3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 31063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(buffer_space() >= kMaxRelocSize); // Too late to grow buffer here. 3108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo reloc_info_with_ast_id(isolate(), pc_, rmode, 3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordedAstId().ToInt(), NULL); 31113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ClearRecordedAstId(); 3112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch reloc_info_writer.Write(&reloc_info_with_ast_id); 3113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 3114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch reloc_info_writer.Write(&rinfo); 3115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 31163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 31173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 31183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 31193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 312044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::BlockTrampolinePoolFor(int instructions) { 3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckTrampolinePoolQuick(instructions); 312244f0eee88ff00398ff7f715fab053374d808c90dSteve Block BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize); 312344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 312444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 312544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 31263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Assembler::CheckTrampolinePool() { 312744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Some small sequences of instructions must not be broken up by the 312844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // insertion of a trampoline pool; such sequences are protected by setting 312944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_, 313044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // which are both checked here. Also, recursive calls to CheckTrampolinePool 313144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // are blocked by trampoline_pool_blocked_nesting_. 313244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if ((trampoline_pool_blocked_nesting_ > 0) || 313344f0eee88ff00398ff7f715fab053374d808c90dSteve Block (pc_offset() < no_trampoline_pool_before_)) { 313444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Emission is currently blocked; make sure we try again as soon as 313544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // possible. 313644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (trampoline_pool_blocked_nesting_ > 0) { 313744f0eee88ff00398ff7f715fab053374d808c90dSteve Block next_buffer_check_ = pc_offset() + kInstrSize; 313844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 313944f0eee88ff00398ff7f715fab053374d808c90dSteve Block next_buffer_check_ = no_trampoline_pool_before_; 314044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 314144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 314244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 314344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!trampoline_emitted_); 3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(unbound_labels_count_ >= 0); 31463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (unbound_labels_count_ > 0) { 31473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // First we emit jump (2 instructions), then we emit trampoline pool. 31483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { BlockTrampolinePoolScope block_trampoline_pool(this); 31493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label after_pool; 3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsMipsArchVariant(kMips32r6)) { 3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bc(&after_pool); 3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch b(&after_pool); 3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nop(); 3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 31563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int pool_start = pc_offset(); 31583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsMipsArchVariant(kMips32r6)) { 31593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = 0; i < unbound_labels_count_; i++) { 31603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t imm32; 31613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm32 = jump_address(&after_pool); 31623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t lui_offset, jic_offset; 31633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch UnpackTargetAddressUnsigned(imm32, lui_offset, jic_offset); 31643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch { 31653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BlockGrowBufferScope block_buf_growth(this); 31663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Buffer growth (and relocation) must be blocked for internal 31673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // references until associated instructions are emitted and 31683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // available to be patched. 31693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED); 31703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch lui(at, lui_offset); 31713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jic(at, jic_offset); 31723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CheckBuffer(); 31743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 31763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = 0; i < unbound_labels_count_; i++) { 31773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t imm32; 31783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch imm32 = jump_address(&after_pool); 31793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch { 31803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BlockGrowBufferScope block_buf_growth(this); 31813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Buffer growth (and relocation) must be blocked for internal 31823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // references until associated instructions are emitted and 31833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // available to be patched. 31843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED); 31853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch lui(at, (imm32 & kHiMask) >> kLuiShift); 31863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ori(at, at, (imm32 & kImm16Mask)); 31873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CheckBuffer(); 31893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jr(at); 31903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch nop(); 31913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 31923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 31933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bind(&after_pool); 31943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trampoline_ = Trampoline(pool_start, unbound_labels_count_); 31953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trampoline_emitted_ = true; 31973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // As we are only going to emit trampoline once, we need to prevent any 31983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // further emission. 31993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next_buffer_check_ = kMaxInt; 320044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 32013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 32023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Number of branches to unbound label at this point is zero, so we can 32033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // move next buffer check to maximum. 32043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next_buffer_check_ = pc_offset() + 32053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kMaxBranchOffset - kTrampolineSlotsSize * 16; 320644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 320744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 320844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 320944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 321044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 32113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress Assembler::target_address_at(Address pc) { 32123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr1 = instr_at(pc); 32133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr2 = instr_at(pc + kInstrSize); 3214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Interpret 2 instructions generated by li: lui/ori 32153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsLui(instr1) && IsOri(instr2)) { 3216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Assemble the 32 bit value. 32173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return reinterpret_cast<Address>((GetImmediate16(instr1) << kLuiShift) | 32183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch GetImmediate16(instr2)); 32193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 32203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We should never get here, force a bad address if we do. 32223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu UNREACHABLE(); 32233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return (Address)0x0; 32243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 32253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 32263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3227db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch// MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32 3228db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch// qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap 3229db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch// snapshot generated on ia32, the resulting MIPS sNaN must be quieted. 3230db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch// OS::nan_value() returns a qNaN. 3231db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdochvoid Assembler::QuietNaN(HeapObject* object) { 3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapNumber::cast(object)->set_value(std::numeric_limits<double>::quiet_NaN()); 3233db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch} 3234db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch 3235db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch 3236589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// On Mips, a target address is stored in a lui/ori instruction pair, each 3237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// of which load 16 bits of the 32-bit address to a register. 3238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Patching the address must replace both instr, and flush the i-cache. 32393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// On r6, target address is stored in a lui/jic pair, and both instr have to be 32403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// patched. 3241589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// 3242589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// There is an optimization below, which emits a nop when the address 3243589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// fits in just 16 bits. This is unlikely to help, and should be benchmarked, 3244589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// and possibly removed. 3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, 3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address target, 3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 32483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr2 = instr_at(pc + kInstrSize); 3249589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t rt_code = GetRtField(instr2); 3250589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t* p = reinterpret_cast<uint32_t*>(pc); 3251589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t itarget = reinterpret_cast<uint32_t>(target); 3252589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 32533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#ifdef DEBUG 3254589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Check we have the result from a li macro-instruction, using instr pair. 32553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr1 = instr_at(pc); 32563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK(IsLui(instr1) && (IsOri(instr2) || IsJicOrJialc(instr2))); 32573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#endif 32583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 32593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsJicOrJialc(instr2)) { 32603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Must use 2 instructions to insure patchable code => use lui and jic 32613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t lui_offset, jic_offset; 32623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Assembler::UnpackTargetAddressUnsigned(itarget, lui_offset, jic_offset); 32633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 32643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *p &= ~kImm16Mask; 32653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *(p + 1) &= ~kImm16Mask; 32663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 32673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *p |= lui_offset; 32683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *(p + 1) |= jic_offset; 32693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 32703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 32713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Must use 2 instructions to insure patchable code => just use lui and ori. 32723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // lui rt, upper-16. 32733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // ori rt rt, lower-16. 32743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *p = LUI | rt_code | ((itarget & kHiMask) >> kLuiShift); 32753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *(p + 1) = ORI | rt_code | (rt_code << 5) | (itarget & kImm16Mask); 32763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3277589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate, pc, 2 * sizeof(int32_t)); 3280589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 3281589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 32823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 32853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3286f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif // V8_TARGET_ARCH_MIPS 3287