15c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Copyright (c) 1994-2006 Sun Microsystems Inc. 25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// All Rights Reserved. 35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without 55c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are 65c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met: 75c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 85c838251403b0be9a882540f1922577abba4c872ager@chromium.org// - Redistributions of source code must retain the above copyright notice, 95c838251403b0be9a882540f1922577abba4c872ager@chromium.org// this list of conditions and the following disclaimer. 105c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 115c838251403b0be9a882540f1922577abba4c872ager@chromium.org// - Redistribution in binary form must reproduce the above copyright 125c838251403b0be9a882540f1922577abba4c872ager@chromium.org// notice, this list of conditions and the following disclaimer in the 135c838251403b0be9a882540f1922577abba4c872ager@chromium.org// documentation and/or other materials provided with the distribution. 145c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 155c838251403b0be9a882540f1922577abba4c872ager@chromium.org// - Neither the name of Sun Microsystems or the names of contributors may 165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// be used to endorse or promote products derived from this software without 175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// specific prior written permission. 185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 275c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 285c838251403b0be9a882540f1922577abba4c872ager@chromium.org// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 295c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 315c838251403b0be9a882540f1922577abba4c872ager@chromium.org// The original source code covered by the above license above has been 325c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modified significantly by Google Inc. 332efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 365c838251403b0be9a882540f1922577abba4c872ager@chromium.org#ifndef V8_MIPS_ASSEMBLER_MIPS_H_ 375c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define V8_MIPS_ASSEMBLER_MIPS_H_ 385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 395c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include <stdio.h> 405c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "assembler.h" 415c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "constants-mips.h" 425c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "serialize.h" 435c838251403b0be9a882540f1922577abba4c872ager@chromium.org 445c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 { 455c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal { 465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 475c838251403b0be9a882540f1922577abba4c872ager@chromium.org// CPU Registers. 485c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 495c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 1) We would prefer to use an enum, but enum values are assignment- 505c838251403b0be9a882540f1922577abba4c872ager@chromium.org// compatible with int, which has caused code-generation bugs. 515c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 525c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 2) We would prefer to use a class instead of a struct but we don't like 535c838251403b0be9a882540f1922577abba4c872ager@chromium.org// the register initialization to depend on the particular initialization 545c838251403b0be9a882540f1922577abba4c872ager@chromium.org// order (which appears to be different on OS X, Linux, and Windows for the 555c838251403b0be9a882540f1922577abba4c872ager@chromium.org// installed versions of C++ we tried). Using a struct permits C-style 565c838251403b0be9a882540f1922577abba4c872ager@chromium.org// "initialization". Also, the Register objects cannot be const as this 575c838251403b0be9a882540f1922577abba4c872ager@chromium.org// forces initialization stubs in MSVC, making us dependent on initialization 585c838251403b0be9a882540f1922577abba4c872ager@chromium.org// order. 595c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 605c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 3) By not using an enum, we are possibly preventing the compiler from 615c838251403b0be9a882540f1922577abba4c872ager@chromium.org// doing certain constant folds, which may significantly reduce the 625c838251403b0be9a882540f1922577abba4c872ager@chromium.org// code generated for some assembly instructions (because they boil down 635c838251403b0be9a882540f1922577abba4c872ager@chromium.org// to a few constants). If this is a problem, we could change the code 645c838251403b0be9a882540f1922577abba4c872ager@chromium.org// such that we use an enum in optimized mode, and the struct in debug 655c838251403b0be9a882540f1922577abba4c872ager@chromium.org// mode. This way we get the compile-time error checking in debug mode 665c838251403b0be9a882540f1922577abba4c872ager@chromium.org// and best performance in optimized code. 675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 695c838251403b0be9a882540f1922577abba4c872ager@chromium.org// ----------------------------------------------------------------------------- 7083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org// Implementation of Register and FPURegister. 715c838251403b0be9a882540f1922577abba4c872ager@chromium.org 725c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Core register. 735c838251403b0be9a882540f1922577abba4c872ager@chromium.orgstruct Register { 747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kNumRegisters = v8::internal::kNumRegisters; 7559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org static const int kMaxNumAllocatableRegisters = 14; // v0 through t7. 7683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static const int kSizeInBytes = 4; 7759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 7859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org inline static int NumAllocatableRegisters(); 797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static int ToAllocationIndex(Register reg) { 817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return reg.code() - 2; // zero_reg and 'at' are skipped. 827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static Register FromAllocationIndex(int index) { 8559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return from_code(index + 2); // zero_reg and 'at' are skipped. 877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const char* AllocationIndexToString(int index) { 9059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org const char* const names[] = { 927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "v0", 937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "v1", 947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "a0", 957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "a1", 967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "a2", 977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "a3", 987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t0", 997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t1", 1007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t2", 1017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t3", 1027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t4", 1037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t5", 1047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t6", 1057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org "t7", 1067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org }; 1077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return names[index]; 1087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 1097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static Register from_code(int code) { 1117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register r = { code }; 1127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return r; 1137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 1147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 1164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org bool is(Register reg) const { return code_ == reg.code_; } 1174a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int code() const { 1185c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_valid()); 1195c838251403b0be9a882540f1922577abba4c872ager@chromium.org return code_; 1205c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 1214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int bit() const { 1225c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_valid()); 1235c838251403b0be9a882540f1922577abba4c872ager@chromium.org return 1 << code_; 1245c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 1255c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1265c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Unfortunately we can't make this private in a struct. 1275c838251403b0be9a882540f1922577abba4c872ager@chromium.org int code_; 1285c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 1295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1307d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org#define REGISTER(N, C) \ 1317d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org const int kRegister_ ## N ## _Code = C; \ 1327d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org const Register N = { C } 1337d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 1347d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(no_reg, -1); 1357d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// Always zero. 1367d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(zero_reg, 0); 1377d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// at: Reserved for synthetic instructions. 1387d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(at, 1); 1397d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// v0, v1: Used when returning multiple values from subroutines. 1407d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(v0, 2); 1417d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(v1, 3); 1427d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// a0 - a4: Used to pass non-FP parameters. 1437d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(a0, 4); 1447d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(a1, 5); 1457d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(a2, 6); 1467d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(a3, 7); 1477d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// t0 - t9: Can be used without reservation, act as temporary registers and are 1487d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// allowed to be destroyed by subroutines. 1497d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t0, 8); 1507d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t1, 9); 1517d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t2, 10); 1527d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t3, 11); 1537d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t4, 12); 1547d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t5, 13); 1557d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t6, 14); 1567d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t7, 15); 1577d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// s0 - s7: Subroutine register variables. Subroutines that write to these 1587d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// registers must restore their values before exiting so that the caller can 1597d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// expect the values to be preserved. 1607d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s0, 16); 1617d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s1, 17); 1627d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s2, 18); 1637d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s3, 19); 1647d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s4, 20); 1657d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s5, 21); 1667d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s6, 22); 1677d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(s7, 23); 1687d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t8, 24); 1697d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(t9, 25); 1707d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// k0, k1: Reserved for system calls and interrupt handlers. 1717d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(k0, 26); 1727d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(k1, 27); 1737d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// gp: Reserved. 1747d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(gp, 28); 1757d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// sp: Stack pointer. 1767d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(sp, 29); 1777d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// fp: Frame pointer. 1787d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(fp, 30); 1797d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// ra: Return address pointer. 1807d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgREGISTER(ra, 31); 1817d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 1827d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org#undef REGISTER 1837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1845c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1855c838251403b0be9a882540f1922577abba4c872ager@chromium.orgint ToNumber(Register reg); 1865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1875c838251403b0be9a882540f1922577abba4c872ager@chromium.orgRegister ToRegister(int num); 1885c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1895c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Coprocessor register. 1905c838251403b0be9a882540f1922577abba4c872ager@chromium.orgstruct FPURegister { 1917c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org static const int kMaxNumRegisters = v8::internal::kNumFPURegisters; 19234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 19334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers 19434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to 19534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // number of Double regs (64-bit regs, or FPU-reg-pairs). 19634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 19734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // A few double registers are reserved: one as a scratch register and one to 19834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // hold 0.0. 19934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // f28: 0.0 20034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // f30: scratch register. 20134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org static const int kNumReservedRegisters = 2; 2027c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org static const int kMaxNumAllocatableRegisters = kMaxNumRegisters / 2 - 20334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org kNumReservedRegisters; 20434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 20559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org inline static int NumRegisters(); 20659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org inline static int NumAllocatableRegisters(); 2072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org inline static int ToAllocationIndex(FPURegister reg); 20859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org static const char* AllocationIndexToString(int index); 2097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static FPURegister FromAllocationIndex(int index) { 21159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 21234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return from_code(index * 2); 2137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 2147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static FPURegister from_code(int code) { 2167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FPURegister r = { code }; 2177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return r; 2187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 2197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2207c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; } 2214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org bool is(FPURegister creg) const { return code_ == creg.code_; } 22234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org FPURegister low() const { 22334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Find low reg of a Double-reg pair, which is the reg itself. 22434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(code_ % 2 == 0); // Specified Double reg must be even. 22534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org FPURegister reg; 22634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org reg.code_ = code_; 22734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(reg.is_valid()); 22834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return reg; 22934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 23034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org FPURegister high() const { 23134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Find high reg of a Doubel-reg pair, which is reg + 1. 23234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(code_ % 2 == 0); // Specified Double reg must be even. 23334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org FPURegister reg; 23434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org reg.code_ = code_ + 1; 23534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(reg.is_valid()); 23634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return reg; 23734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 23834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 2394a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int code() const { 2405c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_valid()); 2415c838251403b0be9a882540f1922577abba4c872ager@chromium.org return code_; 2425c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 2434a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int bit() const { 2445c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(is_valid()); 2455c838251403b0be9a882540f1922577abba4c872ager@chromium.org return 1 << code_; 2465c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 2477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void setcode(int f) { 2487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org code_ = f; 2497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(is_valid()); 2507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 2515c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Unfortunately we can't make this private in a struct. 2525c838251403b0be9a882540f1922577abba4c872ager@chromium.org int code_; 2535c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 2545c838251403b0be9a882540f1922577abba4c872ager@chromium.org 25534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// V8 now supports the O32 ABI, and the FPU Registers are organized as 32 25634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// 32-bit registers, f0 through f31. When used as 'double' they are used 25734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// in pairs, starting with the even numbered register. So a double operation 25834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// on f0 really uses f0 and f1. 25934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// (Modern mips hardware also supports 32 64-bit registers, via setting 26034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// (priviledged) Status Register FR bit to 1. This is used by the N32 ABI, 26134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// but it is not in common use. Someday we will want to support this in v8.) 26234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 26334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. 2647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgtypedef FPURegister DoubleRegister; 26534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgtypedef FPURegister FloatRegister; 2667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 26734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgconst FPURegister no_freg = { -1 }; 2687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f0 = { 0 }; // Return value in hard float mode. 2707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f1 = { 1 }; 2717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f2 = { 2 }; 2727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f3 = { 3 }; 2737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f4 = { 4 }; 2747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f5 = { 5 }; 2757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f6 = { 6 }; 2767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f7 = { 7 }; 2777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f8 = { 8 }; 2787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f9 = { 9 }; 2797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f10 = { 10 }; 2807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f11 = { 11 }; 2817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f12 = { 12 }; // Arg 0 in hard float mode. 2827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f13 = { 13 }; 2837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f14 = { 14 }; // Arg 1 in hard float mode. 2847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f15 = { 15 }; 2857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f16 = { 16 }; 2867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f17 = { 17 }; 2877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f18 = { 18 }; 2887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f19 = { 19 }; 2897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f20 = { 20 }; 2907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f21 = { 21 }; 2917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f22 = { 22 }; 2927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f23 = { 23 }; 2937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f24 = { 24 }; 2947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f25 = { 25 }; 2957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f26 = { 26 }; 2967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f27 = { 27 }; 2977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f28 = { 28 }; 2987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f29 = { 29 }; 2997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f30 = { 30 }; 3007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPURegister f31 = { 31 }; 3017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Register aliases. 3032efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// cp is assumed to be a callee saved register. 30489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org// Defined using #define instead of "static const Register&" because Clang 30589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org// complains otherwise when a compilation unit that includes this header 30689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org// doesn't use the variables. 30789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#define kRootRegister s6 30889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#define cp s7 30989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#define kLithiumScratchReg s3 31089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#define kLithiumScratchReg2 s4 31189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#define kLithiumScratchDouble f30 31289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#define kDoubleRegZero f28 31334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 3147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// FPU (coprocessor 1) control registers. 3157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Currently only FCSR (#31) is implemented. 3167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgstruct FPUControlRegister { 3177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool is_valid() const { return code_ == kFCSRRegister; } 3187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool is(FPUControlRegister creg) const { return code_ == creg.code_; } 3197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int code() const { 3207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(is_valid()); 3217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return code_; 3227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 3237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int bit() const { 3247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(is_valid()); 3257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return 1 << code_; 3267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 3277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void setcode(int f) { 3287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org code_ = f; 3297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(is_valid()); 3307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 3317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Unfortunately we can't make this private in a struct. 3327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int code_; 3335c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 3345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 33583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgconst FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; 3367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgconst FPUControlRegister FCSR = { kFCSRRegister }; 3375c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3395c838251403b0be9a882540f1922577abba4c872ager@chromium.org// ----------------------------------------------------------------------------- 3405c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Machine instruction Operands. 3415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3425c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Class Operand represents a shifter operand in data processing instructions. 3435c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass Operand BASE_EMBEDDED { 3445c838251403b0be9a882540f1922577abba4c872ager@chromium.org public: 3455c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Immediate. 3465c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(explicit Operand(int32_t immediate, 34759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org RelocInfo::Mode rmode = RelocInfo::NONE32)); 3485c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(explicit Operand(const ExternalReference& f)); 3495c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(explicit Operand(const char* s)); 3505c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(explicit Operand(Object** opp)); 3515c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(explicit Operand(Context** cpp)); 3525c838251403b0be9a882540f1922577abba4c872ager@chromium.org explicit Operand(Handle<Object> handle); 3535c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(explicit Operand(Smi* value)); 3545c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3555c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Register. 3565c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(explicit Operand(Register rm)); 3575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3585c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Return true if this is a register operand. 3595c838251403b0be9a882540f1922577abba4c872ager@chromium.org INLINE(bool is_reg() const); 3605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 361594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org inline int32_t immediate() const { 362594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(!is_reg()); 363594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return imm32_; 364594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 365594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 3665c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rm() const { return rm_; } 3675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3685c838251403b0be9a882540f1922577abba4c872ager@chromium.org private: 3695c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rm_; 37083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org int32_t imm32_; // Valid if rm_ == no_reg. 3715c838251403b0be9a882540f1922577abba4c872ager@chromium.org RelocInfo::Mode rmode_; 3725c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3735c838251403b0be9a882540f1922577abba4c872ager@chromium.org friend class Assembler; 3745c838251403b0be9a882540f1922577abba4c872ager@chromium.org friend class MacroAssembler; 3755c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 3765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3775c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3785c838251403b0be9a882540f1922577abba4c872ager@chromium.org// On MIPS we have only one adressing mode with base_reg + offset. 3795c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Class MemOperand represents a memory operand in load and store instructions. 3805c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass MemOperand : public Operand { 3815c838251403b0be9a882540f1922577abba4c872ager@chromium.org public: 3827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org explicit MemOperand(Register rn, int32_t offset = 0); 38304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org int32_t offset() const { return offset_; } 3845c838251403b0be9a882540f1922577abba4c872ager@chromium.org 38534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org bool OffsetIsInt16Encodable() const { 38634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return is_int16(offset_); 38734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 38834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 3895c838251403b0be9a882540f1922577abba4c872ager@chromium.org private: 3907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t offset_; 3915c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3925c838251403b0be9a882540f1922577abba4c872ager@chromium.org friend class Assembler; 3935c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 3945c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3955c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// CpuFeatures keeps track of which features are supported by the target CPU. 397750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// Supported features must be enabled by a CpuFeatureScope before use. 39883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgclass CpuFeatures : public AllStatic { 3997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public: 4007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Detect features of the target CPU. Set safe defaults if the serializer 4017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // is enabled (snapshots must be portable). 40283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static void Probe(); 4037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Check whether a feature is supported by the target CPU. 40583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static bool IsSupported(CpuFeature f) { 40683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(initialized_); 4077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return (supported_ & (1u << f)) != 0; 4087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 4097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 410750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org static bool IsFoundByRuntimeProbingOnly(CpuFeature f) { 41183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(initialized_); 412750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return (found_by_runtime_probing_only_ & 413750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org (static_cast<uint64_t>(1) << f)) != 0; 4147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 41583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 4166e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org static bool IsSafeForSnapshot(CpuFeature f) { 4176e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org return (IsSupported(f) && 4186e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f))); 4196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 4206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 42183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org private: 42283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#ifdef DEBUG 42383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static bool initialized_; 42483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#endif 42583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static unsigned supported_; 426750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org static unsigned found_by_runtime_probing_only_; 4277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 428003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org friend class ExternalReference; 4297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org DISALLOW_COPY_AND_ASSIGN(CpuFeatures); 4307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}; 4317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgclass Assembler : public AssemblerBase { 4345c838251403b0be9a882540f1922577abba4c872ager@chromium.org public: 4355c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Create an assembler. Instructions and relocation information are emitted 4365c838251403b0be9a882540f1922577abba4c872ager@chromium.org // into a buffer, with the instructions starting from the beginning and the 4375c838251403b0be9a882540f1922577abba4c872ager@chromium.org // relocation information starting from the end of the buffer. See CodeDesc 4385c838251403b0be9a882540f1922577abba4c872ager@chromium.org // for a detailed comment on the layout (globals.h). 4395c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 4405c838251403b0be9a882540f1922577abba4c872ager@chromium.org // If the provided buffer is NULL, the assembler allocates and grows its own 4415c838251403b0be9a882540f1922577abba4c872ager@chromium.org // buffer, and buffer_size determines the initial buffer size. The buffer is 4425c838251403b0be9a882540f1922577abba4c872ager@chromium.org // owned by the assembler and deallocated upon destruction of the assembler. 4435c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 4445c838251403b0be9a882540f1922577abba4c872ager@chromium.org // If the provided buffer is not NULL, the assembler uses the provided buffer 4455c838251403b0be9a882540f1922577abba4c872ager@chromium.org // for code generation and assumes its size to be buffer_size. If the buffer 4465c838251403b0be9a882540f1922577abba4c872ager@chromium.org // is too small, a fatal error occurs. No deallocation of the buffer is done 4475c838251403b0be9a882540f1922577abba4c872ager@chromium.org // upon destruction of the assembler. 44883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Assembler(Isolate* isolate, void* buffer, int buffer_size); 4498e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org virtual ~Assembler() { } 4505c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4515c838251403b0be9a882540f1922577abba4c872ager@chromium.org // GetCode emits any pending (non-emitted) code and fills the descriptor 4525c838251403b0be9a882540f1922577abba4c872ager@chromium.org // desc. GetCode() is idempotent; it returns the same result if no other 4535c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Assembler functions are invoked in between GetCode() calls. 4545c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GetCode(CodeDesc* desc); 4555c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4565c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Label operations & relative jumps (PPUM Appendix D). 4575c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 4585c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Takes a branch opcode (cc) and a label (L) and generates 4595c838251403b0be9a882540f1922577abba4c872ager@chromium.org // either a backward branch or a forward branch and links it 4605c838251403b0be9a882540f1922577abba4c872ager@chromium.org // to the label fixup chain. Usage: 4615c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 4625c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Label L; // unbound label 4635c838251403b0be9a882540f1922577abba4c872ager@chromium.org // j(cc, &L); // forward branch to unbound label 4645c838251403b0be9a882540f1922577abba4c872ager@chromium.org // bind(&L); // bind label to the current pc 4655c838251403b0be9a882540f1922577abba4c872ager@chromium.org // j(cc, &L); // backward branch to bound label 4665c838251403b0be9a882540f1922577abba4c872ager@chromium.org // bind(&L); // illegal: a label may be bound only once 4675c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 4685c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Note: The same Label can be used for forward and backward branches 4695c838251403b0be9a882540f1922577abba4c872ager@chromium.org // but it may be bound only once. 47083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void bind(Label* L); // Binds an unbound label L to current code position. 4713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Determines if Label is bound and near enough so that branch instruction 4723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // can be used to reach it, instead of jump instruction. 4733cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org bool is_near(Label* L); 4745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 47583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Returns the branch offset to the given label from the current code 47683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // position. Links the label to the current position if it is still unbound. 4775c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Manages the jump elimination optimization if the second parameter is true. 4785c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t branch_offset(Label* L, bool jump_elimination_allowed); 4795c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { 4805c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t o = branch_offset(L, jump_elimination_allowed); 4815c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT((o & 3) == 0); // Assert the offset is aligned. 4825c838251403b0be9a882540f1922577abba4c872ager@chromium.org return o >> 2; 4835c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 4843cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org uint32_t jump_address(Label* L); 4855c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4865c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Puts a labels target address at the given position. 4875c838251403b0be9a882540f1922577abba4c872ager@chromium.org // The high 8 bits are set to zero. 4885c838251403b0be9a882540f1922577abba4c872ager@chromium.org void label_at_put(Label* L, int at_offset); 4895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4905c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Read/Modify the code target address in the branch/call instruction at pc. 4915c838251403b0be9a882540f1922577abba4c872ager@chromium.org static Address target_address_at(Address pc); 4925c838251403b0be9a882540f1922577abba4c872ager@chromium.org static void set_target_address_at(Address pc, Address target); 4935c838251403b0be9a882540f1922577abba4c872ager@chromium.org 49489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // Return the code target address at a call site from the return address 49589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // of that call in the instruction stream. 49689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org inline static Address target_address_from_return_address(Address pc); 49789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 49834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org static void JumpLabelToJumpRegister(Address pc); 49934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 50028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org static void QuietNaN(HeapObject* nan); 50128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 5025c838251403b0be9a882540f1922577abba4c872ager@chromium.org // This sets the branch destination (which gets loaded at the call address). 50388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org // This is for calls and branches within generated code. The serializer 50488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org // has already deserialized the lui/ori instructions etc. 50588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org inline static void deserialization_set_special_target_at( 50688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org Address instruction_payload, Address target) { 50788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org set_target_address_at( 50888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org instruction_payload - kInstructionsFor32BitConstant * kInstrSize, 50988aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org target); 5105c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 5115c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5125c838251403b0be9a882540f1922577abba4c872ager@chromium.org // This sets the branch destination. 5135c838251403b0be9a882540f1922577abba4c872ager@chromium.org // This is for calls and branches to runtime code. 5145c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline static void set_external_target_at(Address instruction_payload, 5155c838251403b0be9a882540f1922577abba4c872ager@chromium.org Address target) { 5165c838251403b0be9a882540f1922577abba4c872ager@chromium.org set_target_address_at(instruction_payload, target); 5175c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 5185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Size of an instruction. 5207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kInstrSize = sizeof(Instr); 5217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Difference between address of current opcode and target address offset. 5237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kBranchPCOffset = 4; 5247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Here we are patching the address in the LUI/ORI instruction pair. 5267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // These values are used in the serialization process and must be zero for 5277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // MIPS platform, as Code, Embedded Object or External-reference pointers 5287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // are split across two consecutive instructions and don't exist separately 5297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // in the code, so the serializer should not step forwards in memory after 5307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // a target is resolved and written. 53188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org static const int kSpecialTargetSize = 0; 5327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Number of consecutive instructions used to store 32bit constant. 53434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Before jump-optimizations, this constant was used in 53534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // RelocInfo::target_address_address() function to tell serializer address of 53634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // the instruction that follows LUI/ORI instruction pair. Now, with new jump 53734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // optimization, where jump-through-register instruction that usually 53834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // follows LUI/ORI pair is substituted with J/JAL, this constant equals 53934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // to 3 instructions (LUI+ORI+J/JAL/JR/JALR). 54034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org static const int kInstructionsFor32BitConstant = 3; 5415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5425c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Distance between the instruction referring to the address of the call 5435c838251403b0be9a882540f1922577abba4c872ager@chromium.org // target and the return address. 5445c838251403b0be9a882540f1922577abba4c872ager@chromium.org static const int kCallTargetAddressOffset = 4 * kInstrSize; 5455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5465c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Distance between start of patched return sequence and the emitted address 5475c838251403b0be9a882540f1922577abba4c872ager@chromium.org // to jump to. 5487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kPatchReturnSequenceAddressOffset = 0; 5495c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5502356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Distance between start of patched debug break slot and the emitted address 5512356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // to jump to. 5527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; 5537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Difference between address of current opcode and value read from pc 5557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // register. 5567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kPcLoadDelta = 4; 5577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 55889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org static const int kPatchDebugBreakSlotReturnOffset = 4 * kInstrSize; 55989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 5607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Number of instructions used for the JS return sequence. The constant is 5617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // used by the debugger to patch the JS return sequence. 5627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kJSReturnSequenceInstructions = 7; 5637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kDebugBreakSlotInstructions = 4; 5647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kDebugBreakSlotLength = 5657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org kDebugBreakSlotInstructions * kInstrSize; 5667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5685c838251403b0be9a882540f1922577abba4c872ager@chromium.org // --------------------------------------------------------------------------- 5695c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Code generation. 5705c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Insert the smallest number of nop instructions 5727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // possible to align the pc offset to a multiple 5737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // of m. m must be a power of 2 (>= 4). 5747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void Align(int m); 5757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Aligns code to something that's optimal for a jump target for the platform. 5767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void CodeTargetAlign(); 5777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Different nop operations are used by the code generator to detect certain 5797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // states of the generated code. 5807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org enum NopMarkerTypes { 5817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org NON_MARKING_NOP = 0, 5827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org DEBUG_BREAK_NOP, 5837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // IC markers. 5847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org PROPERTY_ACCESS_INLINED, 5857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org PROPERTY_ACCESS_INLINED_CONTEXT, 5867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE, 5877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Helper values. 5887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org LAST_CODE_MARKER, 589fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED, 590fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Code aging 591ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CODE_AGE_MARKER_NOP = 6, 592ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CODE_AGE_SEQUENCE_NOP 5937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org }; 5947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 59533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // Type == 0 is the default non-marking nop. For mips this is a 59633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // sll(zero_reg, zero_reg, 0). We use rt_reg == at for non-zero 59733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // marking, to avoid conflict with ssnop and ehb instructions. 5987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void nop(unsigned int type = 0) { 5997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(type < 32); 60033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Register nop_rt_reg = (type == 0) ? zero_reg : at; 60133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org sll(zero_reg, nop_rt_reg, type, true); 6027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 6035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6045c838251403b0be9a882540f1922577abba4c872ager@chromium.org 60583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // --------Branch-and-jump-instructions---------- 6065c838251403b0be9a882540f1922577abba4c872ager@chromium.org // We don't use likely variant of instructions. 6075c838251403b0be9a882540f1922577abba4c872ager@chromium.org void b(int16_t offset); 6085c838251403b0be9a882540f1922577abba4c872ager@chromium.org void b(Label* L) { b(branch_offset(L, false)>>2); } 6095c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bal(int16_t offset); 6105c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bal(Label* L) { bal(branch_offset(L, false)>>2); } 6115c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6125c838251403b0be9a882540f1922577abba4c872ager@chromium.org void beq(Register rs, Register rt, int16_t offset); 6135c838251403b0be9a882540f1922577abba4c872ager@chromium.org void beq(Register rs, Register rt, Label* L) { 6145c838251403b0be9a882540f1922577abba4c872ager@chromium.org beq(rs, rt, branch_offset(L, false) >> 2); 6155c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 6165c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bgez(Register rs, int16_t offset); 6175c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bgezal(Register rs, int16_t offset); 6185c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bgtz(Register rs, int16_t offset); 6195c838251403b0be9a882540f1922577abba4c872ager@chromium.org void blez(Register rs, int16_t offset); 6205c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bltz(Register rs, int16_t offset); 6215c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bltzal(Register rs, int16_t offset); 6225c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bne(Register rs, Register rt, int16_t offset); 6235c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bne(Register rs, Register rt, Label* L) { 6245c838251403b0be9a882540f1922577abba4c872ager@chromium.org bne(rs, rt, branch_offset(L, false)>>2); 6255c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 6265c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6275c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Never use the int16_t b(l)cond version with a branch offset 62883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // instead of using the Label* version. 6295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6302efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits. 6315c838251403b0be9a882540f1922577abba4c872ager@chromium.org void j(int32_t target); 6325c838251403b0be9a882540f1922577abba4c872ager@chromium.org void jal(int32_t target); 6335c838251403b0be9a882540f1922577abba4c872ager@chromium.org void jalr(Register rs, Register rd = ra); 6345c838251403b0be9a882540f1922577abba4c872ager@chromium.org void jr(Register target); 63534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org void j_or_jr(int32_t target, Register rs); 63634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org void jal_or_jalr(int32_t target, Register rs); 6375c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6395c838251403b0be9a882540f1922577abba4c872ager@chromium.org //-------Data-processing-instructions--------- 6405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6415c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Arithmetic. 6425c838251403b0be9a882540f1922577abba4c872ager@chromium.org void addu(Register rd, Register rs, Register rt); 6435c838251403b0be9a882540f1922577abba4c872ager@chromium.org void subu(Register rd, Register rs, Register rt); 6445c838251403b0be9a882540f1922577abba4c872ager@chromium.org void mult(Register rs, Register rt); 6455c838251403b0be9a882540f1922577abba4c872ager@chromium.org void multu(Register rs, Register rt); 6465c838251403b0be9a882540f1922577abba4c872ager@chromium.org void div(Register rs, Register rt); 6475c838251403b0be9a882540f1922577abba4c872ager@chromium.org void divu(Register rs, Register rt); 6485c838251403b0be9a882540f1922577abba4c872ager@chromium.org void mul(Register rd, Register rs, Register rt); 6495c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6505c838251403b0be9a882540f1922577abba4c872ager@chromium.org void addiu(Register rd, Register rs, int32_t j); 6515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6525c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Logical. 6535c838251403b0be9a882540f1922577abba4c872ager@chromium.org void and_(Register rd, Register rs, Register rt); 6545c838251403b0be9a882540f1922577abba4c872ager@chromium.org void or_(Register rd, Register rs, Register rt); 6555c838251403b0be9a882540f1922577abba4c872ager@chromium.org void xor_(Register rd, Register rs, Register rt); 6565c838251403b0be9a882540f1922577abba4c872ager@chromium.org void nor(Register rd, Register rs, Register rt); 6575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6585c838251403b0be9a882540f1922577abba4c872ager@chromium.org void andi(Register rd, Register rs, int32_t j); 6595c838251403b0be9a882540f1922577abba4c872ager@chromium.org void ori(Register rd, Register rs, int32_t j); 6605c838251403b0be9a882540f1922577abba4c872ager@chromium.org void xori(Register rd, Register rs, int32_t j); 6615c838251403b0be9a882540f1922577abba4c872ager@chromium.org void lui(Register rd, int32_t j); 6625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6635c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Shifts. 6647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop 6657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // and may cause problems in normal code. coming_from_nop makes sure this 6667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // doesn't happen. 6677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false); 6685c838251403b0be9a882540f1922577abba4c872ager@chromium.org void sllv(Register rd, Register rt, Register rs); 6695c838251403b0be9a882540f1922577abba4c872ager@chromium.org void srl(Register rd, Register rt, uint16_t sa); 6705c838251403b0be9a882540f1922577abba4c872ager@chromium.org void srlv(Register rd, Register rt, Register rs); 6715c838251403b0be9a882540f1922577abba4c872ager@chromium.org void sra(Register rt, Register rd, uint16_t sa); 6725c838251403b0be9a882540f1922577abba4c872ager@chromium.org void srav(Register rt, Register rd, Register rs); 6737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void rotr(Register rd, Register rt, uint16_t sa); 6747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void rotrv(Register rd, Register rt, Register rs); 6755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6775c838251403b0be9a882540f1922577abba4c872ager@chromium.org //------------Memory-instructions------------- 6785c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6795c838251403b0be9a882540f1922577abba4c872ager@chromium.org void lb(Register rd, const MemOperand& rs); 6805c838251403b0be9a882540f1922577abba4c872ager@chromium.org void lbu(Register rd, const MemOperand& rs); 6817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void lh(Register rd, const MemOperand& rs); 6827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void lhu(Register rd, const MemOperand& rs); 6835c838251403b0be9a882540f1922577abba4c872ager@chromium.org void lw(Register rd, const MemOperand& rs); 6847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void lwl(Register rd, const MemOperand& rs); 6857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void lwr(Register rd, const MemOperand& rs); 6865c838251403b0be9a882540f1922577abba4c872ager@chromium.org void sb(Register rd, const MemOperand& rs); 6877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void sh(Register rd, const MemOperand& rs); 6885c838251403b0be9a882540f1922577abba4c872ager@chromium.org void sw(Register rd, const MemOperand& rs); 6897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void swl(Register rd, const MemOperand& rs); 6907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void swr(Register rd, const MemOperand& rs); 6915c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6925c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6935c838251403b0be9a882540f1922577abba4c872ager@chromium.org //-------------Misc-instructions-------------- 6945c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6955c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Break / Trap instructions. 696c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void break_(uint32_t code, bool break_as_stop = false); 697c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void stop(const char* msg, uint32_t code = kMaxStopCode); 6985c838251403b0be9a882540f1922577abba4c872ager@chromium.org void tge(Register rs, Register rt, uint16_t code); 6995c838251403b0be9a882540f1922577abba4c872ager@chromium.org void tgeu(Register rs, Register rt, uint16_t code); 7005c838251403b0be9a882540f1922577abba4c872ager@chromium.org void tlt(Register rs, Register rt, uint16_t code); 7015c838251403b0be9a882540f1922577abba4c872ager@chromium.org void tltu(Register rs, Register rt, uint16_t code); 7025c838251403b0be9a882540f1922577abba4c872ager@chromium.org void teq(Register rs, Register rt, uint16_t code); 7035c838251403b0be9a882540f1922577abba4c872ager@chromium.org void tne(Register rs, Register rt, uint16_t code); 7045c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7055c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Move from HI/LO register. 7065c838251403b0be9a882540f1922577abba4c872ager@chromium.org void mfhi(Register rd); 7075c838251403b0be9a882540f1922577abba4c872ager@chromium.org void mflo(Register rd); 7085c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7095c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Set on less than. 7105c838251403b0be9a882540f1922577abba4c872ager@chromium.org void slt(Register rd, Register rs, Register rt); 7115c838251403b0be9a882540f1922577abba4c872ager@chromium.org void sltu(Register rd, Register rs, Register rt); 7125c838251403b0be9a882540f1922577abba4c872ager@chromium.org void slti(Register rd, Register rs, int32_t j); 7135c838251403b0be9a882540f1922577abba4c872ager@chromium.org void sltiu(Register rd, Register rs, int32_t j); 7145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Conditional move. 7167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void movz(Register rd, Register rs, Register rt); 7177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void movn(Register rd, Register rs, Register rt); 7187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void movt(Register rd, Register rs, uint16_t cc = 0); 7197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void movf(Register rd, Register rs, uint16_t cc = 0); 7207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 7217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Bit twiddling. 7227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void clz(Register rd, Register rs); 7237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ins_(Register rt, Register rs, uint16_t pos, uint16_t size); 7247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ext_(Register rt, Register rs, uint16_t pos, uint16_t size); 7255c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7265c838251403b0be9a882540f1922577abba4c872ager@chromium.org //--------Coprocessor-instructions---------------- 7275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7285c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Load, store, and move. 7295c838251403b0be9a882540f1922577abba4c872ager@chromium.org void lwc1(FPURegister fd, const MemOperand& src); 7305c838251403b0be9a882540f1922577abba4c872ager@chromium.org void ldc1(FPURegister fd, const MemOperand& src); 7315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7325c838251403b0be9a882540f1922577abba4c872ager@chromium.org void swc1(FPURegister fs, const MemOperand& dst); 7335c838251403b0be9a882540f1922577abba4c872ager@chromium.org void sdc1(FPURegister fs, const MemOperand& dst); 7345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void mtc1(Register rt, FPURegister fs); 7367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void mfc1(Register rt, FPURegister fs); 7377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 7387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ctc1(Register rt, FPUControlRegister fs); 7397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void cfc1(Register rt, FPUControlRegister fs); 7407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 7417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Arithmetic. 7427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void add_d(FPURegister fd, FPURegister fs, FPURegister ft); 7437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void sub_d(FPURegister fd, FPURegister fs, FPURegister ft); 7447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void mul_d(FPURegister fd, FPURegister fs, FPURegister ft); 74559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft); 7467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void div_d(FPURegister fd, FPURegister fs, FPURegister ft); 7477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void abs_d(FPURegister fd, FPURegister fs); 7487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void mov_d(FPURegister fd, FPURegister fs); 7497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void neg_d(FPURegister fd, FPURegister fs); 7507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void sqrt_d(FPURegister fd, FPURegister fs); 7515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7525c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Conversion. 7535c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_w_s(FPURegister fd, FPURegister fs); 7545c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_w_d(FPURegister fd, FPURegister fs); 7557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void trunc_w_s(FPURegister fd, FPURegister fs); 7567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void trunc_w_d(FPURegister fd, FPURegister fs); 7577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void round_w_s(FPURegister fd, FPURegister fs); 7587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void round_w_d(FPURegister fd, FPURegister fs); 7597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void floor_w_s(FPURegister fd, FPURegister fs); 7607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void floor_w_d(FPURegister fd, FPURegister fs); 7617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ceil_w_s(FPURegister fd, FPURegister fs); 7627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ceil_w_d(FPURegister fd, FPURegister fs); 7635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7645c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_l_s(FPURegister fd, FPURegister fs); 7655c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_l_d(FPURegister fd, FPURegister fs); 7667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void trunc_l_s(FPURegister fd, FPURegister fs); 7677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void trunc_l_d(FPURegister fd, FPURegister fs); 7687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void round_l_s(FPURegister fd, FPURegister fs); 7697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void round_l_d(FPURegister fd, FPURegister fs); 7707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void floor_l_s(FPURegister fd, FPURegister fs); 7717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void floor_l_d(FPURegister fd, FPURegister fs); 7727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ceil_l_s(FPURegister fd, FPURegister fs); 7737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ceil_l_d(FPURegister fd, FPURegister fs); 7745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7755c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_s_w(FPURegister fd, FPURegister fs); 7765c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_s_l(FPURegister fd, FPURegister fs); 7775c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_s_d(FPURegister fd, FPURegister fs); 7785c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7795c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_d_w(FPURegister fd, FPURegister fs); 7805c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_d_l(FPURegister fd, FPURegister fs); 7815c838251403b0be9a882540f1922577abba4c872ager@chromium.org void cvt_d_s(FPURegister fd, FPURegister fs); 7825c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7835c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Conditions and branches. 7845c838251403b0be9a882540f1922577abba4c872ager@chromium.org void c(FPUCondition cond, SecondaryField fmt, 7855c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister ft, FPURegister fs, uint16_t cc = 0); 7865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7875c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bc1f(int16_t offset, uint16_t cc = 0); 7885c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bc1f(Label* L, uint16_t cc = 0) { bc1f(branch_offset(L, false)>>2, cc); } 7895c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bc1t(int16_t offset, uint16_t cc = 0); 7905c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bc1t(Label* L, uint16_t cc = 0) { bc1t(branch_offset(L, false)>>2, cc); } 7917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void fcmp(FPURegister src1, const double src2, FPUCondition cond); 7925c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7935c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Check the code size generated from label to here. 7946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org int SizeOfCodeGeneratedSince(Label* label) { 7956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org return pc_offset() - label->pos(); 7966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 7976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 7986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check the number of instructions generated from label to here. 7996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org int InstructionsGeneratedSince(Label* label) { 8006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org return SizeOfCodeGeneratedSince(label) / kInstrSize; 8015c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 8025c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Class for scoping postponing the trampoline pool generation. 8047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org class BlockTrampolinePoolScope { 8057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public: 8067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) { 8077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org assem_->StartBlockTrampolinePool(); 8087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 8097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ~BlockTrampolinePoolScope() { 8107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org assem_->EndBlockTrampolinePool(); 8117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 8127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private: 8147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Assembler* assem_; 8157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); 8177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org }; 8187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Class for postponing the assembly buffer growth. Typically used for 8203cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // sequences of instructions that must be emitted as a unit, before 8213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // buffer growth (and relocation) can occur. 8223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // This blocking scope is not nestable. 8233cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org class BlockGrowBufferScope { 8243cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org public: 8253cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) { 8263cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org assem_->StartBlockGrowBuffer(); 8273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 8283cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ~BlockGrowBufferScope() { 8293cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org assem_->EndBlockGrowBuffer(); 8303cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 8313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 8323cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org private: 8333cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Assembler* assem_; 8343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 8353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope); 8363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org }; 8373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 8385c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Debugging. 8395c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8405c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Mark address of the ExitJSFrame code. 8415c838251403b0be9a882540f1922577abba4c872ager@chromium.org void RecordJSReturn(); 8425c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Mark address of a debug break slot. 8447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void RecordDebugBreakSlot(); 8457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 84683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Record the AST id of the CallIC being compiled, so that it can be placed 84783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // in the relocation information. 848471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org void SetRecordedAstId(TypeFeedbackId ast_id) { 849471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(recorded_ast_id_.IsNone()); 850717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org recorded_ast_id_ = ast_id; 851717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org } 852717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 853471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId RecordedAstId() { 854471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(!recorded_ast_id_.IsNone()); 855717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org return recorded_ast_id_; 856717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org } 857717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 858471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); } 85983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 8605c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Record a comment relocation entry that can be used by a disassembler. 8617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Use --code-comments to enable. 8625c838251403b0be9a882540f1922577abba4c872ager@chromium.org void RecordComment(const char* msg); 8635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8643cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static int RelocateInternalReference(byte* pc, intptr_t pc_delta); 8653cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 8667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Writes a single byte or word of data in the code stream. Used for 8677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // inline tables, e.g., jump-tables. 8687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void db(uint8_t data); 8697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void dd(uint32_t data); 8705c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org PositionsRecorder* positions_recorder() { return &positions_recorder_; } 8727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Postpone the generation of the trampoline pool for the specified number of 8747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // instructions. 8757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void BlockTrampolinePoolFor(int instructions); 8767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8775c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Check if there is less than kGap bytes available in the buffer. 8785c838251403b0be9a882540f1922577abba4c872ager@chromium.org // If this is the case, we need to grow the buffer before emitting 8795c838251403b0be9a882540f1922577abba4c872ager@chromium.org // an instruction or relocation information. 8805c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; } 8815c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8825c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Get the number of bytes available in the buffer. 8835c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int available_space() const { return reloc_info_writer.pos() - pc_; } 8845c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8855c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Read/patch instructions. 8865c838251403b0be9a882540f1922577abba4c872ager@chromium.org static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 8877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static void instr_at_put(byte* pc, Instr instr) { 8885c838251403b0be9a882540f1922577abba4c872ager@chromium.org *reinterpret_cast<Instr*>(pc) = instr; 8895c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 8905c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 8915c838251403b0be9a882540f1922577abba4c872ager@chromium.org void instr_at_put(int pos, Instr instr) { 8925c838251403b0be9a882540f1922577abba4c872ager@chromium.org *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 8935c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 8945c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8955c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Check if an instruction is a branch of some kind. 8967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsBranch(Instr instr); 89783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static bool IsBeq(Instr instr); 89883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static bool IsBne(Instr instr); 8997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9003cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static bool IsJump(Instr instr); 9013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static bool IsJ(Instr instr); 9023cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static bool IsLui(Instr instr); 9033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static bool IsOri(Instr instr); 9043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 90534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org static bool IsJal(Instr instr); 90634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org static bool IsJr(Instr instr); 90734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org static bool IsJalr(Instr instr); 90834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 9097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsNop(Instr instr, unsigned int type); 9107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsPop(Instr instr); 9117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsPush(Instr instr); 9127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsLwRegFpOffset(Instr instr); 9137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsSwRegFpOffset(Instr instr); 9147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsLwRegFpNegOffset(Instr instr); 9157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsSwRegFpNegOffset(Instr instr); 9167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 91783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static Register GetRtReg(Instr instr); 91883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static Register GetRsReg(Instr instr); 91983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static Register GetRdReg(Instr instr); 92083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 92183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetRt(Instr instr); 92283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetRtField(Instr instr); 92383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetRs(Instr instr); 92483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetRsField(Instr instr); 92583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetRd(Instr instr); 92683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetRdField(Instr instr); 92783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetSa(Instr instr); 92883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetSaField(Instr instr); 92983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetOpcodeField(Instr instr); 9303cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static uint32_t GetFunction(Instr instr); 9313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static uint32_t GetFunctionField(Instr instr); 93283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetImmediate16(Instr instr); 93383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static uint32_t GetLabelConst(Instr instr); 9347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static int32_t GetBranchOffset(Instr instr); 9367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsLw(Instr instr); 9377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static int16_t GetLwOffset(Instr instr); 9387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static Instr SetLwOffset(Instr instr, int16_t offset); 9397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsSw(Instr instr); 9417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static Instr SetSwOffset(Instr instr, int16_t offset); 9427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static bool IsAddImmediate(Instr instr); 9437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static Instr SetAddImmediateOffset(Instr instr, int16_t offset); 9447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 94583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static bool IsAndImmediate(Instr instr); 9467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org static bool IsEmittedConstant(Instr instr); 94783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 9483cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org void CheckTrampolinePool(); 9497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org protected: 95183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Relocation for a type-recording IC has the AST id added to it. This 95283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // member variable is a way to pass the information from the call site to 95383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // the relocation info. 954471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId recorded_ast_id_; 95583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 9567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } 9575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9585c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Decode branch instruction at pos and return branch target pos. 9595c838251403b0be9a882540f1922577abba4c872ager@chromium.org int target_at(int32_t pos); 9605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9615c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Patch branch instruction at pos to branch to given branch target pos. 9625c838251403b0be9a882540f1922577abba4c872ager@chromium.org void target_at_put(int32_t pos, int32_t target_pos); 9635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9645c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Say if we need to relocate with this mode. 9657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool MustUseReg(RelocInfo::Mode rmode); 9665c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9675c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Record reloc info for current pc_. 9685c838251403b0be9a882540f1922577abba4c872ager@chromium.org void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 9695c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Block the emission of the trampoline pool before pc_offset. 9717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void BlockTrampolinePoolBefore(int pc_offset) { 9727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (no_trampoline_pool_before_ < pc_offset) 9737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org no_trampoline_pool_before_ = pc_offset; 9747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 9757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void StartBlockTrampolinePool() { 9777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org trampoline_pool_blocked_nesting_++; 9787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 9793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 9807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void EndBlockTrampolinePool() { 9817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org trampoline_pool_blocked_nesting_--; 9827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 9837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool is_trampoline_pool_blocked() const { 9857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return trampoline_pool_blocked_nesting_ > 0; 9867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 9877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 98883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bool has_exception() const { 98983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return internal_trampoline_exception_; 99083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 99183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 99234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi); 99334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 9943cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org bool is_trampoline_emitted() const { 9953cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return trampoline_emitted_; 9963cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 9973cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 9983cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Temporarily block automatic assembly buffer growth. 9993cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org void StartBlockGrowBuffer() { 10003cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(!block_buffer_growth_); 10013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org block_buffer_growth_ = true; 10023cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 10033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 10043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org void EndBlockGrowBuffer() { 10053cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT(block_buffer_growth_); 10063cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org block_buffer_growth_ = false; 10073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 10083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 10093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org bool is_buffer_growth_blocked() const { 10103cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return block_buffer_growth_; 10113cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 10123cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 10135c838251403b0be9a882540f1922577abba4c872ager@chromium.org private: 10145c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Buffer size and constant pool distance are checked together at regular 10155c838251403b0be9a882540f1922577abba4c872ager@chromium.org // intervals of kBufferCheckInterval emitted bytes. 10165c838251403b0be9a882540f1922577abba4c872ager@chromium.org static const int kBufferCheckInterval = 1*KB/2; 10175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10185c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Code generation. 10195c838251403b0be9a882540f1922577abba4c872ager@chromium.org // The relocation writer's position is at least kGap bytes below the end of 10205c838251403b0be9a882540f1922577abba4c872ager@chromium.org // the generated instructions. This is so that multi-instruction sequences do 10215c838251403b0be9a882540f1922577abba4c872ager@chromium.org // not have to check for overflow. The same is true for writes of large 10225c838251403b0be9a882540f1922577abba4c872ager@chromium.org // relocation info entries. 10235c838251403b0be9a882540f1922577abba4c872ager@chromium.org static const int kGap = 32; 10245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Repeated checking whether the trampoline pool should be emitted is rather 10277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // expensive. By default we only check again once a number of instructions 10287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // has been generated. 10297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kCheckConstIntervalInst = 32; 10307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; 10317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int next_buffer_check_; // pc offset of next buffer check. 10337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Emission of the trampoline pool may be blocked in some code sequences. 10357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. 10367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int no_trampoline_pool_before_; // Block emission before this pc offset. 10377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Keep track of the last emitted pool to guarantee a maximal distance. 10397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int last_trampoline_pool_end_; // pc offset of the end of the last pool. 10407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10413cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Automatic growth of the assembly buffer may be blocked for some sequences. 10423cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org bool block_buffer_growth_; // Block growth when true. 10433cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 10445c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Relocation information generation. 10455c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Each relocation is encoded as a variable size value. 10465c838251403b0be9a882540f1922577abba4c872ager@chromium.org static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 10475c838251403b0be9a882540f1922577abba4c872ager@chromium.org RelocInfoWriter reloc_info_writer; 10485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10495c838251403b0be9a882540f1922577abba4c872ager@chromium.org // The bound position, before this we cannot do instruction elimination. 10505c838251403b0be9a882540f1922577abba4c872ager@chromium.org int last_bound_pos_; 10515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10525c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Code emission. 10535c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void CheckBuffer(); 10545c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GrowBuffer(); 10555c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void emit(Instr x); 10567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org inline void CheckTrampolinePoolQuick(); 10575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10585c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Instruction generation. 10595c838251403b0be9a882540f1922577abba4c872ager@chromium.org // We have 3 different kind of encoding layout on MIPS. 10605c838251403b0be9a882540f1922577abba4c872ager@chromium.org // However due to many different types of objects encoded in the same fields 10615c838251403b0be9a882540f1922577abba4c872ager@chromium.org // we have quite a few aliases for each mode. 10625c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Using the same structure to refer to Register and FPURegister would spare a 10635c838251403b0be9a882540f1922577abba4c872ager@chromium.org // few aliases, but mixing both does not look clean to me. 10645c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Anyway we could surely implement this differently. 10655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10665c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GenInstrRegister(Opcode opcode, 10675c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rs, 10685c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rt, 10695c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rd, 10705c838251403b0be9a882540f1922577abba4c872ager@chromium.org uint16_t sa = 0, 10715c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField func = NULLSF); 10725c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10735c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GenInstrRegister(Opcode opcode, 10747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rs, 10757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt, 10767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uint16_t msb, 10777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uint16_t lsb, 10787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SecondaryField func); 10797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void GenInstrRegister(Opcode opcode, 10815c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField fmt, 10825c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister ft, 10835c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fs, 10845c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fd, 10855c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField func = NULLSF); 10865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10875c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GenInstrRegister(Opcode opcode, 108859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister fr, 108959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister ft, 109059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister fs, 109159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FPURegister fd, 109259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org SecondaryField func = NULLSF); 109359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 109459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org void GenInstrRegister(Opcode opcode, 10955c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField fmt, 10965c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rt, 10975c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fs, 10985c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister fd, 10995c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField func = NULLSF); 11005c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void GenInstrRegister(Opcode opcode, 11027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SecondaryField fmt, 11037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rt, 11047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FPUControlRegister fs, 11057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SecondaryField func = NULLSF); 11067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11075c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11085c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GenInstrImmediate(Opcode opcode, 11095c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rs, 11105c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rt, 11115c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t j); 11125c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GenInstrImmediate(Opcode opcode, 11135c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register rs, 11145c838251403b0be9a882540f1922577abba4c872ager@chromium.org SecondaryField SF, 11155c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t j); 11165c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GenInstrImmediate(Opcode opcode, 11175c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register r1, 11185c838251403b0be9a882540f1922577abba4c872ager@chromium.org FPURegister r2, 11195c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t j); 11205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11215c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11225c838251403b0be9a882540f1922577abba4c872ager@chromium.org void GenInstrJump(Opcode opcode, 11235c838251403b0be9a882540f1922577abba4c872ager@chromium.org uint32_t address); 11245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Helpers. 11267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void LoadRegPlusOffsetToAt(const MemOperand& src); 11275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11285c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Labels. 11295c838251403b0be9a882540f1922577abba4c872ager@chromium.org void print(Label* L); 11305c838251403b0be9a882540f1922577abba4c872ager@chromium.org void bind_to(Label* L, int pos); 11315c838251403b0be9a882540f1922577abba4c872ager@chromium.org void next(Label* L); 11325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // One trampoline consists of: 11347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // - space for trampoline slots, 11357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // - space for labels. 11367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // 11377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Space for trampoline slots is equal to slot_count * 2 * kInstrSize. 11387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Space for trampoline slots preceeds space for labels. Each label is of one 11397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // instruction size, so total amount for labels is equal to 11407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // label_count * kInstrSize. 11417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org class Trampoline { 11427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public: 11433cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Trampoline() { 11443cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org start_ = 0; 11453cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_slot_ = 0; 11463cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org free_slot_count_ = 0; 11473cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org end_ = 0; 11483cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 11493cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Trampoline(int start, int slot_count) { 11507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org start_ = start; 11517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org next_slot_ = start; 11527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org free_slot_count_ = slot_count; 11533cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org end_ = start + slot_count * kTrampolineSlotsSize; 11547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 11557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int start() { 11567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return start_; 11577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 11587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int end() { 11597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return end_; 11607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 11617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int take_slot() { 116283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org int trampoline_slot = kInvalidSlotPos; 116383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (free_slot_count_ <= 0) { 116483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We have run out of space on trampolines. 116583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Make sure we fail in debug mode, so we become aware of each case 116683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // when this happens. 116783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(0); 116883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Internal exception will be caught. 116983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 117083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org trampoline_slot = next_slot_; 117183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org free_slot_count_--; 11723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org next_slot_ += kTrampolineSlotsSize; 117383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 11747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return trampoline_slot; 11757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 117683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org 11777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private: 11787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int start_; 11797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int end_; 11807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int next_slot_; 11817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int free_slot_count_; 11827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org }; 11837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11843cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int32_t get_trampoline_entry(int32_t pos); 11853cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int unbound_labels_count_; 11863cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // If trampoline is emitted, generated code is becoming large. As this is 11873cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // already a slow case which can possibly break our code generation for the 11883cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // extreme case, we use this information to trigger different mode of 11893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // branch instruction generation, where we use jump instructions rather 11903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // than regular branch instructions. 11913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org bool trampoline_emitted_; 11923cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static const int kTrampolineSlotsSize = 4 * kInstrSize; 11937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; 119483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static const int kInvalidSlotPos = -1; 11957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11963cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Trampoline trampoline_; 119783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bool internal_trampoline_exception_; 11987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11995c838251403b0be9a882540f1922577abba4c872ager@chromium.org friend class RegExpMacroAssemblerMIPS; 12005c838251403b0be9a882540f1922577abba4c872ager@chromium.org friend class RelocInfo; 12017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org friend class CodePatcher; 12027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org friend class BlockTrampolinePoolScope; 12037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org PositionsRecorder positions_recorder_; 12057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org friend class PositionsRecorder; 12067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org friend class EnsureSpace; 12077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}; 12087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgclass EnsureSpace BASE_EMBEDDED { 12117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public: 12127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org explicit EnsureSpace(Assembler* assembler) { 12137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org assembler->CheckBuffer(); 12147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 12155c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 12165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12175c838251403b0be9a882540f1922577abba4c872ager@chromium.org} } // namespace v8::internal 12185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12195c838251403b0be9a882540f1922577abba4c872ager@chromium.org#endif // V8_ARM_ASSEMBLER_MIPS_H_ 1220