assembler-mips.h revision 3ef787dbeca8a5fb1086949cda830dccee07bfbd
165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Copyright (c) 1994-2006 Sun Microsystems Inc. 265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// All Rights Reserved. 365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Redistribution and use in source and binary forms, with or without 565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// modification, are permitted provided that the following conditions are 665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// met: 765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// - Redistributions of source code must retain the above copyright notice, 965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// this list of conditions and the following disclaimer. 1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// - Redistribution in binary form must reproduce the above copyright 1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// notice, this list of conditions and the following disclaimer in the 1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// documentation and/or other materials provided with the distribution. 1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// - Neither the name of Sun Microsystems or the names of contributors may 1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// be used to endorse or promote products derived from this software without 1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// specific prior written permission. 1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// The original source code covered by the above license above has been 3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// modified significantly by Google Inc. 3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#ifndef V8_MIPS_ASSEMBLER_MIPS_H_ 3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#define V8_MIPS_ASSEMBLER_MIPS_H_ 3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <stdio.h> 4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "assembler.h" 4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "constants-mips.h" 4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "serialize.h" 4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 442fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocknamespace v8 { 4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace internal { 4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// CPU Registers. 4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 1) We would prefer to use an enum, but enum values are assignment- 5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// compatible with int, which has caused code-generation bugs. 5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 2) We would prefer to use a class instead of a struct but we don't like 5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// the register initialization to depend on the particular initialization 5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// order (which appears to be different on OS X, Linux, and Windows for the 552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// installed versions of C++ we tried). Using a struct permits C-style 562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// "initialization". Also, the Register objects cannot be const as this 572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// forces initialization stubs in MSVC, making us dependent on initialization 582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// order. 592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// 602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// 3) By not using an enum, we are possibly preventing the compiler from 612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// doing certain constant folds, which may significantly reduce the 622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// code generated for some assembly instructions (because they boil down 632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// to a few constants). If this is a problem, we could change the code 642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// such that we use an enum in optimized mode, and the struct in debug 652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// mode. This way we get the compile-time error checking in debug mode 6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// and best performance in optimized code. 6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// ----------------------------------------------------------------------------- 7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Implementation of Register and FPURegister. 7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Core register. 7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstruct Register { 7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kNumRegisters = v8::internal::kNumRegisters; 7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kNumAllocatableRegisters = 14; // v0 through t7. 7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kSizeInBytes = 4; 7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static int ToAllocationIndex(Register reg) { 7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reg.code() - 2; // zero_reg and 'at' are skipped. 8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Register FromAllocationIndex(int index) { 8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(index >= 0 && index < kNumAllocatableRegisters); 842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return from_code(index + 2); // zero_reg and 'at' are skipped. 852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const char* AllocationIndexToString(int index) { 882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(index >= 0 && index < kNumAllocatableRegisters); 892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const char* const names[] = { 902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "v0", 9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "v1", 9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "a0", 9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "a1", 9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "a2", 9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "a3", 9665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t0", 9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t1", 9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t2", 9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t3", 10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t4", 10165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t5", 10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t6", 10365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "t7", 10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch }; 10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return names[index]; 10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Register from_code(int code) { 10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Register r = { code }; 11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return r; 11165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 11265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 11365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 11465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is(Register reg) const { return code_ == reg.code_; } 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int code() const { 1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(is_valid()); 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return code_; 1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int bit() const { 1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(is_valid()); 1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 1 << code_; 1222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Unfortunately we can't make this private in a struct. 1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int code_; 1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}; 1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register no_reg = { -1 }; 1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register zero_reg = { 0 }; // Always zero. 1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register at = { 1 }; // at: Reserved for synthetic instructions. 1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register v0 = { 2 }; // v0, v1: Used when returning multiple values 1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register v1 = { 3 }; // from subroutines. 1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register a0 = { 4 }; // a0 - a4: Used to pass non-FP parameters. 1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register a1 = { 5 }; 1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register a2 = { 6 }; 1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register a3 = { 7 }; 1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t0 = { 8 }; // t0 - t9: Can be used without reservation, act 1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t1 = { 9 }; // as temporary registers and are allowed to 1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t2 = { 10 }; // be destroyed by subroutines. 1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t3 = { 11 }; 1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t4 = { 12 }; 1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t5 = { 13 }; 1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t6 = { 14 }; 1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t7 = { 15 }; 1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s0 = { 16 }; // s0 - s7: Subroutine register variables. 1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s1 = { 17 }; // Subroutines that write to these registers 1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s2 = { 18 }; // must restore their values before exiting so 1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s3 = { 19 }; // that the caller can expect the values to be 1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s4 = { 20 }; // preserved. 1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s5 = { 21 }; 1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s6 = { 22 }; 1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s7 = { 23 }; 1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t8 = { 24 }; 1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register t9 = { 25 }; 1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register k0 = { 26 }; // k0, k1: Reserved for system calls and 1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register k1 = { 27 }; // interrupt handlers. 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register gp = { 28 }; // gp: Reserved. 1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register sp = { 29 }; // sp: Stack pointer. 1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register s8_fp = { 30 }; // fp: Frame pointer. 1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst Register ra = { 31 }; // ra: Return address pointer. 1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockint ToNumber(Register reg); 1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1662fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockRegister ToRegister(int num); 1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Coprocessor register. 1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstruct FPURegister { 1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const int kNumRegisters = v8::internal::kNumFPURegisters; 1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers 1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to 1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // number of Double regs (64-bit regs, or FPU-reg-pairs). 1752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // A few double registers are reserved: one as a scratch register and one to 1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // hold 0.0. 1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // f28: 0.0 1792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // f30: scratch register. 1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const int kNumReservedRegisters = 2; 1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const int kNumAllocatableRegisters = kNumRegisters / 2 - 1822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block kNumReservedRegisters; 1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block inline static int ToAllocationIndex(FPURegister reg); 1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static FPURegister FromAllocationIndex(int index) { 1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(index >= 0 && index < kNumAllocatableRegisters); 1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return from_code(index * 2); 1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const char* AllocationIndexToString(int index) { 1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(index >= 0 && index < kNumAllocatableRegisters); 1942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const char* const names[] = { 1952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "f0", 1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "f2", 1972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "f4", 1982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "f6", 1992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "f8", 2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "f10", 2012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "f12", 20265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "f14", 20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "f16", 20465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "f18", 20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "f20", 20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "f22", 20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "f24", 20865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "f26" 20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch }; 21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return names[index]; 21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static FPURegister from_code(int code) { 21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister r = { code }; 21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return r; 21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 21765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is_valid() const { return 0 <= code_ && code_ < kNumFPURegisters ; } 21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is(FPURegister creg) const { return code_ == creg.code_; } 22065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister low() const { 22165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Find low reg of a Double-reg pair, which is the reg itself. 22265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(code_ % 2 == 0); // Specified Double reg must be even. 22365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister reg; 22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch reg.code_ = code_; 22565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(reg.is_valid()); 22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reg; 22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister high() const { 22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Find high reg of a Doubel-reg pair, which is reg + 1. 23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(code_ % 2 == 0); // Specified Double reg must be even. 23165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister reg; 23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch reg.code_ = code_ + 1; 23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(reg.is_valid()); 23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reg; 23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 23765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int code() const { 23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(is_valid()); 23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return code_; 24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 24165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int bit() const { 24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(is_valid()); 24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return 1 << code_; 24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void setcode(int f) { 24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch code_ = f; 2472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(is_valid()); 2482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Unfortunately we can't make this private in a struct. 25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int code_; 25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}; 2522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// V8 now supports the O32 ABI, and the FPU Registers are organized as 32 25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// 32-bit registers, f0 through f31. When used as 'double' they are used 2552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// in pairs, starting with the even numbered register. So a double operation 2562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// on f0 really uses f0 and f1. 2572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// (Modern mips hardware also supports 32 64-bit registers, via setting 2582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// (priviledged) Status Register FR bit to 1. This is used by the N32 ABI, 25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// but it is not in common use. Someday we will want to support this in v8.) 2602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 26165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. 26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef FPURegister DoubleRegister; 2632fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocktypedef FPURegister FloatRegister; 26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister no_freg = { -1 }; 26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f0 = { 0 }; // Return value in hard float mode. 26865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f1 = { 1 }; 26965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f2 = { 2 }; 27065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f3 = { 3 }; 27165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f4 = { 4 }; 27265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f5 = { 5 }; 27365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f6 = { 6 }; 27465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f7 = { 7 }; 27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f8 = { 8 }; 27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f9 = { 9 }; 27765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f10 = { 10 }; 27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f11 = { 11 }; 27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f12 = { 12 }; // Arg 0 in hard float mode. 2802fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst FPURegister f13 = { 13 }; 2812fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst FPURegister f14 = { 14 }; // Arg 1 in hard float mode. 2822fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst FPURegister f15 = { 15 }; 2832fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst FPURegister f16 = { 16 }; 2842fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst FPURegister f17 = { 17 }; 28565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f18 = { 18 }; 28665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f19 = { 19 }; 28765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f20 = { 20 }; 28865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f21 = { 21 }; 28965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f22 = { 22 }; 29065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f23 = { 23 }; 29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f24 = { 24 }; 29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f25 = { 25 }; 29365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f26 = { 26 }; 29465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f27 = { 27 }; 29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f28 = { 28 }; 29665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f29 = { 29 }; 29765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f30 = { 30 }; 29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPURegister f31 = { 31 }; 29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Register aliases. 30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// cp is assumed to be a callee saved register. 30265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const Register& kLithiumScratchReg = s3; // Scratch register. 30365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const Register& kLithiumScratchReg2 = s4; // Scratch register. 30465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const Register& kRootRegister = s6; // Roots array pointer. 30565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const Register& cp = s7; // JavaScript context pointer. 30665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const Register& fp = s8_fp; // Alias for fp. 30765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const DoubleRegister& kLithiumScratchDouble = f30; 30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const FPURegister& kDoubleRegZero = f28; 30965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 31065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// FPU (coprocessor 1) control registers. 31165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Currently only FCSR (#31) is implemented. 31265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstruct FPUControlRegister { 31365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is_valid() const { return code_ == kFCSRRegister; } 31465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is(FPUControlRegister creg) const { return code_ == creg.code_; } 31565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int code() const { 31665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(is_valid()); 31765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return code_; 31865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 31965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int bit() const { 32065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(is_valid()); 32165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return 1 << code_; 32265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 32365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void setcode(int f) { 32465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch code_ = f; 32565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(is_valid()); 32665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 32765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Unfortunately we can't make this private in a struct. 32865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int code_; 32965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}; 33065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; 33265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst FPUControlRegister FCSR = { kFCSRRegister }; 33365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// ----------------------------------------------------------------------------- 33665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Machine instruction Operands. 33765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Class Operand represents a shifter operand in data processing instructions. 33965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass Operand BASE_EMBEDDED { 34065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch public: 34165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Immediate. 34265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch INLINE(explicit Operand(int32_t immediate, 34365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RelocInfo::Mode rmode = RelocInfo::NONE)); 34465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch INLINE(explicit Operand(const ExternalReference& f)); 34565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch INLINE(explicit Operand(const char* s)); 34665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch INLINE(explicit Operand(Object** opp)); 34765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch INLINE(explicit Operand(Context** cpp)); 34865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch explicit Operand(Handle<Object> handle); 34965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch INLINE(explicit Operand(Smi* value)); 3502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Register. 3522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block INLINE(explicit Operand(Register rm)); 3532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Return true if this is a register operand. 3552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block INLINE(bool is_reg() const); 3562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rm() const { return rm_; } 3582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block private: 3602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rm_; 3612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int32_t imm32_; // Valid if rm_ == no_reg. 3622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RelocInfo::Mode rmode_; 3632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class Assembler; 3652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class MacroAssembler; 3662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}; 3672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// On MIPS we have only one adressing mode with base_reg + offset. 3702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Class MemOperand represents a memory operand in load and store instructions. 3712fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass MemOperand : public Operand { 3722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block public: 37365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch explicit MemOperand(Register rn, int32_t offset = 0); 37465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t offset() const { return offset_; } 37565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 37665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool OffsetIsInt16Encodable() const { 37765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return is_int16(offset_); 37865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 37965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 38065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch private: 38165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t offset_; 38265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 38365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch friend class Assembler; 38465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}; 38565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 38665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 38765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// CpuFeatures keeps track of which features are supported by the target CPU. 38865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Supported features must be enabled by a Scope before use. 38965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass CpuFeatures : public AllStatic { 39065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch public: 39165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Detect features of the target CPU. Set safe defaults if the serializer 39265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // is enabled (snapshots must be portable). 39365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static void Probe(); 39465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 39565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check whether a feature is supported by the target CPU. 39665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsSupported(CpuFeature f) { 39765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(initialized_); 39865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (f == FPU && !FLAG_enable_fpu) return false; 39965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return (supported_ & (1u << f)) != 0; 40065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 40165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 40265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 40365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifdef DEBUG 40465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check whether a feature is currently enabled. 40565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsEnabled(CpuFeature f) { 40665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(initialized_); 4072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Isolate* isolate = Isolate::UncheckedCurrent(); 4082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (isolate == NULL) { 4092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // When no isolate is available, work as if we're running in 4102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // release mode. 4112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return IsSupported(f); 4122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned enabled = static_cast<unsigned>(isolate->enabled_cpu_features()); 4142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return (enabled & (1u << f)) != 0; 4152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif 41781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 4182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Enable a specified feature within a scope. 4192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block class Scope BASE_EMBEDDED { 4202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#ifdef DEBUG 4212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 4222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block public: 4232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block explicit Scope(CpuFeature f) { 4242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned mask = 1u << f; 4252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(CpuFeatures::IsSupported(f)); 4262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!Serializer::enabled() || 4272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block (CpuFeatures::found_by_runtime_probing_ & mask) == 0); 4282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block isolate_ = Isolate::UncheckedCurrent(); 4292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block old_enabled_ = 0; 4302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (isolate_ != NULL) { 4312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block old_enabled_ = static_cast<unsigned>(isolate_->enabled_cpu_features()); 4322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block isolate_->set_enabled_cpu_features(old_enabled_ | mask); 4332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ~Scope() { 4362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_); 4372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (isolate_ != NULL) { 4382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block isolate_->set_enabled_cpu_features(old_enabled_); 4392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 4402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 44181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 44281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch private: 44381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Isolate* isolate_; 44481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch unsigned old_enabled_; 44581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#else 44681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 44781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch public: 44881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch explicit Scope(CpuFeature f) {} 44981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif 45081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch }; 45181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 45281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch class TryForceFeatureScope BASE_EMBEDDED { 45381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch public: 45481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch explicit TryForceFeatureScope(CpuFeature f) 45581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : old_supported_(CpuFeatures::supported_) { 45681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (CanForce()) { 45765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CpuFeatures::supported_ |= (1u << f); 45865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 45965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 46065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 46165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ~TryForceFeatureScope() { 46281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (CanForce()) { 46381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch CpuFeatures::supported_ = old_supported_; 46481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 46581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 46681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 46781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch private: 4682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static bool CanForce() { 46965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // It's only safe to temporarily force support of CPU features 47065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // when there's only a single isolate, which is guaranteed when 47165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // the serializer is enabled. 47265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return Serializer::enabled(); 47365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 47465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 47565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch const unsigned old_supported_; 47665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch }; 47765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 47865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch private: 47965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifdef DEBUG 48065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool initialized_; 48165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 4822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static unsigned supported_; 48365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static unsigned found_by_runtime_probing_; 48465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 48565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch DISALLOW_COPY_AND_ASSIGN(CpuFeatures); 48665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}; 48765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 48865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 48965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass Assembler : public AssemblerBase { 49065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch public: 49165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Create an assembler. Instructions and relocation information are emitted 49265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // into a buffer, with the instructions starting from the beginning and the 4932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // relocation information starting from the end of the buffer. See CodeDesc 4942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // for a detailed comment on the layout (globals.h). 49565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // 49665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // If the provided buffer is NULL, the assembler allocates and grows its own 49765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // buffer, and buffer_size determines the initial buffer size. The buffer is 49865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // owned by the assembler and deallocated upon destruction of the assembler. 49965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // 50065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // If the provided buffer is not NULL, the assembler uses the provided buffer 50165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // for code generation and assumes its size to be buffer_size. If the buffer 50265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // is too small, a fatal error occurs. No deallocation of the buffer is done 50365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // upon destruction of the assembler. 50465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Assembler(Isolate* isolate, void* buffer, int buffer_size); 50565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ~Assembler(); 50665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 50765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Overrides the default provided by FLAG_debug_code. 50865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void set_emit_debug_code(bool value) { emit_debug_code_ = value; } 50965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 51065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // GetCode emits any pending (non-emitted) code and fills the descriptor 51165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // desc. GetCode() is idempotent; it returns the same result if no other 51265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Assembler functions are invoked in between GetCode() calls. 51365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void GetCode(CodeDesc* desc); 51465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 51565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Label operations & relative jumps (PPUM Appendix D). 51665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // 51765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Takes a branch opcode (cc) and a label (L) and generates 51865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // either a backward branch or a forward branch and links it 51965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // to the label fixup chain. Usage: 52065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // 52165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Label L; // unbound label 52265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // j(cc, &L); // forward branch to unbound label 52365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // bind(&L); // bind label to the current pc 52465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // j(cc, &L); // backward branch to bound label 52565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // bind(&L); // illegal: a label may be bound only once 5262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // 5272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Note: The same Label can be used for forward and backward branches 5282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // but it may be bound only once. 5292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void bind(Label* L); // Binds an unbound label L to current code position. 53065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Determines if Label is bound and near enough so that branch instruction 53165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // can be used to reach it, instead of jump instruction. 53265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is_near(Label* L); 53365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 53465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Returns the branch offset to the given label from the current code 53565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // position. Links the label to the current position if it is still unbound. 53665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Manages the jump elimination optimization if the second parameter is true. 53765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t branch_offset(Label* L, bool jump_elimination_allowed); 53865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { 5392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int32_t o = branch_offset(L, jump_elimination_allowed); 5402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT((o & 3) == 0); // Assert the offset is aligned. 54165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return o >> 2; 54265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 5432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block uint32_t jump_address(Label* L); 5442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 54565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Puts a labels target address at the given position. 54665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // The high 8 bits are set to zero. 5472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void label_at_put(Label* L, int at_offset); 54865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 54965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Read/Modify the code target address in the branch/call instruction at pc. 55065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Address target_address_at(Address pc); 55165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static void set_target_address_at(Address pc, Address target); 55265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 55365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static void JumpLabelToJumpRegister(Address pc); 55465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 55565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // This sets the branch destination (which gets loaded at the call address). 55665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // This is for calls and branches within generated code. The serializer 55765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // has already deserialized the lui/ori instructions etc. 55865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch inline static void deserialization_set_special_target_at( 55965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Address instruction_payload, Address target) { 56065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch set_target_address_at( 56165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch instruction_payload - kInstructionsFor32BitConstant * kInstrSize, 56265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch target); 56365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 56465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 56565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // This sets the branch destination. 56665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // This is for calls and branches to runtime code. 56765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch inline static void set_external_target_at(Address instruction_payload, 56865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Address target) { 56965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch set_target_address_at(instruction_payload, target); 57065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 57165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 57265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Size of an instruction. 57365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kInstrSize = sizeof(Instr); 57465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 57565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Difference between address of current opcode and target address offset. 57665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kBranchPCOffset = 4; 57765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 57865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Here we are patching the address in the LUI/ORI instruction pair. 57965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // These values are used in the serialization process and must be zero for 58065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // MIPS platform, as Code, Embedded Object or External-reference pointers 58165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // are split across two consecutive instructions and don't exist separately 58265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // in the code, so the serializer should not step forwards in memory after 58365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // a target is resolved and written. 58465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kSpecialTargetSize = 0; 58565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 58665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Number of consecutive instructions used to store 32bit constant. 58765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Before jump-optimizations, this constant was used in 58865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // RelocInfo::target_address_address() function to tell serializer address of 58965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // the instruction that follows LUI/ORI instruction pair. Now, with new jump 59065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // optimization, where jump-through-register instruction that usually 59165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // follows LUI/ORI pair is substituted with J/JAL, this constant equals 59265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // to 3 instructions (LUI+ORI+J/JAL/JR/JALR). 59365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kInstructionsFor32BitConstant = 3; 59465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 59565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Distance between the instruction referring to the address of the call 59665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // target and the return address. 59765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kCallTargetAddressOffset = 4 * kInstrSize; 59865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 59965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Distance between start of patched return sequence and the emitted address 60065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // to jump to. 60165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kPatchReturnSequenceAddressOffset = 0; 60265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 60365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Distance between start of patched debug break slot and the emitted address 60465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // to jump to. 60565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; 60665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 60765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Difference between address of current opcode and value read from pc 60865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // register. 60965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kPcLoadDelta = 4; 61065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 61165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Number of instructions used for the JS return sequence. The constant is 61265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // used by the debugger to patch the JS return sequence. 61365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kJSReturnSequenceInstructions = 7; 61465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kDebugBreakSlotInstructions = 4; 61565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kDebugBreakSlotLength = 61665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch kDebugBreakSlotInstructions * kInstrSize; 61765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 61865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 61965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // --------------------------------------------------------------------------- 62065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Code generation. 62165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 62265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Insert the smallest number of nop instructions 62365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // possible to align the pc offset to a multiple 62465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // of m. m must be a power of 2 (>= 4). 62565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void Align(int m); 62665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Aligns code to something that's optimal for a jump target for the platform. 62765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void CodeTargetAlign(); 62865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 62965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Different nop operations are used by the code generator to detect certain 63065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // states of the generated code. 63165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch enum NopMarkerTypes { 63265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch NON_MARKING_NOP = 0, 63365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch DEBUG_BREAK_NOP, 63465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // IC markers. 63565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PROPERTY_ACCESS_INLINED, 63665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PROPERTY_ACCESS_INLINED_CONTEXT, 63765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE, 63865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Helper values. 63965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch LAST_CODE_MARKER, 64065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED 64165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch }; 64265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Type == 0 is the default non-marking type. 64465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void nop(unsigned int type = 0) { 64565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(type < 32); 64665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch sll(zero_reg, zero_reg, type, true); 64765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 64865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 64965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 65065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // --------Branch-and-jump-instructions---------- 65165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // We don't use likely variant of instructions. 6522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void b(int16_t offset); 6532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void b(Label* L) { b(branch_offset(L, false)>>2); } 6542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void bal(int16_t offset); 65565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bal(Label* L) { bal(branch_offset(L, false)>>2); } 65665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 65765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void beq(Register rs, Register rt, int16_t offset); 65865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void beq(Register rs, Register rt, Label* L) { 65965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch beq(rs, rt, branch_offset(L, false) >> 2); 66065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 66165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bgez(Register rs, int16_t offset); 66265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bgezal(Register rs, int16_t offset); 66365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bgtz(Register rs, int16_t offset); 66465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void blez(Register rs, int16_t offset); 66565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bltz(Register rs, int16_t offset); 66665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bltzal(Register rs, int16_t offset); 66765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bne(Register rs, Register rt, int16_t offset); 66865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bne(Register rs, Register rt, Label* L) { 669ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch bne(rs, rt, branch_offset(L, false)>>2); 670ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 671ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 672ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // Never use the int16_t b(l)cond version with a branch offset 673ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // instead of using the Label* version. 674ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 67581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits. 67681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void j(int32_t target); 67781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void jal(int32_t target); 67881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void jalr(Register rs, Register rd = ra); 67981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void jr(Register target); 68081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void j_or_jr(int32_t target, Register rs); 68181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void jal_or_jalr(int32_t target, Register rs); 68281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 68365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 68465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch //-------Data-processing-instructions--------- 68565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 68665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Arithmetic. 68765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void addu(Register rd, Register rs, Register rt); 68865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void subu(Register rd, Register rs, Register rt); 68965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mult(Register rs, Register rt); 69065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void multu(Register rs, Register rt); 69165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void div(Register rs, Register rt); 69265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void divu(Register rs, Register rt); 69365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mul(Register rd, Register rs, Register rt); 69465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 69565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void addiu(Register rd, Register rs, int32_t j); 69665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 69765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Logical. 69865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void and_(Register rd, Register rs, Register rt); 69965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void or_(Register rd, Register rs, Register rt); 70065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void xor_(Register rd, Register rs, Register rt); 70165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void nor(Register rd, Register rs, Register rt); 70265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 70365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void andi(Register rd, Register rs, int32_t j); 70465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ori(Register rd, Register rs, int32_t j); 70565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void xori(Register rd, Register rs, int32_t j); 70665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lui(Register rd, int32_t j); 70765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 70865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Shifts. 70965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop 71065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // and may cause problems in normal code. coming_from_nop makes sure this 71165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // doesn't happen. 7122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false); 7132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void sllv(Register rd, Register rt, Register rs); 7142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void srl(Register rd, Register rt, uint16_t sa); 7152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void srlv(Register rd, Register rt, Register rs); 71665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sra(Register rt, Register rd, uint16_t sa); 71765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void srav(Register rt, Register rd, Register rs); 71865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void rotr(Register rd, Register rt, uint16_t sa); 71965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void rotrv(Register rd, Register rt, Register rs); 72065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 72165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 72265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch //------------Memory-instructions------------- 72365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 72465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lb(Register rd, const MemOperand& rs); 72565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lbu(Register rd, const MemOperand& rs); 72665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lh(Register rd, const MemOperand& rs); 72765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lhu(Register rd, const MemOperand& rs); 72865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lw(Register rd, const MemOperand& rs); 72965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lwl(Register rd, const MemOperand& rs); 73065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lwr(Register rd, const MemOperand& rs); 73165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sb(Register rd, const MemOperand& rs); 73265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sh(Register rd, const MemOperand& rs); 73365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sw(Register rd, const MemOperand& rs); 73465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void swl(Register rd, const MemOperand& rs); 73565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void swr(Register rd, const MemOperand& rs); 73665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 73765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 73865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch //-------------Misc-instructions-------------- 73965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 74065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Break / Trap instructions. 74165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void break_(uint32_t code, bool break_as_stop = false); 74265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void stop(const char* msg, uint32_t code = kMaxStopCode); 74365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void tge(Register rs, Register rt, uint16_t code); 74465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void tgeu(Register rs, Register rt, uint16_t code); 74565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void tlt(Register rs, Register rt, uint16_t code); 74665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void tltu(Register rs, Register rt, uint16_t code); 74765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void teq(Register rs, Register rt, uint16_t code); 74865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void tne(Register rs, Register rt, uint16_t code); 74965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 75065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Move from HI/LO register. 75165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mfhi(Register rd); 75265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mflo(Register rd); 75365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 75465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Set on less than. 75565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void slt(Register rd, Register rs, Register rt); 75665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sltu(Register rd, Register rs, Register rt); 75765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void slti(Register rd, Register rs, int32_t j); 75865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sltiu(Register rd, Register rs, int32_t j); 75965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 76065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Conditional move. 76165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void movz(Register rd, Register rs, Register rt); 76265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void movn(Register rd, Register rs, Register rt); 76365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void movt(Register rd, Register rs, uint16_t cc = 0); 76465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void movf(Register rd, Register rs, uint16_t cc = 0); 76565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 76665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Bit twiddling. 76765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void clz(Register rd, Register rs); 76865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ins_(Register rt, Register rs, uint16_t pos, uint16_t size); 76965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ext_(Register rt, Register rs, uint16_t pos, uint16_t size); 77065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 77165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch //--------Coprocessor-instructions---------------- 77265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 77365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Load, store, and move. 77465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void lwc1(FPURegister fd, const MemOperand& src); 77565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ldc1(FPURegister fd, const MemOperand& src); 77665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 77765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void swc1(FPURegister fs, const MemOperand& dst); 77865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sdc1(FPURegister fs, const MemOperand& dst); 77965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 78065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mtc1(Register rt, FPURegister fs); 78165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mfc1(Register rt, FPURegister fs); 78265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 78365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ctc1(Register rt, FPUControlRegister fs); 78465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cfc1(Register rt, FPUControlRegister fs); 78565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 78665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Arithmetic. 78765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void add_d(FPURegister fd, FPURegister fs, FPURegister ft); 78865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sub_d(FPURegister fd, FPURegister fs, FPURegister ft); 78965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mul_d(FPURegister fd, FPURegister fs, FPURegister ft); 79065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void div_d(FPURegister fd, FPURegister fs, FPURegister ft); 79165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void abs_d(FPURegister fd, FPURegister fs); 79265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void mov_d(FPURegister fd, FPURegister fs); 79365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void neg_d(FPURegister fd, FPURegister fs); 79465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void sqrt_d(FPURegister fd, FPURegister fs); 79565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 79665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Conversion. 79765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_w_s(FPURegister fd, FPURegister fs); 79865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_w_d(FPURegister fd, FPURegister fs); 79965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void trunc_w_s(FPURegister fd, FPURegister fs); 80065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void trunc_w_d(FPURegister fd, FPURegister fs); 80165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void round_w_s(FPURegister fd, FPURegister fs); 80265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void round_w_d(FPURegister fd, FPURegister fs); 80365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void floor_w_s(FPURegister fd, FPURegister fs); 80465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void floor_w_d(FPURegister fd, FPURegister fs); 80565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ceil_w_s(FPURegister fd, FPURegister fs); 80665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ceil_w_d(FPURegister fd, FPURegister fs); 80765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 80865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_l_s(FPURegister fd, FPURegister fs); 80965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_l_d(FPURegister fd, FPURegister fs); 81065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void trunc_l_s(FPURegister fd, FPURegister fs); 81165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void trunc_l_d(FPURegister fd, FPURegister fs); 81265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void round_l_s(FPURegister fd, FPURegister fs); 81365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void round_l_d(FPURegister fd, FPURegister fs); 81465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void floor_l_s(FPURegister fd, FPURegister fs); 81565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void floor_l_d(FPURegister fd, FPURegister fs); 81665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ceil_l_s(FPURegister fd, FPURegister fs); 81765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ceil_l_d(FPURegister fd, FPURegister fs); 81865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 81965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_s_w(FPURegister fd, FPURegister fs); 82065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_s_l(FPURegister fd, FPURegister fs); 82165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_s_d(FPURegister fd, FPURegister fs); 82265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 82365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_d_w(FPURegister fd, FPURegister fs); 82465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_d_l(FPURegister fd, FPURegister fs); 82565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void cvt_d_s(FPURegister fd, FPURegister fs); 8262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 82765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Conditions and branches. 8282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void c(FPUCondition cond, SecondaryField fmt, 82965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister ft, FPURegister fs, uint16_t cc = 0); 8302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 83165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bc1f(int16_t offset, uint16_t cc = 0); 83265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bc1f(Label* L, uint16_t cc = 0) { bc1f(branch_offset(L, false)>>2, cc); } 83365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bc1t(int16_t offset, uint16_t cc = 0); 83465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void bc1t(Label* L, uint16_t cc = 0) { bc1t(branch_offset(L, false)>>2, cc); } 83565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void fcmp(FPURegister src1, const double src2, FPUCondition cond); 83665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 83765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check the code size generated from label to here. 83865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int SizeOfCodeGeneratedSince(Label* label) { 83965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return pc_offset() - label->pos(); 84065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 84165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 84265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check the number of instructions generated from label to here. 84365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int InstructionsGeneratedSince(Label* label) { 84465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return SizeOfCodeGeneratedSince(label) / kInstrSize; 84565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 84665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 84765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Class for scoping postponing the trampoline pool generation. 84865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch class BlockTrampolinePoolScope { 84965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch public: 85065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) { 85165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch assem_->StartBlockTrampolinePool(); 85265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 85365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ~BlockTrampolinePoolScope() { 85465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch assem_->EndBlockTrampolinePool(); 85565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 85665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 85765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch private: 85865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Assembler* assem_; 85965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 86065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); 86165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch }; 86265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 86365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Class for postponing the assembly buffer growth. Typically used for 86465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // sequences of instructions that must be emitted as a unit, before 86565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // buffer growth (and relocation) can occur. 86665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // This blocking scope is not nestable. 86765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch class BlockGrowBufferScope { 86865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch public: 86965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) { 87065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch assem_->StartBlockGrowBuffer(); 87165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 87265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ~BlockGrowBufferScope() { 87365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch assem_->EndBlockGrowBuffer(); 87465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 87565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 87665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch private: 87765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Assembler* assem_; 87865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 87965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope); 88065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch }; 88165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 88265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Debugging. 88365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 88465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Mark address of the ExitJSFrame code. 88565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void RecordJSReturn(); 88665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 88765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Mark address of a debug break slot. 88865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void RecordDebugBreakSlot(); 88965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 89065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Record the AST id of the CallIC being compiled, so that it can be placed 89165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // in the relocation information. 89265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void SetRecordedAstId(unsigned ast_id) { 89365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(recorded_ast_id_ == kNoASTId); 89465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch recorded_ast_id_ = ast_id; 89565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 89665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 89765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned RecordedAstId() { 89865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(recorded_ast_id_ != kNoASTId); 89965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return recorded_ast_id_; 90065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 90165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 90265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void ClearRecordedAstId() { recorded_ast_id_ = kNoASTId; } 90365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 90465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Record a comment relocation entry that can be used by a disassembler. 90565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Use --code-comments to enable. 90665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void RecordComment(const char* msg); 90765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 90865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static int RelocateInternalReference(byte* pc, intptr_t pc_delta); 90965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 91065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Writes a single byte or word of data in the code stream. Used for 91165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // inline tables, e.g., jump-tables. 91265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void db(uint8_t data); 91365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void dd(uint32_t data); 91465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 91565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t pc_offset() const { return pc_ - buffer_; } 91665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 91765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PositionsRecorder* positions_recorder() { return &positions_recorder_; } 91865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 91965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Postpone the generation of the trampoline pool for the specified number of 92065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // instructions. 92165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void BlockTrampolinePoolFor(int instructions); 92265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 92365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check if there is less than kGap bytes available in the buffer. 92465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // If this is the case, we need to grow the buffer before emitting 92565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // an instruction or relocation information. 92665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; } 92765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 92865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the number of bytes available in the buffer. 92965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch inline int available_space() const { return reloc_info_writer.pos() - pc_; } 93065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 93165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Read/patch instructions. 93265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 93365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static void instr_at_put(byte* pc, Instr instr) { 93465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *reinterpret_cast<Instr*>(pc) = instr; 93565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 93665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 93765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void instr_at_put(int pos, Instr instr) { 93865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 93965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 94065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 94165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check if an instruction is a branch of some kind. 94265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsBranch(Instr instr); 94365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsBeq(Instr instr); 94465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsBne(Instr instr); 94565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 94665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsJump(Instr instr); 94765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsJ(Instr instr); 94865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsLui(Instr instr); 94965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsOri(Instr instr); 95065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 95165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsJal(Instr instr); 95265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsJr(Instr instr); 95365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsJalr(Instr instr); 95465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 95565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsNop(Instr instr, unsigned int type); 95665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsPop(Instr instr); 95765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsPush(Instr instr); 95865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsLwRegFpOffset(Instr instr); 95965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsSwRegFpOffset(Instr instr); 96065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsLwRegFpNegOffset(Instr instr); 96165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsSwRegFpNegOffset(Instr instr); 96265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 96365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Register GetRtReg(Instr instr); 96465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Register GetRsReg(Instr instr); 96565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Register GetRdReg(Instr instr); 96665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 96765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetRt(Instr instr); 96865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetRtField(Instr instr); 96965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetRs(Instr instr); 97065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetRsField(Instr instr); 97165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetRd(Instr instr); 97265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetRdField(Instr instr); 97365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetSa(Instr instr); 97465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetSaField(Instr instr); 97565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetOpcodeField(Instr instr); 97665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetFunction(Instr instr); 97765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetFunctionField(Instr instr); 97865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetImmediate16(Instr instr); 97965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static uint32_t GetLabelConst(Instr instr); 98065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 98165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static int32_t GetBranchOffset(Instr instr); 98265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsLw(Instr instr); 98365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static int16_t GetLwOffset(Instr instr); 98465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Instr SetLwOffset(Instr instr, int16_t offset); 98565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 98665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsSw(Instr instr); 98765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Instr SetSwOffset(Instr instr, int16_t offset); 98865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsAddImmediate(Instr instr); 98965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static Instr SetAddImmediateOffset(Instr instr, int16_t offset); 99065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 99165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static bool IsAndImmediate(Instr instr); 99265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 99365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void CheckTrampolinePool(); 99465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 99565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch protected: 99665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Relocation for a type-recording IC has the AST id added to it. This 99765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // member variable is a way to pass the information from the call site to 99865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // the relocation info. 99965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned recorded_ast_id_; 100065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 100165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool emit_debug_code() const { return emit_debug_code_; } 100265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 100365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } 100465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 100565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Decode branch instruction at pos and return branch target pos. 100665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int target_at(int32_t pos); 100765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 100865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Patch branch instruction at pos to branch to given branch target pos. 100965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void target_at_put(int32_t pos, int32_t target_pos); 101065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 101165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Say if we need to relocate with this mode. 101265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool MustUseReg(RelocInfo::Mode rmode); 101365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 101465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Record reloc info for current pc_. 101565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 101665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 101765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Block the emission of the trampoline pool before pc_offset. 101865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void BlockTrampolinePoolBefore(int pc_offset) { 101965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (no_trampoline_pool_before_ < pc_offset) 102065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch no_trampoline_pool_before_ = pc_offset; 102165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 102265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 102365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void StartBlockTrampolinePool() { 102465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch trampoline_pool_blocked_nesting_++; 102565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 102665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 102765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void EndBlockTrampolinePool() { 102865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch trampoline_pool_blocked_nesting_--; 102965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 103065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 103165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is_trampoline_pool_blocked() const { 103265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return trampoline_pool_blocked_nesting_ > 0; 103365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 103465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 103565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool has_exception() const { 103665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return internal_trampoline_exception_; 103765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 103865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 103965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi); 104065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 104165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is_trampoline_emitted() const { 104265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return trampoline_emitted_; 104365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 104465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 104565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Temporarily block automatic assembly buffer growth. 104665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void StartBlockGrowBuffer() { 104765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(!block_buffer_growth_); 10482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block block_buffer_growth_ = true; 10492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 105065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 10512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void EndBlockGrowBuffer() { 10522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(block_buffer_growth_); 105365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch block_buffer_growth_ = false; 105465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 105565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 105665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool is_buffer_growth_blocked() const { 105765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return block_buffer_growth_; 105865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 105965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 106065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch private: 106165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Code buffer: 106265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // The buffer into which code and relocation info are generated. 106365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch byte* buffer_; 106465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int buffer_size_; 106565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // True if the assembler owns the buffer, false if buffer is external. 106665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool own_buffer_; 106765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 106865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Buffer size and constant pool distance are checked together at regular 106965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // intervals of kBufferCheckInterval emitted bytes. 107065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kBufferCheckInterval = 1*KB/2; 10712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 107265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Code generation. 107365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // The relocation writer's position is at least kGap bytes below the end of 107465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // the generated instructions. This is so that multi-instruction sequences do 10752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // not have to check for overflow. The same is true for writes of large 10762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // relocation info entries. 107765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kGap = 32; 107865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch byte* pc_; // The program counter - moves forward. 107965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 108065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 108165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Repeated checking whether the trampoline pool should be emitted is rather 108265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // expensive. By default we only check again once a number of instructions 108365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // has been generated. 108465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kCheckConstIntervalInst = 32; 108565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; 108665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 108765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int next_buffer_check_; // pc offset of next buffer check. 108865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 10892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Emission of the trampoline pool may be blocked in some code sequences. 109065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. 10912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int no_trampoline_pool_before_; // Block emission before this pc offset. 10922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 10932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Keep track of the last emitted pool to guarantee a maximal distance. 10942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int last_trampoline_pool_end_; // pc offset of the end of the last pool. 10952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 10962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Automatic growth of the assembly buffer may be blocked for some sequences. 10972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool block_buffer_growth_; // Block growth when true. 10982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 10992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Relocation information generation. 11002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Each relocation is encoded as a variable size value. 11012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 11022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RelocInfoWriter reloc_info_writer; 11032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // The bound position, before this we cannot do instruction elimination. 11052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int last_bound_pos_; 11062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Code emission. 11082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block inline void CheckBuffer(); 11092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void GrowBuffer(); 11102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block inline void emit(Instr x); 11112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block inline void CheckTrampolinePoolQuick(); 11122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Instruction generation. 11142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // We have 3 different kind of encoding layout on MIPS. 11152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // However due to many different types of objects encoded in the same fields 11162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // we have quite a few aliases for each mode. 11172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Using the same structure to refer to Register and FPURegister would spare a 11182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // few aliases, but mixing both does not look clean to me. 11192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Anyway we could surely implement this differently. 11202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void GenInstrRegister(Opcode opcode, 11222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rs, 11232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rt, 11242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rd, 11252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block uint16_t sa = 0, 11262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block SecondaryField func = NULLSF); 11272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void GenInstrRegister(Opcode opcode, 11292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rs, 11302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rt, 11312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block uint16_t msb, 11322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block uint16_t lsb, 11332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block SecondaryField func); 11342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void GenInstrRegister(Opcode opcode, 11362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block SecondaryField fmt, 113765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister ft, 113865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister fs, 113965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister fd, 114065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch SecondaryField func = NULLSF); 114165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 114265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void GenInstrRegister(Opcode opcode, 114381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch SecondaryField fmt, 114465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Register rt, 114565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister fs, 114665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister fd, 114765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch SecondaryField func = NULLSF); 114865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 114965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void GenInstrRegister(Opcode opcode, 115065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch SecondaryField fmt, 115165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Register rt, 115265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPUControlRegister fs, 115365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch SecondaryField func = NULLSF); 115465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 115565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 11562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void GenInstrImmediate(Opcode opcode, 11572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rs, 11582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Register rt, 11592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int32_t j); 116065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void GenInstrImmediate(Opcode opcode, 116165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Register rs, 116265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch SecondaryField SF, 116365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t j); 116465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void GenInstrImmediate(Opcode opcode, 116565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Register r1, 116665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch FPURegister r2, 116765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch int32_t j); 11682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void GenInstrJump(Opcode opcode, 11712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block uint32_t address); 11722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Helpers. 11742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void LoadRegPlusOffsetToAt(const MemOperand& src); 11752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Labels. 11772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void print(Label* L); 11782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void bind_to(Label* L, int pos); 11792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void next(Label* L); 11802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 11812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // One trampoline consists of: 118265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // - space for trampoline slots, 118365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // - space for labels. 118465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // 118565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Space for trampoline slots is equal to slot_count * 2 * kInstrSize. 118665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Space for trampoline slots preceeds space for labels. Each label is of one 118765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // instruction size, so total amount for labels is equal to 118865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // label_count * kInstrSize. 118965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch class Trampoline { 119065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch public: 119165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Trampoline() { 119265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch start_ = 0; 119365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch next_slot_ = 0; 11942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block free_slot_count_ = 0; 11952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block end_ = 0; 11962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 11972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Trampoline(int start, int slot_count) { 11982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block start_ = start; 11992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block next_slot_ = start; 120065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch free_slot_count_ = slot_count; 120165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch end_ = start + slot_count * kTrampolineSlotsSize; 120265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 12032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int start() { 12042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return start_; 12052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 12062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int end() { 12072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return end_; 12082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 12092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int take_slot() { 12102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int trampoline_slot = kInvalidSlotPos; 12112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (free_slot_count_ <= 0) { 12122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // We have run out of space on trampolines. 12132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Make sure we fail in debug mode, so we become aware of each case 12142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // when this happens. 12152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(0); 12162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Internal exception will be caught. 12172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else { 12182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block trampoline_slot = next_slot_; 12192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block free_slot_count_--; 12202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block next_slot_ += kTrampolineSlotsSize; 12212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 12222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return trampoline_slot; 12232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 12242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block private: 12262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int start_; 12272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int end_; 12282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int next_slot_; 12292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int free_slot_count_; 12302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block }; 12312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int32_t get_trampoline_entry(int32_t pos); 12332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int unbound_labels_count_; 12342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // If trampoline is emitted, generated code is becoming large. As this is 12352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // already a slow case which can possibly break our code generation for the 12362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // extreme case, we use this information to trigger different mode of 12372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // branch instruction generation, where we use jump instructions rather 12382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // than regular branch instructions. 12392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool trampoline_emitted_; 12402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const int kTrampolineSlotsSize = 4 * kInstrSize; 12412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; 12422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static const int kInvalidSlotPos = -1; 12432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Trampoline trampoline_; 12452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool internal_trampoline_exception_; 12462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class RegExpMacroAssemblerMIPS; 12482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class RelocInfo; 12492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class CodePatcher; 12502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class BlockTrampolinePoolScope; 12512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block PositionsRecorder positions_recorder_; 12532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool emit_debug_code_; 12542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class PositionsRecorder; 12552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block friend class EnsureSpace; 12562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}; 12572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12592fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass EnsureSpace BASE_EMBEDDED { 12602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block public: 12612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block explicit EnsureSpace(Assembler* assembler) { 12622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block assembler->CheckBuffer(); 12632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 12642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}; 12652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} } // namespace v8::internal 12672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 12682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif // V8_ARM_ASSEMBLER_MIPS_H_ 12692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block