1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright (c) 1994-2006 Sun Microsystems Inc. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All Rights Reserved. 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met: 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistributions of source code must retain the above copyright notice, 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this list of conditions and the following disclaimer. 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistribution in binary form must reproduce the above copyright 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer in the 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// documentation and/or other materials provided with the distribution. 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Neither the name of Sun Microsystems or the names of contributors may 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// be used to endorse or promote products derived from this software without 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// specific prior written permission. 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The original source code covered by the above license above has been 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modified significantly by Google Inc. 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_MIPS_ASSEMBLER_MIPS_H_ 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_MIPS_ASSEMBLER_MIPS_H_ 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdio.h> 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <set> 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h" 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/constants-mips64.h" 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// clang-format off 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \ 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(zero_reg) V(at) V(v0) V(v1) V(a0) V(a1) V(a2) V(a3) \ 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(a4) V(a5) V(a6) V(a7) V(t0) V(t1) V(t2) V(t3) \ 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) V(t8) V(t9) \ 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(k0) V(k1) V(gp) V(sp) V(fp) V(ra) 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(v0) V(v1) V(a0) V(a1) V(a2) V(a3) \ 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(a4) V(a5) V(a6) V(a7) V(t0) V(t1) V(t2) V(s7) 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \ 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(f0) V(f1) V(f2) V(f3) V(f4) V(f5) V(f6) V(f7) \ 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(f8) V(f9) V(f10) V(f11) V(f12) V(f13) V(f14) V(f15) \ 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(f16) V(f17) V(f18) V(f19) V(f20) V(f21) V(f22) V(f23) \ 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31) 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(f0) V(f2) V(f4) V(f6) V(f8) V(f10) V(f12) V(f14) \ 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(f16) V(f18) V(f20) V(f22) V(f24) V(f26) 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// clang-format on 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CPU Registers. 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 1) We would prefer to use an enum, but enum values are assignment- 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// compatible with int, which has caused code-generation bugs. 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 2) We would prefer to use a class instead of a struct but we don't like 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the register initialization to depend on the particular initialization 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// order (which appears to be different on OS X, Linux, and Windows for the 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// installed versions of C++ we tried). Using a struct permits C-style 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "initialization". Also, the Register objects cannot be const as this 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// forces initialization stubs in MSVC, making us dependent on initialization 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// order. 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3) By not using an enum, we are possibly preventing the compiler from 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// doing certain constant folds, which may significantly reduce the 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code generated for some assembly instructions (because they boil down 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to a few constants). If this is a problem, we could change the code 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// such that we use an enum in optimized mode, and the struct in debug 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// mode. This way we get the compile-time error checking in debug mode 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and best performance in optimized code. 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of Register and FPURegister. 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct Register { 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCpRegister = 23; // cp (s7) is the 23rd register. 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if defined(V8_TARGET_LITTLE_ENDIAN) 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMantissaOffset = 0; 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kExponentOffset = 4; 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#elif defined(V8_TARGET_BIG_ENDIAN) 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMantissaOffset = 4; 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kExponentOffset = 0; 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#error Unknown endianness 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GENERAL_REGISTERS(REGISTER_CODE) 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumRegisters = Code::kAfterLast; 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Register from_code(int code) { 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code >= 0); 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code < kNumRegisters); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register r = { code }; 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return r; 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* ToString(); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsAllocatable() const; 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(Register reg) const { return reg_code == reg.reg_code; } 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int code() const { 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bit() const { 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unfortunately we can't make this private in a struct. 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// s7: context register 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// s3: lithium scratch 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// s4: lithium scratch2 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER) 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg}; 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ToNumber(Register reg); 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister ToRegister(int num); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Coprocessor register. 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct DoubleRegister { 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DOUBLE_REGISTERS(REGISTER_CODE) 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxNumRegisters = Code::kAfterLast; 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline static int NumRegisters(); 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // number of Double regs (64-bit regs, or FPU-reg-pairs). 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* ToString(); 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsAllocatable() const; 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister low() const { 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(plind): Create DCHECK for FR=0 mode. This usage suspect for FR=1. 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find low reg of a Double-reg pair, which is the reg itself. 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(reg_code % 2 == 0); // Specified Double reg must be even. 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg; 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg.reg_code = reg_code; 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reg.is_valid()); 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reg; 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister high() const { 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(plind): Create DCHECK for FR=0 mode. This usage illegal in FR=1. 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find high reg of a Doubel-reg pair, which is reg + 1. 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(reg_code % 2 == 0); // Specified Double reg must be even. 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg; 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg.reg_code = reg_code + 1; 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reg.is_valid()); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reg; 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int code() const { 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bit() const { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static DoubleRegister from_code(int code) { 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister r = {code}; 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return r; 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void setcode(int f) { 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg_code = f; 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unfortunately we can't make this private in a struct. 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// A few double registers are reserved: one as a scratch register and one to 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// hold 0.0. 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// f28: 0.0 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// f30: scratch register. 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// V8 now supports the O32 ABI, and the FPU Registers are organized as 32 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 32-bit registers, f0 through f31. When used as 'double' they are used 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// in pairs, starting with the even numbered register. So a double operation 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// on f0 really uses f0 and f1. 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (Modern mips hardware also supports 32 64-bit registers, via setting 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (privileged) Status Register FR bit to 1. This is used by the N32 ABI, 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// but it is not in common use. Someday we will want to support this in v8.) 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef DoubleRegister FPURegister; 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef DoubleRegister FloatRegister; 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister no_freg = {-1}; 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f0 = {0}; // Return value in hard float mode. 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f1 = {1}; 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f2 = {2}; 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f3 = {3}; 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f4 = {4}; 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f5 = {5}; 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f6 = {6}; 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f7 = {7}; 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f8 = {8}; 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f9 = {9}; 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f10 = {10}; 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f11 = {11}; 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f12 = {12}; // Arg 0 in hard float mode. 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f13 = {13}; 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f14 = {14}; // Arg 1 in hard float mode. 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f15 = {15}; 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f16 = {16}; 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f17 = {17}; 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f18 = {18}; 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f19 = {19}; 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f20 = {20}; 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f21 = {21}; 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f22 = {22}; 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f23 = {23}; 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f24 = {24}; 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f25 = {25}; 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f26 = {26}; 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f27 = {27}; 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f28 = {28}; 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f29 = {29}; 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f30 = {30}; 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister f31 = {31}; 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Register aliases. 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// cp is assumed to be a callee saved register. 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Defined using #define instead of "static const Register&" because Clang 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// complains otherwise when a compilation unit that includes this header 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// doesn't use the variables. 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kRootRegister s6 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define cp s7 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kLithiumScratchReg s3 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kLithiumScratchReg2 s4 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kLithiumScratchDouble f30 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kDoubleRegZero f28 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Used on mips64r6 for compare operations. 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// We use the last non-callee saved odd register for N64 ABI 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define kDoubleCompareReg f23 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// FPU (coprocessor 1) control registers. 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Currently only FCSR (#31) is implemented. 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct FPUControlRegister { 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return reg_code == kFCSRRegister; } 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; } 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int code() const { 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bit() const { 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void setcode(int f) { 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg_code = f; 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unfortunately we can't make this private in a struct. 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPUControlRegister FCSR = { kFCSRRegister }; 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Machine instruction Operands. 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int kSmiShift = kSmiTagSize + kSmiShiftSize; 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Class Operand represents a shifter operand in data processing instructions. 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Operand BASE_EMBEDDED { 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Immediate. 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(int64_t immediate, 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::NONE64)); 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(const ExternalReference& f)); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(const char* s)); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Object** opp)); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Context** cpp)); 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Operand(Handle<Object> handle); 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Smi* value)); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register. 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Register rm)); 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return true if this is a register operand. 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(bool is_reg() const); 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline int64_t immediate() const { 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!is_reg()); 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return imm64_; 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rm() const { return rm_; } 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rm_; 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t imm64_; // Valid if rm_ == no_reg. 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode_; 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Assembler; 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MacroAssembler; 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// On MIPS we have only one adressing mode with base_reg + offset. 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Class MemOperand represents a memory operand in load and store instructions. 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MemOperand : public Operand { 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Immediate value attached to offset. 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum OffsetAddend { 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset_minus_one = -1, 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset_zero = 0 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit MemOperand(Register rn, int32_t offset = 0); 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit MemOperand(Register rn, int32_t unit, int32_t multiplier, 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OffsetAddend offset_addend = offset_zero); 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t offset() const { return offset_; } 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool OffsetIsInt16Encodable() const { 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_int16(offset_); 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t offset_; 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Assembler; 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Assembler : public AssemblerBase { 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an assembler. Instructions and relocation information are emitted 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // into a buffer, with the instructions starting from the beginning and the 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relocation information starting from the end of the buffer. See CodeDesc 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for a detailed comment on the layout (globals.h). 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the provided buffer is NULL, the assembler allocates and grows its own 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // buffer, and buffer_size determines the initial buffer size. The buffer is 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // owned by the assembler and deallocated upon destruction of the assembler. 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the provided buffer is not NULL, the assembler uses the provided buffer 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for code generation and assumes its size to be buffer_size. If the buffer 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is too small, a fatal error occurs. No deallocation of the buffer is done 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // upon destruction of the assembler. 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler(Isolate* isolate, void* buffer, int buffer_size); 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~Assembler() { } 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // GetCode emits any pending (non-emitted) code and fills the descriptor 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // desc. GetCode() is idempotent; it returns the same result if no other 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assembler functions are invoked in between GetCode() calls. 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GetCode(CodeDesc* desc); 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Label operations & relative jumps (PPUM Appendix D). 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Takes a branch opcode (cc) and a label (L) and generates 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // either a backward branch or a forward branch and links it 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the label fixup chain. Usage: 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Label L; // unbound label 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // j(cc, &L); // forward branch to unbound label 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bind(&L); // bind label to the current pc 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // j(cc, &L); // backward branch to bound label 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bind(&L); // illegal: a label may be bound only once 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note: The same Label can be used for forward and backward branches 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // but it may be bound only once. 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bind(Label* L); // Binds an unbound label L to current code position. 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum OffsetSize : int { kOffset26 = 26, kOffset21 = 21, kOffset16 = 16 }; 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determines if Label is bound and near enough so that branch instruction 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // can be used to reach it, instead of jump instruction. 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_near(Label* L); 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_near(Label* L, OffsetSize bits); 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_near_branch(Label* L); 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline bool is_near_pre_r6(Label* L) { 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!(kArchVariant == kMips64r6)); 424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize; 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline bool is_near_r6(Label* L) { 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(kArchVariant == kMips64r6); 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pc_offset() - L->pos() < kMaxCompactBranchOffset - 4 * kInstrSize; 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int BranchOffset(Instr instr); 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns the branch offset to the given label from the current code 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position. Links the label to the current position if it is still unbound. 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Manages the jump elimination optimization if the second parameter is true. 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t branch_offset_helper(Label* L, OffsetSize bits); 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline int32_t branch_offset(Label* L) { 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return branch_offset_helper(L, OffsetSize::kOffset16); 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline int32_t branch_offset21(Label* L) { 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return branch_offset_helper(L, OffsetSize::kOffset21); 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline int32_t branch_offset26(Label* L) { 444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return branch_offset_helper(L, OffsetSize::kOffset26); 445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline int32_t shifted_branch_offset(Label* L) { 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return branch_offset(L) >> 2; 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline int32_t shifted_branch_offset21(Label* L) { 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return branch_offset21(L) >> 2; 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline int32_t shifted_branch_offset26(Label* L) { 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return branch_offset26(L) >> 2; 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t jump_address(Label* L); 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t jump_offset(Label* L); 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Puts a labels target address at the given position. 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The high 8 bits are set to zero. 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void label_at_put(Label* L, int at_offset); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Read/Modify the code target address in the branch/call instruction at pc. 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Address target_address_at(Address pc); 464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void set_target_address_at( 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On MIPS there is no Constant Pool so we skip that parameter. 468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static Address target_address_at(Address pc, Address constant_pool)) { 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return target_address_at(pc); 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void set_target_address_at( 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address constant_pool, Address target, 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, pc, target, icache_flush_mode); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static Address target_address_at(Address pc, Code* code)) { 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return target_address_at(pc, constant_pool); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static void set_target_address_at( 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Code* code, Address target, 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, pc, constant_pool, target, 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch icache_flush_mode); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the code target address at a call site from the return address 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of that call in the instruction stream. 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline static Address target_address_from_return_address(Address pc); 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void JumpLabelToJumpRegister(Address pc); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void QuietNaN(HeapObject* nan); 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This sets the branch destination (which gets loaded at the call address). 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for calls and branches within generated code. The serializer 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // has already deserialized the lui/ori instructions etc. 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline static void deserialization_set_special_target_at( 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address instruction_payload, Code* code, 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target) { 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_target_address_at( 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate, 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instruction_payload - kInstructionsFor64BitConstant * kInstrSize, code, 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This sets the internal reference at the pc. 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void deserialization_set_target_internal_reference_at( 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of an instruction. 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kInstrSize = sizeof(Instr); 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Difference between address of current opcode and target address offset. 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kBranchPCOffset = 4; 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Here we are patching the address in the LUI/ORI instruction pair. 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // These values are used in the serialization process and must be zero for 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MIPS platform, as Code, Embedded Object or External-reference pointers 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // are split across two consecutive instructions and don't exist separately 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in the code, so the serializer should not step forwards in memory after 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a target is resolved and written. 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kSpecialTargetSize = 0; 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of consecutive instructions used to store 32bit/64bit constant. 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This constant was used in RelocInfo::target_address_address() function 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to tell serializer address of the instruction that follows 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // LUI/ORI instruction pair. 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kInstructionsFor32BitConstant = 2; 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kInstructionsFor64BitConstant = 4; 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Distance between the instruction referring to the address of the call 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // target and the return address. 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCallTargetAddressOffset = 6 * kInstrSize; 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Distance between start of patched debug break slot and the emitted address 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to jump to. 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kPatchDebugBreakSlotAddressOffset = 6 * kInstrSize; 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Difference between address of current opcode and value read from pc 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // register. 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kPcLoadDelta = 4; 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kDebugBreakSlotInstructions = 6; 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kDebugBreakSlotLength = 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kDebugBreakSlotInstructions * kInstrSize; 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code generation. 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Insert the smallest number of nop instructions 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // possible to align the pc offset to a multiple 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of m. m must be a power of 2 (>= 4). 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Align(int m); 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert the smallest number of zero bytes possible to align the pc offset 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a mulitple of m. m must be a power of 2 (>= 2). 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DataAlign(int m); 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Aligns code to something that's optimal for a jump target for the platform. 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CodeTargetAlign(); 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Different nop operations are used by the code generator to detect certain 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // states of the generated code. 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum NopMarkerTypes { 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NON_MARKING_NOP = 0, 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEBUG_BREAK_NOP, 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // IC markers. 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROPERTY_ACCESS_INLINED, 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROPERTY_ACCESS_INLINED_CONTEXT, 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE, 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Helper values. 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LAST_CODE_MARKER, 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED, 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code aging 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CODE_AGE_MARKER_NOP = 6, 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CODE_AGE_SEQUENCE_NOP 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Type == 0 is the default non-marking nop. For mips this is a 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sll(zero_reg, zero_reg, 0). We use rt_reg == at for non-zero 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // marking, to avoid conflict with ssnop and ehb instructions. 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void nop(unsigned int type = 0) { 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(type < 32); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register nop_rt_reg = (type == 0) ? zero_reg : at; 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sll(zero_reg, nop_rt_reg, type, true); 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------Branch-and-jump-instructions---------- 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We don't use likely variant of instructions. 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void b(int16_t offset); 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void b(Label* L) { b(shifted_branch_offset(L)); } 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bal(int16_t offset); 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bal(Label* L) { bal(shifted_branch_offset(L)); } 597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bc(int32_t offset); 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bc(Label* L) { bc(shifted_branch_offset26(L)); } 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void balc(int32_t offset); 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void balc(Label* L) { balc(shifted_branch_offset26(L)); } 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void beq(Register rs, Register rt, int16_t offset); 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void beq(Register rs, Register rt, Label* L) { 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch beq(rs, rt, shifted_branch_offset(L)); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgez(Register rs, int16_t offset); 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgezc(Register rt, int16_t offset); 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bgezc(Register rt, Label* L) { 609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bgezc(rt, shifted_branch_offset(L)); 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgeuc(Register rs, Register rt, int16_t offset); 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bgeuc(Register rs, Register rt, Label* L) { 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bgeuc(rs, rt, shifted_branch_offset(L)); 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgec(Register rs, Register rt, int16_t offset); 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bgec(Register rs, Register rt, Label* L) { 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bgec(rs, rt, shifted_branch_offset(L)); 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgezal(Register rs, int16_t offset); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgezalc(Register rt, int16_t offset); 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bgezalc(Register rt, Label* L) { 622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bgezalc(rt, shifted_branch_offset(L)); 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgezall(Register rs, int16_t offset); 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bgezall(Register rs, Label* L) { 626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bgezall(rs, branch_offset(L) >> 2); 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgtz(Register rs, int16_t offset); 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgtzc(Register rt, int16_t offset); 630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bgtzc(Register rt, Label* L) { 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bgtzc(rt, shifted_branch_offset(L)); 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void blez(Register rs, int16_t offset); 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void blezc(Register rt, int16_t offset); 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void blezc(Register rt, Label* L) { 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch blezc(rt, shifted_branch_offset(L)); 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bltz(Register rs, int16_t offset); 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bltzc(Register rt, int16_t offset); 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bltzc(Register rt, Label* L) { 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bltzc(rt, shifted_branch_offset(L)); 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bltuc(Register rs, Register rt, int16_t offset); 644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bltuc(Register rs, Register rt, Label* L) { 645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bltuc(rs, rt, shifted_branch_offset(L)); 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bltc(Register rs, Register rt, int16_t offset); 648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bltc(Register rs, Register rt, Label* L) { 649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bltc(rs, rt, shifted_branch_offset(L)); 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bltzal(Register rs, int16_t offset); 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void blezalc(Register rt, int16_t offset); 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void blezalc(Register rt, Label* L) { 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch blezalc(rt, shifted_branch_offset(L)); 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bltzalc(Register rt, int16_t offset); 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bltzalc(Register rt, Label* L) { 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bltzalc(rt, shifted_branch_offset(L)); 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bgtzalc(Register rt, int16_t offset); 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bgtzalc(Register rt, Label* L) { 662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bgtzalc(rt, shifted_branch_offset(L)); 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void beqzalc(Register rt, int16_t offset); 665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void beqzalc(Register rt, Label* L) { 666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch beqzalc(rt, shifted_branch_offset(L)); 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void beqc(Register rs, Register rt, int16_t offset); 669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void beqc(Register rs, Register rt, Label* L) { 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch beqc(rs, rt, shifted_branch_offset(L)); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void beqzc(Register rs, int32_t offset); 673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void beqzc(Register rs, Label* L) { 674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch beqzc(rs, shifted_branch_offset21(L)); 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bnezalc(Register rt, int16_t offset); 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bnezalc(Register rt, Label* L) { 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bnezalc(rt, shifted_branch_offset(L)); 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bnec(Register rs, Register rt, int16_t offset); 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bnec(Register rs, Register rt, Label* L) { 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bnec(rs, rt, shifted_branch_offset(L)); 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bnezc(Register rt, int32_t offset); 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bnezc(Register rt, Label* L) { 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bnezc(rt, shifted_branch_offset21(L)); 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bne(Register rs, Register rt, int16_t offset); 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bne(Register rs, Register rt, Label* L) { 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bne(rs, rt, shifted_branch_offset(L)); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bovc(Register rs, Register rt, int16_t offset); 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bovc(Register rs, Register rt, Label* L) { 694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bovc(rs, rt, shifted_branch_offset(L)); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bnvc(Register rs, Register rt, int16_t offset); 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bnvc(Register rs, Register rt, Label* L) { 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bnvc(rs, rt, shifted_branch_offset(L)); 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Never use the int16_t b(l)cond version with a branch offset 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instead of using the Label* version. 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits. 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void j(int64_t target); 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jal(int64_t target); 707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void j(Label* target); 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void jal(Label* target); 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jalr(Register rs, Register rd = ra); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jr(Register target); 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void jic(Register rt, int16_t offset); 712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void jialc(Register rt, int16_t offset); 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -------Data-processing-instructions--------- 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arithmetic. 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addu(Register rd, Register rs, Register rt); 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subu(Register rd, Register rs, Register rt); 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void div(Register rs, Register rt); 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divu(Register rs, Register rt); 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ddiv(Register rs, Register rt); 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ddivu(Register rs, Register rt); 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void div(Register rd, Register rs, Register rt); 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divu(Register rd, Register rs, Register rt); 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ddiv(Register rd, Register rs, Register rt); 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ddivu(Register rd, Register rs, Register rt); 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mod(Register rd, Register rs, Register rt); 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void modu(Register rd, Register rs, Register rt); 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmod(Register rd, Register rs, Register rt); 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmodu(Register rd, Register rs, Register rt); 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mul(Register rd, Register rs, Register rt); 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void muh(Register rd, Register rs, Register rt); 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulu(Register rd, Register rs, Register rt); 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void muhu(Register rd, Register rs, Register rt); 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mult(Register rs, Register rt); 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void multu(Register rs, Register rt); 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmul(Register rd, Register rs, Register rt); 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmuh(Register rd, Register rs, Register rt); 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmulu(Register rd, Register rs, Register rt); 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmuhu(Register rd, Register rs, Register rt); 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void daddu(Register rd, Register rs, Register rt); 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsubu(Register rd, Register rs, Register rt); 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmult(Register rs, Register rt); 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmultu(Register rs, Register rt); 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addiu(Register rd, Register rs, int32_t j); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void daddiu(Register rd, Register rs, int32_t j); 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Logical. 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void and_(Register rd, Register rs, Register rt); 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void or_(Register rd, Register rs, Register rt); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xor_(Register rd, Register rs, Register rt); 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void nor(Register rd, Register rs, Register rt); 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void andi(Register rd, Register rs, int32_t j); 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ori(Register rd, Register rs, int32_t j); 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xori(Register rd, Register rs, int32_t j); 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lui(Register rd, int32_t j); 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void aui(Register rt, Register rs, int32_t j); 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void daui(Register rt, Register rs, int32_t j); 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dahi(Register rs, int32_t j); 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dati(Register rs, int32_t j); 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shifts. 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and may cause problems in normal code. coming_from_nop makes sure this 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // doesn't happen. 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false); 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sllv(Register rd, Register rt, Register rs); 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void srl(Register rd, Register rt, uint16_t sa); 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void srlv(Register rd, Register rt, Register rs); 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sra(Register rt, Register rd, uint16_t sa); 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void srav(Register rt, Register rd, Register rs); 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void rotr(Register rd, Register rt, uint16_t sa); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void rotrv(Register rd, Register rt, Register rs); 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsll(Register rd, Register rt, uint16_t sa); 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsllv(Register rd, Register rt, Register rs); 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsrl(Register rd, Register rt, uint16_t sa); 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsrlv(Register rd, Register rt, Register rs); 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void drotr(Register rd, Register rt, uint16_t sa); 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void drotrv(Register rd, Register rt, Register rs); 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsra(Register rt, Register rd, uint16_t sa); 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsrav(Register rd, Register rt, Register rs); 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsll32(Register rt, Register rd, uint16_t sa); 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsrl32(Register rt, Register rd, uint16_t sa); 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dsra32(Register rt, Register rd, uint16_t sa); 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Address computing instructions with shift. 792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lsa(Register rd, Register rt, Register rs, uint8_t sa); 793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dlsa(Register rd, Register rt, Register rs, uint8_t sa); 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------Memory-instructions------------- 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lb(Register rd, const MemOperand& rs); 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lbu(Register rd, const MemOperand& rs); 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lh(Register rd, const MemOperand& rs); 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lhu(Register rd, const MemOperand& rs); 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lw(Register rd, const MemOperand& rs); 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lwu(Register rd, const MemOperand& rs); 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lwl(Register rd, const MemOperand& rs); 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lwr(Register rd, const MemOperand& rs); 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sb(Register rd, const MemOperand& rs); 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sh(Register rd, const MemOperand& rs); 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sw(Register rd, const MemOperand& rs); 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void swl(Register rd, const MemOperand& rs); 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void swr(Register rd, const MemOperand& rs); 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ldl(Register rd, const MemOperand& rs); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ldr(Register rd, const MemOperand& rs); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sdl(Register rd, const MemOperand& rs); 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sdr(Register rd, const MemOperand& rs); 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ld(Register rd, const MemOperand& rs); 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sd(Register rd, const MemOperand& rs); 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // ---------PC-Relative-instructions----------- 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void addiupc(Register rs, int32_t imm19); 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lwpc(Register rs, int32_t offset19); 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lwupc(Register rs, int32_t offset19); 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ldpc(Register rs, int32_t offset18); 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void auipc(Register rs, int16_t imm16); 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void aluipc(Register rs, int16_t imm16); 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------Prefetch-------------------- 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pref(int32_t hint, const MemOperand& rs); 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -------------Misc-instructions-------------- 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Break / Trap instructions. 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void break_(uint32_t code, bool break_as_stop = false); 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void stop(const char* msg, uint32_t code = kMaxStopCode); 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void tge(Register rs, Register rt, uint16_t code); 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void tgeu(Register rs, Register rt, uint16_t code); 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void tlt(Register rs, Register rt, uint16_t code); 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void tltu(Register rs, Register rt, uint16_t code); 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void teq(Register rs, Register rt, uint16_t code); 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void tne(Register rs, Register rt, uint16_t code); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move from HI/LO register. 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mfhi(Register rd); 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mflo(Register rd); 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set on less than. 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void slt(Register rd, Register rs, Register rt); 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sltu(Register rd, Register rs, Register rt); 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void slti(Register rd, Register rs, int32_t j); 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sltiu(Register rd, Register rs, int32_t j); 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Conditional move. 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movz(Register rd, Register rs, Register rt); 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movn(Register rd, Register rs, Register rt); 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movt(Register rd, Register rs, uint16_t cc = 0); 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movf(Register rd, Register rs, uint16_t cc = 0); 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sel(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft); 862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sel_s(FPURegister fd, FPURegister fs, FPURegister ft); 863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sel_d(FPURegister fd, FPURegister fs, FPURegister ft); 864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void seleqz(Register rd, Register rs, Register rt); 865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs, 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft); 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void selnez(Register rs, Register rt, Register rd); 868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void selnez(SecondaryField fmt, FPURegister fd, FPURegister fs, 869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister ft); 870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft); 871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft); 872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void selnez_d(FPURegister fd, FPURegister fs, FPURegister ft); 873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void selnez_s(FPURegister fd, FPURegister fs, FPURegister ft); 874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movz_s(FPURegister fd, FPURegister fs, Register rt); 876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movz_d(FPURegister fd, FPURegister fs, Register rt); 877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movt_s(FPURegister fd, FPURegister fs, uint16_t cc = 0); 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movt_d(FPURegister fd, FPURegister fs, uint16_t cc = 0); 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movf_s(FPURegister fd, FPURegister fs, uint16_t cc = 0); 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movf_d(FPURegister fd, FPURegister fs, uint16_t cc = 0); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movn_s(FPURegister fd, FPURegister fs, Register rt); 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movn_d(FPURegister fd, FPURegister fs, Register rt); 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bit twiddling. 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void clz(Register rd, Register rs); 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dclz(Register rd, Register rs); 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ins_(Register rt, Register rs, uint16_t pos, uint16_t size); 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ext_(Register rt, Register rs, uint16_t pos, uint16_t size); 888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void dext_(Register rt, Register rs, uint16_t pos, uint16_t size); 889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dextm(Register rt, Register rs, uint16_t pos, uint16_t size); 890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dextu(Register rt, Register rs, uint16_t pos, uint16_t size); 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dins_(Register rt, Register rs, uint16_t pos, uint16_t size); 892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bitswap(Register rd, Register rt); 893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dbitswap(Register rd, Register rt); 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void align(Register rd, Register rs, Register rt, uint8_t bp); 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dalign(Register rd, Register rs, Register rt, uint8_t bp); 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------Coprocessor-instructions---------------- 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load, store, and move. 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lwc1(FPURegister fd, const MemOperand& src); 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ldc1(FPURegister fd, const MemOperand& src); 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void swc1(FPURegister fs, const MemOperand& dst); 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sdc1(FPURegister fs, const MemOperand& dst); 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mtc1(Register rt, FPURegister fs); 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mthc1(Register rt, FPURegister fs); 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmtc1(Register rt, FPURegister fs); 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mfc1(Register rt, FPURegister fs); 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mfhc1(Register rt, FPURegister fs); 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dmfc1(Register rt, FPURegister fs); 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ctc1(Register rt, FPUControlRegister fs); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cfc1(Register rt, FPUControlRegister fs); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arithmetic. 918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void add_s(FPURegister fd, FPURegister fs, FPURegister ft); 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void add_d(FPURegister fd, FPURegister fs, FPURegister ft); 920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sub_s(FPURegister fd, FPURegister fs, FPURegister ft); 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sub_d(FPURegister fd, FPURegister fs, FPURegister ft); 922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mul_s(FPURegister fd, FPURegister fs, FPURegister ft); 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mul_d(FPURegister fd, FPURegister fs, FPURegister ft); 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft); 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void div_s(FPURegister fd, FPURegister fs, FPURegister ft); 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void div_d(FPURegister fd, FPURegister fs, FPURegister ft); 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void abs_s(FPURegister fd, FPURegister fs); 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void abs_d(FPURegister fd, FPURegister fs); 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_d(FPURegister fd, FPURegister fs); 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mov_s(FPURegister fd, FPURegister fs); 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void neg_s(FPURegister fd, FPURegister fs); 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void neg_d(FPURegister fd, FPURegister fs); 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sqrt_s(FPURegister fd, FPURegister fs); 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sqrt_d(FPURegister fd, FPURegister fs); 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rsqrt_s(FPURegister fd, FPURegister fs); 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rsqrt_d(FPURegister fd, FPURegister fs); 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void recip_d(FPURegister fd, FPURegister fs); 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void recip_s(FPURegister fd, FPURegister fs); 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Conversion. 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_w_s(FPURegister fd, FPURegister fs); 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_w_d(FPURegister fd, FPURegister fs); 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void trunc_w_s(FPURegister fd, FPURegister fs); 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void trunc_w_d(FPURegister fd, FPURegister fs); 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void round_w_s(FPURegister fd, FPURegister fs); 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void round_w_d(FPURegister fd, FPURegister fs); 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void floor_w_s(FPURegister fd, FPURegister fs); 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void floor_w_d(FPURegister fd, FPURegister fs); 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ceil_w_s(FPURegister fd, FPURegister fs); 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ceil_w_d(FPURegister fd, FPURegister fs); 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rint_s(FPURegister fd, FPURegister fs); 952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rint_d(FPURegister fd, FPURegister fs); 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rint(SecondaryField fmt, FPURegister fd, FPURegister fs); 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_l_s(FPURegister fd, FPURegister fs); 957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_l_d(FPURegister fd, FPURegister fs); 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void trunc_l_s(FPURegister fd, FPURegister fs); 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void trunc_l_d(FPURegister fd, FPURegister fs); 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void round_l_s(FPURegister fd, FPURegister fs); 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void round_l_d(FPURegister fd, FPURegister fs); 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void floor_l_s(FPURegister fd, FPURegister fs); 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void floor_l_d(FPURegister fd, FPURegister fs); 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ceil_l_s(FPURegister fd, FPURegister fs); 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ceil_l_d(FPURegister fd, FPURegister fs); 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void class_s(FPURegister fd, FPURegister fs); 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void class_d(FPURegister fd, FPURegister fs); 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void min(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft); 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mina(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft); 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void max(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft); 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxa(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft); 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void min_s(FPURegister fd, FPURegister fs, FPURegister ft); 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void min_d(FPURegister fd, FPURegister fs, FPURegister ft); 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void max_s(FPURegister fd, FPURegister fs, FPURegister ft); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void max_d(FPURegister fd, FPURegister fs, FPURegister ft); 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mina_s(FPURegister fd, FPURegister fs, FPURegister ft); 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mina_d(FPURegister fd, FPURegister fs, FPURegister ft); 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxa_s(FPURegister fd, FPURegister fs, FPURegister ft); 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxa_d(FPURegister fd, FPURegister fs, FPURegister ft); 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_s_w(FPURegister fd, FPURegister fs); 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_s_l(FPURegister fd, FPURegister fs); 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_s_d(FPURegister fd, FPURegister fs); 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_d_w(FPURegister fd, FPURegister fs); 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_d_l(FPURegister fd, FPURegister fs); 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvt_d_s(FPURegister fd, FPURegister fs); 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Conditions and branches for MIPSr6. 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(FPUCondition cond, SecondaryField fmt, 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fd, FPURegister ft, FPURegister fs); 994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft); 995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft); 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bc1eqz(int16_t offset, FPURegister ft); 998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bc1eqz(Label* L, FPURegister ft) { 999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bc1eqz(shifted_branch_offset(L), ft); 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bc1nez(int16_t offset, FPURegister ft); 1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bc1nez(Label* L, FPURegister ft) { 1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bc1nez(shifted_branch_offset(L), ft); 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Conditions and branches for non MIPSr6. 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void c(FPUCondition cond, SecondaryField fmt, 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister ft, FPURegister fs, uint16_t cc = 0); 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void c_s(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0); 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void c_d(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0); 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bc1f(int16_t offset, uint16_t cc = 0); 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bc1f(Label* L, uint16_t cc = 0) { 1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bc1f(shifted_branch_offset(L), cc); 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bc1t(int16_t offset, uint16_t cc = 0); 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void bc1t(Label* L, uint16_t cc = 0) { 1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bc1t(shifted_branch_offset(L), cc); 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fcmp(FPURegister src1, const double src2, FPUCondition cond); 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the code size generated from label to here. 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int SizeOfCodeGeneratedSince(Label* label) { 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pc_offset() - label->pos(); 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the number of instructions generated from label to here. 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int InstructionsGeneratedSince(Label* label) { 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SizeOfCodeGeneratedSince(label) / kInstrSize; 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Class for scoping postponing the trampoline pool generation. 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class BlockTrampolinePoolScope { 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) { 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assem_->StartBlockTrampolinePool(); 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~BlockTrampolinePoolScope() { 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assem_->EndBlockTrampolinePool(); 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler* assem_; 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Class for postponing the assembly buffer growth. Typically used for 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sequences of instructions that must be emitted as a unit, before 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // buffer growth (and relocation) can occur. 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This blocking scope is not nestable. 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class BlockGrowBufferScope { 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) { 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assem_->StartBlockGrowBuffer(); 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~BlockGrowBufferScope() { 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assem_->EndBlockGrowBuffer(); 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler* assem_; 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Debugging. 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark generator continuation. 1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordGeneratorContinuation(); 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark address of a debug break slot. 1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordDebugBreakSlot(RelocInfo::Mode mode); 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Record the AST id of the CallIC being compiled, so that it can be placed 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in the relocation information. 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetRecordedAstId(TypeFeedbackId ast_id) { 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(recorded_ast_id_.IsNone()); 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch recorded_ast_id_ = ast_id; 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId RecordedAstId() { 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!recorded_ast_id_.IsNone()); 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return recorded_ast_id_; 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); } 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Record a comment relocation entry that can be used by a disassembler. 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use --code-comments to enable. 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordComment(const char* msg); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Record a deoptimization reason that can be used by a log or cpu profiler. 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --trace-deopt to enable. 1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordDeoptReason(const int reason, const SourcePosition position); 1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int RelocateInternalReference(RelocInfo::Mode rmode, byte* pc, 1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t pc_delta); 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Writes a single byte or word of data in the code stream. Used for 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inline tables, e.g., jump-tables. 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void db(uint8_t data); 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dd(uint32_t data); 1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(uint64_t data); 1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dp(uintptr_t data) { dq(data); } 1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dd(Label* label); 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PositionsRecorder* positions_recorder() { return &positions_recorder_; } 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Postpone the generation of the trampoline pool for the specified number of 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instructions. 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BlockTrampolinePoolFor(int instructions); 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if there is less than kGap bytes available in the buffer. 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If this is the case, we need to grow the buffer before emitting 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an instruction or relocation information. 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; } 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the number of bytes available in the buffer. 1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline intptr_t available_space() const { 1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reloc_info_writer.pos() - pc_; 1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Read/patch instructions. 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void instr_at_put(byte* pc, Instr instr) { 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reinterpret_cast<Instr*>(pc) = instr; 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instr_at_put(int pos, Instr instr) { 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if an instruction is a branch of some kind. 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsBranch(Instr instr); 1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsBc(Instr instr); 1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsBzc(Instr instr); 1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsBeq(Instr instr); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsBne(Instr instr); 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsBeqzc(Instr instr); 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsBnezc(Instr instr); 1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsBeqc(Instr instr); 1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsBnec(Instr instr); 1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsJump(Instr instr); 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsJ(Instr instr); 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsLui(Instr instr); 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsOri(Instr instr); 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsJal(Instr instr); 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsJr(Instr instr); 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsJalr(Instr instr); 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsNop(Instr instr, unsigned int type); 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsPop(Instr instr); 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsPush(Instr instr); 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsLwRegFpOffset(Instr instr); 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsSwRegFpOffset(Instr instr); 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsLwRegFpNegOffset(Instr instr); 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsSwRegFpNegOffset(Instr instr); 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Register GetRtReg(Instr instr); 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Register GetRsReg(Instr instr); 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Register GetRdReg(Instr instr); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetRt(Instr instr); 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetRtField(Instr instr); 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetRs(Instr instr); 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetRsField(Instr instr); 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetRd(Instr instr); 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetRdField(Instr instr); 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetSa(Instr instr); 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetSaField(Instr instr); 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetOpcodeField(Instr instr); 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetFunction(Instr instr); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetFunctionField(Instr instr); 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetImmediate16(Instr instr); 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t GetLabelConst(Instr instr); 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int32_t GetBranchOffset(Instr instr); 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsLw(Instr instr); 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int16_t GetLwOffset(Instr instr); 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Instr SetLwOffset(Instr instr, int16_t offset); 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsSw(Instr instr); 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Instr SetSwOffset(Instr instr, int16_t offset); 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsAddImmediate(Instr instr); 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Instr SetAddImmediateOffset(Instr instr, int16_t offset); 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsAndImmediate(Instr instr); 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsEmittedConstant(Instr instr); 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckTrampolinePool(); 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access, 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No embedded constant pool support. 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; } 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Relocation for a type-recording IC has the AST id added to it. This 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // member variable is a way to pass the information from the call site to 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the relocation info. 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId recorded_ast_id_; 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void set_target_internal_reference_encoded_at(Address pc, 1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target); 1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; } 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Decode branch instruction at pos and return branch target pos. 1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int target_at(int pos, bool is_internal); 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Patch branch instruction at pos to branch to given branch target pos. 1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void target_at_put(int pos, int target_pos, bool is_internal); 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Say if we need to relocate with this mode. 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool MustUseReg(RelocInfo::Mode rmode); 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Record reloc info for current pc_. 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Block the emission of the trampoline pool before pc_offset. 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BlockTrampolinePoolBefore(int pc_offset) { 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (no_trampoline_pool_before_ < pc_offset) 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_trampoline_pool_before_ = pc_offset; 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StartBlockTrampolinePool() { 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trampoline_pool_blocked_nesting_++; 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndBlockTrampolinePool() { 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trampoline_pool_blocked_nesting_--; 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_trampoline_pool_blocked() const { 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return trampoline_pool_blocked_nesting_ > 0; 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_exception() const { 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return internal_trampoline_exception_; 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi); 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_trampoline_emitted() const { 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return trampoline_emitted_; 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Temporarily block automatic assembly buffer growth. 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StartBlockGrowBuffer() { 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!block_buffer_growth_); 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_buffer_growth_ = true; 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EndBlockGrowBuffer() { 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_buffer_growth_); 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_buffer_growth_ = false; 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_buffer_growth_blocked() const { 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return block_buffer_growth_; 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EmitForbiddenSlotInstruction() { 1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsPrevInstrCompactBranch()) { 1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nop(); 1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ClearCompactBranchState(); 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void CheckTrampolinePoolQuick(int extra_instructions = 0); 1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Buffer size and constant pool distance are checked together at regular 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // intervals of kBufferCheckInterval emitted bytes. 1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kBufferCheckInterval = 1*KB/2; 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code generation. 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The relocation writer's position is at least kGap bytes below the end of 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the generated instructions. This is so that multi-instruction sequences do 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not have to check for overflow. The same is true for writes of large 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relocation info entries. 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kGap = 32; 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Repeated checking whether the trampoline pool should be emitted is rather 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // expensive. By default we only check again once a number of instructions 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // has been generated. 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCheckConstIntervalInst = 32; 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int next_buffer_check_; // pc offset of next buffer check. 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emission of the trampoline pool may be blocked in some code sequences. 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int no_trampoline_pool_before_; // Block emission before this pc offset. 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep track of the last emitted pool to guarantee a maximal distance. 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last_trampoline_pool_end_; // pc offset of the end of the last pool. 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Automatic growth of the assembly buffer may be blocked for some sequences. 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool block_buffer_growth_; // Block growth when true. 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Relocation information generation. 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Each relocation is encoded as a variable size value. 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfoWriter reloc_info_writer; 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The bound position, before this we cannot do instruction elimination. 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last_bound_pos_; 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Readable constants for compact branch handling in emit() 1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum class CompactBranchType : bool { NO = false, COMPACT_BRANCH = true }; 1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code emission. 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void CheckBuffer(); 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GrowBuffer(); 1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit(Instr x, 1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch = CompactBranchType::NO); 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit(uint64_t x); 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void CheckForEmitInForbiddenSlot(); 1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename T> 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void EmitHelper(T x); 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void EmitHelper(Instr x, CompactBranchType is_compact_branch); 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Instruction generation. 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have 3 different kind of encoding layout on MIPS. 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // However due to many different types of objects encoded in the same fields 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we have quite a few aliases for each mode. 1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Using the same structure to refer to Register and FPURegister would spare a 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // few aliases, but mixing both does not look clean to me. 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Anyway we could surely implement this differently. 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenInstrRegister(Opcode opcode, 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rs, 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rt, 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rd, 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint16_t sa = 0, 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField func = NULLSF); 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenInstrRegister(Opcode opcode, 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rs, 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rt, 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint16_t msb, 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint16_t lsb, 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField func); 1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenInstrRegister(Opcode opcode, 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField fmt, 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister ft, 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fs, 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fd, 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField func = NULLSF); 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenInstrRegister(Opcode opcode, 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fr, 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister ft, 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fs, 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fd, 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField func = NULLSF); 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenInstrRegister(Opcode opcode, 1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField fmt, 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rt, 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fs, 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fd, 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField func = NULLSF); 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenInstrRegister(Opcode opcode, 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField fmt, 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rt, 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPUControlRegister fs, 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SecondaryField func = NULLSF); 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenInstrImmediate( 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Opcode opcode, Register rs, Register rt, int32_t j, 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch = CompactBranchType::NO); 1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenInstrImmediate( 1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Opcode opcode, Register rs, SecondaryField SF, int32_t j, 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch = CompactBranchType::NO); 1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenInstrImmediate( 1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Opcode opcode, Register r1, FPURegister r2, int32_t j, 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch = CompactBranchType::NO); 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenInstrImmediate( 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Opcode opcode, Register rs, int32_t offset21, 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch = CompactBranchType::NO); 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenInstrImmediate(Opcode opcode, Register rs, uint32_t offset21); 1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenInstrImmediate( 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Opcode opcode, int32_t offset26, 1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompactBranchType is_compact_branch = CompactBranchType::NO); 1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenInstrJump(Opcode opcode, 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t address); 1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Helpers. 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadRegPlusOffsetToAt(const MemOperand& src); 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Labels. 1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void print(Label* L); 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bind_to(Label* L, int pos); 1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void next(Label* L, bool is_internal); 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // One trampoline consists of: 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - space for trampoline slots, 1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - space for labels. 1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Space for trampoline slots is equal to slot_count * 2 * kInstrSize. 1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Space for trampoline slots preceeds space for labels. Each label is of one 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction size, so total amount for labels is equal to 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // label_count * kInstrSize. 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class Trampoline { 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Trampoline() { 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_ = 0; 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_slot_ = 0; 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free_slot_count_ = 0; 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_ = 0; 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Trampoline(int start, int slot_count) { 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_ = start; 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_slot_ = start; 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free_slot_count_ = slot_count; 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_ = start + slot_count * kTrampolineSlotsSize; 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start() { 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return start_; 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end() { 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return end_; 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int take_slot() { 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int trampoline_slot = kInvalidSlotPos; 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (free_slot_count_ <= 0) { 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have run out of space on trampolines. 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure we fail in debug mode, so we become aware of each case 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // when this happens. 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(0); 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Internal exception will be caught. 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trampoline_slot = next_slot_; 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free_slot_count_--; 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_slot_ += kTrampolineSlotsSize; 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return trampoline_slot; 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start_; 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end_; 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int next_slot_; 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int free_slot_count_; 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t get_trampoline_entry(int32_t pos); 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int unbound_labels_count_; 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // After trampoline is emitted, long branches are used in generated code for 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the forward branches whose target offsets could be beyond reach of branch 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // instruction. We use this information to trigger different mode of 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // branch instruction generation, where we use jump instructions rather 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // than regular branch instructions. 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool trampoline_emitted_; 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kTrampolineSlotsSize = 2 * kInstrSize; 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; 1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1; 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kInvalidSlotPos = -1; 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Internal reference positions, required for unbounded internal reference 1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // labels. 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::set<int64_t> internal_reference_positions_; 1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EmittedCompactBranchInstruction() { prev_instr_compact_branch_ = true; } 1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearCompactBranchState() { prev_instr_compact_branch_ = false; } 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool prev_instr_compact_branch_ = false; 1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Trampoline trampoline_; 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool internal_trampoline_exception_; 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class RegExpMacroAssemblerMIPS; 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class RelocInfo; 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class CodePatcher; 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class BlockTrampolinePoolScope; 1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PositionsRecorder positions_recorder_; 1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class PositionsRecorder; 1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class EnsureSpace; 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass EnsureSpace BASE_EMBEDDED { 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit EnsureSpace(Assembler* assembler) { 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assembler->CheckBuffer(); 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_ARM_ASSEMBLER_MIPS_H_ 1509