assembler-mips.h revision 6ded16be15dd865a9b21ea304d5273c8be299c87
13100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Copyright (c) 1994-2006 Sun Microsystems Inc. 23100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// All Rights Reserved. 33100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 43100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Redistribution and use in source and binary forms, with or without 53100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modification, are permitted provided that the following conditions are 63100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// met: 73100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 83100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistributions of source code must retain the above copyright notice, 93100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// this list of conditions and the following disclaimer. 103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistribution in binary form must reproduce the above copyright 123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// notice, this list of conditions and the following disclaimer in the 133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// documentation and/or other materials provided with the distribution. 143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Neither the name of Sun Microsystems or the names of contributors may 163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// be used to endorse or promote products derived from this software without 173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// specific prior written permission. 183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// The original source code covered by the above license above has been 323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modified significantly by Google Inc. 333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Copyright 2010 the V8 project authors. All rights reserved. 343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#ifndef V8_MIPS_ASSEMBLER_MIPS_H_ 373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#define V8_MIPS_ASSEMBLER_MIPS_H_ 383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include <stdio.h> 403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "assembler.h" 413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "constants-mips.h" 423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "serialize.h" 433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuusing namespace assembler::mips; 453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace v8 { 473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace internal { 483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// CPU Registers. 503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 1) We would prefer to use an enum, but enum values are assignment- 523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// compatible with int, which has caused code-generation bugs. 533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 2) We would prefer to use a class instead of a struct but we don't like 553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// the register initialization to depend on the particular initialization 563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// order (which appears to be different on OS X, Linux, and Windows for the 573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// installed versions of C++ we tried). Using a struct permits C-style 583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// "initialization". Also, the Register objects cannot be const as this 593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// forces initialization stubs in MSVC, making us dependent on initialization 603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// order. 613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 3) By not using an enum, we are possibly preventing the compiler from 633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// doing certain constant folds, which may significantly reduce the 643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// code generated for some assembly instructions (because they boil down 653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// to a few constants). If this is a problem, we could change the code 663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// such that we use an enum in optimized mode, and the struct in debug 673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// mode. This way we get the compile-time error checking in debug mode 683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// and best performance in optimized code. 693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Implementation of Register and FPURegister 733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Core register. 753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustruct Register { 763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool is(Register reg) const { return code_ == reg.code_; } 783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int code() const { 793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(is_valid()); 803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return code_; 813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int bit() const { 833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(is_valid()); 843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return 1 << code_; 853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Unfortunately we can't make this private in a struct. 883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int code_; 893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register no_reg; 923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register zero_reg; 943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register at; 953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register v0; 963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register v1; 973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register a0; 983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register a1; 993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register a2; 1003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register a3; 1013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t0; 1023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t1; 1033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t2; 1043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t3; 1053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t4; 1063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t5; 1073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t6; 1083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t7; 1093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s0; 1103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s1; 1113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s2; 1123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s3; 1133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s4; 1143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s5; 1153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s6; 1163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s7; 1173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t8; 1183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register t9; 1193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register k0; 1203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register k1; 1213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register gp; 1223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register sp; 1233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register s8_fp; 1243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const Register ra; 1253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuint ToNumber(Register reg); 1273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuRegister ToRegister(int num); 1293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Coprocessor register. 1313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustruct FPURegister { 1323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool is_valid() const { return 0 <= code_ && code_ < kNumFPURegister ; } 1333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool is(FPURegister creg) const { return code_ == creg.code_; } 1343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int code() const { 1353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(is_valid()); 1363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return code_; 1373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 1383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int bit() const { 1393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(is_valid()); 1403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return 1 << code_; 1413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 1423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Unfortunately we can't make this private in a struct. 1443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int code_; 1453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 1463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister no_creg; 1483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f0; 1503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f1; 1513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f2; 1523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f3; 1533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f4; 1543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f5; 1553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f6; 1563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f7; 1573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f8; 1583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f9; 1593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f10; 1603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f11; 1613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f12; // arg 1623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f13; 1633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f14; // arg 1643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f15; 1653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f16; 1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f17; 1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f18; 1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f19; 1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f20; 1703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f21; 1713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f22; 1723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f23; 1733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f24; 1743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f25; 1753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f26; 1763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f27; 1773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f28; 1783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f29; 1793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f30; 1803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuextern const FPURegister f31; 1813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Returns the equivalent of !cc. 1843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Negation of the default no_condition (-1) results in a non-default 1853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// no_condition value (-2). As long as tests for no_condition check 1863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// for condition < 0, this will work as expected. 1873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuinline Condition NegateCondition(Condition cc); 1883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuinline Condition ReverseCondition(Condition cc) { 1903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu switch (cc) { 1913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case Uless: 1923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Ugreater; 1933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case Ugreater: 1943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Uless; 1953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case Ugreater_equal: 1963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Uless_equal; 1973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case Uless_equal: 1983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Ugreater_equal; 1993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case less: 2003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return greater; 2013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case greater: 2023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return less; 2033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case greater_equal: 2043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return less_equal; 2053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case less_equal: 2063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return greater_equal; 2073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu default: 2083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return cc; 2093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu }; 2103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuenum Hint { 2143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu no_hint = 0 2153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 2163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuinline Hint NegateHint(Hint hint) { 2183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return no_hint; 2193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 2233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Machine instruction Operands. 2243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Class Operand represents a shifter operand in data processing instructions. 2263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuclass Operand BASE_EMBEDDED { 2273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu public: 2283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Immediate. 2293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(explicit Operand(int32_t immediate, 2303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu RelocInfo::Mode rmode = RelocInfo::NONE)); 2313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(explicit Operand(const ExternalReference& f)); 2323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(explicit Operand(const char* s)); 2333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(explicit Operand(Object** opp)); 2343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(explicit Operand(Context** cpp)); 2353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu explicit Operand(Handle<Object> handle); 2363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(explicit Operand(Smi* value)); 2373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Register. 2393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(explicit Operand(Register rm)); 2403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Return true if this is a register operand. 2423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu INLINE(bool is_reg() const); 2433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rm() const { return rm_; } 2453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu private: 2473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rm_; 2483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t imm32_; // Valid if rm_ == no_reg 2493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu RelocInfo::Mode rmode_; 2503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu friend class Assembler; 2523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu friend class MacroAssembler; 2533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 2543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// On MIPS we have only one adressing mode with base_reg + offset. 2573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Class MemOperand represents a memory operand in load and store instructions. 2583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuclass MemOperand : public Operand { 2593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu public: 2603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu explicit MemOperand(Register rn, int16_t offset = 0); 2623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu private: 2643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int16_t offset_; 2653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu friend class Assembler; 2673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 2683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuclass Assembler : public Malloced { 2713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu public: 2723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Create an assembler. Instructions and relocation information are emitted 2733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // into a buffer, with the instructions starting from the beginning and the 2743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // relocation information starting from the end of the buffer. See CodeDesc 2753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // for a detailed comment on the layout (globals.h). 2763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 2773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // If the provided buffer is NULL, the assembler allocates and grows its own 2783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // buffer, and buffer_size determines the initial buffer size. The buffer is 2793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // owned by the assembler and deallocated upon destruction of the assembler. 2803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 2813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // If the provided buffer is not NULL, the assembler uses the provided buffer 2823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // for code generation and assumes its size to be buffer_size. If the buffer 2833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // is too small, a fatal error occurs. No deallocation of the buffer is done 2843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // upon destruction of the assembler. 2853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Assembler(void* buffer, int buffer_size); 2863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ~Assembler(); 2873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // GetCode emits any pending (non-emitted) code and fills the descriptor 2893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // desc. GetCode() is idempotent; it returns the same result if no other 2903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Assembler functions are invoked in between GetCode() calls. 2913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GetCode(CodeDesc* desc); 2923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Label operations & relative jumps (PPUM Appendix D). 2943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 2953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Takes a branch opcode (cc) and a label (L) and generates 2963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // either a backward branch or a forward branch and links it 2973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // to the label fixup chain. Usage: 2983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 2993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Label L; // unbound label 3003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // j(cc, &L); // forward branch to unbound label 3013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // bind(&L); // bind label to the current pc 3023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // j(cc, &L); // backward branch to bound label 3033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // bind(&L); // illegal: a label may be bound only once 3043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // 3053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Note: The same Label can be used for forward and backward branches 3063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // but it may be bound only once. 3073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bind(Label* L); // binds an unbound label L to the current code position 3083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Returns the branch offset to the given label from the current code position 3103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Links the label to the current position if it is still unbound 3113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Manages the jump elimination optimization if the second parameter is true. 3123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t branch_offset(Label* L, bool jump_elimination_allowed); 3133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { 3143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t o = branch_offset(L, jump_elimination_allowed); 3153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT((o & 3) == 0); // Assert the offset is aligned. 3163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return o >> 2; 3173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Puts a labels target address at the given position. 3203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // The high 8 bits are set to zero. 3213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void label_at_put(Label* L, int at_offset); 3223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Size of an instruction. 3243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kInstrSize = sizeof(Instr); 3253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Difference between address of current opcode and target address offset. 3273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kBranchPCOffset = 4; 3283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Read/Modify the code target address in the branch/call instruction at pc. 3303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static Address target_address_at(Address pc); 3313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static void set_target_address_at(Address pc, Address target); 3323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // This sets the branch destination (which gets loaded at the call address). 3343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // This is for calls and branches within generated code. 3353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline static void set_target_at(Address instruction_payload, 3363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Address target) { 3373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu set_target_address_at(instruction_payload, target); 3383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // This sets the branch destination. 3413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // This is for calls and branches to runtime code. 3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline static void set_external_target_at(Address instruction_payload, 3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Address target) { 3443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu set_target_address_at(instruction_payload, target); 3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kCallTargetSize = 3 * kPointerSize; 3483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kExternalTargetSize = 3 * kPointerSize; 3493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Distance between the instruction referring to the address of the call 3513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // target and the return address. 3523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kCallTargetAddressOffset = 4 * kInstrSize; 3533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Distance between start of patched return sequence and the emitted address 3553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // to jump to. 3563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kPatchReturnSequenceAddressOffset = kInstrSize; 3573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // --------------------------------------------------------------------------- 3603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Code generation. 3613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void nop() { sll(zero_reg, zero_reg, 0); } 3633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu //------- Branch and jump instructions -------- 3663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // We don't use likely variant of instructions. 3673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void b(int16_t offset); 3683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void b(Label* L) { b(branch_offset(L, false)>>2); } 3693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bal(int16_t offset); 3703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bal(Label* L) { bal(branch_offset(L, false)>>2); } 3713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void beq(Register rs, Register rt, int16_t offset); 3733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void beq(Register rs, Register rt, Label* L) { 3743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu beq(rs, rt, branch_offset(L, false) >> 2); 3753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bgez(Register rs, int16_t offset); 3773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bgezal(Register rs, int16_t offset); 3783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bgtz(Register rs, int16_t offset); 3793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void blez(Register rs, int16_t offset); 3803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bltz(Register rs, int16_t offset); 3813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bltzal(Register rs, int16_t offset); 3823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bne(Register rs, Register rt, int16_t offset); 3833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bne(Register rs, Register rt, Label* L) { 3843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bne(rs, rt, branch_offset(L, false)>>2); 3853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Never use the int16_t b(l)cond version with a branch offset 3883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // instead of using the Label* version. See Twiki for infos. 3893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Jump targets must be in the current 256 MB-aligned region. ie 28 bits. 3913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void j(int32_t target); 3923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void jal(int32_t target); 3933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void jalr(Register rs, Register rd = ra); 3943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void jr(Register target); 3953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu //-------Data-processing-instructions--------- 3983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Arithmetic. 4003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void add(Register rd, Register rs, Register rt); 4013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void addu(Register rd, Register rs, Register rt); 4023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sub(Register rd, Register rs, Register rt); 4033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void subu(Register rd, Register rs, Register rt); 4043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mult(Register rs, Register rt); 4053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void multu(Register rs, Register rt); 4063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void div(Register rs, Register rt); 4073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void divu(Register rs, Register rt); 4083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mul(Register rd, Register rs, Register rt); 4093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void addi(Register rd, Register rs, int32_t j); 4113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void addiu(Register rd, Register rs, int32_t j); 4123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Logical. 4143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void and_(Register rd, Register rs, Register rt); 4153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void or_(Register rd, Register rs, Register rt); 4163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void xor_(Register rd, Register rs, Register rt); 4173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void nor(Register rd, Register rs, Register rt); 4183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void andi(Register rd, Register rs, int32_t j); 4203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void ori(Register rd, Register rs, int32_t j); 4213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void xori(Register rd, Register rs, int32_t j); 4223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void lui(Register rd, int32_t j); 4233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Shifts. 4253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sll(Register rd, Register rt, uint16_t sa); 4263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sllv(Register rd, Register rt, Register rs); 4273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void srl(Register rd, Register rt, uint16_t sa); 4283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void srlv(Register rd, Register rt, Register rs); 4293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sra(Register rt, Register rd, uint16_t sa); 4303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void srav(Register rt, Register rd, Register rs); 4313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu //------------Memory-instructions------------- 4343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void lb(Register rd, const MemOperand& rs); 4363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void lbu(Register rd, const MemOperand& rs); 4373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void lw(Register rd, const MemOperand& rs); 4383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sb(Register rd, const MemOperand& rs); 4393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sw(Register rd, const MemOperand& rs); 4403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu //-------------Misc-instructions-------------- 4433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Break / Trap instructions. 4453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void break_(uint32_t code); 4463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void tge(Register rs, Register rt, uint16_t code); 4473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void tgeu(Register rs, Register rt, uint16_t code); 4483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void tlt(Register rs, Register rt, uint16_t code); 4493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void tltu(Register rs, Register rt, uint16_t code); 4503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void teq(Register rs, Register rt, uint16_t code); 4513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void tne(Register rs, Register rt, uint16_t code); 4523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Move from HI/LO register. 4543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mfhi(Register rd); 4553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mflo(Register rd); 4563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Set on less than. 4583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void slt(Register rd, Register rs, Register rt); 4593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sltu(Register rd, Register rs, Register rt); 4603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void slti(Register rd, Register rs, int32_t j); 4613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sltiu(Register rd, Register rs, int32_t j); 4623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu //--------Coprocessor-instructions---------------- 4653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Load, store, and move. 4673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void lwc1(FPURegister fd, const MemOperand& src); 4683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void ldc1(FPURegister fd, const MemOperand& src); 4693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void swc1(FPURegister fs, const MemOperand& dst); 4713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void sdc1(FPURegister fs, const MemOperand& dst); 4723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // When paired with MTC1 to write a value to a 64-bit FPR, the MTC1 must be 4743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // executed first, followed by the MTHC1. 4753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mtc1(FPURegister fs, Register rt); 4763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mthc1(FPURegister fs, Register rt); 4773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mfc1(FPURegister fs, Register rt); 4783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void mfhc1(FPURegister fs, Register rt); 4793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Conversion. 4813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_w_s(FPURegister fd, FPURegister fs); 4823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_w_d(FPURegister fd, FPURegister fs); 4833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_l_s(FPURegister fd, FPURegister fs); 4853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_l_d(FPURegister fd, FPURegister fs); 4863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_s_w(FPURegister fd, FPURegister fs); 4883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_s_l(FPURegister fd, FPURegister fs); 4893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_s_d(FPURegister fd, FPURegister fs); 4903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_d_w(FPURegister fd, FPURegister fs); 4923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_d_l(FPURegister fd, FPURegister fs); 4933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void cvt_d_s(FPURegister fd, FPURegister fs); 4943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Conditions and branches. 4963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void c(FPUCondition cond, SecondaryField fmt, 4973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister ft, FPURegister fs, uint16_t cc = 0); 4983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bc1f(int16_t offset, uint16_t cc = 0); 5003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bc1f(Label* L, uint16_t cc = 0) { bc1f(branch_offset(L, false)>>2, cc); } 5013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bc1t(int16_t offset, uint16_t cc = 0); 5023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bc1t(Label* L, uint16_t cc = 0) { bc1t(branch_offset(L, false)>>2, cc); } 5033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Check the code size generated from label to here. 5063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int InstructionsGeneratedSince(Label* l) { 5073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return (pc_offset() - l->pos()) / kInstrSize; 5083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 5093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Debugging. 5113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Mark address of the ExitJSFrame code. 5133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void RecordJSReturn(); 5143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Record a comment relocation entry that can be used by a disassembler. 5163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Use --debug_code to enable. 5173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void RecordComment(const char* msg); 5183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void RecordPosition(int pos); 5203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void RecordStatementPosition(int pos); 5213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void WriteRecordedPositions(); 5223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t pc_offset() const { return pc_ - buffer_; } 5243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t current_position() const { return current_position_; } 5256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int32_t current_statement_position() const { 5266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return current_statement_position_; 5276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Check if there is less than kGap bytes available in the buffer. 5303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // If this is the case, we need to grow the buffer before emitting 5313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // an instruction or relocation information. 5323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; } 5333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Get the number of bytes available in the buffer. 5353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int available_space() const { return reloc_info_writer.pos() - pc_; } 5363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu protected: 5383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } 5393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Read/patch instructions. 5413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 5423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void instr_at_put(byte* pc, Instr instr) { 5433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu *reinterpret_cast<Instr*>(pc) = instr; 5443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 5453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 5463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void instr_at_put(int pos, Instr instr) { 5473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 5483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 5493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Check if an instruction is a branch of some kind. 5513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool is_branch(Instr instr); 5523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Decode branch instruction at pos and return branch target pos. 5543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int target_at(int32_t pos); 5553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Patch branch instruction at pos to branch to given branch target pos. 5573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void target_at_put(int32_t pos, int32_t target_pos); 5583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Say if we need to relocate with this mode. 5603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool MustUseAt(RelocInfo::Mode rmode); 5613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Record reloc info for current pc_. 5633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 5643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu private: 5663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Code buffer: 5673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // The buffer into which code and relocation info are generated. 5683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu byte* buffer_; 5693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int buffer_size_; 5703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // True if the assembler owns the buffer, false if buffer is external. 5713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu bool own_buffer_; 5723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Buffer size and constant pool distance are checked together at regular 5743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // intervals of kBufferCheckInterval emitted bytes. 5753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kBufferCheckInterval = 1*KB/2; 5763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Code generation. 5783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // The relocation writer's position is at least kGap bytes below the end of 5793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // the generated instructions. This is so that multi-instruction sequences do 5803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // not have to check for overflow. The same is true for writes of large 5813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // relocation info entries. 5823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kGap = 32; 5833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu byte* pc_; // The program counter - moves forward. 5843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Relocation information generation. 5863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Each relocation is encoded as a variable size value. 5873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 5883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu RelocInfoWriter reloc_info_writer; 5893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // The bound position, before this we cannot do instruction elimination. 5913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int last_bound_pos_; 5923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Source position information. 5943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int current_position_; 5953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int current_statement_position_; 5963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int written_position_; 5973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int written_statement_position_; 5983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Code emission. 6003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline void CheckBuffer(); 6013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GrowBuffer(); 6023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline void emit(Instr x); 6033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Instruction generation. 6053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // We have 3 different kind of encoding layout on MIPS. 6063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // However due to many different types of objects encoded in the same fields 6073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // we have quite a few aliases for each mode. 6083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Using the same structure to refer to Register and FPURegister would spare a 6093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // few aliases, but mixing both does not look clean to me. 6103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Anyway we could surely implement this differently. 6113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GenInstrRegister(Opcode opcode, 6133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rs, 6143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rt, 6153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rd, 6163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu uint16_t sa = 0, 6173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField func = NULLSF); 6183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GenInstrRegister(Opcode opcode, 6203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField fmt, 6213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister ft, 6223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fs, 6233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fd, 6243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField func = NULLSF); 6253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GenInstrRegister(Opcode opcode, 6273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField fmt, 6283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rt, 6293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fs, 6303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister fd, 6313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField func = NULLSF); 6323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GenInstrImmediate(Opcode opcode, 6353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rs, 6363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rt, 6373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t j); 6383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GenInstrImmediate(Opcode opcode, 6393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register rs, 6403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SecondaryField SF, 6413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t j); 6423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GenInstrImmediate(Opcode opcode, 6433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Register r1, 6443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FPURegister r2, 6453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int32_t j); 6463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void GenInstrJump(Opcode opcode, 6493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu uint32_t address); 6503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Labels. 6533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void print(Label* L); 6543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void bind_to(Label* L, int pos); 6553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void link_to(Label* L, Label* appendix); 6563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void next(Label* L); 6573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu friend class RegExpMacroAssemblerMIPS; 6593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu friend class RelocInfo; 6603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 6613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} } // namespace v8::internal 6633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#endif // V8_ARM_ASSEMBLER_MIPS_H_ 6653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 666